Skip to content

Commit 0183817

Browse files
committed
allow multiline
1 parent cccccc1 commit 0183817

File tree

2 files changed

+71
-1
lines changed

2 files changed

+71
-1
lines changed

src/Parser/PhpDocParser.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,11 @@ private function parseTypeAliasTagValue(TokenIterator $tokens): Ast\PhpDoc\TypeA
10691069

10701070
$templateTypes = [];
10711071
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET)) {
1072+
// Skip whitespace and newlines after opening bracket
1073+
while ($tokens->isCurrentTokenType(Lexer::TOKEN_HORIZONTAL_WS, Lexer::TOKEN_PHPDOC_EOL)) {
1074+
$tokens->next();
1075+
}
1076+
10721077
do {
10731078
$startLine = $tokens->currentTokenLine();
10741079
$startIndex = $tokens->currentTokenIndex();
@@ -1078,7 +1083,21 @@ private function parseTypeAliasTagValue(TokenIterator $tokens): Ast\PhpDoc\TypeA
10781083
$startLine,
10791084
$startIndex,
10801085
);
1081-
} while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA));
1086+
1087+
// Skip whitespace and newlines after template type
1088+
while ($tokens->isCurrentTokenType(Lexer::TOKEN_HORIZONTAL_WS, Lexer::TOKEN_PHPDOC_EOL)) {
1089+
$tokens->next();
1090+
}
1091+
1092+
if (!$tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)) {
1093+
break;
1094+
}
1095+
1096+
// Skip whitespace and newlines after comma
1097+
while ($tokens->isCurrentTokenType(Lexer::TOKEN_HORIZONTAL_WS, Lexer::TOKEN_PHPDOC_EOL)) {
1098+
$tokens->next();
1099+
}
1100+
} while (true);
10821101
$tokens->consumeTokenType(Lexer::TOKEN_CLOSE_ANGLE_BRACKET);
10831102
}
10841103

tests/PHPStan/Parser/PhpDocParserTest.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5225,6 +5225,57 @@ public function provideTypeAliasTagsData(): Iterator
52255225
),
52265226
]),
52275227
];
5228+
5229+
yield [
5230+
'OK multiline with two template types',
5231+
'/**
5232+
* @phpstan-type Widget<
5233+
* TFoo,
5234+
* TBar
5235+
* > array{foo: TFoo, bar: TBar}
5236+
*/',
5237+
new PhpDocNode([
5238+
new PhpDocTagNode(
5239+
'@phpstan-type',
5240+
new TypeAliasTagValueNode(
5241+
'Widget',
5242+
ArrayShapeNode::createSealed([
5243+
new ArrayShapeItemNode(new IdentifierTypeNode('foo'), false, new IdentifierTypeNode('TFoo')),
5244+
new ArrayShapeItemNode(new IdentifierTypeNode('bar'), false, new IdentifierTypeNode('TBar')),
5245+
]),
5246+
[
5247+
new TemplateTagValueNode('TFoo', null, ''),
5248+
new TemplateTagValueNode('TBar', null, ''),
5249+
],
5250+
),
5251+
),
5252+
]),
5253+
];
5254+
5255+
yield [
5256+
'OK multiline with bounded template',
5257+
'/**
5258+
* @phpstan-type Collection<
5259+
* T of object
5260+
* > list<T>
5261+
*/',
5262+
new PhpDocNode([
5263+
new PhpDocTagNode(
5264+
'@phpstan-type',
5265+
new TypeAliasTagValueNode(
5266+
'Collection',
5267+
new GenericTypeNode(
5268+
new IdentifierTypeNode('list'),
5269+
[new IdentifierTypeNode('T')],
5270+
[GenericTypeNode::VARIANCE_INVARIANT],
5271+
),
5272+
[
5273+
new TemplateTagValueNode('T', new IdentifierTypeNode('object'), ''),
5274+
],
5275+
),
5276+
),
5277+
]),
5278+
];
52285279
}
52295280

52305281
public function provideTypeAliasImportTagsData(): Iterator

0 commit comments

Comments
 (0)