|
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