From 685ba8a63e904c776033ba85c13f8903952e73e4 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Tue, 19 Mar 2024 21:45:46 +0700 Subject: [PATCH] [Renaming][AutoImport] Handle after change annotation to attribute with rename on AnnotationToAttributeRector + RenameClassRector with auto import (#5741) * [Renaming][AutoImport] Handle after change annotation to attribute with rename on AnnotationToAttributeRector + RenameClassRector with auto import * Fix * Fix --- ...yQualifiedNameClassNameImportSkipVoter.php | 15 +++++++- .../Rector/ClassRenamingPostRector.php | 34 ++++++++++++++----- .../Fixture/with_existing_attribute.php.inc | 3 +- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/rules/CodingStyle/ClassNameImport/ClassNameImportSkipVoter/FullyQualifiedNameClassNameImportSkipVoter.php b/rules/CodingStyle/ClassNameImport/ClassNameImportSkipVoter/FullyQualifiedNameClassNameImportSkipVoter.php index ef7253c1cf2..46e933f61c1 100644 --- a/rules/CodingStyle/ClassNameImport/ClassNameImportSkipVoter/FullyQualifiedNameClassNameImportSkipVoter.php +++ b/rules/CodingStyle/ClassNameImport/ClassNameImportSkipVoter/FullyQualifiedNameClassNameImportSkipVoter.php @@ -6,9 +6,12 @@ use Nette\Utils\Strings; use PhpParser\Node; +use PhpParser\Node\Name; +use PhpParser\Node\Name\FullyQualified; use Rector\CodingStyle\ClassNameImport\ShortNameResolver; use Rector\CodingStyle\Contract\ClassNameImport\ClassNameImportSkipVoterInterface; use Rector\Configuration\RenamedClassesDataCollector; +use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType; use Rector\ValueObject\Application\File; @@ -38,6 +41,12 @@ public function shouldSkip(File $file, FullyQualifiedObjectType $fullyQualifiedO $className = $fullyQualifiedObjectType->getClassName(); $removedUses = $this->renamedClassesDataCollector->getOldClasses(); + $originalName = $node->getAttribute(AttributeKey::ORIGINAL_NAME); + $originalNameToAttribute = null; + if ($originalName instanceof Name && ! $originalName instanceof FullyQualified && $originalName->hasAttribute(AttributeKey::PHP_ATTRIBUTE_NAME)) { + $originalNameToAttribute = $originalName->getAttribute(AttributeKey::PHP_ATTRIBUTE_NAME); + } + foreach ($shortNamesToFullyQualifiedNames as $shortName => $fullyQualifiedName) { if ($fullyQualifiedObjectTypeShortName !== $shortName) { $shortName = $this->cleanShortName($shortName); @@ -52,7 +61,11 @@ public function shouldSkip(File $file, FullyQualifiedObjectType $fullyQualifiedO return false; } - return ! in_array($fullyQualifiedName, $removedUses, true); + if (! in_array($fullyQualifiedName, $removedUses, true)) { + return $originalNameToAttribute == null || ! in_array($originalNameToAttribute, $removedUses, true); + } + + return false; } return false; diff --git a/src/PostRector/Rector/ClassRenamingPostRector.php b/src/PostRector/Rector/ClassRenamingPostRector.php index f17388bd6b2..b525bc05630 100644 --- a/src/PostRector/Rector/ClassRenamingPostRector.php +++ b/src/PostRector/Rector/ClassRenamingPostRector.php @@ -69,14 +69,7 @@ public function enterNode(Node $node): ?Node if ($node instanceof FullyQualified) { $result = $this->classRenamer->renameNode($node, $oldToNewClasses, $scope); } else { - $phpAttributeName = $node->getAttribute(AttributeKey::PHP_ATTRIBUTE_NAME); - if (is_string($phpAttributeName)) { - $result = $this->classRenamer->renameNode( - new FullyQualified($phpAttributeName, $node->getAttributes()), - $oldToNewClasses, - $scope - ); - } + $result = $this->resolveResultWithPhpAttributeName($node, $oldToNewClasses, $scope); } if (! SimpleParameterProvider::provideBoolParameter(Option::AUTO_IMPORT_NAMES)) { @@ -102,4 +95,29 @@ public function afterTraverse(array $nodes): array $this->renamedNameCollector->reset(); return $nodes; } + + /** + * @param array $oldToNewClasses + */ + private function resolveResultWithPhpAttributeName( + Name $name, + array $oldToNewClasses, + ?Scope $scope + ): ?FullyQualified { + $phpAttributeName = $name->getAttribute(AttributeKey::PHP_ATTRIBUTE_NAME); + if (is_string($phpAttributeName)) { + $result = $this->classRenamer->renameNode( + new FullyQualified($phpAttributeName, $name->getAttributes()), + $oldToNewClasses, + $scope + ); + if ($result instanceof FullyQualified) { + $result->setAttribute(AttributeKey::ORIGINAL_NAME, $name); + } + + return $result; + } + + return null; + } } diff --git a/tests/Issues/AnnotationToAttributeRenameAutoImport/Fixture/with_existing_attribute.php.inc b/tests/Issues/AnnotationToAttributeRenameAutoImport/Fixture/with_existing_attribute.php.inc index 9818c1c2582..5326ab04705 100644 --- a/tests/Issues/AnnotationToAttributeRenameAutoImport/Fixture/with_existing_attribute.php.inc +++ b/tests/Issues/AnnotationToAttributeRenameAutoImport/Fixture/with_existing_attribute.php.inc @@ -20,11 +20,12 @@ class WithExistingAttribute extends AbstractController namespace Rector\Tests\Issues\RenameAnnotationToAttributeAutoImport\Fixture; +use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Routing\Annotation\Route; #[Route(path: '/pro/{id}/networks/{networkId}/sectors', name: 'api_network_sectors', requirements: ['id' => '\d+', 'networkId' => '\d+'])] -#[\Symfony\Component\Security\Http\Attribute\IsGranted('TEST')] +#[IsGranted('TEST')] class WithExistingAttribute extends AbstractController { }