@@ -62,11 +62,12 @@ public function parse(TokenIterator $tokens): Ast\Type\TypeNode
62
62
}
63
63
64
64
/**
65
+ * @internal
65
66
* @template T of Ast\Node
66
67
* @param T $type
67
68
* @return T
68
69
*/
69
- private function enrichWithAttributes (TokenIterator $ tokens , Ast \Node $ type , int $ startLine , int $ startIndex ): Ast \Node
70
+ public function enrichWithAttributes (TokenIterator $ tokens , Ast \Node $ type , int $ startLine , int $ startIndex ): Ast \Node
70
71
{
71
72
$ endLine = $ tokens ->currentTokenLine ();
72
73
$ endIndex = $ tokens ->currentTokenIndex ();
@@ -166,7 +167,7 @@ private function parseAtomic(TokenIterator $tokens): Ast\Type\TypeNode
166
167
$ isHtml = $ this ->isHtml ($ tokens );
167
168
$ tokens ->rollback ();
168
169
if ($ isHtml ) {
169
- return $ this -> enrichWithAttributes ( $ tokens , $ type, $ startLine , $ startIndex ) ;
170
+ return $ type ;
170
171
}
171
172
172
173
$ type = $ this ->parseGeneric ($ tokens , $ type );
@@ -188,7 +189,10 @@ private function parseAtomic(TokenIterator $tokens): Ast\Type\TypeNode
188
189
}
189
190
190
191
if ($ tokens ->isCurrentTokenType (Lexer::TOKEN_OPEN_SQUARE_BRACKET )) {
191
- $ type = $ this ->tryParseArrayOrOffsetAccess ($ tokens , $ type );
192
+ $ type = $ this ->tryParseArrayOrOffsetAccess (
193
+ $ tokens ,
194
+ $ this ->enrichWithAttributes ($ tokens , $ type , $ startLine , $ startIndex )
195
+ );
192
196
}
193
197
}
194
198
@@ -398,7 +402,14 @@ public function parseGeneric(TokenIterator $tokens, Ast\Type\IdentifierTypeNode
398
402
$ tokens ->tryConsumeTokenType (Lexer::TOKEN_PHPDOC_EOL );
399
403
if ($ tokens ->tryConsumeTokenType (Lexer::TOKEN_CLOSE_ANGLE_BRACKET )) {
400
404
// trailing comma case
401
- return new Ast \Type \GenericTypeNode ($ baseType , $ genericTypes , $ variances );
405
+ $ type = new Ast \Type \GenericTypeNode ($ baseType , $ genericTypes , $ variances );
406
+ $ startLine = $ baseType ->getAttribute (Ast \Attribute::START_LINE );
407
+ $ startIndex = $ baseType ->getAttribute (Ast \Attribute::START_INDEX );
408
+ if ($ startLine !== null && $ startIndex !== null ) {
409
+ $ type = $ this ->enrichWithAttributes ($ tokens , $ type , $ startLine , $ startIndex );
410
+ }
411
+
412
+ return $ type ;
402
413
}
403
414
[$ genericTypes [], $ variances []] = $ this ->parseGenericTypeArgument ($ tokens );
404
415
$ tokens ->tryConsumeTokenType (Lexer::TOKEN_PHPDOC_EOL );
@@ -407,7 +418,14 @@ public function parseGeneric(TokenIterator $tokens, Ast\Type\IdentifierTypeNode
407
418
$ tokens ->tryConsumeTokenType (Lexer::TOKEN_PHPDOC_EOL );
408
419
$ tokens ->consumeTokenType (Lexer::TOKEN_CLOSE_ANGLE_BRACKET );
409
420
410
- return new Ast \Type \GenericTypeNode ($ baseType , $ genericTypes , $ variances );
421
+ $ type = new Ast \Type \GenericTypeNode ($ baseType , $ genericTypes , $ variances );
422
+ $ startLine = $ baseType ->getAttribute (Ast \Attribute::START_LINE );
423
+ $ startIndex = $ baseType ->getAttribute (Ast \Attribute::START_INDEX );
424
+ if ($ startLine !== null && $ startIndex !== null ) {
425
+ $ type = $ this ->enrichWithAttributes ($ tokens , $ type , $ startLine , $ startIndex );
426
+ }
427
+
428
+ return $ type ;
411
429
}
412
430
413
431
@@ -417,9 +435,11 @@ public function parseGeneric(TokenIterator $tokens, Ast\Type\IdentifierTypeNode
417
435
*/
418
436
public function parseGenericTypeArgument (TokenIterator $ tokens ): array
419
437
{
438
+ $ startLine = $ tokens ->currentTokenLine ();
439
+ $ startIndex = $ tokens ->currentTokenIndex ();
420
440
if ($ tokens ->tryConsumeTokenType (Lexer::TOKEN_WILDCARD )) {
421
441
return [
422
- new Ast \Type \IdentifierTypeNode ('mixed ' ),
442
+ $ this -> enrichWithAttributes ( $ tokens , new Ast \Type \IdentifierTypeNode ('mixed ' ), $ startLine , $ startIndex ),
423
443
Ast \Type \GenericTypeNode::VARIANCE_BIVARIANT ,
424
444
];
425
445
}
@@ -498,6 +518,8 @@ private function parseCallableParameter(TokenIterator $tokens): Ast\Type\Callabl
498
518
/** @phpstan-impure */
499
519
private function parseCallableReturnType (TokenIterator $ tokens ): Ast \Type \TypeNode
500
520
{
521
+ $ startLine = $ tokens ->currentTokenLine ();
522
+ $ startIndex = $ tokens ->currentTokenIndex ();
501
523
if ($ tokens ->isCurrentTokenType (Lexer::TOKEN_NULLABLE )) {
502
524
$ type = $ this ->parseNullable ($ tokens );
503
525
@@ -510,15 +532,33 @@ private function parseCallableReturnType(TokenIterator $tokens): Ast\Type\TypeNo
510
532
$ tokens ->consumeTokenType (Lexer::TOKEN_IDENTIFIER );
511
533
512
534
if ($ tokens ->isCurrentTokenType (Lexer::TOKEN_OPEN_ANGLE_BRACKET )) {
513
- $ type = $ this ->parseGeneric ($ tokens , $ type );
535
+ $ type = $ this ->parseGeneric (
536
+ $ tokens ,
537
+ $ this ->enrichWithAttributes (
538
+ $ tokens ,
539
+ $ type ,
540
+ $ startLine ,
541
+ $ startIndex
542
+ )
543
+ );
514
544
515
545
} elseif (in_array ($ type ->name , ['array ' , 'list ' ], true ) && $ tokens ->isCurrentTokenType (Lexer::TOKEN_OPEN_CURLY_BRACKET ) && !$ tokens ->isPrecededByHorizontalWhitespace ()) {
516
- $ type = $ this ->parseArrayShape ($ tokens , $ type , $ type ->name );
546
+ $ type = $ this ->parseArrayShape ($ tokens , $ this ->enrichWithAttributes (
547
+ $ tokens ,
548
+ $ type ,
549
+ $ startLine ,
550
+ $ startIndex
551
+ ), $ type ->name );
517
552
}
518
553
}
519
554
520
555
if ($ tokens ->isCurrentTokenType (Lexer::TOKEN_OPEN_SQUARE_BRACKET )) {
521
- $ type = $ this ->tryParseArrayOrOffsetAccess ($ tokens , $ type );
556
+ $ type = $ this ->tryParseArrayOrOffsetAccess ($ tokens , $ this ->enrichWithAttributes (
557
+ $ tokens ,
558
+ $ type ,
559
+ $ startLine ,
560
+ $ startIndex
561
+ ));
522
562
}
523
563
524
564
return $ type ;
@@ -545,6 +585,8 @@ private function tryParseCallable(TokenIterator $tokens, Ast\Type\IdentifierType
545
585
/** @phpstan-impure */
546
586
private function tryParseArrayOrOffsetAccess (TokenIterator $ tokens , Ast \Type \TypeNode $ type ): Ast \Type \TypeNode
547
587
{
588
+ $ startLine = $ tokens ->currentTokenLine ();
589
+ $ startIndex = $ tokens ->currentTokenIndex ();
548
590
try {
549
591
while ($ tokens ->isCurrentTokenType (Lexer::TOKEN_OPEN_SQUARE_BRACKET )) {
550
592
$ tokens ->pushSavePoint ();
@@ -556,11 +598,21 @@ private function tryParseArrayOrOffsetAccess(TokenIterator $tokens, Ast\Type\Typ
556
598
$ offset = $ this ->parse ($ tokens );
557
599
$ tokens ->consumeTokenType (Lexer::TOKEN_CLOSE_SQUARE_BRACKET );
558
600
$ tokens ->dropSavePoint ();
559
- $ type = new Ast \Type \OffsetAccessTypeNode ($ type , $ offset );
601
+ $ type = $ this ->enrichWithAttributes (
602
+ $ tokens ,
603
+ new Ast \Type \OffsetAccessTypeNode ($ type , $ offset ),
604
+ $ startLine ,
605
+ $ startIndex
606
+ );
560
607
} else {
561
608
$ tokens ->consumeTokenType (Lexer::TOKEN_CLOSE_SQUARE_BRACKET );
562
609
$ tokens ->dropSavePoint ();
563
- $ type = new Ast \Type \ArrayTypeNode ($ type );
610
+ $ type = $ this ->enrichWithAttributes (
611
+ $ tokens ,
612
+ new Ast \Type \ArrayTypeNode ($ type ),
613
+ $ startLine ,
614
+ $ startIndex
615
+ );
564
616
}
565
617
}
566
618
0 commit comments