• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

donatj / php-dnf-solver / 6565093245

18 Oct 2023 06:32PM UTC coverage: 98.347% (-1.7%) from 100.0%
6565093245

push

github

web-flow
Merge pull request #6 from donatj/fix/phpstan

Add phpstan CI step

13 of 13 new or added lines in 2 files covered. (100.0%)

119 of 121 relevant lines covered (98.35%)

11.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.12
/src/DNF.php
1
<?php
2

3
namespace donatj\PhpDnfSolver;
4

5
use donatj\PhpDnfSolver\Exceptions\InvalidArgumentException;
6
use donatj\PhpDnfSolver\Exceptions\LogicException;
7
use donatj\PhpDnfSolver\Types\AndClause;
8
use donatj\PhpDnfSolver\Types\OrClause;
9

10
class DNF {
11

12
        /**
13
         * Helper to convert a ReflectionType into it's DNF representation
14
         *
15
         * Example sources include:
16
         * - ReflectionFunctionAbstract::getParameters()[…]->getType()
17
         * - ReflectionParameter::getType()
18
         * - ReflectionMethod::getReturnType()
19
         * - ReflectionProperty::getType()
20
         */
21
        public static function getFromReflectionType( \ReflectionType $type ) : SingularDnfTypeInterface|NestedDnfTypeInterface {
22
                if( $type instanceof \ReflectionNamedType ) {
27✔
23
                        if( $type->isBuiltin() ) {
26✔
24
                                if( $type->getName() === 'callable' ) {
19✔
25
                                        return new Types\CallableType;
7✔
26
                                }
27

28
                                $dnfType = new Types\BuiltInType($type->getName());
13✔
29
                                if( $type->getName() === 'mixed' ) {
13✔
30
                                        return $dnfType;
4✔
31
                                }
32
                        } else {
33
                                // @phpstan-ignore-next-line
34
                                $dnfType = new Types\UserDefinedType($type->getName());
20✔
35
                        }
36

37
                        if( $type->allowsNull() && $type->getName() !== 'null' ) {
25✔
38
                                return new OrClause($dnfType, new Types\BuiltInType('null'));
2✔
39
                        }
40

41
                        return $dnfType;
25✔
42
                }
43

44
                if( $type instanceof \ReflectionIntersectionType ) {
16✔
45
                        $types = array_map(
12✔
46
                                function ( \ReflectionType $type ) : SingularDnfTypeInterface {
12✔
47
                                        $reflectionType = self::getFromReflectionType($type);
12✔
48
                                        if( !$reflectionType instanceof SingularDnfTypeInterface ) {
12✔
49
                                                throw new LogicException('Intersection types must be singular');
×
50
                                        }
51

52
                                        return $reflectionType;
12✔
53
                                },
12✔
54
                                $type->getTypes()
12✔
55
                        );
12✔
56

57
                        return new Types\AndClause(...$types);
12✔
58
                }
59

60
                if( $type instanceof \ReflectionUnionType ) {
13✔
61
                        $types = array_map(
12✔
62
                                function ( \ReflectionType $type ) : SingularDnfTypeInterface|AndClause {
12✔
63
                                        $reflectionType = self::getFromReflectionType($type);
12✔
64
                                        if( (!$reflectionType instanceof SingularDnfTypeInterface) && (!$reflectionType instanceof AndClause) ) {
12✔
65
                                                throw new LogicException('Intersection types must be singular');
×
66
                                        }
67

68
                                        return $reflectionType;
12✔
69
                                },
12✔
70
                                $type->getTypes()
12✔
71
                        );
12✔
72

73
                        return new Types\OrClause(...$types);
12✔
74
                }
75

76
                throw new InvalidArgumentException('Unknown ReflectionType: ' . get_class($type));
1✔
77
        }
78

79
        /**
80
         * Helper to quickly check if a ReflectionType satisfies another ReflectionType
81
         *
82
         * @param \ReflectionType $satisfyingType The type which must be satisfied (e.g. a parameter type)
83
         * @param \ReflectionType $satisfiedType  The type which must satisfy the other (e.g. a return type)
84
         */
85
        public static function reflectionTypeSatisfiesReflectionType(
86
                \ReflectionType $satisfyingType,
87
                \ReflectionType $satisfiedType
88
        ) : bool {
89
                $satisfyingDnf = self::getFromReflectionType($satisfyingType);
22✔
90
                $satisfiedDnf  = self::getFromReflectionType($satisfiedType);
22✔
91

92
                return $satisfyingDnf->isSatisfiedBy($satisfiedDnf);
22✔
93
        }
94

95
        /**
96
         * Helper to quickly get a DNF representation of a (ReflectionParameter or ReflectionProperty)'s return type
97
         */
98
        public static function getFromVarType(
99
                \ReflectionParameter|\ReflectionProperty $parameter
100
        ) : SingularDnfTypeInterface|NestedDnfTypeInterface|null {
101
                $type = $parameter->getType();
1✔
102

103
                return $type ? self::getFromReflectionType($type) : null;
1✔
104
        }
105

106
        /**
107
         * Helper to quickly get a DNF representation of a ReflectionFunctionAbstract (ReflectionFunction /
108
         * ReflectionMethod)'s return type
109
         */
110
        public static function getFromReturnType(
111
                \ReflectionFunctionAbstract $func
112
        ) : SingularDnfTypeInterface|NestedDnfTypeInterface|null {
113
                $type = $func->getReturnType();
1✔
114

115
                return $type ? self::getFromReflectionType($type) : null;
1✔
116
        }
117

118
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc