Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
namespace Rector\Tests\CodingStyle\ClassNameImport\ShortNameResolver;

use Iterator;
use PhpParser\Node\Identifier;
use PhpParser\Node\Stmt\Class_;
use PhpParser\NodeFinder;
use PHPUnit\Framework\Attributes\DataProvider;
use Rector\CodingStyle\ClassNameImport\ShortNameResolver;
use Rector\Testing\PHPUnit\AbstractLazyTestCase;
Expand Down Expand Up @@ -36,6 +39,31 @@ public function test(string $filePath, array $expectedShortNames): void
$this->assertSame($expectedShortNames, $shortNames);
}

public function testResolveShortClassLikeNamesAgainAfterStmtsChange(): void
{
$file = $this->testingParser->parseFilePathToFile(__DIR__ . '/Fixture/various_imports.php.inc');
$this->assertSame(['VariousImports'], $this->shortNameResolver->resolveShortClassLikeNames($file));

$class = new NodeFinder()
->findFirstInstanceOf($file->getNewStmts(), Class_::class);
$this->assertInstanceOf(Class_::class, $class);

$class->name = new Identifier('RenamedClass');
$file->changeNewStmts($file->getNewStmts());

$this->assertSame(['RenamedClass'], $this->shortNameResolver->resolveShortClassLikeNames($file));
}

public function testResolveShortClassLikeNamesPerFile(): void
{
$firstFile = $this->testingParser->parseFilePathToFile(__DIR__ . '/Fixture/various_imports.php.inc');
$secondFile = $this->testingParser->parseFilePathToFile(__DIR__ . '/Fixture/partial_names.php.inc');

$this->assertSame(['VariousImports'], $this->shortNameResolver->resolveShortClassLikeNames($firstFile));
$this->assertSame(['PartialNames'], $this->shortNameResolver->resolveShortClassLikeNames($secondFile));
$this->assertSame(['VariousImports'], $this->shortNameResolver->resolveShortClassLikeNames($firstFile));
}

/**
* @return Iterator<array<array<int, mixed>, mixed>>
*/
Expand Down
26 changes: 26 additions & 0 deletions rules/CodingStyle/ClassNameImport/ShortNameResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@ final class ShortNameResolver
*/
private array $shortNamesByFilePath = [];

private ?File $shortClassLikeNamesFile = null;

private int $shortClassLikeNamesVersion = 0;

/**
* @var string[]
*/
private array $shortClassLikeNames = [];

public function __construct(
private readonly SimpleCallableNodeTraverser $simpleCallableNodeTraverser,
private readonly NodeNameResolver $nodeNameResolver,
Expand Down Expand Up @@ -62,6 +71,23 @@ public function resolveFromFile(File $file): array
* @return string[]
*/
public function resolveShortClassLikeNames(File $file): array
{
// asked for every imported name, while the class-likes only change with a new version of the file stmts
if ($file === $this->shortClassLikeNamesFile && $file->getNewStmtsVersion() === $this->shortClassLikeNamesVersion) {
return $this->shortClassLikeNames;
}

$this->shortClassLikeNamesFile = $file;
$this->shortClassLikeNamesVersion = $file->getNewStmtsVersion();
$this->shortClassLikeNames = $this->findShortClassLikeNames($file);

return $this->shortClassLikeNames;
}

/**
* @return string[]
*/
private function findShortClassLikeNames(File $file): array
{
$rootNode = $file->getUseImportsRootNode();

Expand Down
11 changes: 11 additions & 0 deletions src/ValueObject/Application/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ final class File
*/
private array $newStmts = [];

private int $newStmtsVersion = 0;

/**
* @var array<int, Token>
*/
Expand Down Expand Up @@ -146,6 +148,15 @@ public function getOldTokens(): array
public function changeNewStmts(array $newStmts): void
{
$this->newStmts = $newStmts;
++$this->newStmtsVersion;
}

/**
* Increases with every change of the new stmts, so data derived from them can be cached per version
*/
public function getNewStmtsVersion(): int
{
return $this->newStmtsVersion;
}

public function addRectorClassWithLine(RectorWithLineChange $rectorWithLineChange): void
Expand Down
Loading