diff --git a/src/Parser/TypeParser.php b/src/Parser/TypeParser.php index 410359d..1b80a97 100644 --- a/src/Parser/TypeParser.php +++ b/src/Parser/TypeParser.php @@ -167,6 +167,7 @@ class TypeParser $tokens->consumeTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET); $tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL); $genericTypes = [$this->parse($tokens)]; + $tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL); while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)) { $tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL); diff --git a/tests/PHPStan/Parser/PhpDocParserTest.php b/tests/PHPStan/Parser/PhpDocParserTest.php index 11f22b0..f5c2233 100644 --- a/tests/PHPStan/Parser/PhpDocParserTest.php +++ b/tests/PHPStan/Parser/PhpDocParserTest.php @@ -3078,6 +3078,54 @@ chunk. Must be higher that in the previous request.'), ), ]), ]; + +// yield [ +// 'multiline generic types - trailing comma', +// '/**' . PHP_EOL . +// ' * @implements Foo<' . PHP_EOL . +// ' * A,' . PHP_EOL . +// ' * >' . PHP_EOL . +// ' */', +// new PhpDocNode([ +// new PhpDocTagNode( +// '@implements', +// new ImplementsTagValueNode( +// new GenericTypeNode( +// new IdentifierTypeNode('Foo'), +// [ +// new IdentifierTypeNode('A'), +// ] +// ), +// '' +// ) +// ), +// ]), +// ]; + + yield [ + 'multiline generic types - leading comma', + '/**' . PHP_EOL . + ' * @implements Foo<' . PHP_EOL . + ' * A' . PHP_EOL . + ' * , B' . PHP_EOL . + ' * >' . PHP_EOL . + ' */', + new PhpDocNode([ + new PhpDocTagNode( + '@implements', + new ImplementsTagValueNode( + new GenericTypeNode( + new IdentifierTypeNode('Foo'), + [ + new IdentifierTypeNode('A'), + new IdentifierTypeNode('B'), + ] + ), + '' + ) + ), + ]), + ]; } public function dataParseTagValue(): array