Skip to content

Commit 4e27270

Browse files
committed
PhpDocParser: support variadic parameters in @param tag
1 parent 597aa4d commit 4e27270

File tree

4 files changed

+34
-4
lines changed

4 files changed

+34
-4
lines changed

doc/grammars/phpdoc-param.peg

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
PhpDocParam
2-
= AnnotationName Type ParameterName Description?
2+
= AnnotationName Type IsVariadic? ParameterName Description?
33

44
AnnotationName
55
= '@param'
66

7+
IsVariaric
8+
= '...'
9+
710
ParameterName
811
= '$' [a-zA-Z_\127-\255][a-zA-Z0-9_\127-\255]*
912

src/Ast/PhpDoc/ParamTagValueNode.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,28 @@ class ParamTagValueNode implements PhpDocTagValueNode
1010
/** @var TypeNode */
1111
public $type;
1212

13+
/** @var bool */
14+
public $isVariadic;
15+
1316
/** @var string (may be empty) */
1417
public $parameterName;
1518

1619
/** @var string (may be empty) */
1720
public $description;
1821

19-
public function __construct(TypeNode $type, string $parameterName, string $description)
22+
public function __construct(TypeNode $type, bool $isVariadic, string $parameterName, string $description)
2023
{
2124
$this->type = $type;
25+
$this->isVariadic = $isVariadic;
2226
$this->parameterName = $parameterName;
2327
$this->description = $description;
2428
}
2529

2630

2731
public function __toString(): string
2832
{
29-
return trim("{$this->type} {$this->parameterName} {$this->description}");
33+
$variadic = $this->isVariadic ? '...' : '';
34+
return trim("{$this->type} {$variadic}{$this->parameterName} {$this->description}");
3035
}
3136

3237
}

src/Parser/PhpDocParser.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,10 @@ private function parseTagValue(TokenIterator $tokens, string $tag): Ast\PhpDoc\P
122122
private function parseParamTagValue(TokenIterator $tokens): Ast\PhpDoc\ParamTagValueNode
123123
{
124124
$type = $this->typeParser->parse($tokens);
125+
$isVariadic = $tokens->tryConsumeTokenType(Lexer::TOKEN_VARIADIC);
125126
$parameterName = $this->parseRequiredVariableName($tokens);
126127
$description = $this->parseOptionalDescription($tokens);
127-
return new Ast\PhpDoc\ParamTagValueNode($type, $parameterName, $description);
128+
return new Ast\PhpDoc\ParamTagValueNode($type, $isVariadic, $parameterName, $description);
128129
}
129130

130131

tests/PHPStan/Parser/PhpDocParserTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ public function provideParseData(): array
9595
'@param',
9696
new ParamTagValueNode(
9797
new IdentifierTypeNode('Foo'),
98+
false,
9899
'$foo',
99100
''
100101
)
@@ -127,6 +128,22 @@ public function provideParseData(): array
127128
'@param',
128129
new ParamTagValueNode(
129130
new IdentifierTypeNode('Foo'),
131+
false,
132+
'$foo',
133+
'optional description '
134+
)
135+
),
136+
]),
137+
],
138+
[
139+
'/** @param Foo ...$foo optional description */',
140+
new PhpDocNode([
141+
new PhpDocTextNode(' '),
142+
new PhpDocTagNode(
143+
'@param',
144+
new ParamTagValueNode(
145+
new IdentifierTypeNode('Foo'),
146+
true,
130147
'$foo',
131148
'optional description '
132149
)
@@ -289,6 +306,7 @@ public function provideParseData(): array
289306
'@param',
290307
new ParamTagValueNode(
291308
new IdentifierTypeNode('Foo'),
309+
false,
292310
'$foo',
293311
'1st multi world description'
294312
)
@@ -298,6 +316,7 @@ public function provideParseData(): array
298316
'@param',
299317
new ParamTagValueNode(
300318
new IdentifierTypeNode('Bar'),
319+
false,
301320
'$bar',
302321
'2nd multi world description'
303322
)
@@ -317,6 +336,7 @@ public function provideParseData(): array
317336
'@param',
318337
new ParamTagValueNode(
319338
new IdentifierTypeNode('Foo'),
339+
false,
320340
'$foo',
321341
'1st multi world description'
322342
)
@@ -326,6 +346,7 @@ public function provideParseData(): array
326346
'@param',
327347
new ParamTagValueNode(
328348
new IdentifierTypeNode('Bar'),
349+
false,
329350
'$bar',
330351
'2nd multi world description'
331352
)

0 commit comments

Comments
 (0)