Skip to content

Commit 3fe355c

Browse files
authored
[experiment] Remove leaveNode() method on AbstractRector and CallableNodeVisitor (#7767)
1 parent 3f2b48a commit 3fe355c

File tree

2 files changed

+11
-94
lines changed

2 files changed

+11
-94
lines changed

src/PhpDocParser/NodeVisitor/CallableNodeVisitor.php

Lines changed: 5 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,6 @@ final class CallableNodeVisitor extends NodeVisitorAbstract
1818
*/
1919
private $callable;
2020

21-
private ?int $nodeIdToRemove = null;
22-
23-
/**
24-
* @var array<int, Node[]>
25-
*/
26-
private array $nodesToReturn = [];
27-
2821
/**
2922
* @param callable(Node $node): (int|Node|null|Node[]) $callable
3023
*/
@@ -33,48 +26,22 @@ public function __construct(callable $callable)
3326
$this->callable = $callable;
3427
}
3528

36-
public function enterNode(Node $node): int|Node|null
29+
/**
30+
* @return NodeVisitor::*|Node|null|Node[]
31+
*/
32+
public function enterNode(Node $node): int|Node|null|array
3733
{
3834
$originalNode = $node;
3935

4036
$callable = $this->callable;
4137

42-
/** @var int|Node|null|Node[] $newNode */
38+
/** @var NodeVisitor::*|Node|null|Node[] $newNode */
4339
$newNode = $callable($node);
4440

45-
if ($newNode === NodeVisitor::REMOVE_NODE) {
46-
$this->nodeIdToRemove = spl_object_id($originalNode);
47-
return $originalNode;
48-
}
49-
50-
if (is_array($newNode)) {
51-
$nodeId = spl_object_id($node);
52-
$this->nodesToReturn[$nodeId] = $newNode;
53-
54-
return $node;
55-
}
56-
5741
if ($originalNode instanceof Stmt && $newNode instanceof Expr) {
5842
return new Expression($newNode);
5943
}
6044

6145
return $newNode;
6246
}
63-
64-
/**
65-
* @return int|Node|Node[]
66-
*/
67-
public function leaveNode(Node $node): int|Node|array
68-
{
69-
if ($this->nodeIdToRemove !== null && $this->nodeIdToRemove === spl_object_id($node)) {
70-
$this->nodeIdToRemove = null;
71-
return NodeVisitor::REMOVE_NODE;
72-
}
73-
74-
if ($this->nodesToReturn === []) {
75-
return $node;
76-
}
77-
78-
return $this->nodesToReturn[spl_object_id($node)] ?? $node;
79-
}
8047
}

src/Rector/AbstractRector.php

Lines changed: 6 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
use PhpParser\Node\Stmt\Interface_;
1313
use PhpParser\Node\Stmt\Property;
1414
use PhpParser\Node\Stmt\Trait_;
15-
use PhpParser\NodeTraverser;
1615
use PhpParser\NodeVisitor;
1716
use PhpParser\NodeVisitorAbstract;
1817
use PHPStan\Analyser\MutatingScope;
@@ -72,15 +71,8 @@ abstract class AbstractRector extends NodeVisitorAbstract implements RectorInter
7271

7372
private CommentsMerger $commentsMerger;
7473

75-
/**
76-
* @var array<int, Node[]>
77-
*/
78-
private array $nodesToReturn = [];
79-
8074
private CreatedByRuleDecorator $createdByRuleDecorator;
8175

82-
private ?int $toBeRemovedNodeId = null;
83-
8476
public function autowire(
8577
NodeNameResolver $nodeNameResolver,
8678
NodeTypeResolver $nodeTypeResolver,
@@ -128,9 +120,9 @@ public function beforeTraverse(array $nodes): ?array
128120
}
129121

130122
/**
131-
* @return NodeTraverser::REMOVE_NODE|Node|null
123+
* @return NodeVisitor::REMOVE_NODE|Node|null|Node[]
132124
*/
133-
final public function enterNode(Node $node): int|Node|null
125+
final public function enterNode(Node $node): int|Node|null|array
134126
{
135127
if (is_a($this, HTMLAverseRectorInterface::class, true) && $this->file->containsHTML()) {
136128
return null;
@@ -167,47 +159,16 @@ final public function enterNode(Node $node): int|Node|null
167159
return null;
168160
}
169161

170-
// log here, so we can remove the node in leaveNode() method
171-
$this->toBeRemovedNodeId = spl_object_id($originalNode);
172-
173162
// notify this rule changed code
174163
$rectorWithLineChange = new RectorWithLineChange(static::class, $originalNode->getStartLine());
175164
$this->file->addRectorClassWithLine($rectorWithLineChange);
176165

177-
// keep original node as node will be removed in leaveNode()
178-
return $originalNode;
166+
return $refactoredNodeOrState;
179167
}
180168

181169
return $this->postRefactorProcess($originalNode, $node, $refactoredNodeOrState, $filePath);
182170
}
183171

184-
/**
185-
* Replacing nodes in leaveNode() method avoids infinite recursion
186-
* see"infinite recursion" in https://github.com/nikic/PHP-Parser/blob/master/doc/component/Walking_the_AST.markdown
187-
*
188-
* @return Node|Node[]|NodeVisitor::REMOVE_NODE|null
189-
*/
190-
final public function leaveNode(Node $node): array|int|Node|null
191-
{
192-
if ($node->hasAttribute(AttributeKey::ORIGINAL_NODE)) {
193-
return null;
194-
}
195-
196-
// nothing to change here
197-
if ($this->toBeRemovedNodeId === null && $this->nodesToReturn === []) {
198-
return null;
199-
}
200-
201-
$objectId = spl_object_id($node);
202-
if ($this->toBeRemovedNodeId === $objectId) {
203-
$this->toBeRemovedNodeId = null;
204-
205-
return NodeVisitor::REMOVE_NODE;
206-
}
207-
208-
return $this->nodesToReturn[$objectId] ?? $node;
209-
}
210-
211172
protected function isName(Node $node, string $name): bool
212173
{
213174
return $this->nodeNameResolver->isName($node, $name);
@@ -270,13 +231,14 @@ protected function mirrorComments(Node $newNode, Node $oldNode): void
270231

271232
/**
272233
* @param Node|Node[] $refactoredNode
234+
* @return Node|Node[]
273235
*/
274236
private function postRefactorProcess(
275237
Node $originalNode,
276238
Node $node,
277239
Node|array $refactoredNode,
278240
string $filePath
279-
): Node {
241+
): Node|array {
280242
/** @var non-empty-array<Node>|Node $refactoredNode */
281243
$this->createdByRuleDecorator->decorate($refactoredNode, $originalNode, static::class);
282244

@@ -285,20 +247,8 @@ private function postRefactorProcess(
285247

286248
/** @var MutatingScope|null $currentScope */
287249
$currentScope = $node->getAttribute(AttributeKey::SCOPE);
288-
289-
if (is_array($refactoredNode)) {
290-
$this->refreshScopeNodes($refactoredNode, $filePath, $currentScope);
291-
292-
// search "infinite recursion" in https://github.com/nikic/PHP-Parser/blob/master/doc/component/Walking_the_AST.markdown
293-
$originalNodeId = spl_object_id($originalNode);
294-
295-
// will be replaced in leaveNode() the original node must be passed
296-
$this->nodesToReturn[$originalNodeId] = $refactoredNode;
297-
298-
return $originalNode;
299-
}
300-
301250
$this->refreshScopeNodes($refactoredNode, $filePath, $currentScope);
251+
302252
return $refactoredNode;
303253
}
304254

0 commit comments

Comments
 (0)