Skip to content

Commit 879faa0

Browse files
janwaleed09TomasVotruba
authored andcommitted
[Performance] Resolve class-like names once per file version in ShortNameResolver
1 parent 9024bc5 commit 879faa0

3 files changed

Lines changed: 65 additions & 0 deletions

File tree

‎rules-tests/CodingStyle/ClassNameImport/ShortNameResolver/ShortNameResolverTest.php‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
namespace Rector\Tests\CodingStyle\ClassNameImport\ShortNameResolver;
66

77
use Iterator;
8+
use PhpParser\Node\Identifier;
9+
use PhpParser\Node\Stmt\Class_;
10+
use PhpParser\NodeFinder;
811
use PHPUnit\Framework\Attributes\DataProvider;
912
use Rector\CodingStyle\ClassNameImport\ShortNameResolver;
1013
use Rector\Testing\PHPUnit\AbstractLazyTestCase;
@@ -36,6 +39,31 @@ public function test(string $filePath, array $expectedShortNames): void
3639
$this->assertSame($expectedShortNames, $shortNames);
3740
}
3841

42+
public function testResolveShortClassLikeNamesAgainAfterStmtsChange(): void
43+
{
44+
$file = $this->testingParser->parseFilePathToFile(__DIR__ . '/Fixture/various_imports.php.inc');
45+
$this->assertSame(['VariousImports'], $this->shortNameResolver->resolveShortClassLikeNames($file));
46+
47+
$class = new NodeFinder()
48+
->findFirstInstanceOf($file->getNewStmts(), Class_::class);
49+
$this->assertInstanceOf(Class_::class, $class);
50+
51+
$class->name = new Identifier('RenamedClass');
52+
$file->changeNewStmts($file->getNewStmts());
53+
54+
$this->assertSame(['RenamedClass'], $this->shortNameResolver->resolveShortClassLikeNames($file));
55+
}
56+
57+
public function testResolveShortClassLikeNamesPerFile(): void
58+
{
59+
$firstFile = $this->testingParser->parseFilePathToFile(__DIR__ . '/Fixture/various_imports.php.inc');
60+
$secondFile = $this->testingParser->parseFilePathToFile(__DIR__ . '/Fixture/partial_names.php.inc');
61+
62+
$this->assertSame(['VariousImports'], $this->shortNameResolver->resolveShortClassLikeNames($firstFile));
63+
$this->assertSame(['PartialNames'], $this->shortNameResolver->resolveShortClassLikeNames($secondFile));
64+
$this->assertSame(['VariousImports'], $this->shortNameResolver->resolveShortClassLikeNames($firstFile));
65+
}
66+
3967
/**
4068
* @return Iterator<array<array<int, mixed>, mixed>>
4169
*/

‎rules/CodingStyle/ClassNameImport/ShortNameResolver.php‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ final class ShortNameResolver
3131
*/
3232
private array $shortNamesByFilePath = [];
3333

34+
private ?File $shortClassLikeNamesFile = null;
35+
36+
private int $shortClassLikeNamesVersion = 0;
37+
38+
/**
39+
* @var string[]
40+
*/
41+
private array $shortClassLikeNames = [];
42+
3443
public function __construct(
3544
private readonly SimpleCallableNodeTraverser $simpleCallableNodeTraverser,
3645
private readonly NodeNameResolver $nodeNameResolver,
@@ -62,6 +71,23 @@ public function resolveFromFile(File $file): array
6271
* @return string[]
6372
*/
6473
public function resolveShortClassLikeNames(File $file): array
74+
{
75+
// asked for every imported name, while the class-likes only change with a new version of the file stmts
76+
if ($file === $this->shortClassLikeNamesFile && $file->getNewStmtsVersion() === $this->shortClassLikeNamesVersion) {
77+
return $this->shortClassLikeNames;
78+
}
79+
80+
$this->shortClassLikeNamesFile = $file;
81+
$this->shortClassLikeNamesVersion = $file->getNewStmtsVersion();
82+
$this->shortClassLikeNames = $this->findShortClassLikeNames($file);
83+
84+
return $this->shortClassLikeNames;
85+
}
86+
87+
/**
88+
* @return string[]
89+
*/
90+
private function findShortClassLikeNames(File $file): array
6591
{
6692
$rootNode = $file->getUseImportsRootNode();
6793

‎src/ValueObject/Application/File.php‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ final class File
3333
*/
3434
private array $newStmts = [];
3535

36+
private int $newStmtsVersion = 0;
37+
3638
/**
3739
* @var array<int, Token>
3840
*/
@@ -146,6 +148,15 @@ public function getOldTokens(): array
146148
public function changeNewStmts(array $newStmts): void
147149
{
148150
$this->newStmts = $newStmts;
151+
++$this->newStmtsVersion;
152+
}
153+
154+
/**
155+
* Increases with every change of the new stmts, so data derived from them can be cached per version
156+
*/
157+
public function getNewStmtsVersion(): int
158+
{
159+
return $this->newStmtsVersion;
149160
}
150161

151162
public function addRectorClassWithLine(RectorWithLineChange $rectorWithLineChange): void

0 commit comments

Comments
 (0)