Skip to content

Commit 8b775d2

Browse files
committed
[perf] [experiment] preload all node classes once at start
1 parent 9e7f77d commit 8b775d2

2 files changed

Lines changed: 86 additions & 16 deletions

File tree

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Scripts\Finder;
6+
7+
require __DIR__ . '/../../../vendor/autoload.php';
8+
9+
use Nette\Loaders\RobotLoader;
10+
use ReflectionClass;
11+
12+
final class NodeClassFinder
13+
{
14+
/**
15+
* @return array<class-string<\PhpParser\Node>>
16+
*/
17+
public static function find(): array
18+
{
19+
$robotLoader = new RobotLoader();
20+
$robotLoader->acceptFiles = ['*.php'];
21+
22+
$phpParserNodeDirectory = __DIR__ . '/../../../vendor/nikic/php-parser/lib/PhpParser/Node/';
23+
$robotLoader->addDirectory($phpParserNodeDirectory);
24+
25+
$robotLoader->setTempDirectory(sys_get_temp_dir() . '/node-classes');
26+
$robotLoader->refresh();
27+
28+
/** @var array<class-string> $nodeClasses */
29+
$nodeClasses = array_keys($robotLoader->getIndexedClasses());
30+
31+
$instantiableNodeClasses = array_filter($nodeClasses, function (string $nodeClass): bool {
32+
$nodeClassReflection = new ReflectionClass($nodeClass);
33+
if ($nodeClassReflection->isAbstract()) {
34+
return false;
35+
}
36+
37+
return ! $nodeClassReflection->isInterface();
38+
});
39+
40+
return $instantiableNodeClasses;
41+
}
42+
}

src/PhpParser/NodeTraverser/RectorNodeTraverser.php

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
use PhpParser\NodeVisitor;
1010
use Rector\Configuration\ConfigurationRuleFilter;
1111
use Rector\Contract\Rector\RectorInterface;
12+
use Rector\Scripts\Finder\NodeClassFinder;
1213
use Rector\VersionBonding\PhpVersionedFilter;
14+
use Webmozart\Assert\Assert;
1315

1416
/**
1517
* @see \Rector\Tests\PhpParser\NodeTraverser\RectorNodeTraverserTest
@@ -63,22 +65,31 @@ public function refreshPhpRectors(array $rectors): void
6365
*/
6466
public function getVisitorsForNode(Node $node): array
6567
{
66-
$nodeClass = $node::class;
67-
68-
if (! isset($this->visitorsPerNodeClass[$nodeClass])) {
69-
$this->visitorsPerNodeClass[$nodeClass] = [];
70-
/** @var RectorInterface $visitor */
71-
foreach ($this->visitors as $visitor) {
72-
foreach ($visitor->getNodeTypes() as $nodeType) {
73-
if (is_a($nodeClass, $nodeType, true)) {
74-
$this->visitorsPerNodeClass[$nodeClass][] = $visitor;
75-
continue 2;
76-
}
77-
}
78-
}
79-
}
80-
81-
return $this->visitorsPerNodeClass[$nodeClass];
68+
Assert::true($this->areNodeVisitorsPrepared);
69+
70+
return $this->visitorsPerNodeClass[$node::class] ?? [];
71+
//
72+
// $nodeClass = $node::class;
73+
//
74+
// static $isACheckCounter = 0;
75+
//
76+
// if (! isset($this->visitorsPerNodeClass[$nodeClass])) {
77+
// $this->visitorsPerNodeClass[$nodeClass] = [];
78+
// /** @var RectorInterface $visitor */
79+
// foreach ($this->visitors as $visitor) {
80+
// foreach ($visitor->getNodeTypes() as $nodeType) {
81+
// if (is_a($nodeClass, $nodeType, true)) {
82+
// ++$isACheckCounter;
83+
//
84+
// $this->visitorsPerNodeClass[$nodeClass][] = $visitor;
85+
// continue 2;
86+
// }
87+
// }
88+
// }
89+
//
90+
// dump($isACheckCounter);
91+
// }
92+
// return $this->visitorsPerNodeClass[$nodeClass];
8293
}
8394

8495
/**
@@ -97,6 +108,23 @@ private function prepareNodeVisitors(): void
97108
// filter by configuration
98109
$this->visitors = $this->configurationRuleFilter->filter($this->visitors);
99110

111+
static $counter = 0;
112+
113+
// 1. get all node non-interface, non-abstract classes
114+
// 2. iterate through them
115+
foreach (NodeClassFinder::find() as $nodeClass) {
116+
/** @var RectorInterface $visitor */
117+
foreach ($this->visitors as $visitor) {
118+
foreach ($visitor->getNodeTypes() as $matchingNodeType) {
119+
if (is_a($nodeClass, $matchingNodeType, true)) {
120+
$this->visitorsPerNodeClass[$nodeClass][] = $visitor;
121+
122+
++$counter;
123+
}
124+
}
125+
}
126+
}
127+
100128
$this->areNodeVisitorsPrepared = true;
101129
}
102130
}

0 commit comments

Comments
 (0)