From d02f4076ed2f368cbd3f491f1f4162eaaaaba06e Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Fri, 27 Feb 2026 23:50:56 +0700 Subject: [PATCH 1/2] [CodeQuality] Skip used by other property hooks on InlineConstructorDefaultToPropertyRector --- .../skip_used_by_property_hook.php.inc | 33 ++++++++++++++++++ ...lineConstructorDefaultToPropertyRector.php | 34 +++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Fixture/skip_used_by_property_hook.php.inc 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..343c8360738 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 = $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 instanceof Node) { + 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; From 0d3caab8db91f58e0c3feb57f5036f8692791a70 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Fri, 27 Feb 2026 23:53:09 +0700 Subject: [PATCH 2/2] [CodeQuality] Skip used by other property hooks on InlineConstructorDefaultToPropertyRector --- .../Class_/InlineConstructorDefaultToPropertyRector.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rules/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector.php b/rules/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector.php index 343c8360738..4db91e566e5 100644 --- a/rules/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector.php +++ b/rules/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector.php @@ -161,7 +161,7 @@ private function isFoundInAnyPropertyHooks(Class_ $class, string $propertyName): continue; } - $isFoundInPropertyAnyHooks = $this->betterNodeFinder->findFirst($property->hooks, function (Node $subNode) use ( + $isFoundInPropertyAnyHooks = (bool) $this->betterNodeFinder->findFirst($property->hooks, function (Node $subNode) use ( $class, $propertyName ): bool { @@ -172,7 +172,7 @@ private function isFoundInAnyPropertyHooks(Class_ $class, string $propertyName): return $this->propertyFetchFinder->isLocalPropertyFetchByName($subNode, $class, $propertyName); }); - if ($isFoundInPropertyAnyHooks instanceof Node) { + if ($isFoundInPropertyAnyHooks) { return true; } }