mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-08 04:10:51 +00:00
[Attribute] Fix UseAliasNameMatcher for the last part of use import rename (#2402)
Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
parent
02803bf7d5
commit
73055d87fb
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace Rector\Tests\PhpAttribute;
|
||||
|
||||
use Iterator;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Stmt\Use_;
|
||||
use PhpParser\Node\Stmt\UseUse;
|
||||
|
@ -11,21 +12,13 @@ use Rector\Php80\ValueObject\AnnotationToAttribute;
|
|||
use Rector\PhpAttribute\UseAliasNameMatcher;
|
||||
use Rector\PhpAttribute\ValueObject\UseAliasMetadata;
|
||||
use Rector\Testing\PHPUnit\AbstractTestCase;
|
||||
use Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\Source\Annotation\OpenApi\Annotation\NestedPastAnnotation;
|
||||
use Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\Source\Annotation\OpenApi\PastAnnotation;
|
||||
use Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\Source\Attribute\OpenApi\Attribute\NestedFutureAttribute;
|
||||
use Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\Source\Attribute\OpenApi\FutureAttribute;
|
||||
|
||||
final class UseAliasNameMatcherTest extends AbstractTestCase
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const USE_IMPORT_NAME = 'Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\Source\Annotation\OpenApi';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const USE_ALIAS = 'OA';
|
||||
|
||||
private UseAliasNameMatcher $useAliasNameMatcher;
|
||||
|
||||
protected function setUp(): void
|
||||
|
@ -34,24 +27,66 @@ final class UseAliasNameMatcherTest extends AbstractTestCase
|
|||
$this->useAliasNameMatcher = $this->getService(UseAliasNameMatcher::class);
|
||||
}
|
||||
|
||||
public function test(): void
|
||||
{
|
||||
$annotationToAttribute = new AnnotationToAttribute(PastAnnotation::class, FutureAttribute::class);
|
||||
|
||||
$uses = [new Use_([new UseUse(new Name(self::USE_IMPORT_NAME), self::USE_ALIAS), self::USE_ALIAS])];
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(
|
||||
AnnotationToAttribute $annotationToAttribute,
|
||||
string $useImportName,
|
||||
string $useAlias,
|
||||
string $shortAnnotationName,
|
||||
// attribute
|
||||
string $expectedAttributeUseImportName,
|
||||
string $expectedShortAttributeName,
|
||||
): void {
|
||||
$uses = [new Use_([new UseUse(new Name($useImportName), $useAlias), $useAlias])];
|
||||
|
||||
// uses
|
||||
$useAliasMetadata = $this->useAliasNameMatcher->match($uses, '@OA\PastAnnotation', $annotationToAttribute);
|
||||
$useAliasMetadata = $this->useAliasNameMatcher->match($uses, $shortAnnotationName, $annotationToAttribute);
|
||||
|
||||
$this->assertInstanceOf(UseAliasMetadata::class, $useAliasMetadata);
|
||||
|
||||
// test new use import
|
||||
$this->assertSame('OA\FutureAttribute', $useAliasMetadata->getShortAttributeName());
|
||||
$this->assertSame($expectedShortAttributeName, $useAliasMetadata->getShortAttributeName());
|
||||
|
||||
// test new short attribute name
|
||||
$this->assertSame(
|
||||
$this->assertSame($expectedAttributeUseImportName, $useAliasMetadata->getUseImportName());
|
||||
}
|
||||
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
yield [
|
||||
// configuration
|
||||
new AnnotationToAttribute(PastAnnotation::class, FutureAttribute::class),
|
||||
|
||||
// use import
|
||||
'Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\Source\Annotation\OpenApi',
|
||||
// use import alias
|
||||
'OA',
|
||||
// short attribute name
|
||||
'@OA\PastAnnotation',
|
||||
|
||||
// expected attribute import
|
||||
'Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\Source\Attribute\OpenApi',
|
||||
$useAliasMetadata->getUseImportName()
|
||||
);
|
||||
// expected attribute short name
|
||||
'OA\FutureAttribute',
|
||||
];
|
||||
|
||||
yield [
|
||||
// configuration
|
||||
new AnnotationToAttribute(NestedPastAnnotation::class, NestedFutureAttribute::class),
|
||||
|
||||
// use import
|
||||
'Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\Source\Annotation\OpenApi\Annotation',
|
||||
// use import alias
|
||||
'OA',
|
||||
// short attribute name
|
||||
'@OA\NestedPastAnnotation',
|
||||
|
||||
// expected attribute import
|
||||
'Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\Source\Attribute\OpenApi\Attribute',
|
||||
// expected attribute short name
|
||||
'OA\NestedFutureAttribute',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace Rector\PhpAttribute;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use PhpParser\Node\Stmt\Use_;
|
||||
use Rector\Php80\ValueObject\AnnotationToAttribute;
|
||||
use Rector\PhpAttribute\ValueObject\UseAliasMetadata;
|
||||
|
@ -35,23 +34,31 @@ final class UseAliasNameMatcher
|
|||
continue;
|
||||
}
|
||||
|
||||
$importName = $useUse->name->toString();
|
||||
|
||||
// previous keyword
|
||||
$lastImportKeyword = Strings::after($importName, '\\', -1);
|
||||
if ($lastImportKeyword === null) {
|
||||
$fullyQualifiedAnnotationName = $useUse->name->toString() . ltrim($shortAnnotationName, $alias);
|
||||
if ($fullyQualifiedAnnotationName !== $annotationToAttribute->getTag()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// resolve new short name
|
||||
$newShortname = Strings::after($annotationToAttribute->getAttributeClass(), $lastImportKeyword);
|
||||
$annotationParts = explode('\\', $fullyQualifiedAnnotationName);
|
||||
$attributeParts = explode('\\', $annotationToAttribute->getAttributeClass());
|
||||
|
||||
$beforeImportName = Strings::before(
|
||||
$annotationToAttribute->getAttributeClass(),
|
||||
$lastImportKeyword
|
||||
) . $lastImportKeyword;
|
||||
// requirement for matching single part rename
|
||||
if (count($annotationParts) !== count($attributeParts)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return new UseAliasMetadata($alias . $newShortname, $beforeImportName, $useUse);
|
||||
// now we now we are matching correct contanct and old and new have the same number of parts
|
||||
$useImportPartCount = substr_count($useUse->name->toString(), '\\') + 1;
|
||||
$newAttributeImportPart = array_slice($attributeParts, 0, $useImportPartCount);
|
||||
$newAttributeImport = implode('\\', $newAttributeImportPart);
|
||||
|
||||
$shortNamePartCount = count($attributeParts) - $useImportPartCount;
|
||||
|
||||
// +1, to remove the alias part
|
||||
$attributeParts = array_slice($attributeParts, -$shortNamePartCount);
|
||||
$shortAttributeName = $alias . '\\' . implode('\\', $attributeParts);
|
||||
|
||||
return new UseAliasMetadata($shortAttributeName, $newAttributeImport, $useUse);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user