|
15 | 15 | use PHPStan\Reflection\FunctionReflection; |
16 | 16 | use PHPStan\Rules\Properties\PropertyReflectionFinder; |
17 | 17 | use PHPStan\Type\Accessory\HasPropertyType; |
| 18 | +use PHPStan\Type\ClassStringType; |
18 | 19 | use PHPStan\Type\Constant\ConstantBooleanType; |
19 | 20 | use PHPStan\Type\Constant\ConstantStringType; |
20 | 21 | use PHPStan\Type\FunctionTypeSpecifyingExtension; |
21 | 22 | use PHPStan\Type\IntersectionType; |
22 | 23 | use PHPStan\Type\ObjectWithoutClassType; |
| 24 | +use PHPStan\Type\UnionType; |
23 | 25 | use function count; |
24 | 26 |
|
25 | 27 | #[AutowiredService] |
@@ -71,17 +73,35 @@ public function specifyTypes( |
71 | 73 | } |
72 | 74 |
|
73 | 75 | $objectType = $scope->getType($args[0]->value); |
74 | | - if ($objectType instanceof ConstantStringType) { |
75 | | - return new SpecifiedTypes([], []); |
76 | | - } elseif ($objectType->isObject()->yes()) { |
77 | | - $propertyNode = new PropertyFetch( |
| 76 | + if ($objectType->isString()->yes()) { |
| 77 | + return $this->typeSpecifier->create( |
| 78 | + new FuncCall(new FullyQualified('property_exists'), $node->getRawArgs()), |
| 79 | + new ConstantBooleanType(true), |
| 80 | + $context, |
| 81 | + $scope, |
| 82 | + ); |
| 83 | + } |
| 84 | + |
| 85 | + if (!$objectType->isObject()->yes()) { |
| 86 | + return $this->typeSpecifier->create( |
78 | 87 | $args[0]->value, |
79 | | - new Identifier($propertyNameType->getValue()), |
| 88 | + new UnionType([ |
| 89 | + new IntersectionType([ |
| 90 | + new ObjectWithoutClassType(), |
| 91 | + new HasPropertyType($propertyNameType->getValue()), |
| 92 | + ]), |
| 93 | + new ClassStringType(), |
| 94 | + ]), |
| 95 | + $context, |
| 96 | + $scope, |
80 | 97 | ); |
81 | | - } else { |
82 | | - return new SpecifiedTypes([], []); |
83 | 98 | } |
84 | 99 |
|
| 100 | + $propertyNode = new PropertyFetch( |
| 101 | + $args[0]->value, |
| 102 | + new Identifier($propertyNameType->getValue()), |
| 103 | + ); |
| 104 | + |
85 | 105 | $propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($propertyNode, $scope); |
86 | 106 | if ($propertyReflection !== null) { |
87 | 107 | if (!$propertyReflection->isNative()) { |
|
0 commit comments