From 3ceeb47c4a31c54467817133a98fba38d5981421 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Mon, 24 Nov 2025 22:57:46 +0700 Subject: [PATCH 1/4] [internal] Add LeaveNodeAbstract for move duplicated code of leaveNode() method --- .../NodeVisitor/CallableNodeVisitor.php | 30 ++----------- .../NodeTraverser/AbstractLeaveNode.php | 45 +++++++++++++++++++ src/Rector/AbstractRector.php | 35 +-------------- 3 files changed, 50 insertions(+), 60 deletions(-) create mode 100644 src/PhpParser/NodeTraverser/AbstractLeaveNode.php diff --git a/src/PhpDocParser/NodeVisitor/CallableNodeVisitor.php b/src/PhpDocParser/NodeVisitor/CallableNodeVisitor.php index bcb70edeecd..e7eb7b7a629 100644 --- a/src/PhpDocParser/NodeVisitor/CallableNodeVisitor.php +++ b/src/PhpDocParser/NodeVisitor/CallableNodeVisitor.php @@ -9,22 +9,15 @@ use PhpParser\Node\Stmt; use PhpParser\Node\Stmt\Expression; use PhpParser\NodeVisitor; -use PhpParser\NodeVisitorAbstract; +use Rector\PhpParser\NodeTraverser\AbstractLeaveNode; -final class CallableNodeVisitor extends NodeVisitorAbstract +final class CallableNodeVisitor extends AbstractLeaveNode { /** * @var callable(Node): (int|Node|null|Node[]) */ private $callable; - private ?int $nodeIdToRemove = null; - - /** - * @var array - */ - private array $nodesToReturn = []; - /** * @param callable(Node $node): (int|Node|null|Node[]) $callable */ @@ -43,7 +36,7 @@ public function enterNode(Node $node): int|Node|null $newNode = $callable($node); if ($newNode === NodeVisitor::REMOVE_NODE) { - $this->nodeIdToRemove = spl_object_id($originalNode); + $this->toBeRemovedNodeId = spl_object_id($originalNode); return $originalNode; } @@ -60,21 +53,4 @@ public function enterNode(Node $node): int|Node|null return $newNode; } - - /** - * @return int|Node|Node[] - */ - public function leaveNode(Node $node): int|Node|array - { - if ($this->nodeIdToRemove !== null && $this->nodeIdToRemove === spl_object_id($node)) { - $this->nodeIdToRemove = null; - return NodeVisitor::REMOVE_NODE; - } - - if ($this->nodesToReturn === []) { - return $node; - } - - return $this->nodesToReturn[spl_object_id($node)] ?? $node; - } } diff --git a/src/PhpParser/NodeTraverser/AbstractLeaveNode.php b/src/PhpParser/NodeTraverser/AbstractLeaveNode.php new file mode 100644 index 00000000000..cc17d60e9c5 --- /dev/null +++ b/src/PhpParser/NodeTraverser/AbstractLeaveNode.php @@ -0,0 +1,45 @@ + + */ + protected array $nodesToReturn = []; + + /** + * Replacing nodes in leaveNode() method avoids infinite recursion + * see"infinite recursion" in https://github.com/nikic/PHP-Parser/blob/master/doc/component/Walking_the_AST.markdown + * + * @return NodeVisitor::REMOVE_NODE|Node|null|Node[] + */ + final public function leaveNode(Node $node): int|Node|null|array + { + // nothing to change here + if ($this->toBeRemovedNodeId === null && $this->nodesToReturn === []) { + return null; + } + + $objectId = spl_object_id($node); + if ($this->toBeRemovedNodeId === $objectId) { + $this->toBeRemovedNodeId = null; + + return NodeVisitor::REMOVE_NODE; + } + + return $this->nodesToReturn[$objectId] ?? $node; + } +} \ No newline at end of file diff --git a/src/Rector/AbstractRector.php b/src/Rector/AbstractRector.php index 789560ff739..5a594abe5b1 100644 --- a/src/Rector/AbstractRector.php +++ b/src/Rector/AbstractRector.php @@ -33,10 +33,11 @@ use Rector\PhpDocParser\NodeTraverser\SimpleCallableNodeTraverser; use Rector\PhpParser\Comparing\NodeComparator; use Rector\PhpParser\Node\NodeFactory; +use Rector\PhpParser\NodeTraverser\AbstractLeaveNode; use Rector\Skipper\Skipper\Skipper; use Rector\ValueObject\Application\File; -abstract class AbstractRector extends NodeVisitorAbstract implements RectorInterface +abstract class AbstractRector extends AbstractLeaveNode implements RectorInterface { /** * @var string @@ -71,15 +72,8 @@ abstract class AbstractRector extends NodeVisitorAbstract implements RectorInter private CurrentFileProvider $currentFileProvider; - /** - * @var array - */ - private array $nodesToReturn = []; - private CreatedByRuleDecorator $createdByRuleDecorator; - private ?int $toBeRemovedNodeId = null; - public function autowire( NodeNameResolver $nodeNameResolver, NodeTypeResolver $nodeTypeResolver, @@ -186,31 +180,6 @@ final public function enterNode(Node $node): int|Node|null return $this->postRefactorProcess($originalNode, $node, $refactoredNode, $filePath); } - /** - * Replacing nodes in leaveNode() method avoids infinite recursion - * see"infinite recursion" in https://github.com/nikic/PHP-Parser/blob/master/doc/component/Walking_the_AST.markdown - */ - final public function leaveNode(Node $node): array|int|Node|null - { - if ($node->hasAttribute(AttributeKey::ORIGINAL_NODE)) { - return null; - } - - // nothing to change here - if ($this->toBeRemovedNodeId === null && $this->nodesToReturn === []) { - return null; - } - - $objectId = spl_object_id($node); - if ($this->toBeRemovedNodeId === $objectId) { - $this->toBeRemovedNodeId = null; - - return NodeVisitor::REMOVE_NODE; - } - - return $this->nodesToReturn[$objectId] ?? $node; - } - protected function isName(Node $node, string $name): bool { return $this->nodeNameResolver->isName($node, $name); From b274b1e5b69f8969e61ae6c379ce6f9d7652e123 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Mon, 24 Nov 2025 23:20:39 +0700 Subject: [PATCH 2/4] rectify --- src/Rector/AbstractRector.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Rector/AbstractRector.php b/src/Rector/AbstractRector.php index 5a594abe5b1..14d7ac60043 100644 --- a/src/Rector/AbstractRector.php +++ b/src/Rector/AbstractRector.php @@ -15,7 +15,6 @@ use PhpParser\Node\Stmt\Property; use PhpParser\Node\Stmt\Trait_; use PhpParser\NodeVisitor; -use PhpParser\NodeVisitorAbstract; use PHPStan\Analyser\MutatingScope; use PHPStan\Type\ObjectType; use PHPStan\Type\Type; From e4f3391f0666f9f57a3d54238c99e9118a0755b9 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Mon, 24 Nov 2025 23:23:59 +0700 Subject: [PATCH 3/4] eol --- src/PhpParser/NodeTraverser/AbstractLeaveNode.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PhpParser/NodeTraverser/AbstractLeaveNode.php b/src/PhpParser/NodeTraverser/AbstractLeaveNode.php index cc17d60e9c5..a933b2cb0d2 100644 --- a/src/PhpParser/NodeTraverser/AbstractLeaveNode.php +++ b/src/PhpParser/NodeTraverser/AbstractLeaveNode.php @@ -42,4 +42,4 @@ final public function leaveNode(Node $node): int|Node|null|array return $this->nodesToReturn[$objectId] ?? $node; } -} \ No newline at end of file +} From bf1e25d2764916cf3c94f433e423007c1e04b558 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Mon, 24 Nov 2025 23:32:41 +0700 Subject: [PATCH 4/4] final touch: use NodeVisitor sub namespace --- src/PhpDocParser/NodeVisitor/CallableNodeVisitor.php | 2 +- .../{NodeTraverser => NodeVisitor}/AbstractLeaveNode.php | 2 +- src/Rector/AbstractRector.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename src/PhpParser/{NodeTraverser => NodeVisitor}/AbstractLeaveNode.php (96%) diff --git a/src/PhpDocParser/NodeVisitor/CallableNodeVisitor.php b/src/PhpDocParser/NodeVisitor/CallableNodeVisitor.php index e7eb7b7a629..11d64ba3a0b 100644 --- a/src/PhpDocParser/NodeVisitor/CallableNodeVisitor.php +++ b/src/PhpDocParser/NodeVisitor/CallableNodeVisitor.php @@ -9,7 +9,7 @@ use PhpParser\Node\Stmt; use PhpParser\Node\Stmt\Expression; use PhpParser\NodeVisitor; -use Rector\PhpParser\NodeTraverser\AbstractLeaveNode; +use Rector\PhpParser\NodeVisitor\AbstractLeaveNode; final class CallableNodeVisitor extends AbstractLeaveNode { diff --git a/src/PhpParser/NodeTraverser/AbstractLeaveNode.php b/src/PhpParser/NodeVisitor/AbstractLeaveNode.php similarity index 96% rename from src/PhpParser/NodeTraverser/AbstractLeaveNode.php rename to src/PhpParser/NodeVisitor/AbstractLeaveNode.php index a933b2cb0d2..93b9dc2713a 100644 --- a/src/PhpParser/NodeTraverser/AbstractLeaveNode.php +++ b/src/PhpParser/NodeVisitor/AbstractLeaveNode.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Rector\PhpParser\NodeTraverser; +namespace Rector\PhpParser\NodeVisitor; use PhpParser\Node; use PhpParser\NodeVisitor; diff --git a/src/Rector/AbstractRector.php b/src/Rector/AbstractRector.php index 14d7ac60043..f0844e7367c 100644 --- a/src/Rector/AbstractRector.php +++ b/src/Rector/AbstractRector.php @@ -32,7 +32,7 @@ use Rector\PhpDocParser\NodeTraverser\SimpleCallableNodeTraverser; use Rector\PhpParser\Comparing\NodeComparator; use Rector\PhpParser\Node\NodeFactory; -use Rector\PhpParser\NodeTraverser\AbstractLeaveNode; +use Rector\PhpParser\NodeVisitor\AbstractLeaveNode; use Rector\Skipper\Skipper\Skipper; use Rector\ValueObject\Application\File;