add doctrine embedded php doc node (#4424)

* Add a tag value node for Doctrine Embedded tags

* fix getter name

Co-authored-by: Matthias Noback <matthiasnoback@gmail.com>
This commit is contained in:
Tomas Votruba 2020-10-15 22:48:23 +02:00 committed by GitHub
parent 16031da4b7
commit b7e3dad887
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 159 additions and 0 deletions

View File

@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Class_;
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\AbstractDoctrineTagValueNode;
final class EmbeddedTagValueNode extends AbstractDoctrineTagValueNode
{
/**
* @var string
*/
private $fullyQualifiedClassName;
public function __construct(array $items, ?string $originalContent, string $fullyQualifiedClassName)
{
parent::__construct($items, $originalContent);
$this->fullyQualifiedClassName = $fullyQualifiedClassName;
}
public function getShortName(): string
{
return '@ORM\Embedded';
}
public function getClass(): string
{
return $this->items['class'];
}
public function getFullyQualifiedClassName(): string
{
return $this->fullyQualifiedClassName;
}
public function getColumnPrefix(): ?string
{
return $this->items['columnPrefix'];
}
}

View File

@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
namespace Rector\BetterPhpDocParser\PhpDocNodeFactory\Doctrine\Property_;
use Doctrine\ORM\Mapping\Embedded;
use PhpParser\Node;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode;
use PHPStan\PhpDocParser\Parser\TokenIterator;
use Rector\BetterPhpDocParser\Contract\GenericPhpDocNodeFactoryInterface;
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Class_\EmbeddedTagValueNode;
use Rector\BetterPhpDocParser\PhpDocNodeFactory\AbstractPhpDocNodeFactory;
final class DoctrineEmbeddedPhpDocNodeFactory extends AbstractPhpDocNodeFactory implements GenericPhpDocNodeFactoryInterface
{
/**
* @return array<string, string>
*/
public function getTagValueNodeClassesToAnnotationClasses(): array
{
return [
EmbeddedTagValueNode::class => 'Doctrine\ORM\Mapping\Embedded',
];
}
public function createFromNodeAndTokens(
Node $node,
TokenIterator $tokenIterator,
string $annotationClass
): ?PhpDocTagValueNode {
/** @var Embedded|null $annotation */
$annotation = $this->nodeAnnotationReader->readAnnotation($node, $annotationClass);
if ($annotation === null) {
return null;
}
$content = $this->resolveContentFromTokenIterator($tokenIterator);
$items = $this->annotationItemsResolver->resolve($annotation);
$fullyQualifiedClassName = $this->resolveFqnTargetEntity($annotation->class, $node);
return new EmbeddedTagValueNode($items, $content, $fullyQualifiedClassName);
}
}

View File

@ -10,6 +10,7 @@ use PhpParser\Node\Stmt\Property;
use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\TemplateTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Class_\EmbeddedTagValueNode;
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Class_\EntityTagValueNode;
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Class_\TableTagValueNode;
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Property_\ColumnTagValueNode;
@ -43,6 +44,7 @@ final class TagValueToPhpParserNodeMap
TableTagValueNode::class => Class_::class,
CustomIdGeneratorTagValueNode::class => Property::class,
GeneratedValueTagValueNode::class => Property::class,
EmbeddedTagValueNode::class => Property::class,
// special case for constants
GenericTagValueNode::class => Property::class,
SensioTemplateTagValueNode::class => Class_::class,

View File

@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace Rector\BetterPhpDocParser\Tests\PhpDocParser\TagValueNodeReprint\Fixture\DoctrineEmbedded;
use Doctrine\ORM\Mapping as ORM;
use Rector\BetterPhpDocParser\Tests\PhpDocParser\TagValueNodeReprint\Source\Embeddable;
final class AnEntityWithAnEmbedded
{
/**
* @ORM\Embedded(class="Embeddable")
*/
private $embedded;
}

View File

@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace Rector\BetterPhpDocParser\Tests\PhpDocParser\TagValueNodeReprint\Fixture\DoctrineEmbedded;
use Doctrine\ORM\Mapping as ORM;
use Rector\BetterPhpDocParser\Tests\PhpDocParser\TagValueNodeReprint\Source\Embeddable;
final class AnEntityWithAnEmbeddedAndAColumnPrefix
{
/**
* @ORM\Embedded(class="Embeddable", columnPrefix="prefix_")
*/
private $embedded;
}

View File

@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace Rector\BetterPhpDocParser\Tests\PhpDocParser\TagValueNodeReprint\Source;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Embeddable
*/
final class Embeddable
{
}

View File

@ -8,6 +8,7 @@ use Iterator;
use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\TemplateTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Class_\EmbeddedTagValueNode;
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Class_\EntityTagValueNode;
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Class_\TableTagValueNode;
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Property_\ColumnTagValueNode;
@ -64,6 +65,7 @@ final class TagValueNodeReprintTest extends AbstractPhpDocInfoTest
TableTagValueNode::class => __DIR__ . '/Fixture/DoctrineTable',
CustomIdGeneratorTagValueNode::class => __DIR__ . '/Fixture/DoctrineCustomIdGenerator',
GeneratedValueTagValueNode::class => __DIR__ . '/Fixture/DoctrineGeneratedValue',
EmbeddedTagValueNode::class => __DIR__ . '/Fixture/DoctrineEmbedded',
// special case
GenericTagValueNode::class => __DIR__ . '/Fixture/ConstantReference',
SensioTemplateTagValueNode::class => __DIR__ . '/Fixture/SensioTemplate',

View File

@ -0,0 +1,27 @@
<?php
namespace Doctrine\ORM\Mapping;
// mimics @see https://github.com/doctrine/orm/blob/master/lib/Doctrine/ORM/Annotation/Embedded.php
if (class_exists('Doctrine\ORM\Mapping\Embedded')) {
return;
}
/**
* @Annotation
* @Target("PROPERTY")
*/
final class Embedded implements Annotation
{
/**
* @Required
* @var string
*/
public $class;
/**
* @var mixed
*/
public $columnPrefix;
}