|
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] |
@@ -66,17 +68,35 @@ public function specifyTypes( |
66 | 68 | } |
67 | 69 |
|
68 | 70 | $objectType = $scope->getType($args[0]->value); |
69 | | - if ($objectType instanceof ConstantStringType) { |
70 | | - return new SpecifiedTypes([], []); |
71 | | - } elseif ($objectType->isObject()->yes()) { |
72 | | - $propertyNode = new PropertyFetch( |
| 71 | + if ($objectType->isString()->yes()) { |
| 72 | + return $this->typeSpecifier->create( |
| 73 | + new FuncCall(new FullyQualified('property_exists'), $node->getRawArgs()), |
| 74 | + new ConstantBooleanType(true), |
| 75 | + $context, |
| 76 | + $scope, |
| 77 | + ); |
| 78 | + } |
| 79 | + |
| 80 | + if (!$objectType->isObject()->yes()) { |
| 81 | + return $this->typeSpecifier->create( |
73 | 82 | $args[0]->value, |
74 | | - new Identifier($propertyNameType->getValue()), |
| 83 | + new UnionType([ |
| 84 | + new IntersectionType([ |
| 85 | + new ObjectWithoutClassType(), |
| 86 | + new HasPropertyType($propertyNameType->getValue()), |
| 87 | + ]), |
| 88 | + new ClassStringType(), |
| 89 | + ]), |
| 90 | + $context, |
| 91 | + $scope, |
75 | 92 | ); |
76 | | - } else { |
77 | | - return new SpecifiedTypes([], []); |
78 | 93 | } |
79 | 94 |
|
| 95 | + $propertyNode = new PropertyFetch( |
| 96 | + $args[0]->value, |
| 97 | + new Identifier($propertyNameType->getValue()), |
| 98 | + ); |
| 99 | + |
80 | 100 | $propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($propertyNode, $scope); |
81 | 101 | if ($propertyReflection !== null) { |
82 | 102 | if (!$propertyReflection->isNative()) { |
|
0 commit comments