Skip to content

Commit

Permalink
[Renaming] Add RenamedNameCollector to ensure remove uses on auto imp…
Browse files Browse the repository at this point in the history
…ort on ClassRenamingPostRector with verify there is Node name that renamed (#5232)
  • Loading branch information
samsonasik committed Nov 7, 2023
1 parent 290f2a0 commit cb1b0c7
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@
use Rector\BetterPhpDocParser\PhpDocParser\ClassAnnotationMatcher;
use Rector\BetterPhpDocParser\ValueObject\PhpDoc\DoctrineAnnotation\CurlyListNode;
use Rector\BetterPhpDocParser\ValueObject\PhpDocAttributeKey;
use Rector\Renaming\Collector\RenamedNameCollector;

final class PhpDocClassRenamer
{
public function __construct(
private readonly ClassAnnotationMatcher $classAnnotationMatcher
private readonly ClassAnnotationMatcher $classAnnotationMatcher,
private readonly RenamedNameCollector $renamedNameCollector
) {
}

Expand Down Expand Up @@ -80,6 +82,7 @@ private function processAssertChoiceTagValueNode(
continue;
}

$this->renamedNameCollector->add($oldClass);
$classNameStringNode->value = $newClass;

// trigger reprint
Expand Down Expand Up @@ -135,6 +138,7 @@ private function processSerializerTypeTagValueNode(
continue;
}

$this->renamedNameCollector->add($oldClass);
$classNameStringNode->value = Strings::replace(
$classNameStringNode->value,
'#\b' . preg_quote($oldClass, '#') . '\b#',
Expand Down Expand Up @@ -197,6 +201,7 @@ private function processDoctrineToMany(
continue;
}

$this->renamedNameCollector->add($oldClass);
$targetEntityStringNode->value = $newClass;
$targetEntityArrayItemNode->setAttribute(PhpDocAttributeKey::ORIG_NODE, null);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\ValueObject\OldToNewType;
use Rector\PhpDocParser\PhpDocParser\PhpDocNodeVisitor\AbstractPhpDocNodeVisitor;
use Rector\Renaming\Collector\RenamedNameCollector;
use Rector\StaticTypeMapper\StaticTypeMapper;
use Rector\StaticTypeMapper\ValueObject\Type\ShortenedObjectType;

Expand All @@ -37,6 +38,7 @@ final class ClassRenamePhpDocNodeVisitor extends AbstractPhpDocNodeVisitor
public function __construct(
private readonly StaticTypeMapper $staticTypeMapper,
private readonly UseImportsResolver $useImportsResolver,
private readonly RenamedNameCollector $renamedNameCollector
) {
}

Expand Down Expand Up @@ -79,7 +81,9 @@ public function enterNode(Node $node): ?Node
// make sure to compare FQNs
$objectType = $this->expandShortenedObjectType($staticType);
foreach ($this->oldToNewTypes as $oldToNewType) {
if (! $objectType->equals($oldToNewType->getOldType())) {
/** @var ObjectType $oldType */
$oldType = $oldToNewType->getOldType();
if (! $objectType->equals($oldType)) {
continue;
}

Expand All @@ -93,6 +97,7 @@ public function enterNode(Node $node): ?Node

$this->hasChanged = true;

$this->renamedNameCollector->add($oldType->getClassName());
return $newTypeNode;
}

Expand Down
14 changes: 13 additions & 1 deletion packages/PostRector/Rector/ClassRenamingPostRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Rector\Core\PhpParser\Node\CustomNode\FileWithoutNamespace;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Renaming\NodeManipulator\ClassRenamer;
use Rector\Renaming\Collector\RenamedNameCollector;

final class ClassRenamingPostRector extends AbstractPostRector
{
Expand All @@ -25,7 +26,8 @@ final class ClassRenamingPostRector extends AbstractPostRector
public function __construct(
private readonly ClassRenamer $classRenamer,
private readonly RenamedClassesDataCollector $renamedClassesDataCollector,
private readonly UseImportsRemover $useImportsRemover
private readonly UseImportsRemover $useImportsRemover,
private readonly RenamedNameCollector $renamedNameCollector
) {
}

Expand Down Expand Up @@ -88,4 +90,14 @@ public function enterNode(Node $node): ?Node

return $result;
}

/**
* @param Node[] $nodes
* @return Stmt[]
*/
public function afterTraverse(array $nodes): array
{
$this->renamedNameCollector->reset();
return $nodes;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace Rector\Tests\Renaming\Rector\Name\RenameClassRector\FixtureAutoImportNamesWithoutRemoveUnusedImport;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;

/**
* IsGranted annotation is not changed, as the real use case is to change to attribute first
*
* @see https://github.com/rectorphp/rector-src/blob/290f2a03d53d0b8da35beb973d724f95a77983cb/tests/Issues/AnnotationToAttributeRenameAutoImport/config/configured_rule.php#L13-L22
* @see https://github.com/rectorphp/rector-symfony/issues/535
*
* @IsGranted
*/
class SkipIsGrantedAnnotation
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,16 @@
$rectorConfig->ruleWithConfiguration(RenameClassRector::class, [
'Interop\Container\ContainerInterface' => 'Psr\Container\ContainerInterface',
'DateTime' => 'DateTimeInterface',
/**
* This test never renamed as it is annotation @IsGranted
*
* Only Assert, Doctrine, and Serializer type annotation that currently supported
*
* For @IsGranted, it needs to be changed to Attribute instead
*
* @see https://github.com/rectorphp/rector-src/blob/290f2a03d53d0b8da35beb973d724f95a77983cb/tests/Issues/AnnotationToAttributeRenameAutoImport/config/configured_rule.php#L13-L22
* @see https://github.com/rectorphp/rector-symfony/issues/535
*/
'Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted' => 'Symfony\Component\Security\Http\Attribute\IsGranted',
]);
};
15 changes: 13 additions & 2 deletions rules/CodingStyle/Application/UseImportsRemover.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@

use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Use_;
use Rector\Renaming\Collector\RenamedNameCollector;

final class UseImportsRemover
{
public function __construct(private readonly RenamedNameCollector $renamedNameCollector)
{
}

/**
* @param Stmt[] $stmts
* @param string[] $removedUses
Expand Down Expand Up @@ -39,9 +44,15 @@ private function removeUseFromUse(array $removedUses, Use_ $use): Use_
{
foreach ($use->uses as $usesKey => $useUse) {
$useName = $useUse->name->toString();
if (in_array($useName, $removedUses, true)) {
unset($use->uses[$usesKey]);
if (! in_array($useName, $removedUses, true)) {
continue;
}

if (! $this->renamedNameCollector->has($useName)) {
continue;
}

unset($use->uses[$usesKey]);
}

return $use;
Expand Down
28 changes: 28 additions & 0 deletions rules/Renaming/Collector/RenamedNameCollector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Rector\Renaming\Collector;

final class RenamedNameCollector
{
/**
* @var string[]
*/
private array $names = [];

public function add(string $name): void
{
$this->names[] = $name;
}

public function has(string $name): bool
{
return in_array($name, $this->names, true);
}

public function reset(): void
{
$this->names = [];
}
}
3 changes: 3 additions & 0 deletions rules/Renaming/NodeManipulator/ClassRenamer.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockClassRenamer;
use Rector\NodeTypeResolver\ValueObject\OldToNewType;
use Rector\PhpDocParser\NodeTraverser\SimpleCallableNodeTraverser;
use Rector\Renaming\Collector\RenamedNameCollector;
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;

final class ClassRenamer
Expand All @@ -54,6 +55,7 @@ public function __construct(
private readonly ReflectionProvider $reflectionProvider,
private readonly FileHasher $fileHasher,
private readonly DocBlockUpdater $docBlockUpdater,
private readonly RenamedNameCollector $renamedNameCollector
) {
}

Expand Down Expand Up @@ -167,6 +169,7 @@ private function refactorName(Name $name, array $oldToNewClasses): ?Name
return null;
}

$this->renamedNameCollector->add($stringName);
return new FullyQualified($newName);
}

Expand Down

0 comments on commit cb1b0c7

Please sign in to comment.