From 6bbdd262fdd0f41d5c0a1a28fa19973dcce74d4b Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sun, 11 Oct 2026 18:26:49 +0200 Subject: [PATCH 1/2] [perf] Skip phpdoc path in RenameClassRector for nodes without a docblock The rule visits Expression, If_, FunctionLike, Property and ClassLike nodes. For every one it built a PhpDocInfo and ran the phpdoc rename, even though only a real docblock can carry a renamable type. On rector-src src+rules that phpdoc path fired 28k times but only ~4k nodes had a docblock. Guard it with a cheap getDocComment() check so createFromNode and refactorPhpDoc run only when there is a docblock. Also drop the per-call serialize()+hash in createOldToNewTypes; the rename map is constant during a run, so memoize on the identical array and remove the now unused FileHasher dependency. --- .../Renaming/NodeManipulator/ClassRenamer.php | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/rules/Renaming/NodeManipulator/ClassRenamer.php b/rules/Renaming/NodeManipulator/ClassRenamer.php index 1f1d2ed767f..fe672918522 100644 --- a/rules/Renaming/NodeManipulator/ClassRenamer.php +++ b/rules/Renaming/NodeManipulator/ClassRenamer.php @@ -24,21 +24,24 @@ use Rector\NodeTypeResolver\ValueObject\OldToNewType; use Rector\Renaming\Collector\RenamedNameCollector; use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType; -use Rector\Util\FileHasher; final class ClassRenamer { /** - * @var array + * @var array */ - private array $oldToNewTypesByCacheKey = []; + private array $oldToNewClasses = []; + + /** + * @var OldToNewType[] + */ + private array $oldToNewTypes = []; public function __construct( private readonly PhpDocClassRenamer $phpDocClassRenamer, private readonly PhpDocInfoFactory $phpDocInfoFactory, private readonly DocBlockClassRenamer $docBlockClassRenamer, private readonly ReflectionProvider $reflectionProvider, - private readonly FileHasher $fileHasher, private readonly DocBlockUpdater $docBlockUpdater, private readonly RenamedNameCollector $renamedNameCollector ) { @@ -65,13 +68,16 @@ public function renameNode(Node $node, array $oldToNewClasses, ?Scope $scope): ? return null; } - $phpDocInfo = $this->phpDocInfoFactory->createFromNode($node); - if ($phpDocInfo instanceof PhpDocInfo) { - $oldToNewTypes = $this->createOldToNewTypes($oldToNewClasses); - $hasPhpDocChanged = $this->refactorPhpDoc($node, $oldToNewTypes, $oldToNewClasses, $phpDocInfo); + // only a real docblock can carry a renamable type; plain comments or none never change here + if ($node->getDocComment() !== null) { + $phpDocInfo = $this->phpDocInfoFactory->createFromNode($node); + if ($phpDocInfo instanceof PhpDocInfo) { + $oldToNewTypes = $this->createOldToNewTypes($oldToNewClasses); + $hasPhpDocChanged = $this->refactorPhpDoc($node, $oldToNewTypes, $oldToNewClasses, $phpDocInfo); - if ($hasPhpDocChanged) { - return $node; + if ($hasPhpDocChanged) { + return $node; + } } } @@ -261,11 +267,9 @@ private function isValidClassNameChange(FullyQualified $fullyQualified, ClassRef */ private function createOldToNewTypes(array $oldToNewClasses): array { - $serialized = \serialize($oldToNewClasses); - $cacheKey = $this->fileHasher->hash($serialized); - - if (isset($this->oldToNewTypesByCacheKey[$cacheKey])) { - return $this->oldToNewTypesByCacheKey[$cacheKey]; + // the rename map is constant during a run, so memoize on the identical array + if ($this->oldToNewClasses === $oldToNewClasses) { + return $this->oldToNewTypes; } $oldToNewTypes = []; @@ -276,7 +280,8 @@ private function createOldToNewTypes(array $oldToNewClasses): array $oldToNewTypes[] = new OldToNewType($oldObjectType, $newObjectType); } - $this->oldToNewTypesByCacheKey[$cacheKey] = $oldToNewTypes; + $this->oldToNewClasses = $oldToNewClasses; + $this->oldToNewTypes = $oldToNewTypes; return $oldToNewTypes; } From b1b944543d7eea96c1ddc1c1e40b4898fe4a6dca Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Sun, 11 Oct 2026 16:28:09 +0000 Subject: [PATCH 2/2] [ci-review] Rector Rectify --- rules/Renaming/NodeManipulator/ClassRenamer.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rules/Renaming/NodeManipulator/ClassRenamer.php b/rules/Renaming/NodeManipulator/ClassRenamer.php index fe672918522..01e92030d1d 100644 --- a/rules/Renaming/NodeManipulator/ClassRenamer.php +++ b/rules/Renaming/NodeManipulator/ClassRenamer.php @@ -4,6 +4,7 @@ namespace Rector\Renaming\NodeManipulator; +use PhpParser\Comment\Doc; use PhpParser\Node; use PhpParser\Node\AttributeGroup; use PhpParser\Node\Name; @@ -69,7 +70,7 @@ public function renameNode(Node $node, array $oldToNewClasses, ?Scope $scope): ? } // only a real docblock can carry a renamable type; plain comments or none never change here - if ($node->getDocComment() !== null) { + if ($node->getDocComment() instanceof Doc) { $phpDocInfo = $this->phpDocInfoFactory->createFromNode($node); if ($phpDocInfo instanceof PhpDocInfo) { $oldToNewTypes = $this->createOldToNewTypes($oldToNewClasses);