Skip to content

Commit 0df59c0

Browse files
committed
match node type just once; avoid traverse once node type changes
1 parent aebf87d commit 0df59c0

File tree

3 files changed

+18
-16
lines changed

3 files changed

+18
-16
lines changed

src/PhpParser/NodeTraverser/AbstractImmutableNodeTraverser.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,19 @@ protected function traverseNode(Node $node): void
105105
$return = $visitor->enterNode($subNode);
106106
if ($return !== null) {
107107
if ($return instanceof Node) {
108+
$originalSubNodeClass = $subNode::class;
109+
108110
$this->ensureReplacementReasonable($subNode, $return);
109111
$subNode = $return;
110112
$node->{$name} = $return;
113+
114+
if ($originalSubNodeClass !== $subNode::class) {
115+
// stop traversing as node has changed its class and visitors do not work
116+
$traverseChildren = false;
117+
$this->stopTraversal = true;
118+
break 2;
119+
}
120+
111121
} elseif ($return === NodeVisitor::DONT_TRAVERSE_CHILDREN) {
112122
$traverseChildren = false;
113123
} elseif ($return === NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN) {
@@ -181,8 +191,15 @@ protected function traverseArray(array $nodes): array
181191
$return = $visitor->enterNode($node);
182192
if ($return !== null) {
183193
if ($return instanceof Node) {
194+
$originalNodeNodeClass = $node::class;
184195
$this->ensureReplacementReasonable($node, $return);
185196
$nodes[$i] = $node = $return;
197+
198+
if ($originalNodeNodeClass !== $return::class) {
199+
// stop traversing as node has changed its class and visitors do not work
200+
$this->stopTraversal = true;
201+
break 2;
202+
}
186203
} elseif (\is_array($return)) {
187204
$doNodes[] = [$i, $return];
188205
continue 2;

src/PhpParser/NodeTraverser/RectorNodeTraverser.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ public function getVisitorsForNode(Node $node): array
6767

6868
if (! isset($this->visitorsPerNodeClass[$nodeClass])) {
6969
$this->visitorsPerNodeClass[$nodeClass] = [];
70+
7071
/** @var RectorInterface $visitor */
7172
foreach ($this->visitors as $visitor) {
7273
foreach ($visitor->getNodeTypes() as $nodeType) {

src/Rector/AbstractRector.php

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,6 @@ public function beforeTraverse(array $nodes): ?array
128128
*/
129129
final public function enterNode(Node $node): int|Node|null
130130
{
131-
if (! $this->isMatchingNodeType($node)) {
132-
return null;
133-
}
134-
135131
if (is_a($this, HTMLAverseRectorInterface::class, true) && $this->file->containsHTML()) {
136132
return null;
137133
}
@@ -319,16 +315,4 @@ private function refreshScopeNodes(array | Node $node, string $filePath, ?Mutati
319315
$this->changedNodeScopeRefresher->refresh($node, $filePath, $mutatingScope);
320316
}
321317
}
322-
323-
private function isMatchingNodeType(Node $node): bool
324-
{
325-
$nodeClass = $node::class;
326-
foreach ($this->getNodeTypes() as $nodeType) {
327-
if (is_a($nodeClass, $nodeType, true)) {
328-
return true;
329-
}
330-
}
331-
332-
return false;
333-
}
334318
}

0 commit comments

Comments
 (0)