diff --git a/packages/BetterPhpDocParser/src/Contract/PhpDocParserExtensionInterface.php b/packages/BetterPhpDocParser/src/Contract/PhpDocParserExtensionInterface.php index 11a997f82cbc..c1dd7bc23cda 100644 --- a/packages/BetterPhpDocParser/src/Contract/PhpDocParserExtensionInterface.php +++ b/packages/BetterPhpDocParser/src/Contract/PhpDocParserExtensionInterface.php @@ -9,5 +9,5 @@ interface PhpDocParserExtensionInterface { public function matchTag(string $tag): bool; - public function parse(TokenIterator $tokenIterator, string $tag): PhpDocTagValueNode; + public function parse(TokenIterator $tokenIterator, string $tag): ?PhpDocTagValueNode; } diff --git a/packages/BetterPhpDocParser/src/PhpDocParser/BetterPhpDocParser.php b/packages/BetterPhpDocParser/src/PhpDocParser/BetterPhpDocParser.php index 5fb9ad334415..c55dbdbec73f 100644 --- a/packages/BetterPhpDocParser/src/PhpDocParser/BetterPhpDocParser.php +++ b/packages/BetterPhpDocParser/src/PhpDocParser/BetterPhpDocParser.php @@ -131,12 +131,20 @@ public function parseTag(TokenIterator $tokenIterator): PhpDocTagNode public function parseTagValue(TokenIterator $tokenIterator, string $tag): PhpDocTagValueNode { + $tokenIteratorBackup = clone $tokenIterator; + foreach ($this->phpDocParserExtensions as $phpDocParserExtension) { if (! $phpDocParserExtension->matchTag($tag)) { continue; } - return $phpDocParserExtension->parse($tokenIterator, $tag); + $phpDocTagValueNode = $phpDocParserExtension->parse($tokenIterator, $tag); + if ($phpDocTagValueNode !== null) { + return $phpDocTagValueNode; + } + // return back + $tokenIterator = $tokenIteratorBackup; + break; } // needed for reference support in params, see https://github.com/rectorphp/rector/issues/1734 diff --git a/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/AbstractDoctrineTagValueNode.php b/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/AbstractDoctrineTagValueNode.php index 6c737520d53d..7fa9af6da879 100644 --- a/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/AbstractDoctrineTagValueNode.php +++ b/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/AbstractDoctrineTagValueNode.php @@ -10,7 +10,7 @@ use Rector\DoctrinePhpDocParser\Array_\ArrayItemStaticHelper; use Rector\DoctrinePhpDocParser\Contract\Ast\PhpDoc\DoctrineTagNodeInterface; -abstract class AbstractDoctrineTagValueNode implements PhpDocTagValueNode, AttributeAwareNodeInterface, DoctrineTagNodeInterface +abstract class AbstractDoctrineTagValueNode implements AttributeAwareNodeInterface, DoctrineTagNodeInterface { use AttributeTrait; @@ -20,15 +20,15 @@ abstract class AbstractDoctrineTagValueNode implements PhpDocTagValueNode, Attri protected $orderedVisibleItems = []; /** - * @param mixed[] $cascade + * @param mixed[] $item */ - protected function printCascadeItem(array $cascade): string + protected function printArrayItem(array $item, string $key): string { - $json = Json::encode($cascade); + $json = Json::encode($item); $json = Strings::replace($json, '#,#', ', '); $json = Strings::replace($json, '#\[(.*?)\]#', '{$1}'); - return sprintf('cascade=%s', $json); + return sprintf('%s=%s', $key, $json); } /** diff --git a/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Class_/EntityTagValueNode.php b/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Class_/EntityTagValueNode.php index 312e31af66f3..5010c2de512f 100644 --- a/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Class_/EntityTagValueNode.php +++ b/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Class_/EntityTagValueNode.php @@ -31,8 +31,6 @@ public function __toString(): string $contentItems = []; $contentItems['repositoryClass'] = sprintf('repositoryClass="%s"', $this->repositoryClass); - - // default value $contentItems['readOnly'] = sprintf('readOnly=%s', $this->readOnly ? 'true' : 'false'); return $this->printContentItems($contentItems); diff --git a/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Property_/ManyToManyTagValueNode.php b/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Property_/ManyToManyTagValueNode.php index 71fb92db060e..3cf410d3e0fc 100644 --- a/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Property_/ManyToManyTagValueNode.php +++ b/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Property_/ManyToManyTagValueNode.php @@ -84,7 +84,7 @@ public function __toString(): string $contentItems['inversedBy'] = sprintf('inversedBy="%s"', $this->inversedBy); if ($this->cascade) { - $contentItems['cascade'] = $this->printCascadeItem($this->cascade); + $contentItems['cascade'] = $this->printArrayItem($this->cascade, 'cascade'); } $contentItems['fetch'] = sprintf('fetch="%s"', $this->fetch); diff --git a/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Property_/ManyToOneTagValueNode.php b/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Property_/ManyToOneTagValueNode.php index 06ada9d4b25d..ba3e6178f03b 100644 --- a/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Property_/ManyToOneTagValueNode.php +++ b/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Property_/ManyToOneTagValueNode.php @@ -59,7 +59,7 @@ public function __toString(): string $contentItems['targetEntity'] = sprintf('targetEntity="%s"', $this->targetEntity); if ($this->cascade) { - $contentItems['cascade'] = $this->printCascadeItem($this->cascade); + $contentItems['cascade'] = $this->printArrayItem($this->cascade, 'cascade'); } $contentItems['fetch'] = sprintf('fetch="%s"', $this->fetch); $contentItems['inversedBy'] = sprintf('inversedBy="%s"', $this->inversedBy); diff --git a/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Property_/OneToManyTagValueNode.php b/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Property_/OneToManyTagValueNode.php index 3c99d730878c..6b582c9c0ccd 100644 --- a/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Property_/OneToManyTagValueNode.php +++ b/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Property_/OneToManyTagValueNode.php @@ -75,7 +75,7 @@ public function __toString(): string $contentItems['targetEntity'] = sprintf('targetEntity="%s"', $this->targetEntity); if ($this->cascade) { - $contentItems['cascade'] = $this->printCascadeItem($this->cascade); + $contentItems['cascade'] = $this->printArrayItem($this->cascade, 'cascade'); } $contentItems['fetch'] = sprintf('fetch="%s"', $this->fetch); $contentItems['orphanRemoval'] = sprintf('orphanRemoval=%s', $this->orphanRemoval ? 'true' : 'false'); diff --git a/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Property_/OneToOneTagValueNode.php b/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Property_/OneToOneTagValueNode.php index 2a07f4dc8b4d..7c726b519f77 100644 --- a/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Property_/OneToOneTagValueNode.php +++ b/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Property_/OneToOneTagValueNode.php @@ -78,7 +78,7 @@ public function __toString(): string $contentItems['inversedBy'] = sprintf('inversedBy="%s"', $this->inversedBy); if ($this->cascade) { - $contentItems['cascade'] = $this->printCascadeItem($this->cascade); + $contentItems['cascade'] = $this->printArrayItem($this->cascade, 'cascade'); } $contentItems['fetch'] = sprintf('fetch="%s"', $this->fetch); diff --git a/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Property_/OrderByTagValueNode.php b/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Property_/OrderByTagValueNode.php index 3505a3b12419..2df66fc4f1aa 100644 --- a/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Property_/OrderByTagValueNode.php +++ b/packages/DoctrinePhpDocParser/src/Ast/PhpDoc/Property_/OrderByTagValueNode.php @@ -4,15 +4,10 @@ use Nette\Utils\Json; use Nette\Utils\Strings; -use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode; -use Rector\BetterPhpDocParser\Attributes\Attribute\AttributeTrait; -use Rector\BetterPhpDocParser\Attributes\Contract\Ast\AttributeAwareNodeInterface; -use Rector\DoctrinePhpDocParser\Contract\Ast\PhpDoc\DoctrineTagNodeInterface; +use Rector\DoctrinePhpDocParser\Ast\PhpDoc\AbstractDoctrineTagValueNode; -final class OrderByTagValueNode implements PhpDocTagValueNode, AttributeAwareNodeInterface, DoctrineTagNodeInterface +final class OrderByTagValueNode extends AbstractDoctrineTagValueNode { - use AttributeTrait; - /** * @var mixed[] */ diff --git a/packages/DoctrinePhpDocParser/src/Contract/Ast/PhpDoc/DoctrineTagNodeInterface.php b/packages/DoctrinePhpDocParser/src/Contract/Ast/PhpDoc/DoctrineTagNodeInterface.php index 6abc32906d48..99e4db6e15cf 100644 --- a/packages/DoctrinePhpDocParser/src/Contract/Ast/PhpDoc/DoctrineTagNodeInterface.php +++ b/packages/DoctrinePhpDocParser/src/Contract/Ast/PhpDoc/DoctrineTagNodeInterface.php @@ -2,6 +2,8 @@ namespace Rector\DoctrinePhpDocParser\Contract\Ast\PhpDoc; -interface DoctrineTagNodeInterface +use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode; + +interface DoctrineTagNodeInterface extends PhpDocTagValueNode { } diff --git a/packages/DoctrinePhpDocParser/src/Extension/DoctrinePhpDocParserExtension.php b/packages/DoctrinePhpDocParser/src/Extension/DoctrinePhpDocParserExtension.php index 165fce0ada8f..2fd8b98a27a9 100644 --- a/packages/DoctrinePhpDocParser/src/Extension/DoctrinePhpDocParserExtension.php +++ b/packages/DoctrinePhpDocParser/src/Extension/DoctrinePhpDocParserExtension.php @@ -25,7 +25,7 @@ public function matchTag(string $tag): bool return (bool) Strings::match($tag, '#^@ORM\\\\(\w+)$#'); } - public function parse(TokenIterator $tokenIterator, string $tag): PhpDocTagValueNode + public function parse(TokenIterator $tokenIterator, string $tag): ?PhpDocTagValueNode { return $this->ormTagParser->parse($tokenIterator, $tag); } diff --git a/packages/DoctrinePhpDocParser/src/PhpDocParser/OrmTagParser.php b/packages/DoctrinePhpDocParser/src/PhpDocParser/OrmTagParser.php index 207fe45e0654..445ca5414812 100644 --- a/packages/DoctrinePhpDocParser/src/PhpDocParser/OrmTagParser.php +++ b/packages/DoctrinePhpDocParser/src/PhpDocParser/OrmTagParser.php @@ -58,7 +58,7 @@ public function __construct( $this->nodeAnnotationReader = $nodeAnnotationReader; } - public function parse(TokenIterator $tokenIterator, string $tag): PhpDocTagValueNode + public function parse(TokenIterator $tokenIterator, string $tag): ?PhpDocTagValueNode { /** @var Class_|Property $node */ $node = $this->currentNodeProvider->getNode(); @@ -93,7 +93,7 @@ public function parse(TokenIterator $tokenIterator, string $tag): PhpDocTagValue return $this->createPropertyTagValueNode($tag, $node, $annotationContent); } - throw new NotImplementedException(__METHOD__ . ' ' . $tag); + return null; } /** @@ -350,7 +350,6 @@ private function createJoinColumnTagValueNodeFromJoinColumnAnnotation( private function cleanMultilineAnnotationContent(string $annotationContent): string { - // @todo record for original * content restoration return Strings::replace($annotationContent, '#(\s+)\*(\s+)#m', '$1$3'); } } diff --git a/packages/DoctrinePhpDocParser/tests/PhpDocParser/OrmTagParser/Class_/Fixture/SomeEntity.php b/packages/DoctrinePhpDocParser/tests/PhpDocParser/OrmTagParser/Class_/Fixture/SomeEntity.php index a625bc689d48..c832e7f4a1e4 100644 --- a/packages/DoctrinePhpDocParser/tests/PhpDocParser/OrmTagParser/Class_/Fixture/SomeEntity.php +++ b/packages/DoctrinePhpDocParser/tests/PhpDocParser/OrmTagParser/Class_/Fixture/SomeEntity.php @@ -8,6 +8,7 @@ * @ORM\Entity(readOnly=true, repositoryClass="Rector\DoctrinePhpDocParser\Tests\PhpDocParser\OrmTagParser\Class_\Source\ExistingRepositoryClass") * @ORM\Entity * @ORM\Entity() + * @ORM\Table(name="answer") */ final class SomeEntity { diff --git a/packages/DoctrinePhpDocParser/tests/PhpDocParser/OrmTagParser/Class_/Fixture/expected_some_entity.txt b/packages/DoctrinePhpDocParser/tests/PhpDocParser/OrmTagParser/Class_/Fixture/expected_some_entity.txt index 132293899793..f8d47a3c22bd 100644 --- a/packages/DoctrinePhpDocParser/tests/PhpDocParser/OrmTagParser/Class_/Fixture/expected_some_entity.txt +++ b/packages/DoctrinePhpDocParser/tests/PhpDocParser/OrmTagParser/Class_/Fixture/expected_some_entity.txt @@ -2,4 +2,5 @@ * @ORM\Entity(readOnly=true, repositoryClass="Rector\DoctrinePhpDocParser\Tests\PhpDocParser\OrmTagParser\Class_\Source\ExistingRepositoryClass") * @ORM\Entity * @ORM\Entity + * @ORM\Table(name="answer") */ \ No newline at end of file