Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 21b93d8

Browse files
mglamanondrejmirtes
authored andcommitted
Support multiple line descriptions for all tags
1 parent deaac7c commit 21b93d8

File tree

2 files changed

+75
-20
lines changed

2 files changed

+75
-20
lines changed

‎src/Parser/PhpDocParser.php‎

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,38 @@ private function parseChild(TokenIterator $tokens): Ast\PhpDoc\PhpDocChildNode
6161

6262
private function parseText(TokenIterator $tokens): Ast\PhpDoc\PhpDocTextNode
6363
{
64-
$text = $tokens->joinUntil(Lexer::TOKEN_PHPDOC_EOL, Lexer::TOKEN_CLOSE_PHPDOC, Lexer::TOKEN_END);
65-
$text = rtrim($text, "\t"); // the trimmed characters MUST match Lexer::TOKEN_HORIZONTAL_WS
64+
$text = '';
65+
while (true) {
66+
// If we received a Lexer::TOKEN_PHPDOC_EOL, exit early to prevent
67+
// them from being processed.
68+
if ($tokens->currentTokenType() === Lexer::TOKEN_PHPDOC_EOL) {
69+
break;
70+
}
71+
$text .= $tokens->joinUntil(Lexer::TOKEN_PHPDOC_EOL, Lexer::TOKEN_CLOSE_PHPDOC, Lexer::TOKEN_END);
72+
$text = rtrim($text, "\t");
73+
74+
// If we joined until TOKEN_PHPDOC_EOL, peak at the next tokens to see
75+
// if we have a multiline string to join.
76+
if ($tokens->currentTokenType() !== Lexer::TOKEN_PHPDOC_EOL) {
77+
break;
78+
}
79+
80+
// Peek at the next token to determine if it is more text that needs
81+
// to be combined.
82+
$tokens->pushSavePoint();
83+
$tokens->next();
84+
if ($tokens->currentTokenType() === Lexer::TOKEN_PHPDOC_EOL) {
85+
$tokens->next();
86+
}
87+
if ($tokens->currentTokenType() !== Lexer::TOKEN_IDENTIFIER) {
88+
$tokens->rollback();
89+
break;
90+
}
91+
92+
// There's more text on a new line, ensure spacing.
93+
$text .= '';
94+
}
95+
$text = trim($text, "\t");
6696

6797
return new Ast\PhpDoc\PhpDocTextNode($text);
6898
}
@@ -170,18 +200,7 @@ private function parseThrowsTagValue(TokenIterator $tokens): Ast\PhpDoc\ThrowsTa
170200

171201
private function parseDeprecatedTagValue(TokenIterator $tokens): Ast\PhpDoc\DeprecatedTagValueNode
172202
{
173-
$description = '';
174-
while ($tokens->currentTokenType() !== Lexer::TOKEN_CLOSE_PHPDOC) {
175-
$description .= $tokens->joinUntil(Lexer::TOKEN_PHPDOC_EOL, Lexer::TOKEN_CLOSE_PHPDOC, Lexer::TOKEN_END);
176-
$description = rtrim($description, "\t");
177-
if ($tokens->currentTokenType() !== Lexer::TOKEN_PHPDOC_EOL) {
178-
break;
179-
}
180-
// There's more text on a new line, ensure spacing.
181-
$description .= '';
182-
$tokens->next();
183-
}
184-
$description = rtrim($description, "\t");
203+
$description = $this->parseOptionalDescription($tokens);
185204
return new Ast\PhpDoc\DeprecatedTagValueNode($description);
186205
}
187206

‎tests/PHPStan/Parser/PhpDocParserTest.php‎

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,41 @@ public function provideDeprecatedTagsData(): \Iterator
994994
),
995995
]),
996996
];
997+
yield [
998+
'OK with two simple description with break',
999+
'/** @deprecated text first
1000+
*
1001+
* @deprecated text second
1002+
*/',
1003+
new PhpDocNode([
1004+
new PhpDocTagNode(
1005+
'@deprecated',
1006+
new DeprecatedTagValueNode('text first')
1007+
),
1008+
new PhpDocTextNode(''),
1009+
new PhpDocTagNode(
1010+
'@deprecated',
1011+
new DeprecatedTagValueNode('text second')
1012+
),
1013+
]),
1014+
];
1015+
1016+
yield [
1017+
'OK with two simple description without break',
1018+
'/** @deprecated text first
1019+
* @deprecated text second
1020+
*/',
1021+
new PhpDocNode([
1022+
new PhpDocTagNode(
1023+
'@deprecated',
1024+
new DeprecatedTagValueNode('text first')
1025+
),
1026+
new PhpDocTagNode(
1027+
'@deprecated',
1028+
new DeprecatedTagValueNode('text second')
1029+
),
1030+
]),
1031+
];
9971032

9981033
yield [
9991034
'OK with long descriptions',
@@ -1543,10 +1578,9 @@ public function provideMultiLinePhpDocData(): array
15431578
new IdentifierTypeNode('Foo'),
15441579
false,
15451580
'$foo',
1546-
'1st multi world description'
1581+
'1st multi world description some text in the middle'
15471582
)
15481583
),
1549-
new PhpDocTextNode('some text in the middle'),
15501584
new PhpDocTagNode(
15511585
'@param',
15521586
new ParamTagValueNode(
@@ -1563,15 +1597,16 @@ public function provideMultiLinePhpDocData(): array
15631597
'/**
15641598
*
15651599
*
1566-
* @param Foo $foo 1st multi world description
1600+
* @param Foo $foo 1st multi world description with empty lines
15671601
*
15681602
*
15691603
* some text in the middle
15701604
*
15711605
*
1572-
* @param Bar $bar 2nd multi world description
1606+
* @param Bar $bar 2nd multi world description with empty lines
15731607
*
15741608
*
1609+
* test
15751610
*/',
15761611
new PhpDocNode([
15771612
new PhpDocTextNode(''),
@@ -1582,7 +1617,7 @@ public function provideMultiLinePhpDocData(): array
15821617
new IdentifierTypeNode('Foo'),
15831618
false,
15841619
'$foo',
1585-
'1st multi world description'
1620+
'1st multi world description with empty lines'
15861621
)
15871622
),
15881623
new PhpDocTextNode(''),
@@ -1596,11 +1631,12 @@ public function provideMultiLinePhpDocData(): array
15961631
new IdentifierTypeNode('Bar'),
15971632
false,
15981633
'$bar',
1599-
'2nd multi world description'
1634+
'2nd multi world description with empty lines'
16001635
)
16011636
),
16021637
new PhpDocTextNode(''),
16031638
new PhpDocTextNode(''),
1639+
new PhpDocTextNode('test'),
16041640
]),
16051641
],
16061642
[

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /