|
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