From 677e920dbeba84dd7073f6558feda51b7df120da Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Wed, 21 Aug 2019 18:32:14 +0200 Subject: [PATCH] [RenameClassRector] Include @ORM, @Assert, @Serializer etc annotations --- .../NodeAnalyzer/DocBlockManipulator.php | 5 -- src/Rector/Class_/RenameClassRector.php | 39 ++++++++++ .../Fixture/class_annotations.php.inc | 77 +++++++++++++++++++ .../RenameClassRectorTest.php | 3 + 4 files changed, 119 insertions(+), 5 deletions(-) create mode 100644 tests/Rector/Class_/RenameClassRector/Fixture/class_annotations.php.inc diff --git a/packages/NodeTypeResolver/src/PhpDoc/NodeAnalyzer/DocBlockManipulator.php b/packages/NodeTypeResolver/src/PhpDoc/NodeAnalyzer/DocBlockManipulator.php index 2f2c6ed2a6e3..45bfc8457edd 100644 --- a/packages/NodeTypeResolver/src/PhpDoc/NodeAnalyzer/DocBlockManipulator.php +++ b/packages/NodeTypeResolver/src/PhpDoc/NodeAnalyzer/DocBlockManipulator.php @@ -500,11 +500,6 @@ public function changeUnderscoreType(Node $node, string $namespacePrefix, ?array $this->updateNodeWithPhpDocInfo($node, $phpDocInfo); } - public function resetImportedNames(): void - { - $this->importedNames = []; - } - /** * For better performance */ diff --git a/src/Rector/Class_/RenameClassRector.php b/src/Rector/Class_/RenameClassRector.php index 8dc93632ace1..891ecd0e94af 100644 --- a/src/Rector/Class_/RenameClassRector.php +++ b/src/Rector/Class_/RenameClassRector.php @@ -2,6 +2,8 @@ namespace Rector\Rector\Class_; +use Nette\Utils\Strings; +use PhpParser\Comment\Doc; use PhpParser\Node; use PhpParser\Node\Expr\New_; use PhpParser\Node\FunctionLike; @@ -121,6 +123,8 @@ public function refactor(Node $node): ?Node } } + $this->changeTypeInAnnotationTypes($node); + if ($node instanceof Name) { return $this->refactorName($node); } @@ -297,4 +301,39 @@ private function refactorName(Node $node): ?Name return new FullyQualified($newName); } + + /** + * Covers annotations like @ORM, @Serializer, @Assert etc + * See https://github.com/rectorphp/rector/issues/1872 + */ + private function changeTypeInAnnotationTypes(Node $node): void + { + $docComment = $node->getDocComment(); + if ($docComment === null) { + return; + } + + $textDocComment = $docComment->getText(); + + $oldTypes = array_keys($this->oldToNewClasses); + + $oldTypesPregQuoted = []; + foreach ($oldTypes as $oldType) { + $oldTypesPregQuoted[] = '\b' . preg_quote($oldType) . '\b'; + } + + $oldTypesPattern = '#(?|' . implode('|', $oldTypesPregQuoted) . ')#x'; + + $match = Strings::match($textDocComment, $oldTypesPattern); + if ($match === null) { + return; + } + + foreach ($match as $matchedOldType) { + $newType = $this->oldToNewClasses[$matchedOldType]; + $textDocComment = Strings::replace($textDocComment, '#\b' . preg_quote($matchedOldType) . '\b#', $newType); + } + + $node->setDocComment(new Doc($textDocComment)); + } } diff --git a/tests/Rector/Class_/RenameClassRector/Fixture/class_annotations.php.inc b/tests/Rector/Class_/RenameClassRector/Fixture/class_annotations.php.inc new file mode 100644 index 000000000000..e3e646c980c1 --- /dev/null +++ b/tests/Rector/Class_/RenameClassRector/Fixture/class_annotations.php.inc @@ -0,0 +1,77 @@ +") + * @Serializer\Type("iterable") + */ + public $flights = []; + + /** + * @ORM\OneToMany(targetEntity="Rector\Tests\Rector\Class_\RenameClassRector\Source\OldClass") + */ + public $entityProperty; +} + +?> +----- +") + * @Serializer\Type("iterable") + */ + public $flights = []; + + /** + * @ORM\OneToMany(targetEntity="Rector\Tests\Rector\Class_\RenameClassRector\Source\NewClass") + */ + public $entityProperty; +} + +?> diff --git a/tests/Rector/Class_/RenameClassRector/RenameClassRectorTest.php b/tests/Rector/Class_/RenameClassRector/RenameClassRectorTest.php index abe00e8a8f47..81869338168a 100644 --- a/tests/Rector/Class_/RenameClassRector/RenameClassRectorTest.php +++ b/tests/Rector/Class_/RenameClassRector/RenameClassRectorTest.php @@ -43,6 +43,9 @@ public function provideTestFiles(): Iterator yield [__DIR__ . '/Fixture/rename_trait.php.inc']; yield [__DIR__ . '/Fixture/rename_class_without_namespace_to_class_without_namespace.php.inc']; yield [__DIR__ . '/Fixture/rename_class_to_class_without_namespace.php.inc']; + + // Symfony/Validator + Doctrine + JMS/Serializer annotations + yield [__DIR__ . '/Fixture/class_annotations.php.inc']; } /**