|
15 | 15 | use PHPStan\Type\ClassStringType; |
16 | 16 | use PHPStan\Type\Constant\ConstantBooleanType; |
17 | 17 | use PHPStan\Type\FunctionTypeSpecifyingExtension; |
18 | | -use PHPStan\Type\IntersectionType; |
19 | 18 | use PHPStan\Type\ObjectWithoutClassType; |
20 | 19 | use PHPStan\Type\TypeCombinator; |
21 | | -use PHPStan\Type\UnionType; |
22 | 20 | use function count; |
23 | 21 |
|
24 | 22 | #[AutowiredService] |
@@ -50,53 +48,57 @@ public function specifyTypes( |
50 | 48 | TypeSpecifierContext $context, |
51 | 49 | ): SpecifiedTypes |
52 | 50 | { |
| 51 | + $specifiedTypes = $this->typeSpecifier->create( |
| 52 | + new FuncCall(new FullyQualified('method_exists'), $node->getRawArgs()), |
| 53 | + new ConstantBooleanType(true), |
| 54 | + $context, |
| 55 | + $scope, |
| 56 | + ); |
| 57 | + |
53 | 58 | $methodNameTypes = $scope->getType($node->getArgs()[1]->value)->getConstantStrings(); |
54 | 59 | if ($methodNameTypes === []) { |
55 | | - return $this->typeSpecifier->create( |
56 | | - new FuncCall(new FullyQualified('method_exists'), $node->getRawArgs()), |
57 | | - new ConstantBooleanType(true), |
58 | | - $context, |
59 | | - $scope, |
60 | | - ); |
| 60 | + return $specifiedTypes; |
61 | 61 | } |
62 | 62 |
|
63 | | - $specifiedTypes = new SpecifiedTypes([], []); |
64 | | - |
65 | 63 | $objectType = $scope->getType($node->getArgs()[0]->value); |
66 | 64 | if ($objectType->isString()->yes()) { |
67 | 65 | if ($objectType->isClassString()->yes()) { |
| 66 | + $types = []; |
68 | 67 | foreach ($methodNameTypes as $methodNameType) { |
69 | | - $specifiedTypes = $specifiedTypes->unionWith($this->typeSpecifier->create( |
70 | | - $node->getArgs()[0]->value, |
71 | | - TypeCombinator::intersect( |
72 | | - $objectType, |
73 | | - new HasMethodType($methodNameType->getValue()), |
74 | | - ), |
75 | | - $context, |
76 | | - $scope, |
77 | | - )); |
| 68 | + $types[] = TypeCombinator::intersect( |
| 69 | + $objectType, |
| 70 | + new HasMethodType($methodNameType->getValue()), |
| 71 | + ); |
78 | 72 | } |
| 73 | + |
| 74 | + return $specifiedTypes->unionWith($this->typeSpecifier->create( |
| 75 | + $node->getArgs()[0]->value, |
| 76 | + TypeCombinator::union(...$types), |
| 77 | + $context, |
| 78 | + $scope, |
| 79 | + )); |
79 | 80 | } |
80 | 81 |
|
81 | 82 | return $specifiedTypes; |
82 | 83 | } |
83 | 84 |
|
| 85 | + $types = []; |
84 | 86 | foreach ($methodNameTypes as $methodNameType) { |
85 | | - $specifiedTypes = $specifiedTypes->unionWith($this->typeSpecifier->create( |
86 | | - $node->getArgs()[0]->value, |
87 | | - TypeCombinator::union( |
88 | | - TypeCombinator::intersect( |
89 | | - new ObjectWithoutClassType(), |
90 | | - new HasMethodType($methodNameType->getValue()), |
91 | | - ), |
92 | | - new ClassStringType(), |
| 87 | + $types[] = TypeCombinator::union( |
| 88 | + TypeCombinator::intersect( |
| 89 | + new ObjectWithoutClassType(), |
| 90 | + new HasMethodType($methodNameType->getValue()), |
93 | 91 | ), |
94 | | - $context, |
95 | | - $scope, |
96 | | - )); |
| 92 | + new ClassStringType(), |
| 93 | + ); |
97 | 94 | } |
98 | 95 |
|
99 | | - return $specifiedTypes; |
| 96 | + return $specifiedTypes->unionWith($this->typeSpecifier->create( |
| 97 | + $node->getArgs()[0]->value, |
| 98 | + TypeCombinator::union(...$types), |
| 99 | + $context, |
| 100 | + $scope, |
| 101 | + )); |
100 | 102 | } |
101 | 103 |
|
102 | 104 | } |
0 commit comments