33namespace PHPStan \PhpDocParser \Parser ;
44
55use LogicException ;
6+ use PHPStan \PhpDocParser \Ast \Comment ;
67use PHPStan \PhpDocParser \Lexer \Lexer ;
78use function array_pop ;
89use function assert ;
@@ -19,7 +20,10 @@ class TokenIterator
1920
2021 private int $ index ;
2122
22- /** @var int[] */
23+ /** @var list<Comment> */
24+ private array $ comments = [];
25+
26+ /** @var list<array{int, list<Comment>}> */
2327 private array $ savePoints = [];
2428
2529 /** @var list<int> */
@@ -152,8 +156,7 @@ public function consumeTokenType(int $tokenType): void
152156 }
153157 }
154158
155- $ this ->index ++;
156- $ this ->skipIrrelevantTokens ();
159+ $ this ->next ();
157160 }
158161
159162
@@ -166,8 +169,7 @@ public function consumeTokenValue(int $tokenType, string $tokenValue): void
166169 $ this ->throwError ($ tokenType , $ tokenValue );
167170 }
168171
169- $ this ->index ++;
170- $ this ->skipIrrelevantTokens ();
172+ $ this ->next ();
171173 }
172174
173175
@@ -178,12 +180,20 @@ public function tryConsumeTokenValue(string $tokenValue): bool
178180 return false ;
179181 }
180182
181- $ this ->index ++;
182- $ this ->skipIrrelevantTokens ();
183+ $ this ->next ();
183184
184185 return true ;
185186 }
186187
188+ /**
189+ * @return list<Comment>
190+ */
191+ public function flushComments (): array
192+ {
193+ $ res = $ this ->comments ;
194+ $ this ->comments = [];
195+ return $ res ;
196+ }
187197
188198 /** @phpstan-impure */
189199 public function tryConsumeTokenType (int $ tokenType ): bool
@@ -198,14 +208,15 @@ public function tryConsumeTokenType(int $tokenType): bool
198208 }
199209 }
200210
201- $ this ->index ++;
202- $ this ->skipIrrelevantTokens ();
211+ $ this ->next ();
203212
204213 return true ;
205214 }
206215
207216
208- /** @phpstan-impure */
217+ /**
218+ * @deprecated Use skipNewLineTokensAndConsumeComments instead (when parsing a type)
219+ */
209220 public function skipNewLineTokens (): void
210221 {
211222 if (!$ this ->isCurrentTokenType (Lexer::TOKEN_PHPDOC_EOL )) {
@@ -218,6 +229,29 @@ public function skipNewLineTokens(): void
218229 }
219230
220231
232+ public function skipNewLineTokensAndConsumeComments (): void
233+ {
234+ if ($ this ->currentTokenType () === Lexer::TOKEN_COMMENT ) {
235+ $ this ->comments [] = new Comment ($ this ->currentTokenValue (), $ this ->currentTokenLine (), $ this ->currentTokenIndex ());
236+ $ this ->next ();
237+ }
238+
239+ if (!$ this ->isCurrentTokenType (Lexer::TOKEN_PHPDOC_EOL )) {
240+ return ;
241+ }
242+
243+ do {
244+ $ foundNewLine = $ this ->tryConsumeTokenType (Lexer::TOKEN_PHPDOC_EOL );
245+ if ($ this ->currentTokenType () !== Lexer::TOKEN_COMMENT ) {
246+ continue ;
247+ }
248+
249+ $ this ->comments [] = new Comment ($ this ->currentTokenValue (), $ this ->currentTokenLine (), $ this ->currentTokenIndex ());
250+ $ this ->next ();
251+ } while ($ foundNewLine === true );
252+ }
253+
254+
221255 private function detectNewline (): void
222256 {
223257 $ value = $ this ->currentTokenValue ();
@@ -293,7 +327,7 @@ public function forwardToTheEnd(): void
293327
294328 public function pushSavePoint (): void
295329 {
296- $ this ->savePoints [] = $ this ->index ;
330+ $ this ->savePoints [] = [ $ this ->index , $ this -> comments ] ;
297331 }
298332
299333
@@ -305,9 +339,9 @@ public function dropSavePoint(): void
305339
306340 public function rollback (): void
307341 {
308- $ index = array_pop ($ this ->savePoints );
309- assert ($ index !== null );
310- $ this ->index = $ index ;
342+ $ savepoint = array_pop ($ this ->savePoints );
343+ assert ($ savepoint !== null );
344+ [ $ this ->index , $ this -> comments ] = $ savepoint ;
311345 }
312346
313347
0 commit comments