diff --git a/packages/BetterPhpDocParser/PhpDocManipulator/PhpDocClassRenamer.php b/packages/BetterPhpDocParser/PhpDocManipulator/PhpDocClassRenamer.php index f448910fab7..19a076f9f8e 100644 --- a/packages/BetterPhpDocParser/PhpDocManipulator/PhpDocClassRenamer.php +++ b/packages/BetterPhpDocParser/PhpDocManipulator/PhpDocClassRenamer.php @@ -12,6 +12,7 @@ use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo; 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 { /** @@ -19,9 +20,15 @@ final class PhpDocClassRenamer * @var \Rector\BetterPhpDocParser\PhpDocParser\ClassAnnotationMatcher */ private $classAnnotationMatcher; - public function __construct(ClassAnnotationMatcher $classAnnotationMatcher) + /** + * @readonly + * @var \Rector\Renaming\Collector\RenamedNameCollector + */ + private $renamedNameCollector; + public function __construct(ClassAnnotationMatcher $classAnnotationMatcher, RenamedNameCollector $renamedNameCollector) { $this->classAnnotationMatcher = $classAnnotationMatcher; + $this->renamedNameCollector = $renamedNameCollector; } /** * Covers annotations like @ORM, @Serializer, @Assert etc @@ -64,6 +71,7 @@ final class PhpDocClassRenamer if ($classNameStringNode->value !== $oldClass) { continue; } + $this->renamedNameCollector->add($oldClass); $classNameStringNode->value = $newClass; // trigger reprint $classNameArrayItemNode->setAttribute(PhpDocAttributeKey::ORIG_NODE, null); @@ -99,6 +107,7 @@ final class PhpDocClassRenamer $classNameStringNode->value = $newClass; continue; } + $this->renamedNameCollector->add($oldClass); $classNameStringNode->value = Strings::replace($classNameStringNode->value, '#\\b' . \preg_quote($oldClass, '#') . '\\b#', $newClass); $classNameArrayItemNode->setAttribute(PhpDocAttributeKey::ORIG_NODE, null); $hasChanged = \true; @@ -138,6 +147,7 @@ final class PhpDocClassRenamer if ($tagFullyQualifiedName !== $oldClass) { continue; } + $this->renamedNameCollector->add($oldClass); $targetEntityStringNode->value = $newClass; $targetEntityArrayItemNode->setAttribute(PhpDocAttributeKey::ORIG_NODE, null); $hasChanged = \true; diff --git a/packages/NodeTypeResolver/PhpDocNodeVisitor/ClassRenamePhpDocNodeVisitor.php b/packages/NodeTypeResolver/PhpDocNodeVisitor/ClassRenamePhpDocNodeVisitor.php index 14f54d0f8c1..c4be43754ec 100644 --- a/packages/NodeTypeResolver/PhpDocNodeVisitor/ClassRenamePhpDocNodeVisitor.php +++ b/packages/NodeTypeResolver/PhpDocNodeVisitor/ClassRenamePhpDocNodeVisitor.php @@ -19,6 +19,7 @@ use Rector\Naming\Naming\UseImportsResolver; 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; final class ClassRenamePhpDocNodeVisitor extends AbstractPhpDocNodeVisitor @@ -33,6 +34,11 @@ final class ClassRenamePhpDocNodeVisitor extends AbstractPhpDocNodeVisitor * @var \Rector\Naming\Naming\UseImportsResolver */ private $useImportsResolver; + /** + * @readonly + * @var \Rector\Renaming\Collector\RenamedNameCollector + */ + private $renamedNameCollector; /** * @var OldToNewType[] */ @@ -45,10 +51,11 @@ final class ClassRenamePhpDocNodeVisitor extends AbstractPhpDocNodeVisitor * @var PhpNode|null */ private $currentPhpNode; - public function __construct(StaticTypeMapper $staticTypeMapper, UseImportsResolver $useImportsResolver) + public function __construct(StaticTypeMapper $staticTypeMapper, UseImportsResolver $useImportsResolver, RenamedNameCollector $renamedNameCollector) { $this->staticTypeMapper = $staticTypeMapper; $this->useImportsResolver = $useImportsResolver; + $this->renamedNameCollector = $renamedNameCollector; } public function setCurrentPhpNode(PhpNode $phpNode) : void { @@ -81,7 +88,9 @@ final class ClassRenamePhpDocNodeVisitor extends AbstractPhpDocNodeVisitor // 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; } $newTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($oldToNewType->getNewType()); @@ -91,6 +100,7 @@ final class ClassRenamePhpDocNodeVisitor extends AbstractPhpDocNodeVisitor $newTypeNode->setAttribute(PhpDocAttributeKey::PARENT, $parentType); } $this->hasChanged = \true; + $this->renamedNameCollector->add($oldType->getClassName()); return $newTypeNode; } return null; diff --git a/packages/PostRector/Rector/ClassRenamingPostRector.php b/packages/PostRector/Rector/ClassRenamingPostRector.php index d0cb55705db..4ad04490ca3 100644 --- a/packages/PostRector/Rector/ClassRenamingPostRector.php +++ b/packages/PostRector/Rector/ClassRenamingPostRector.php @@ -16,6 +16,7 @@ use Rector\Core\Configuration\RenamedClassesDataCollector; 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 \Rector\PostRector\Rector\AbstractPostRector { /** @@ -33,15 +34,21 @@ final class ClassRenamingPostRector extends \Rector\PostRector\Rector\AbstractPo * @var \Rector\CodingStyle\Application\UseImportsRemover */ private $useImportsRemover; + /** + * @readonly + * @var \Rector\Renaming\Collector\RenamedNameCollector + */ + private $renamedNameCollector; /** * @var \Rector\Core\PhpParser\Node\CustomNode\FileWithoutNamespace|\PhpParser\Node\Stmt\Namespace_|null */ private $rootNode = null; - public function __construct(ClassRenamer $classRenamer, RenamedClassesDataCollector $renamedClassesDataCollector, UseImportsRemover $useImportsRemover) + public function __construct(ClassRenamer $classRenamer, RenamedClassesDataCollector $renamedClassesDataCollector, UseImportsRemover $useImportsRemover, RenamedNameCollector $renamedNameCollector) { $this->classRenamer = $classRenamer; $this->renamedClassesDataCollector = $renamedClassesDataCollector; $this->useImportsRemover = $useImportsRemover; + $this->renamedNameCollector = $renamedNameCollector; } /** * @param Stmt[] $nodes @@ -88,4 +95,13 @@ final class ClassRenamingPostRector extends \Rector\PostRector\Rector\AbstractPo $this->rootNode->stmts = $this->useImportsRemover->removeImportsFromStmts($this->rootNode->stmts, $removedUses); return $result; } + /** + * @param Node[] $nodes + * @return Stmt[] + */ + public function afterTraverse(array $nodes) : array + { + $this->renamedNameCollector->reset(); + return $nodes; + } } diff --git a/rules/CodingStyle/Application/UseImportsRemover.php b/rules/CodingStyle/Application/UseImportsRemover.php index 0315d9f2284..9508d7a8951 100644 --- a/rules/CodingStyle/Application/UseImportsRemover.php +++ b/rules/CodingStyle/Application/UseImportsRemover.php @@ -5,8 +5,18 @@ namespace Rector\CodingStyle\Application; use PhpParser\Node\Stmt; use PhpParser\Node\Stmt\Use_; +use Rector\Renaming\Collector\RenamedNameCollector; final class UseImportsRemover { + /** + * @readonly + * @var \Rector\Renaming\Collector\RenamedNameCollector + */ + private $renamedNameCollector; + public function __construct(RenamedNameCollector $renamedNameCollector) + { + $this->renamedNameCollector = $renamedNameCollector; + } /** * @param Stmt[] $stmts * @param string[] $removedUses @@ -33,9 +43,13 @@ final class UseImportsRemover { 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; } diff --git a/rules/Renaming/Collector/RenamedNameCollector.php b/rules/Renaming/Collector/RenamedNameCollector.php new file mode 100644 index 00000000000..753acc8d837 --- /dev/null +++ b/rules/Renaming/Collector/RenamedNameCollector.php @@ -0,0 +1,24 @@ +names[] = $name; + } + public function has(string $name) : bool + { + return \in_array($name, $this->names, \true); + } + public function reset() : void + { + $this->names = []; + } +} diff --git a/rules/Renaming/NodeManipulator/ClassRenamer.php b/rules/Renaming/NodeManipulator/ClassRenamer.php index 703f6291c8f..e52f702752d 100644 --- a/rules/Renaming/NodeManipulator/ClassRenamer.php +++ b/rules/Renaming/NodeManipulator/ClassRenamer.php @@ -28,6 +28,7 @@ use Rector\NodeTypeResolver\Node\AttributeKey; 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 { @@ -81,6 +82,11 @@ final class ClassRenamer * @var \Rector\Comments\NodeDocBlock\DocBlockUpdater */ private $docBlockUpdater; + /** + * @readonly + * @var \Rector\Renaming\Collector\RenamedNameCollector + */ + private $renamedNameCollector; /** * @var string[] */ @@ -89,7 +95,7 @@ final class ClassRenamer * @var array */ private $oldToNewTypesByCacheKey = []; - public function __construct(BetterNodeFinder $betterNodeFinder, SimpleCallableNodeTraverser $simpleCallableNodeTraverser, ClassNaming $classNaming, NodeNameResolver $nodeNameResolver, PhpDocClassRenamer $phpDocClassRenamer, PhpDocInfoFactory $phpDocInfoFactory, DocBlockClassRenamer $docBlockClassRenamer, ReflectionProvider $reflectionProvider, FileHasher $fileHasher, DocBlockUpdater $docBlockUpdater) + public function __construct(BetterNodeFinder $betterNodeFinder, SimpleCallableNodeTraverser $simpleCallableNodeTraverser, ClassNaming $classNaming, NodeNameResolver $nodeNameResolver, PhpDocClassRenamer $phpDocClassRenamer, PhpDocInfoFactory $phpDocInfoFactory, DocBlockClassRenamer $docBlockClassRenamer, ReflectionProvider $reflectionProvider, FileHasher $fileHasher, DocBlockUpdater $docBlockUpdater, RenamedNameCollector $renamedNameCollector) { $this->betterNodeFinder = $betterNodeFinder; $this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser; @@ -101,6 +107,7 @@ final class ClassRenamer $this->reflectionProvider = $reflectionProvider; $this->fileHasher = $fileHasher; $this->docBlockUpdater = $docBlockUpdater; + $this->renamedNameCollector = $renamedNameCollector; } /** * @param array $oldToNewClasses @@ -179,6 +186,7 @@ final class ClassRenamer if ($this->shouldSkip($newName, $name)) { return null; } + $this->renamedNameCollector->add($stringName); return new FullyQualified($newName); } /** diff --git a/src/Application/VersionResolver.php b/src/Application/VersionResolver.php index 1ca6b6b94be..c8ef76a8bc4 100644 --- a/src/Application/VersionResolver.php +++ b/src/Application/VersionResolver.php @@ -19,12 +19,12 @@ final class VersionResolver * @api * @var string */ - public const PACKAGE_VERSION = '290f2a03d53d0b8da35beb973d724f95a77983cb'; + public const PACKAGE_VERSION = 'cb1b0c7348d1e80806b2e600823dbfa38b9836c7'; /** * @api * @var string */ - public const RELEASE_DATE = '2023-11-08 02:10:08'; + public const RELEASE_DATE = '2023-11-07 22:49:21'; /** * @var int */ diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 44c25ad0f99..00005e9552c 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -1969,6 +1969,7 @@ return array( 'Rector\\Removing\\Rector\\FuncCall\\RemoveFuncCallRector' => $baseDir . '/rules/Removing/Rector/FuncCall/RemoveFuncCallRector.php', 'Rector\\Removing\\ValueObject\\ArgumentRemover' => $baseDir . '/rules/Removing/ValueObject/ArgumentRemover.php', 'Rector\\Removing\\ValueObject\\RemoveFuncCallArg' => $baseDir . '/rules/Removing/ValueObject/RemoveFuncCallArg.php', + 'Rector\\Renaming\\Collector\\RenamedNameCollector' => $baseDir . '/rules/Renaming/Collector/RenamedNameCollector.php', 'Rector\\Renaming\\Contract\\MethodCallRenameInterface' => $baseDir . '/rules/Renaming/Contract/MethodCallRenameInterface.php', 'Rector\\Renaming\\Contract\\RenameAnnotationInterface' => $baseDir . '/rules/Renaming/Contract/RenameAnnotationInterface.php', 'Rector\\Renaming\\Contract\\RenameClassConstFetchInterface' => $baseDir . '/rules/Renaming/Contract/RenameClassConstFetchInterface.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 3cb2556c217..e67f9641b18 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -2187,6 +2187,7 @@ class ComposerStaticInit18ad0e678efbbb500e116f7c54cccdd4 'Rector\\Removing\\Rector\\FuncCall\\RemoveFuncCallRector' => __DIR__ . '/../..' . '/rules/Removing/Rector/FuncCall/RemoveFuncCallRector.php', 'Rector\\Removing\\ValueObject\\ArgumentRemover' => __DIR__ . '/../..' . '/rules/Removing/ValueObject/ArgumentRemover.php', 'Rector\\Removing\\ValueObject\\RemoveFuncCallArg' => __DIR__ . '/../..' . '/rules/Removing/ValueObject/RemoveFuncCallArg.php', + 'Rector\\Renaming\\Collector\\RenamedNameCollector' => __DIR__ . '/../..' . '/rules/Renaming/Collector/RenamedNameCollector.php', 'Rector\\Renaming\\Contract\\MethodCallRenameInterface' => __DIR__ . '/../..' . '/rules/Renaming/Contract/MethodCallRenameInterface.php', 'Rector\\Renaming\\Contract\\RenameAnnotationInterface' => __DIR__ . '/../..' . '/rules/Renaming/Contract/RenameAnnotationInterface.php', 'Rector\\Renaming\\Contract\\RenameClassConstFetchInterface' => __DIR__ . '/../..' . '/rules/Renaming/Contract/RenameClassConstFetchInterface.php',