diff --git a/packages/attribute-aware-php-doc/src/Ast/PhpDoc/AttributeAwareTemplateTagValueNode.php b/packages/attribute-aware-php-doc/src/Ast/PhpDoc/AttributeAwareTemplateTagValueNode.php index a7ec2843ae6..e67b40ca886 100644 --- a/packages/attribute-aware-php-doc/src/Ast/PhpDoc/AttributeAwareTemplateTagValueNode.php +++ b/packages/attribute-aware-php-doc/src/Ast/PhpDoc/AttributeAwareTemplateTagValueNode.php @@ -4,11 +4,36 @@ declare(strict_types=1); namespace Rector\AttributeAwarePhpDoc\Ast\PhpDoc; +use Nette\Utils\Strings; use PHPStan\PhpDocParser\Ast\PhpDoc\TemplateTagValueNode; +use PHPStan\PhpDocParser\Ast\Type\TypeNode; use Rector\BetterPhpDocParser\Attributes\Attribute\AttributeTrait; use Rector\BetterPhpDocParser\Contract\PhpDocNode\AttributeAwareNodeInterface; final class AttributeAwareTemplateTagValueNode extends TemplateTagValueNode implements AttributeAwareNodeInterface { use AttributeTrait; + + /** + * @var string + */ + private $preposition; + + public function __construct(string $name, ?TypeNode $bound, string $description, string $originalContent) + { + parent::__construct($name, $bound, $description); + + $matches = Strings::match($originalContent, '#\s+(?as|of)\s+#'); + $this->preposition = $matches['preposition'] ?? 'of'; + } + + public function __toString(): string + { + // @see https://github.com/rectorphp/rector/issues/3438 + # 'as'/'of' + $bound = $this->bound !== null ? ' ' . $this->preposition . ' ' . $this->bound : ''; + + $content = $this->name . $bound . ' ' . $this->description; + return trim($content); + } } diff --git a/packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwareTemplateTagValueNodeFactory.php b/packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwareTemplateTagValueNodeFactory.php index 2e084637060..9531928eb17 100644 --- a/packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwareTemplateTagValueNodeFactory.php +++ b/packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwareTemplateTagValueNodeFactory.php @@ -27,6 +27,6 @@ final class AttributeAwareTemplateTagValueNodeFactory implements AttributeNodeAw */ public function create(Node $node, string $docContent): AttributeAwareNodeInterface { - return new AttributeAwareTemplateTagValueNode($node->name, $node->bound, $node->description); + return new AttributeAwareTemplateTagValueNode($node->name, $node->bound, $node->description, $docContent); } } diff --git a/packages/better-php-doc-parser/tests/PhpDocParser/Helper/TagValueToPhpParserNodeMap.php b/packages/better-php-doc-parser/tests/PhpDocParser/Helper/TagValueToPhpParserNodeMap.php index fab23904ff4..c01b87ba057 100644 --- a/packages/better-php-doc-parser/tests/PhpDocParser/Helper/TagValueToPhpParserNodeMap.php +++ b/packages/better-php-doc-parser/tests/PhpDocParser/Helper/TagValueToPhpParserNodeMap.php @@ -8,6 +8,7 @@ use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\Property; use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode; +use PHPStan\PhpDocParser\Ast\PhpDoc\TemplateTagValueNode; use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Class_\EntityTagValueNode; use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Class_\TableTagValueNode; use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Property_\ColumnTagValueNode; @@ -48,5 +49,6 @@ final class TagValueToPhpParserNodeMap SensioTemplateTagValueNode::class => Class_::class, SensioMethodTagValueNode::class => ClassMethod::class, + TemplateTagValueNode::class => Class_::class, ]; } diff --git a/packages/better-php-doc-parser/tests/PhpDocParser/TagValueNodeReprint/Fixture/Native/Template/TemplateTagAsOf.php b/packages/better-php-doc-parser/tests/PhpDocParser/TagValueNodeReprint/Fixture/Native/Template/TemplateTagAsOf.php new file mode 100644 index 00000000000..5ddd2f6f56c --- /dev/null +++ b/packages/better-php-doc-parser/tests/PhpDocParser/TagValueNodeReprint/Fixture/Native/Template/TemplateTagAsOf.php @@ -0,0 +1,11 @@ + __DIR__ . '/Fixture/SensioTemplate', SensioMethodTagValueNode::class => __DIR__ . '/Fixture/SensioMethod', + + TemplateTagValueNode::class => __DIR__ . '/Fixture/Native/Template', ]; } }