|
5 | 5 | use PhpParser\Node;
|
6 | 6 | use PHPStan\Analyser\Scope;
|
7 | 7 | use PHPStan\Rules\IdentifierRuleError;
|
| 8 | +use PHPStan\Rules\Properties\PropertyReflectionFinder; |
8 | 9 | use PHPStan\Rules\Rule;
|
9 | 10 | use PHPStan\Rules\RuleErrorBuilder;
|
10 | 11 | use PHPStan\Type\VerbosityLevel;
|
|
17 | 18 | final class UnsetRule implements Rule
|
18 | 19 | {
|
19 | 20 |
|
| 21 | + public function __construct( |
| 22 | + private PropertyReflectionFinder $propertyReflectionFinder, |
| 23 | + ) |
| 24 | + { |
| 25 | + } |
| 26 | + |
20 | 27 | public function getNodeType(): string
|
21 | 28 | {
|
22 | 29 | return Node\Stmt\Unset_::class;
|
@@ -73,26 +80,30 @@ private function canBeUnset(Node $node, Scope $scope): ?IdentifierRuleError
|
73 | 80 | $node instanceof Node\Expr\PropertyFetch
|
74 | 81 | && $node->name instanceof Node\Identifier
|
75 | 82 | ) {
|
76 |
| - $type = $scope->getType($node->var); |
77 |
| - foreach ($type->getObjectClassReflections() as $classReflection) { |
78 |
| - if (!$classReflection->hasNativeProperty($node->name->name)) { |
79 |
| - continue; |
80 |
| - } |
81 |
| - |
82 |
| - $propertyReflection = $classReflection->getNativeProperty($node->name->name); |
83 |
| - if ($propertyReflection->isReadOnly() || $propertyReflection->isReadOnlyByPhpDoc()) { |
84 |
| - return RuleErrorBuilder::message( |
85 |
| - sprintf( |
86 |
| - 'Cannot unset %s property %s of %s.', |
87 |
| - $propertyReflection->isReadOnly() ? 'readonly' : '@readonly', |
88 |
| - $node->name->name, |
89 |
| - $type->describe(VerbosityLevel::value()), |
90 |
| - ), |
91 |
| - ) |
92 |
| - ->line($node->getStartLine()) |
93 |
| - ->identifier($propertyReflection->isReadOnly() ? 'unset.readOnlyProperty' : 'unset.readOnlyPropertyByPhpDoc') |
94 |
| - ->build(); |
95 |
| - } |
| 83 | + $foundPropertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($node, $scope); |
| 84 | + if ($foundPropertyReflection === null) { |
| 85 | + return null; |
| 86 | + } |
| 87 | + |
| 88 | + $propertyReflection = $foundPropertyReflection->getNativeReflection(); |
| 89 | + if ($propertyReflection === null) { |
| 90 | + return null; |
| 91 | + } |
| 92 | + |
| 93 | + if ($propertyReflection->isReadOnly() || $propertyReflection->isReadOnlyByPhpDoc()) { |
| 94 | + $type = $scope->getType($node->var); |
| 95 | + |
| 96 | + return RuleErrorBuilder::message( |
| 97 | + sprintf( |
| 98 | + 'Cannot unset %s property %s of %s.', |
| 99 | + $propertyReflection->isReadOnly() ? 'readonly' : '@readonly', |
| 100 | + $node->name->name, |
| 101 | + $type->describe(VerbosityLevel::value()), |
| 102 | + ), |
| 103 | + ) |
| 104 | + ->line($node->getStartLine()) |
| 105 | + ->identifier($propertyReflection->isReadOnly() ? 'unset.readOnlyProperty' : 'unset.readOnlyPropertyByPhpDoc') |
| 106 | + ->build(); |
96 | 107 | }
|
97 | 108 | }
|
98 | 109 |
|
|
0 commit comments