Add ShortNameResolver test (#1146)

This commit is contained in:
Tomas Votruba 2021-11-04 21:27:26 +01:00 committed by GitHub
parent 5c32bd09e7
commit 78f7f0dec1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 160 additions and 29 deletions

View File

@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\CodingStyle\ClassNameImport\ShortNameResolver\Fixture;
use Rector\Tests\CodingStyle\ClassNameImport\ShortNameResolver\Source\SomeFile as AnotherFile;
final Class AlsoAliases
{
public function run()
{
return new AnotherFile();
}
}

View File

@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\CodingStyle\ClassNameImport\ShortNameResolver\Fixture;
use Rector\Tests\CodingStyle\ClassNameImport\ShortNameResolver\Source;
final Class PartialNames
{
public function run()
{
return new Source\SomeFile();
}
}

View File

@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\CodingStyle\ClassNameImport\ShortNameResolver\Fixture;
use Rector\Tests\CodingStyle\ClassNameImport\ShortNameResolver\Source\SomeFile;
final Class VariousImports
{
public function run()
{
return new SomeFile();
}
}

View File

@ -0,0 +1,69 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\CodingStyle\ClassNameImport\ShortNameResolver;
use Iterator;
use Rector\CodingStyle\ClassNameImport\ShortNameResolver;
use Rector\Core\PhpParser\Parser\RectorParser;
use Rector\Core\ValueObject\Application\File;
use Rector\Testing\PHPUnit\AbstractTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;
final class ShortNameResolverTest extends AbstractTestCase
{
private ShortNameResolver $shortNameResolver;
private RectorParser $rectorParser;
protected function setUp(): void
{
$this->boot();
$this->shortNameResolver = $this->getService(ShortNameResolver::class);
$this->rectorParser = $this->getService(RectorParser::class);
}
/**
* @dataProvider provideData()
* @param array<string, class-string<SomeFile>|string> $expectedShortNames
*/
public function test(string $filePath, array $expectedShortNames): void
{
$file = $this->createFileFromFilePath($filePath);
$shortNames = $this->shortNameResolver->resolveFromFile($file);
$this->assertSame($expectedShortNames, $shortNames);
}
/**
* @return Iterator<array<int, array<string, string|class-string>>
*/
public function provideData(): Iterator
{
yield [__DIR__ . '/Fixture/various_imports.php.inc', [
'VariousImports' => 'Rector\Tests\CodingStyle\ClassNameImport\ShortNameResolver\Fixture\VariousImports',
'SomeFile' => 'Rector\Tests\CodingStyle\ClassNameImport\ShortNameResolver\Source\SomeFile',
]];
yield [__DIR__ . '/Fixture/also_aliases.php.inc', [
'AlsoAliases' => 'Rector\Tests\CodingStyle\ClassNameImport\ShortNameResolver\Fixture\AlsoAliases',
'AnotherFile' => 'Rector\Tests\CodingStyle\ClassNameImport\ShortNameResolver\Source\SomeFile',
]];
yield [__DIR__ . '/Fixture/partial_names.php.inc', [
'PartialNames' => 'Rector\Tests\CodingStyle\ClassNameImport\ShortNameResolver\Fixture\PartialNames',
]];
}
private function createFileFromFilePath(string $filePath): File
{
$smartFileInfo = new SmartFileInfo($filePath);
$file = new File($smartFileInfo, $smartFileInfo->getContents());
$stmts = $this->rectorParser->parseFile($smartFileInfo);
$file->hydrateStmtsAndTokens($stmts, $stmts, []);
return $file;
}
}

View File

@ -0,0 +1,10 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\CodingStyle\ClassNameImport\ShortNameResolver\Source;
final class SomeFile
{
}

View File

@ -2,9 +2,9 @@
namespace Rector\Tests\CodingStyle\Rector\MethodCall\PreferThisOrSelfMethodCallRector\Fixture;
use Rector\Tests\CodingStyle\Rector\MethodCall\PreferThisOrSelfMethodCallRector\Source\AbstractTestCase;
use Rector\Tests\CodingStyle\Rector\MethodCall\PreferThisOrSelfMethodCallRector\Source\SomeAbstractTestCase;
class ToSelf extends AbstractTestCase
class ToSelf extends SomeAbstractTestCase
{
public function run()
{
@ -21,9 +21,9 @@ class ToSelf extends AbstractTestCase
namespace Rector\Tests\CodingStyle\Rector\MethodCall\PreferThisOrSelfMethodCallRector\Fixture;
use Rector\Tests\CodingStyle\Rector\MethodCall\PreferThisOrSelfMethodCallRector\Source\AbstractTestCase;
use Rector\Tests\CodingStyle\Rector\MethodCall\PreferThisOrSelfMethodCallRector\Source\SomeAbstractTestCase;
class ToSelf extends AbstractTestCase
class ToSelf extends SomeAbstractTestCase
{
public function run()
{

View File

@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Rector\Tests\CodingStyle\Rector\MethodCall\PreferThisOrSelfMethodCallRector\Source;
abstract class AbstractTestCase
abstract class SomeAbstractTestCase
{
}

View File

@ -6,8 +6,8 @@ use PHPUnit\Framework\TestCase;
use Rector\CodingStyle\Enum\PreferenceSelfThis;
use Rector\CodingStyle\Rector\MethodCall\PreferThisOrSelfMethodCallRector;
use Rector\Tests\CodingStyle\Rector\MethodCall\PreferThisOrSelfMethodCallRector\Source\AbstractTestCase;
use Rector\Tests\CodingStyle\Rector\MethodCall\PreferThisOrSelfMethodCallRector\Source\BeLocalClass;
use Rector\Tests\CodingStyle\Rector\MethodCall\PreferThisOrSelfMethodCallRector\Source\SomeAbstractTestCase;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symplify\SymfonyPhpConfig\ValueObjectInliner;
@ -16,7 +16,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
$services->set(PreferThisOrSelfMethodCallRector::class)
->call('configure', [[
PreferThisOrSelfMethodCallRector::TYPE_TO_PREFERENCE => [
AbstractTestCase::class => ValueObjectInliner::inline(PreferenceSelfThis::PREFER_SELF()),
SomeAbstractTestCase::class => ValueObjectInliner::inline(PreferenceSelfThis::PREFER_SELF()),
BeLocalClass::class => ValueObjectInliner::inline(PreferenceSelfThis::PREFER_THIS()),
TestCase::class => ValueObjectInliner::inline(PreferenceSelfThis::PREFER_SELF()),
],

View File

@ -29,8 +29,7 @@ final class FullyQualifiedNameClassNameImportSkipVoter implements ClassNameImpor
public function shouldSkip(File $file, FullyQualifiedObjectType $fullyQualifiedObjectType, Node $node): bool
{
// "new X" or "X::static()"
$shortNamesToFullyQualifiedNames = $this->shortNameResolver->resolveForNode($file);
$shortNamesToFullyQualifiedNames = $this->shortNameResolver->resolveFromFile($file);
foreach ($shortNamesToFullyQualifiedNames as $shortName => $fullyQualifiedName) {
$shortNameLowered = strtolower($shortName);
if ($fullyQualifiedObjectType->getShortNameLowered() !== $shortNameLowered) {

View File

@ -28,6 +28,9 @@ use Symfony\Contracts\Service\Attribute\Required;
use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
use Symplify\SimplePhpDocParser\PhpDocNodeTraverser;
/**
* @see \Rector\Tests\CodingStyle\ClassNameImport\ShortNameResolver\ShortNameResolverTest
*/
final class ShortNameResolver
{
/**
@ -64,17 +67,16 @@ final class ShortNameResolver
/**
* @return array<string, string>
*/
public function resolveForNode(File $file): array
public function resolveFromFile(File $file): array
{
$smartFileInfo = $file->getSmartFileInfo();
$nodeRealPath = $smartFileInfo->getRealPath();
$filePath = $file->getFilePath();
if (isset($this->shortNamesByFilePath[$nodeRealPath])) {
return $this->shortNamesByFilePath[$nodeRealPath];
if (isset($this->shortNamesByFilePath[$filePath])) {
return $this->shortNamesByFilePath[$filePath];
}
$shortNamesToFullyQualifiedNames = $this->resolveForStmts($file->getNewStmts());
$this->shortNamesByFilePath[$nodeRealPath] = $shortNamesToFullyQualifiedNames;
$this->shortNamesByFilePath[$filePath] = $shortNamesToFullyQualifiedNames;
return $shortNamesToFullyQualifiedNames;
}

View File

@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Rector\CodingStyle\Node;
use PhpParser\Node\Stmt\Use_;
use Rector\CodingStyle\ClassNameImport\ShortNameResolver;
use Rector\CodingStyle\Naming\ClassNaming;
use Rector\Core\ValueObject\Application\File;
@ -20,11 +19,11 @@ final class UseNameAliasToNameResolver
/**
* @return array<string, string[]>
*/
public function resolve(File $file, Use_ $use): array
public function resolve(File $file): array
{
$useNamesAliasToName = [];
$shortNames = $this->shortNameResolver->resolveForNode($file);
$shortNames = $this->shortNameResolver->resolveFromFile($file);
foreach ($shortNames as $alias => $useImport) {
if (! is_string($alias)) {
continue;

View File

@ -102,7 +102,7 @@ CODE_SAMPLE
$this->resolvedNodeNames = $this->useManipulator->resolveUsedNameNodes($searchNode);
$this->resolvedDocPossibleAliases = $this->docAliasResolver->resolve($searchNode);
$this->useNamesAliasToName = $this->useNameAliasToNameResolver->resolve($this->file, $node);
$this->useNamesAliasToName = $this->useNameAliasToNameResolver->resolve($this->file);
// lowercase
$this->resolvedDocPossibleAliases = $this->lowercaseArray($this->resolvedDocPossibleAliases);

View File

@ -204,8 +204,19 @@ final class ProcessCommand extends Command
* @param File[] $files
*/
private function configurePHPStanNodeScopeResolver(array $files): void
{
$filePaths = $this->resolvePhpFilePaths($files);
$this->nodeScopeResolver->setAnalysedFiles($filePaths);
}
/**
* @param File[] $files
* @return string[]
*/
private function resolvePhpFilePaths(array $files): array
{
$filePaths = [];
foreach ($files as $file) {
$smartFileInfo = $file->getSmartFileInfo();
$pathName = $smartFileInfo->getPathname();
@ -215,6 +226,6 @@ final class ProcessCommand extends Command
}
}
$this->nodeScopeResolver->setAnalysedFiles($filePaths);
return $filePaths;
}
}

View File

@ -53,6 +53,11 @@ final class File
$this->originalFileContent = $fileContent;
}
public function getFilePath(): string
{
return $this->smartFileInfo->getRealPath();
}
public function getSmartFileInfo(): SmartFileInfo
{
return $this->smartFileInfo;
@ -114,15 +119,6 @@ final class File
throw new ShouldNotHappenException('Double stmts override');
}
/*
* If newStmts is equal to $oldStmts,
* it is necessary to fill oldTokens only to avoid content of the file removed or spacing changed
*/
if ($newStmts === $oldStmts) {
$this->oldTokens = $oldTokens;
return;
}
$this->oldStmts = $oldStmts;
$this->newStmts = $newStmts;
$this->oldTokens = $oldTokens;