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
16 changes: 11 additions & 5 deletions packages/PostRector/Rector/ClassRenamingPostRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand All @@ -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);
}
}
Comment on lines +67 to +72
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the trick 👍 , on ClassRenamingPostRector, verify that Name is not FullyQualified, which:

$this->phpAttributeGroupFactory->create()

can return a Name instead of FullyQualified with bring original attribute name to be renamed, then use it to be returned so it can be processed on next loop on FileProcessor.


if (! SimpleParameterProvider::provideBoolParameter(Option::AUTO_IMPORT_NAMES)) {
return $result;
}
Expand Down
25 changes: 1 addition & 24 deletions packages/PostRector/Rector/NameImportingPostRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
) {
}

Expand All @@ -62,7 +60,6 @@ public function enterNode(Node $node): ?Node
}

if ($node instanceof Name) {
$node = $this->resolveNameFromAttribute($node);
return $this->processNodeName($node, $file);
}

Expand All @@ -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()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -23,6 +24,7 @@ final class FullyQualifiedNameClassNameImportSkipVoter implements ClassNameImpor
{
public function __construct(
private readonly ShortNameResolver $shortNameResolver,
private readonly RenamedClassesDataCollector $renamedClassesDataCollector
) {
}

Expand All @@ -31,12 +33,17 @@ public function shouldSkip(File $file, FullyQualifiedObjectType $fullyQualifiedO
// "new X" or "X::static()"
/** @var array<string, string> $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;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Rector\Core\Tests\Issues\RenameAnnotationToAttributeAutoImport\Fixture;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

/**
* @IsGranted("TEST")
*/
#[Route(path: '/pro/{id}/networks/{networkId}/sectors', name: 'api_network_sectors', requirements: ['id' => '\d+', 'networkId' => '\d+'])]
class WithExistingAttribute extends AbstractController
{
}

?>
-----
<?php

namespace Rector\Core\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+'])]
#[IsGranted('TEST')]
class WithExistingAttribute extends AbstractController
{
}

?>