diff --git a/rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Fixture/skip_used_by_property_hook.php.inc b/rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Fixture/skip_used_by_property_hook.php.inc new file mode 100644 index 00000000000..783394091b7 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Fixture/skip_used_by_property_hook.php.inc @@ -0,0 +1,33 @@ +value; + } + set { + if (!$this->isConstructed) { + $this->value = $value; + return; + } + + if (!is_string($value)) { + throw new \TypeError('$value must be a string when it is already constructed!'); + } + + $this->value = $value; + } + } + + public function __construct( + mixed $value = null, + ) { + $this->value = $value; + $this->isConstructed = true; + } +} diff --git a/rules/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector.php b/rules/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector.php index 92ef0bafc8c..4db91e566e5 100644 --- a/rules/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector.php +++ b/rules/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector.php @@ -15,6 +15,8 @@ use PhpParser\Node\Stmt\Property; use Rector\NodeAnalyzer\ExprAnalyzer; use Rector\NodeTypeResolver\Node\AttributeKey; +use Rector\PhpParser\Node\BetterNodeFinder; +use Rector\PhpParser\NodeFinder\PropertyFetchFinder; use Rector\Rector\AbstractRector; use Rector\ValueObject\MethodName; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; @@ -27,6 +29,8 @@ final class InlineConstructorDefaultToPropertyRector extends AbstractRector { public function __construct( private readonly ExprAnalyzer $exprAnalyzer, + private readonly BetterNodeFinder $betterNodeFinder, + private readonly PropertyFetchFinder $propertyFetchFinder ) { } @@ -150,6 +154,32 @@ private function matchAssignedLocalPropertyName(Assign $assign): ?string return $propertyName; } + private function isFoundInAnyPropertyHooks(Class_ $class, string $propertyName): bool + { + foreach ($class->getProperties() as $property) { + if ($property->hooks === []) { + continue; + } + + $isFoundInPropertyAnyHooks = (bool) $this->betterNodeFinder->findFirst($property->hooks, function (Node $subNode) use ( + $class, + $propertyName + ): bool { + if (! $subNode instanceof PropertyFetch) { + return false; + } + + return $this->propertyFetchFinder->isLocalPropertyFetchByName($subNode, $class, $propertyName); + }); + + if ($isFoundInPropertyAnyHooks) { + return true; + } + } + + return false; + } + private function refactorProperty( Class_ $class, string $propertyName, @@ -161,6 +191,10 @@ private function refactorProperty( return false; } + if ($this->isFoundInAnyPropertyHooks($class, $propertyName)) { + return false; + } + foreach ($class->stmts as $classStmt) { if (! $classStmt instanceof Property) { continue;