mirror of
https://github.com/danog/phpdoc-parser.git
synced 2024-11-30 04:29:20 +01:00
type aliases: support @phpstan-import-type and @psalm-import-type tags
This commit is contained in:
parent
2d862ef746
commit
2e17e4a907
@ -252,6 +252,20 @@ class PhpDocNode implements Node
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return TypeAliasImportTagValueNode[]
|
||||
*/
|
||||
public function getTypeAliasImportTagValues(string $tagName = '@phpstan-import-type'): array
|
||||
{
|
||||
return array_column(
|
||||
array_filter($this->getTagsByName($tagName), static function (PhpDocTagNode $tag): bool {
|
||||
return $tag->value instanceof TypeAliasImportTagValueNode;
|
||||
}),
|
||||
'value'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return "/**\n * " . implode("\n * ", $this->children) . '*/';
|
||||
|
34
src/Ast/PhpDoc/TypeAliasImportTagValueNode.php
Normal file
34
src/Ast/PhpDoc/TypeAliasImportTagValueNode.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
||||
|
||||
class TypeAliasImportTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
/** @var string */
|
||||
public $importedAlias;
|
||||
|
||||
/** @var IdentifierTypeNode */
|
||||
public $importedFrom;
|
||||
|
||||
/** @var string|null */
|
||||
public $importedAs;
|
||||
|
||||
public function __construct(string $importedAlias, IdentifierTypeNode $importedFrom, ?string $importedAs)
|
||||
{
|
||||
$this->importedAlias = $importedAlias;
|
||||
$this->importedFrom = $importedFrom;
|
||||
$this->importedAs = $importedAs;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return trim(
|
||||
"{$this->importedAlias} from {$this->importedFrom}"
|
||||
. ($this->importedAs !== null ? " as {$this->importedAs}" : '')
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -194,6 +194,11 @@ class PhpDocParser
|
||||
$tagValue = $this->parseTypeAliasTagValue($tokens);
|
||||
break;
|
||||
|
||||
case '@phpstan-import-type':
|
||||
case '@psalm-import-type':
|
||||
$tagValue = $this->parseTypeAliasImportTagValue($tokens);
|
||||
break;
|
||||
|
||||
default:
|
||||
$tagValue = new Ast\PhpDoc\GenericTagValueNode($this->parseOptionalDescription($tokens));
|
||||
break;
|
||||
@ -382,6 +387,32 @@ class PhpDocParser
|
||||
return new Ast\PhpDoc\TypeAliasTagValueNode($alias, $type);
|
||||
}
|
||||
|
||||
private function parseTypeAliasImportTagValue(TokenIterator $tokens): Ast\PhpDoc\TypeAliasImportTagValueNode
|
||||
{
|
||||
$importedAlias = $tokens->currentTokenValue();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
|
||||
|
||||
if (!$tokens->tryConsumeTokenValue('from')) {
|
||||
throw new \PHPStan\PhpDocParser\Parser\ParserException(
|
||||
$tokens->currentTokenValue(),
|
||||
$tokens->currentTokenType(),
|
||||
$tokens->currentTokenOffset(),
|
||||
Lexer::TOKEN_IDENTIFIER
|
||||
);
|
||||
}
|
||||
|
||||
$importedFrom = $this->typeParser->parse($tokens);
|
||||
assert($importedFrom instanceof IdentifierTypeNode);
|
||||
|
||||
$importedAs = null;
|
||||
if ($tokens->tryConsumeTokenValue('as')) {
|
||||
$importedAs = $tokens->currentTokenValue();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
|
||||
}
|
||||
|
||||
return new Ast\PhpDoc\TypeAliasImportTagValueNode($importedAlias, $importedFrom, $importedAs);
|
||||
}
|
||||
|
||||
private function parseOptionalVariableName(TokenIterator $tokens): string
|
||||
{
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_VARIABLE)) {
|
||||
|
@ -23,6 +23,7 @@ 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\TypeAliasImportTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\TypeAliasTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\UsesTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
|
||||
@ -68,6 +69,7 @@ class PhpDocParserTest extends \PHPUnit\Framework\TestCase
|
||||
* @dataProvider provideTemplateTagsData
|
||||
* @dataProvider provideExtendsTagsData
|
||||
* @dataProvider provideTypeAliasTagsData
|
||||
* @dataProvider provideTypeAliasImportTagsData
|
||||
* @dataProvider provideRealWorldExampleData
|
||||
* @dataProvider provideDescriptionWithOrWithoutHtml
|
||||
* @param string $label
|
||||
@ -2904,7 +2906,7 @@ some text in the middle'
|
||||
'@phpstan-type',
|
||||
new InvalidTagValueNode(
|
||||
'TypeAlias',
|
||||
new ParserException(
|
||||
new \PHPStan\PhpDocParser\Parser\ParserException(
|
||||
'*/',
|
||||
Lexer::TOKEN_CLOSE_PHPDOC,
|
||||
28,
|
||||
@ -2923,7 +2925,7 @@ some text in the middle'
|
||||
'@phpstan-type',
|
||||
new InvalidTagValueNode(
|
||||
'',
|
||||
new ParserException(
|
||||
new \PHPStan\PhpDocParser\Parser\ParserException(
|
||||
'*/',
|
||||
Lexer::TOKEN_CLOSE_PHPDOC,
|
||||
18,
|
||||
@ -2935,6 +2937,96 @@ some text in the middle'
|
||||
];
|
||||
}
|
||||
|
||||
public function provideTypeAliasImportTagsData(): \Iterator
|
||||
{
|
||||
yield [
|
||||
'OK',
|
||||
'/** @phpstan-import-type TypeAlias from AnotherClass */',
|
||||
new PhpDocNode([
|
||||
new PhpDocTagNode(
|
||||
'@phpstan-import-type',
|
||||
new TypeAliasImportTagValueNode(
|
||||
'TypeAlias',
|
||||
new IdentifierTypeNode('AnotherClass'),
|
||||
null
|
||||
)
|
||||
),
|
||||
]),
|
||||
];
|
||||
|
||||
yield [
|
||||
'OK with alias',
|
||||
'/** @phpstan-import-type TypeAlias from AnotherClass as DifferentAlias */',
|
||||
new PhpDocNode([
|
||||
new PhpDocTagNode(
|
||||
'@phpstan-import-type',
|
||||
new TypeAliasImportTagValueNode(
|
||||
'TypeAlias',
|
||||
new IdentifierTypeNode('AnotherClass'),
|
||||
'DifferentAlias'
|
||||
)
|
||||
),
|
||||
]),
|
||||
];
|
||||
|
||||
yield [
|
||||
'invalid missing from',
|
||||
'/** @phpstan-import-type TypeAlias */',
|
||||
new PhpDocNode([
|
||||
new PhpDocTagNode(
|
||||
'@phpstan-import-type',
|
||||
new InvalidTagValueNode(
|
||||
'TypeAlias',
|
||||
new \PHPStan\PhpDocParser\Parser\ParserException(
|
||||
'*/',
|
||||
Lexer::TOKEN_CLOSE_PHPDOC,
|
||||
35,
|
||||
Lexer::TOKEN_IDENTIFIER
|
||||
)
|
||||
)
|
||||
),
|
||||
]),
|
||||
];
|
||||
|
||||
yield [
|
||||
'invalid missing from with alias',
|
||||
'/** @phpstan-import-type TypeAlias as DifferentAlias */',
|
||||
new PhpDocNode([
|
||||
new PhpDocTagNode(
|
||||
'@phpstan-import-type',
|
||||
new InvalidTagValueNode(
|
||||
'TypeAlias as DifferentAlias',
|
||||
new \PHPStan\PhpDocParser\Parser\ParserException(
|
||||
'as',
|
||||
Lexer::TOKEN_IDENTIFIER,
|
||||
35,
|
||||
Lexer::TOKEN_IDENTIFIER
|
||||
)
|
||||
)
|
||||
),
|
||||
]),
|
||||
];
|
||||
|
||||
yield [
|
||||
'invalid empty',
|
||||
'/** @phpstan-import-type */',
|
||||
new PhpDocNode([
|
||||
new PhpDocTagNode(
|
||||
'@phpstan-import-type',
|
||||
new InvalidTagValueNode(
|
||||
'',
|
||||
new \PHPStan\PhpDocParser\Parser\ParserException(
|
||||
'*/',
|
||||
Lexer::TOKEN_CLOSE_PHPDOC,
|
||||
25,
|
||||
Lexer::TOKEN_IDENTIFIER
|
||||
)
|
||||
)
|
||||
),
|
||||
]),
|
||||
];
|
||||
}
|
||||
|
||||
public function providerDebug(): \Iterator
|
||||
{
|
||||
$sample = '/**
|
||||
|
Loading…
Reference in New Issue
Block a user