Skip to content

Commit

Permalink
Fix parsing invalid types in type aliases
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Apr 4, 2023
1 parent bfec872 commit d3753fc
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/Parser/PhpDocParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -460,9 +460,20 @@ private function parseTypeAliasTagValue(TokenIterator $tokens): Ast\PhpDoc\TypeA
if ($this->preserveTypeAliasesWithInvalidTypes) {
try {
$type = $this->typeParser->parse($tokens);
if (!$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PHPDOC)) {
if (!$tokens->isCurrentTokenType(Lexer::TOKEN_PHPDOC_EOL)) {
throw new ParserException(
$tokens->currentTokenValue(),
$tokens->currentTokenType(),
$tokens->currentTokenOffset(),
Lexer::TOKEN_PHPDOC_EOL
);
}
}

return new Ast\PhpDoc\TypeAliasTagValueNode($alias, $type);
} catch (ParserException $e) {
$this->parseOptionalDescription($tokens);
return new Ast\PhpDoc\TypeAliasTagValueNode($alias, new Ast\Type\InvalidTypeNode($e));
}
}
Expand Down
118 changes: 118 additions & 0 deletions tests/PHPStan/Parser/PhpDocParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,24 @@ public function provideVarTagsData(): Iterator
)
),
]),
null,
new PhpDocNode([
new PhpDocTagNode(
'@psalm-type',
new TypeAliasTagValueNode(
'PARTSTRUCTURE_PARAM',
new InvalidTypeNode(
new ParserException(
'{',
Lexer::TOKEN_OPEN_CURLY_BRACKET,
44,
Lexer::TOKEN_PHPDOC_EOL,
null
)
)
)
),
]),
];
}

Expand Down Expand Up @@ -3954,6 +3972,106 @@ public function provideTypeAliasTagsData(): Iterator
]),
];

yield [
'invalid type that should be an error',
'/**
* @phpstan-type Foo array{}
* @phpstan-type InvalidFoo what{}
*/',
new PhpDocNode([
new PhpDocTagNode(
'@phpstan-type',
new InvalidTagValueNode(
"Unexpected token \"{\", expected '*/' at offset 65",
new ParserException(
'{',
Lexer::TOKEN_OPEN_CURLY_BRACKET,
65,
Lexer::TOKEN_CLOSE_PHPDOC,
null
)
)
),
]),
null,
new PhpDocNode([
new PhpDocTagNode(
'@phpstan-type',
new TypeAliasTagValueNode(
'Foo',
new ArrayShapeNode([])
)
),
new PhpDocTagNode(
'@phpstan-type',
new TypeAliasTagValueNode(
'InvalidFoo',
new InvalidTypeNode(new ParserException(
'{',
Lexer::TOKEN_OPEN_CURLY_BRACKET,
65,
Lexer::TOKEN_PHPDOC_EOL,
null
))
)
),
]),
];

yield [
'invalid type that should be an error followed by valid again',
'/**
* @phpstan-type Foo array{}
* @phpstan-type InvalidFoo what{}
* @phpstan-type Bar array{}
*/',
new PhpDocNode([
new PhpDocTagNode(
'@phpstan-type',
new InvalidTagValueNode(
"Unexpected token \"{\", expected '*/' at offset 65",
new ParserException(
'{',
Lexer::TOKEN_OPEN_CURLY_BRACKET,
65,
Lexer::TOKEN_CLOSE_PHPDOC,
null
)
)
),
]),
null,
new PhpDocNode([
new PhpDocTagNode(
'@phpstan-type',
new TypeAliasTagValueNode(
'Foo',
new ArrayShapeNode([])
)
),
new PhpDocTagNode(
'@phpstan-type',
new TypeAliasTagValueNode(
'InvalidFoo',
new InvalidTypeNode(new ParserException(
'{',
Lexer::TOKEN_OPEN_CURLY_BRACKET,
65,
Lexer::TOKEN_PHPDOC_EOL,
null
))
)
),
new PhpDocTagNode(
'@phpstan-type',
new TypeAliasTagValueNode(
'Bar',
new ArrayShapeNode([])
)
),
]),
];

yield [
'invalid empty',
'/** @phpstan-type */',
Expand Down

0 comments on commit d3753fc

Please sign in to comment.