|
2 | 2 |
|
3 | 3 | namespace PHPStan\Type;
|
4 | 4 |
|
| 5 | +use PhpParser\Node\Identifier; |
| 6 | +use PhpParser\Node\Name\FullyQualified; |
| 7 | +use PHPStan\BetterReflection\Reflection\Adapter\ReflectionIntersectionType; |
| 8 | +use PHPStan\BetterReflection\Reflection\Adapter\ReflectionNamedType; |
| 9 | +use PHPStan\BetterReflection\Reflection\Adapter\ReflectionUnionType; |
5 | 10 | use PHPStan\Reflection\ClassReflection;
|
6 | 11 | use PHPStan\Reflection\ReflectionProviderStaticAccessor;
|
7 | 12 | use PHPStan\ShouldNotHappenException;
|
8 |
| -use PHPStan\Type\Constant\ConstantBooleanType; |
9 | 13 | use PHPStan\Type\Generic\TemplateTypeHelper;
|
10 |
| -use ReflectionIntersectionType; |
11 |
| -use ReflectionNamedType; |
12 | 14 | use ReflectionType;
|
13 |
| -use ReflectionUnionType; |
14 | 15 | use function array_map;
|
15 | 16 | use function count;
|
16 | 17 | use function get_class;
|
17 | 18 | use function is_string;
|
18 | 19 | use function sprintf;
|
19 |
| -use function strtolower; |
20 | 20 |
|
21 | 21 | class TypehintHelper
|
22 | 22 | {
|
23 | 23 |
|
24 |
| - private static function getTypeObjectFromTypehint(string $typeString, ClassReflection|string|null $selfClass): Type |
25 |
| - { |
26 |
| - switch (strtolower($typeString)) { |
27 |
| - case 'int': |
28 |
| - return new IntegerType(); |
29 |
| - case 'bool': |
30 |
| - return new BooleanType(); |
31 |
| - case 'false': |
32 |
| - return new ConstantBooleanType(false); |
33 |
| - case 'true': |
34 |
| - return new ConstantBooleanType(true); |
35 |
| - case 'string': |
36 |
| - return new StringType(); |
37 |
| - case 'float': |
38 |
| - return new FloatType(); |
39 |
| - case 'array': |
40 |
| - return new ArrayType(new MixedType(), new MixedType()); |
41 |
| - case 'iterable': |
42 |
| - return new IterableType(new MixedType(), new MixedType()); |
43 |
| - case 'callable': |
44 |
| - return new CallableType(); |
45 |
| - case 'void': |
46 |
| - return new VoidType(); |
47 |
| - case 'object': |
48 |
| - return new ObjectWithoutClassType(); |
49 |
| - case 'mixed': |
50 |
| - return new MixedType(true); |
51 |
| - case 'self': |
52 |
| - if ($selfClass instanceof ClassReflection) { |
53 |
| - $selfClass = $selfClass->getName(); |
54 |
| - } |
55 |
| - return $selfClass !== null ? new ObjectType($selfClass) : new ErrorType(); |
56 |
| - case 'parent': |
57 |
| - $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); |
58 |
| - if (is_string($selfClass)) { |
59 |
| - if ($reflectionProvider->hasClass($selfClass)) { |
60 |
| - $selfClass = $reflectionProvider->getClass($selfClass); |
61 |
| - } else { |
62 |
| - $selfClass = null; |
63 |
| - } |
64 |
| - } |
65 |
| - if ($selfClass !== null) { |
66 |
| - if ($selfClass->getParentClass() !== null) { |
67 |
| - return new ObjectType($selfClass->getParentClass()->getName()); |
68 |
| - } |
69 |
| - } |
70 |
| - return new NonexistentParentClassType(); |
71 |
| - case 'static': |
72 |
| - $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); |
73 |
| - if (is_string($selfClass)) { |
74 |
| - if ($reflectionProvider->hasClass($selfClass)) { |
75 |
| - $selfClass = $reflectionProvider->getClass($selfClass); |
76 |
| - } else { |
77 |
| - $selfClass = null; |
78 |
| - } |
79 |
| - } |
80 |
| - if ($selfClass !== null) { |
81 |
| - return new StaticType($selfClass); |
82 |
| - } |
83 |
| - |
84 |
| - return new ErrorType(); |
85 |
| - case 'null': |
86 |
| - return new NullType(); |
87 |
| - case 'never': |
88 |
| - return new NonAcceptingNeverType(); |
89 |
| - default: |
90 |
| - return new ObjectType($typeString); |
91 |
| - } |
92 |
| - } |
93 |
| - |
94 | 24 | /** @api */
|
95 | 25 | public static function decideTypeFromReflection(
|
96 | 26 | ?ReflectionType $reflectionType,
|
@@ -130,9 +60,21 @@ public static function decideTypeFromReflection(
|
130 | 60 | throw new ShouldNotHappenException(sprintf('Unexpected type: %s', get_class($reflectionType)));
|
131 | 61 | }
|
132 | 62 |
|
133 |
| - $reflectionTypeString = $reflectionType->getName(); |
| 63 | + if ($reflectionType->isIdentifier()) { |
| 64 | + $typeNode = new Identifier($reflectionType->getName()); |
| 65 | + } else { |
| 66 | + $typeNode = new FullyQualified($reflectionType->getName()); |
| 67 | + } |
134 | 68 |
|
135 |
| - $type = self::getTypeObjectFromTypehint($reflectionTypeString, $selfClass); |
| 69 | + if (is_string($selfClass)) { |
| 70 | + $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); |
| 71 | + if ($reflectionProvider->hasClass($selfClass)) { |
| 72 | + $selfClass = $reflectionProvider->getClass($selfClass); |
| 73 | + } else { |
| 74 | + $selfClass = null; |
| 75 | + } |
| 76 | + } |
| 77 | + $type = ParserNodeTypeToPHPStanType::resolve($typeNode, $selfClass); |
136 | 78 | if ($reflectionType->allowsNull()) {
|
137 | 79 | $type = TypeCombinator::addNull($type);
|
138 | 80 | } elseif ($phpDocType !== null) {
|
|
0 commit comments