mirror of
https://github.com/danog/phpdoc-parser.git
synced 2025-01-22 13:51:20 +01:00
Support @template tag
This commit is contained in:
parent
472d3161d2
commit
847540a54b
@ -70,6 +70,20 @@ class PhpDocNode implements Node
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return TemplateTagValueNode[]
|
||||
*/
|
||||
public function getTemplateTagValues(): array
|
||||
{
|
||||
return array_column(
|
||||
array_filter($this->getTagsByName('@template'), static function (PhpDocTagNode $tag): bool {
|
||||
return $tag->value instanceof TemplateTagValueNode;
|
||||
}),
|
||||
'value'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return ReturnTagValueNode[]
|
||||
*/
|
||||
|
32
src/Ast/PhpDoc/TemplateTagValueNode.php
Normal file
32
src/Ast/PhpDoc/TemplateTagValueNode.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
|
||||
class TemplateTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
/** @var string */
|
||||
public $name;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $bound;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
|
||||
public function __construct(string $name, TypeNode $bound, string $description)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->bound = $bound;
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return trim("{$this->name} of {$this->bound} {$this->description}");
|
||||
}
|
||||
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
namespace PHPStan\PhpDocParser\Parser;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast;
|
||||
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
||||
use PHPStan\PhpDocParser\Lexer\Lexer;
|
||||
|
||||
class PhpDocParser
|
||||
@ -113,6 +114,10 @@ class PhpDocParser
|
||||
$tagValue = $this->parseMethodTagValue($tokens);
|
||||
break;
|
||||
|
||||
case '@template':
|
||||
$tagValue = $this->parseTemplateTagValue($tokens);
|
||||
break;
|
||||
|
||||
default:
|
||||
$tagValue = new Ast\PhpDoc\GenericTagValueNode($this->parseOptionalDescription($tokens));
|
||||
break;
|
||||
@ -243,6 +248,22 @@ class PhpDocParser
|
||||
return new Ast\PhpDoc\MethodTagValueParameterNode($parameterType, $isReference, $isVariadic, $parameterName, $defaultValue);
|
||||
}
|
||||
|
||||
private function parseTemplateTagValue(TokenIterator $tokens): Ast\PhpDoc\TemplateTagValueNode
|
||||
{
|
||||
$name = $tokens->currentTokenValue();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
|
||||
|
||||
if ($tokens->tryConsumeTokenValue('of')) {
|
||||
$bound = $this->typeParser->parse($tokens);
|
||||
|
||||
} else {
|
||||
$bound = new IdentifierTypeNode('mixed');
|
||||
}
|
||||
|
||||
$description = $this->parseOptionalDescription($tokens);
|
||||
|
||||
return new Ast\PhpDoc\TemplateTagValueNode($name, $bound, $description);
|
||||
}
|
||||
|
||||
private function parseOptionalVariableName(TokenIterator $tokens): string
|
||||
{
|
||||
|
@ -15,6 +15,7 @@ use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTextNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\TemplateTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\ThrowsTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\ArrayTypeNode;
|
||||
@ -49,6 +50,7 @@ class PhpDocParserTest extends \PHPUnit\Framework\TestCase
|
||||
* @dataProvider provideMethodTagsData
|
||||
* @dataProvider provideSingleLinePhpDocData
|
||||
* @dataProvider provideMultiLinePhpDocData
|
||||
* @dataProvider provideTemplateTagsData
|
||||
* @param string $label
|
||||
* @param string $input
|
||||
* @param PhpDocNode $expectedPhpDocNode
|
||||
@ -2198,4 +2200,106 @@ class PhpDocParserTest extends \PHPUnit\Framework\TestCase
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function provideTemplateTagsData(): \Iterator
|
||||
{
|
||||
yield [
|
||||
'OK without bound and description',
|
||||
'/** @template T */',
|
||||
new PhpDocNode([
|
||||
new PhpDocTagNode(
|
||||
'@template',
|
||||
new TemplateTagValueNode(
|
||||
'T',
|
||||
new IdentifierTypeNode('mixed'),
|
||||
''
|
||||
)
|
||||
),
|
||||
]),
|
||||
];
|
||||
|
||||
yield [
|
||||
'OK without bound',
|
||||
'/** @template T the value type*/',
|
||||
new PhpDocNode([
|
||||
new PhpDocTagNode(
|
||||
'@template',
|
||||
new TemplateTagValueNode(
|
||||
'T',
|
||||
new IdentifierTypeNode('mixed'),
|
||||
'the value type'
|
||||
)
|
||||
),
|
||||
]),
|
||||
];
|
||||
|
||||
yield [
|
||||
'OK without description',
|
||||
'/** @template T of DateTime */',
|
||||
new PhpDocNode([
|
||||
new PhpDocTagNode(
|
||||
'@template',
|
||||
new TemplateTagValueNode(
|
||||
'T',
|
||||
new IdentifierTypeNode('DateTime'),
|
||||
''
|
||||
)
|
||||
),
|
||||
]),
|
||||
];
|
||||
|
||||
yield [
|
||||
'OK with bound and description',
|
||||
'/** @template T of DateTime the value type */',
|
||||
new PhpDocNode([
|
||||
new PhpDocTagNode(
|
||||
'@template',
|
||||
new TemplateTagValueNode(
|
||||
'T',
|
||||
new IdentifierTypeNode('DateTime'),
|
||||
'the value type'
|
||||
)
|
||||
),
|
||||
]),
|
||||
];
|
||||
|
||||
yield [
|
||||
'invalid without bound and description',
|
||||
'/** @template */',
|
||||
new PhpDocNode([
|
||||
new PhpDocTagNode(
|
||||
'@template',
|
||||
new InvalidTagValueNode(
|
||||
'',
|
||||
new \PHPStan\PhpDocParser\Parser\ParserException(
|
||||
'*/',
|
||||
Lexer::TOKEN_CLOSE_PHPDOC,
|
||||
14,
|
||||
Lexer::TOKEN_IDENTIFIER
|
||||
)
|
||||
)
|
||||
),
|
||||
]),
|
||||
];
|
||||
|
||||
yield [
|
||||
'invalid without bound and with description',
|
||||
'/** @template #desc */',
|
||||
new PhpDocNode([
|
||||
new PhpDocTagNode(
|
||||
'@template',
|
||||
new InvalidTagValueNode(
|
||||
'#desc',
|
||||
new \PHPStan\PhpDocParser\Parser\ParserException(
|
||||
'#desc',
|
||||
Lexer::TOKEN_OTHER,
|
||||
14,
|
||||
Lexer::TOKEN_IDENTIFIER
|
||||
)
|
||||
)
|
||||
),
|
||||
]),
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user