Skip to content

Commit a165178

Browse files
committedSep 7, 2024
Parsing Doctrine annotations is no longer optional
1 parent 87b7f74 commit a165178

File tree

5 files changed

+40
-72
lines changed

5 files changed

+40
-72
lines changed
 

‎src/Lexer/Lexer.php

+5-16
Original file line numberDiff line numberDiff line change
@@ -94,17 +94,9 @@ class Lexer
9494
public const TYPE_OFFSET = 1;
9595
public const LINE_OFFSET = 2;
9696

97-
/** @var bool */
98-
private $parseDoctrineAnnotations;
99-
10097
/** @var string|null */
10198
private $regexp;
10299

103-
public function __construct(bool $parseDoctrineAnnotations = false)
104-
{
105-
$this->parseDoctrineAnnotations = $parseDoctrineAnnotations;
106-
}
107-
108100
/**
109101
* @return list<array{string, int, int}>
110102
*/
@@ -170,23 +162,20 @@ private function generateRegexp(): string
170162
self::TOKEN_OPEN_PHPDOC => '/\\*\\*(?=\\s)\\x20?+',
171163
self::TOKEN_CLOSE_PHPDOC => '\\*/',
172164
self::TOKEN_PHPDOC_TAG => '@(?:[a-z][a-z0-9-\\\\]+:)?[a-z][a-z0-9-\\\\]*+',
165+
self::TOKEN_DOCTRINE_TAG => '@[a-z_\\\\][a-z0-9_\:\\\\]*[a-z_][a-z0-9_]*',
173166
self::TOKEN_PHPDOC_EOL => '\\r?+\\n[\\x09\\x20]*+(?:\\*(?!/)\\x20?+)?',
174167

175168
self::TOKEN_FLOAT => '[+\-]?(?:(?:[0-9]++(_[0-9]++)*\\.[0-9]*+(_[0-9]++)*(?:e[+\-]?[0-9]++(_[0-9]++)*)?)|(?:[0-9]*+(_[0-9]++)*\\.[0-9]++(_[0-9]++)*(?:e[+\-]?[0-9]++(_[0-9]++)*)?)|(?:[0-9]++(_[0-9]++)*e[+\-]?[0-9]++(_[0-9]++)*))',
176169
self::TOKEN_INTEGER => '[+\-]?(?:(?:0b[0-1]++(_[0-1]++)*)|(?:0o[0-7]++(_[0-7]++)*)|(?:0x[0-9a-f]++(_[0-9a-f]++)*)|(?:[0-9]++(_[0-9]++)*))',
177170
self::TOKEN_SINGLE_QUOTED_STRING => '\'(?:\\\\[^\\r\\n]|[^\'\\r\\n\\\\])*+\'',
178171
self::TOKEN_DOUBLE_QUOTED_STRING => '"(?:\\\\[^\\r\\n]|[^"\\r\\n\\\\])*+"',
172+
self::TOKEN_DOCTRINE_ANNOTATION_STRING => '"(?:""|[^"])*+"',
179173

180174
self::TOKEN_WILDCARD => '\\*',
181-
];
182-
183-
if ($this->parseDoctrineAnnotations) {
184-
$patterns[self::TOKEN_DOCTRINE_TAG] = '@[a-z_\\\\][a-z0-9_\:\\\\]*[a-z_][a-z0-9_]*';
185-
$patterns[self::TOKEN_DOCTRINE_ANNOTATION_STRING] = '"(?:""|[^"])*+"';
186-
}
187175

188-
// anything but TOKEN_CLOSE_PHPDOC or TOKEN_HORIZONTAL_WS or TOKEN_EOL
189-
$patterns[self::TOKEN_OTHER] = '(?:(?!\\*/)[^\\s])++';
176+
// anything but TOKEN_CLOSE_PHPDOC or TOKEN_HORIZONTAL_WS or TOKEN_EOL
177+
self::TOKEN_OTHER => '(?:(?!\\*/)[^\\s])++',
178+
];
190179

191180
foreach ($patterns as $type => &$pattern) {
192181
$pattern = '(?:' . $pattern . ')(*MARK:' . $type . ')';

‎src/Parser/PhpDocParser.php

+26-46
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,6 @@ class PhpDocParser
4444
/** @var bool */
4545
private $preserveTypeAliasesWithInvalidTypes;
4646

47-
/** @var bool */
48-
private $parseDoctrineAnnotations;
49-
5047
/** @var bool */
5148
private $useLinesAttributes;
5249

@@ -65,7 +62,6 @@ public function __construct(
6562
bool $requireWhitespaceBeforeDescription = false,
6663
bool $preserveTypeAliasesWithInvalidTypes = false,
6764
array $usedAttributes = [],
68-
bool $parseDoctrineAnnotations = false,
6965
bool $textBetweenTagsBelongsToDescription = false
7066
)
7167
{
@@ -74,7 +70,6 @@ public function __construct(
7470
$this->doctrineConstantExprParser = $constantExprParser->toDoctrine();
7571
$this->requireWhitespaceBeforeDescription = $requireWhitespaceBeforeDescription;
7672
$this->preserveTypeAliasesWithInvalidTypes = $preserveTypeAliasesWithInvalidTypes;
77-
$this->parseDoctrineAnnotations = $parseDoctrineAnnotations;
7873
$this->useLinesAttributes = $usedAttributes['lines'] ?? false;
7974
$this->useIndexAttributes = $usedAttributes['indexes'] ?? false;
8075
$this->textBetweenTagsBelongsToDescription = $textBetweenTagsBelongsToDescription;
@@ -88,44 +83,35 @@ public function parse(TokenIterator $tokens): Ast\PhpDoc\PhpDocNode
8883

8984
$children = [];
9085

91-
if ($this->parseDoctrineAnnotations) {
92-
if (!$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PHPDOC)) {
93-
$lastChild = $this->parseChild($tokens);
94-
$children[] = $lastChild;
95-
while (!$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PHPDOC)) {
96-
if (
97-
$lastChild instanceof Ast\PhpDoc\PhpDocTagNode
98-
&& (
99-
$lastChild->value instanceof Doctrine\DoctrineTagValueNode
100-
|| $lastChild->value instanceof Ast\PhpDoc\GenericTagValueNode
101-
)
102-
) {
103-
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
104-
if ($tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PHPDOC)) {
105-
break;
106-
}
107-
$lastChild = $this->parseChild($tokens);
108-
$children[] = $lastChild;
109-
continue;
110-
}
111-
112-
if (!$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL)) {
113-
break;
114-
}
86+
if (!$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PHPDOC)) {
87+
$lastChild = $this->parseChild($tokens);
88+
$children[] = $lastChild;
89+
while (!$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PHPDOC)) {
90+
if (
91+
$lastChild instanceof Ast\PhpDoc\PhpDocTagNode
92+
&& (
93+
$lastChild->value instanceof Doctrine\DoctrineTagValueNode
94+
|| $lastChild->value instanceof Ast\PhpDoc\GenericTagValueNode
95+
)
96+
) {
97+
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
11598
if ($tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PHPDOC)) {
11699
break;
117100
}
118-
119101
$lastChild = $this->parseChild($tokens);
120102
$children[] = $lastChild;
103+
continue;
121104
}
122-
}
123-
} else {
124-
if (!$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PHPDOC)) {
125-
$children[] = $this->parseChild($tokens);
126-
while ($tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL) && !$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PHPDOC)) {
127-
$children[] = $this->parseChild($tokens);
105+
106+
if (!$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL)) {
107+
break;
128108
}
109+
if ($tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PHPDOC)) {
110+
break;
111+
}
112+
113+
$lastChild = $this->parseChild($tokens);
114+
$children[] = $lastChild;
129115
}
130116
}
131117

@@ -539,17 +525,11 @@ function ($tokens) {
539525
break;
540526

541527
default:
542-
if ($this->parseDoctrineAnnotations) {
543-
if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_PARENTHESES)) {
544-
$tagValue = $this->parseDoctrineTagValue($tokens, $tag);
545-
} else {
546-
$tagValue = new Ast\PhpDoc\GenericTagValueNode($this->parseOptionalDescriptionAfterDoctrineTag($tokens));
547-
}
548-
break;
528+
if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_PARENTHESES)) {
529+
$tagValue = $this->parseDoctrineTagValue($tokens, $tag);
530+
} else {
531+
$tagValue = new Ast\PhpDoc\GenericTagValueNode($this->parseOptionalDescriptionAfterDoctrineTag($tokens));
549532
}
550-
551-
$tagValue = new Ast\PhpDoc\GenericTagValueNode($this->parseOptionalDescription($tokens));
552-
553533
break;
554534
}
555535

‎tests/PHPStan/Parser/PhpDocParserTest.php

+6-6
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,12 @@ class PhpDocParserTest extends TestCase
8787
protected function setUp(): void
8888
{
8989
parent::setUp();
90-
$this->lexer = new Lexer(true);
90+
$this->lexer = new Lexer();
9191
$constExprParser = new ConstExprParser();
9292
$typeParser = new TypeParser($constExprParser);
93-
$this->phpDocParser = new PhpDocParser($typeParser, $constExprParser, false, false, [], true);
94-
$this->phpDocParserWithRequiredWhitespaceBeforeDescription = new PhpDocParser($typeParser, $constExprParser, true, false, [], true);
95-
$this->phpDocParserWithPreserveTypeAliasesWithInvalidTypes = new PhpDocParser($typeParser, $constExprParser, true, true, [], true);
93+
$this->phpDocParser = new PhpDocParser($typeParser, $constExprParser, false, false, []);
94+
$this->phpDocParserWithRequiredWhitespaceBeforeDescription = new PhpDocParser($typeParser, $constExprParser, true, false, []);
95+
$this->phpDocParserWithPreserveTypeAliasesWithInvalidTypes = new PhpDocParser($typeParser, $constExprParser, true, true, []);
9696
}
9797

9898

@@ -7143,7 +7143,7 @@ public function testDeepNodesLinesAndIndexes(string $phpDoc, array $nodeAttribut
71437143
];
71447144
$constExprParser = new ConstExprParser(true, true, $usedAttributes);
71457145
$typeParser = new TypeParser($constExprParser, true, $usedAttributes);
7146-
$phpDocParser = new PhpDocParser($typeParser, $constExprParser, true, true, $usedAttributes, true);
7146+
$phpDocParser = new PhpDocParser($typeParser, $constExprParser, true, true, $usedAttributes);
71477147
$visitor = new NodeCollectingVisitor();
71487148
$traverser = new NodeTraverser([$visitor]);
71497149
$traverser->traverse([$phpDocParser->parse($tokens)]);
@@ -7559,7 +7559,7 @@ public function testTextBetweenTagsBelongsToDescription(
75597559
{
75607560
$constExprParser = new ConstExprParser();
75617561
$typeParser = new TypeParser($constExprParser);
7562-
$phpDocParser = new PhpDocParser($typeParser, $constExprParser, true, true, [], true, true);
7562+
$phpDocParser = new PhpDocParser($typeParser, $constExprParser, true, [], true, true);
75637563

75647564
$tokens = new TokenIterator($this->lexer->tokenize($input));
75657565
$actualPhpDocNode = $phpDocParser->parse($tokens);

‎tests/PHPStan/Parser/TokenIteratorTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public function dataGetDetectedNewline(): iterable
4646
*/
4747
public function testGetDetectedNewline(string $phpDoc, ?string $expectedNewline): void
4848
{
49-
$lexer = new Lexer(true);
49+
$lexer = new Lexer();
5050
$tokens = new TokenIterator($lexer->tokenize($phpDoc));
5151
$constExprParser = new ConstExprParser();
5252
$typeParser = new TypeParser($constExprParser);

‎tests/PHPStan/Printer/PrinterTest.php

+2-3
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ protected function setUp(): void
7575
$constExprParser,
7676
true,
7777
true,
78-
$usedAttributes,
79-
true
78+
$usedAttributes
8079
);
8180
}
8281

@@ -1871,7 +1870,7 @@ public function enterNode(Node $node)
18711870
*/
18721871
public function testPrintFormatPreserving(string $phpDoc, string $expectedResult, NodeVisitor $visitor): void
18731872
{
1874-
$lexer = new Lexer(true);
1873+
$lexer = new Lexer();
18751874
$tokens = new TokenIterator($lexer->tokenize($phpDoc));
18761875
$phpDocNode = $this->phpDocParser->parse($tokens);
18771876
$cloningTraverser = new NodeTraverser([new NodeVisitor\CloningVisitor()]);

0 commit comments

Comments
 (0)
Failed to load comments.