From b0019699444865a77e8b499318b30de59d53b5ac Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Fri, 5 Jul 2019 13:47:36 +0300 Subject: [PATCH] [Doctrine] Add RemoveRepositoryFromEntityAnnotationRector --- .../doctrine-repository-as-service.yaml | 1 + ...veRepositoryFromEntityAnnotationRector.php | 103 ++++++++++++++++++ .../Fixture/fixture.php.inc | 29 +++++ .../Fixture/skip_done.php.inc | 12 ++ ...positoryFromEntityAnnotationRectorTest.php | 22 ++++ .../NodeAnalyzer/DocBlockManipulator.php | 24 ++-- 6 files changed, 179 insertions(+), 12 deletions(-) create mode 100644 packages/Architecture/src/Rector/Class_/RemoveRepositoryFromEntityAnnotationRector.php create mode 100644 packages/Architecture/tests/Rector/Class_/RemoveRepositoryFromEntityAnnotationRector/Fixture/fixture.php.inc create mode 100644 packages/Architecture/tests/Rector/Class_/RemoveRepositoryFromEntityAnnotationRector/Fixture/skip_done.php.inc create mode 100644 packages/Architecture/tests/Rector/Class_/RemoveRepositoryFromEntityAnnotationRector/RemoveRepositoryFromEntityAnnotationRectorTest.php diff --git a/config/set/architecture/doctrine-repository-as-service.yaml b/config/set/architecture/doctrine-repository-as-service.yaml index d362f636fc7d..98ff27e0a2b2 100644 --- a/config/set/architecture/doctrine-repository-as-service.yaml +++ b/config/set/architecture/doctrine-repository-as-service.yaml @@ -7,3 +7,4 @@ services: Rector\Rector\Architecture\RepositoryAsService\ReplaceParentRepositoryCallsByRepositoryPropertyRector: ~ Rector\Rector\Architecture\RepositoryAsService\MoveRepositoryFromParentToConstructorRector: ~ Rector\Rector\Architecture\RepositoryAsService\ServiceLocatorToDIRector: ~ + Rector\Architecture\Rector\Class_\RemoveRepositoryFromEntityAnnotationRector: ~ diff --git a/packages/Architecture/src/Rector/Class_/RemoveRepositoryFromEntityAnnotationRector.php b/packages/Architecture/src/Rector/Class_/RemoveRepositoryFromEntityAnnotationRector.php new file mode 100644 index 000000000000..ada3b238dc32 --- /dev/null +++ b/packages/Architecture/src/Rector/Class_/RemoveRepositoryFromEntityAnnotationRector.php @@ -0,0 +1,103 @@ +docBlockManipulator = $docBlockManipulator; + } + + public function getDefinition(): RectorDefinition + { + return new RectorDefinition('Removes repository class from @Entity annotation', [ + new CodeSample( + <<<'CODE_SAMPLE' +use Doctrine\ORM\Mapping as ORM; + +/** + * @ORM\Entity(repositoryClass="ProductRepository") + */ +class Product +{ +} +CODE_SAMPLE + , + <<<'CODE_SAMPLE' +use Doctrine\ORM\Mapping as ORM; + +/** + * @ORM\Entity + */ +class Product +{ +} +CODE_SAMPLE + ), + ]); + } + + /** + * @return string[] + */ + public function getNodeTypes(): array + { + return [Class_::class]; + } + + /** + * @param Node\Stmt\Class_ $node + */ + public function refactor(Node $node): ?Node + { + if ($node->getDocComment() === null) { + return null; + } + + $phpDocInfo = $this->docBlockManipulator->createPhpDocInfoFromNode($node); + if (! $phpDocInfo->hasTag(self::DOCTRINE_ORM_MAPPING_ENTITY)) { + return null; + } + + $entityTags = $phpDocInfo->getTagsByName(self::DOCTRINE_ORM_MAPPING_ENTITY); + if ($entityTags === []) { + return null; + } + + $entityTag = $entityTags[0]; + if (! $entityTag->value instanceof GenericTagValueNode) { + return null; + } + + $entityTag->value->value = Strings::replace($entityTag->value->value, '#\(repositoryClass="(.*?)"\)#'); + + // save the entity tag + $this->docBlockManipulator->updateNodeWithPhpDocInfo($node, $phpDocInfo); + + return $node; + } +} diff --git a/packages/Architecture/tests/Rector/Class_/RemoveRepositoryFromEntityAnnotationRector/Fixture/fixture.php.inc b/packages/Architecture/tests/Rector/Class_/RemoveRepositoryFromEntityAnnotationRector/Fixture/fixture.php.inc new file mode 100644 index 000000000000..bcf74eff1040 --- /dev/null +++ b/packages/Architecture/tests/Rector/Class_/RemoveRepositoryFromEntityAnnotationRector/Fixture/fixture.php.inc @@ -0,0 +1,29 @@ + +----- + diff --git a/packages/Architecture/tests/Rector/Class_/RemoveRepositoryFromEntityAnnotationRector/Fixture/skip_done.php.inc b/packages/Architecture/tests/Rector/Class_/RemoveRepositoryFromEntityAnnotationRector/Fixture/skip_done.php.inc new file mode 100644 index 000000000000..0e7e0ffbb2e1 --- /dev/null +++ b/packages/Architecture/tests/Rector/Class_/RemoveRepositoryFromEntityAnnotationRector/Fixture/skip_done.php.inc @@ -0,0 +1,12 @@ +doTestFiles([ + __DIR__ . '/Fixture/fixture.php.inc', + __DIR__ . '/Fixture/skip_done.php.inc', + ]); + } + + protected function getRectorClass(): string + { + return RemoveRepositoryFromEntityAnnotationRector::class; + } +} diff --git a/packages/NodeTypeResolver/src/PhpDoc/NodeAnalyzer/DocBlockManipulator.php b/packages/NodeTypeResolver/src/PhpDoc/NodeAnalyzer/DocBlockManipulator.php index 8d6248f16b6b..fc20c7370e17 100644 --- a/packages/NodeTypeResolver/src/PhpDoc/NodeAnalyzer/DocBlockManipulator.php +++ b/packages/NodeTypeResolver/src/PhpDoc/NodeAnalyzer/DocBlockManipulator.php @@ -530,6 +530,18 @@ public function updateNodeWithPhpDocInfo(Node $node, PhpDocInfo $phpDocInfo): bo return true; } + public function createPhpDocInfoFromNode(Node $node): PhpDocInfo + { + if ($node->getDocComment() === null) { + throw new ShouldNotHappenException(sprintf( + 'Node must have a comment. Check `$node->getDocComment() !== null` before passing it to %s', + __METHOD__ + )); + } + + return $this->phpDocInfoFactory->createFromNode($node); + } + private function addTypeSpecificTag(Node $node, string $name, string $type): void { // there might be no phpdoc at all @@ -553,18 +565,6 @@ private function addTypeSpecificTag(Node $node, string $name, string $type): voi } } - private function createPhpDocInfoFromNode(Node $node): PhpDocInfo - { - if ($node->getDocComment() === null) { - throw new ShouldNotHappenException(sprintf( - 'Node must have a comment. Check `$node->getDocComment() !== null` before passing it to %s', - __METHOD__ - )); - } - - return $this->phpDocInfoFactory->createFromNode($node); - } - private function isTagValueNodeWithType(PhpDocTagNode $phpDocTagNode): bool { return $phpDocTagNode->value instanceof ParamTagValueNode ||