Skip to content

Commit faeb90a

Browse files
committed
make RectorNodeTraverser immutable
1 parent e44afd9 commit faeb90a

File tree

2 files changed

+21
-11
lines changed

2 files changed

+21
-11
lines changed

src/PhpParser/NodeTraverser/RectorNodeTraverser.php

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Rector\PhpParser\Node\CustomNode\FileWithoutNamespace;
1717
use Rector\PhpParser\Node\FileNode;
1818
use Rector\VersionBonding\PhpVersionedFilter;
19+
use Webmozart\Assert\Assert;
1920

2021
/**
2122
* Based on native NodeTraverser class, but heavily customized for Rector needs.
@@ -54,9 +55,13 @@ public function __construct(
5455
/**
5556
* @param RectorInterface[] $rectors
5657
* @api used in tests to update the active rules
58+
*
59+
* @internal Used only in Rector core, not supported outside. Might change any time.
5760
*/
5861
public function refreshPhpRectors(array $rectors): void
5962
{
63+
Assert::allIsInstanceOf($rectors, RectorInterface::class);
64+
6065
$this->rectors = $rectors;
6166
$this->visitors = [];
6267
$this->visitorsPerNodeClass = [];
@@ -72,11 +77,14 @@ public function getVisitorsForNode(Node $node): array
7277
{
7378
$nodeClass = $node::class;
7479

80+
if (! $this->areNodeVisitorsPrepared) {
81+
$this->prepareNodeVisitors();
82+
}
83+
7584
if (! isset($this->visitorsPerNodeClass[$nodeClass])) {
7685
$this->visitorsPerNodeClass[$nodeClass] = [];
7786

78-
/** @var RectorInterface $visitor */
79-
foreach ($this->visitors as $visitor) {
87+
foreach ($this->rectors as $visitor) {
8088
foreach ($visitor->getNodeTypes() as $nodeType) {
8189
// BC layer matching
8290
if ($nodeType === FileWithoutNamespace::class && $nodeClass === FileNode::class) {
@@ -95,12 +103,9 @@ public function getVisitorsForNode(Node $node): array
95103
return $this->visitorsPerNodeClass[$nodeClass];
96104
}
97105

98-
/**
99-
* @deprecated @todo remove completely, even in tests to avoid mutable state
100-
*/
101106
public function addVisitor(NodeVisitor $visitor): void
102107
{
103-
$this->visitors[] = $visitor;
108+
throw new ShouldNotHappenException('The immutable node traverser does not support adding visitors.');
104109
}
105110

106111
public function removeVisitor(NodeVisitor $visitor): void

tests/PhpParser/NodeTraverser/RectorNodeTraverserTest.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public function testGetVisitorsForNodeWhenNoVisitorsAvailable(): void
4848
public function testGetVisitorsForNodeWhenNoVisitorsMatch(): void
4949
{
5050
$class = new Class_('test');
51-
$this->rectorNodeTraverser->addVisitor($this->ruleUsingFunctionRector);
51+
$this->rectorNodeTraverser->refreshPhpRectors([$this->ruleUsingFunctionRector]);
5252

5353
$visitors = $this->rectorNodeTraverser->getVisitorsForNode($class);
5454

@@ -58,8 +58,11 @@ public function testGetVisitorsForNodeWhenNoVisitorsMatch(): void
5858
public function testGetVisitorsForNodeWhenSomeVisitorsMatch(): void
5959
{
6060
$class = new Class_('test');
61-
$this->rectorNodeTraverser->addVisitor($this->ruleUsingFunctionRector);
62-
$this->rectorNodeTraverser->addVisitor($this->ruleUsingClassRector);
61+
62+
$this->rectorNodeTraverser->refreshPhpRectors([
63+
$this->ruleUsingFunctionRector,
64+
$this->ruleUsingClassRector,
65+
]);
6366

6467
$visitors = $this->rectorNodeTraverser->getVisitorsForNode($class);
6568

@@ -69,8 +72,10 @@ public function testGetVisitorsForNodeWhenSomeVisitorsMatch(): void
6972
public function testGetVisitorsForNodeWhenAllVisitorsMatch(): void
7073
{
7174
$class = new Class_('test');
72-
$this->rectorNodeTraverser->addVisitor($this->ruleUsingClassRector);
73-
$this->rectorNodeTraverser->addVisitor($this->ruleUsingClassLikeRector);
75+
$this->rectorNodeTraverser->refreshPhpRectors([
76+
$this->ruleUsingClassRector,
77+
$this->ruleUsingClassLikeRector,
78+
]);
7479

7580
$visitors = $this->rectorNodeTraverser->getVisitorsForNode($class);
7681

0 commit comments

Comments
 (0)