diff --git a/packages/PostRector/Rector/ClassRenamingPostRector.php b/packages/PostRector/Rector/ClassRenamingPostRector.php index 524005068b5..1876764912c 100644 --- a/packages/PostRector/Rector/ClassRenamingPostRector.php +++ b/packages/PostRector/Rector/ClassRenamingPostRector.php @@ -5,11 +5,10 @@ namespace Rector\PostRector\Rector; use PhpParser\Node; -use PhpParser\Node\Arg; -use PhpParser\Node\Expr; +use PhpParser\Node\Name; +use PhpParser\Node\Name\FullyQualified; use PhpParser\Node\Stmt; use PhpParser\Node\Stmt\Namespace_; -use PhpParser\Node\Stmt\PropertyProperty; use PHPStan\Analyser\Scope; use Rector\CodingStyle\Application\UseImportsRemover; use Rector\Core\Configuration\Option; @@ -51,8 +50,8 @@ public function beforeTraverse(array $nodes): array public function enterNode(Node $node): ?Node { - // cannot be renamed - if ($node instanceof Expr || $node instanceof Arg || $node instanceof PropertyProperty) { + // no longer need post rename + if (! $node instanceof Name) { return null; } @@ -65,6 +64,13 @@ public function enterNode(Node $node): ?Node $scope = $node->getAttribute(AttributeKey::SCOPE); $result = $this->classRenamer->renameNode($node, $oldToNewClasses, $scope); + if (! $result instanceof Name && ! $node instanceof FullyQualified) { + $phpAttributeName = $node->getAttribute(AttributeKey::PHP_ATTRIBUTE_NAME); + if (is_string($phpAttributeName)) { + return $this->classRenamer->renameNode(new FullyQualified($phpAttributeName, $node->getAttributes()), $oldToNewClasses, $scope); + } + } + if (! SimpleParameterProvider::provideBoolParameter(Option::AUTO_IMPORT_NAMES)) { return $result; } diff --git a/packages/PostRector/Rector/NameImportingPostRector.php b/packages/PostRector/Rector/NameImportingPostRector.php index 76e3d576d2d..c1f4c511d8b 100644 --- a/packages/PostRector/Rector/NameImportingPostRector.php +++ b/packages/PostRector/Rector/NameImportingPostRector.php @@ -21,7 +21,6 @@ use Rector\Comments\NodeDocBlock\DocBlockUpdater; use Rector\Core\Configuration\Option; use Rector\Core\Configuration\Parameter\SimpleParameterProvider; -use Rector\Core\Configuration\RenamedClassesDataCollector; use Rector\Core\PhpParser\Node\CustomNode\FileWithoutNamespace; use Rector\Core\Provider\CurrentFileProvider; use Rector\Core\ValueObject\Application\File; @@ -40,8 +39,7 @@ public function __construct( private readonly CurrentFileProvider $currentFileProvider, private readonly UseImportsResolver $useImportsResolver, private readonly AliasNameResolver $aliasNameResolver, - private readonly DocBlockUpdater $docBlockUpdater, - private readonly RenamedClassesDataCollector $renamedClassesDataCollector + private readonly DocBlockUpdater $docBlockUpdater ) { } @@ -62,7 +60,6 @@ public function enterNode(Node $node): ?Node } if ($node instanceof Name) { - $node = $this->resolveNameFromAttribute($node); return $this->processNodeName($node, $file); } @@ -89,26 +86,6 @@ public function enterNode(Node $node): ?Node return $node; } - private function resolveNameFromAttribute(Name $name): Name - { - if ($name instanceof FullyQualified) { - return $name; - } - - if (array_keys($name->getAttributes()) === [AttributeKey::PHP_ATTRIBUTE_NAME]) { - $oldToNewClasses = $this->renamedClassesDataCollector->getOldToNewClasses(); - $phpAttributeName = $name->getAttribute(AttributeKey::PHP_ATTRIBUTE_NAME); - - foreach ($oldToNewClasses as $oldName => $newName) { - if ($oldName === $phpAttributeName) { - return new FullyQualified($newName, $name->getAttributes()); - } - } - } - - return $name; - } - private function processNodeName(Name $name, File $file): ?Node { if ($name->isSpecialClassName()) { diff --git a/rules/CodingStyle/ClassNameImport/ClassNameImportSkipVoter/FullyQualifiedNameClassNameImportSkipVoter.php b/rules/CodingStyle/ClassNameImport/ClassNameImportSkipVoter/FullyQualifiedNameClassNameImportSkipVoter.php index b230f16db03..0b8e9bf8175 100644 --- a/rules/CodingStyle/ClassNameImport/ClassNameImportSkipVoter/FullyQualifiedNameClassNameImportSkipVoter.php +++ b/rules/CodingStyle/ClassNameImport/ClassNameImportSkipVoter/FullyQualifiedNameClassNameImportSkipVoter.php @@ -7,6 +7,7 @@ use PhpParser\Node; use Rector\CodingStyle\ClassNameImport\ShortNameResolver; use Rector\CodingStyle\Contract\ClassNameImport\ClassNameImportSkipVoterInterface; +use Rector\Core\Configuration\RenamedClassesDataCollector; use Rector\Core\ValueObject\Application\File; use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType; @@ -23,6 +24,7 @@ final class FullyQualifiedNameClassNameImportSkipVoter implements ClassNameImpor { public function __construct( private readonly ShortNameResolver $shortNameResolver, + private readonly RenamedClassesDataCollector $renamedClassesDataCollector ) { } @@ -31,12 +33,17 @@ public function shouldSkip(File $file, FullyQualifiedObjectType $fullyQualifiedO // "new X" or "X::static()" /** @var array $shortNamesToFullyQualifiedNames */ $shortNamesToFullyQualifiedNames = $this->shortNameResolver->resolveFromFile($file); + $removedUses = $this->renamedClassesDataCollector->getOldClasses(); foreach ($shortNamesToFullyQualifiedNames as $shortName => $fullyQualifiedName) { if ($fullyQualifiedObjectType->getShortName() !== $shortName) { continue; } + if (in_array($fullyQualifiedName, $removedUses, true)) { + continue; + } + return $fullyQualifiedObjectType->getClassName() !== $fullyQualifiedName; } diff --git a/tests/Issues/AnnotationToAttributeRenameAutoImport/Fixture/with_existing_attribute.php.inc b/tests/Issues/AnnotationToAttributeRenameAutoImport/Fixture/with_existing_attribute.php.inc new file mode 100644 index 00000000000..456bb21bc6e --- /dev/null +++ b/tests/Issues/AnnotationToAttributeRenameAutoImport/Fixture/with_existing_attribute.php.inc @@ -0,0 +1,33 @@ + '\d+', 'networkId' => '\d+'])] +class WithExistingAttribute extends AbstractController +{ +} + +?> +----- + '\d+', 'networkId' => '\d+'])] +#[IsGranted('TEST')] +class WithExistingAttribute extends AbstractController +{ +} + +?>