@@ -31,12 +31,25 @@ class PhpDocParser
3131 /** @var bool */
3232 private $ preserveTypeAliasesWithInvalidTypes ;
3333
34- public function __construct (TypeParser $ typeParser , ConstExprParser $ constantExprParser , bool $ requireWhitespaceBeforeDescription = false , bool $ preserveTypeAliasesWithInvalidTypes = false )
34+ /** @var bool */
35+ private $ useLinesAttributes ;
36+
37+ /**
38+ * @param array{lines?: bool} $usedAttributes
39+ */
40+ public function __construct (
41+ TypeParser $ typeParser ,
42+ ConstExprParser $ constantExprParser ,
43+ bool $ requireWhitespaceBeforeDescription = false ,
44+ bool $ preserveTypeAliasesWithInvalidTypes = false ,
45+ array $ usedAttributes = []
46+ )
3547 {
3648 $ this ->typeParser = $ typeParser ;
3749 $ this ->constantExprParser = $ constantExprParser ;
3850 $ this ->requireWhitespaceBeforeDescription = $ requireWhitespaceBeforeDescription ;
3951 $ this ->preserveTypeAliasesWithInvalidTypes = $ preserveTypeAliasesWithInvalidTypes ;
52+ $ this ->useLinesAttributes = $ usedAttributes ['lines ' ] ?? false ;
4053 }
4154
4255
@@ -77,11 +90,28 @@ public function parse(TokenIterator $tokens): Ast\PhpDoc\PhpDocNode
7790 private function parseChild (TokenIterator $ tokens ): Ast \PhpDoc \PhpDocChildNode
7891 {
7992 if ($ tokens ->isCurrentTokenType (Lexer::TOKEN_PHPDOC_TAG )) {
80- return $ this ->parseTag ($ tokens );
93+ $ startLine = $ tokens ->currentTokenLine ();
94+ $ tag = $ this ->parseTag ($ tokens );
95+ $ endLine = $ tokens ->currentTokenLine ();
8196
97+ if ($ this ->useLinesAttributes ) {
98+ $ tag ->setAttribute (Ast \Attribute::START_LINE , $ startLine );
99+ $ tag ->setAttribute (Ast \Attribute::END_LINE , $ endLine );
100+ }
101+
102+ return $ tag ;
82103 }
83104
84- return $ this ->parseText ($ tokens );
105+ $ startLine = $ tokens ->currentTokenLine ();
106+ $ text = $ this ->parseText ($ tokens );
107+ $ endLine = $ tokens ->currentTokenLine ();
108+
109+ if ($ this ->useLinesAttributes ) {
110+ $ text ->setAttribute (Ast \Attribute::START_LINE , $ startLine );
111+ $ text ->setAttribute (Ast \Attribute::END_LINE , $ endLine );
112+ }
113+
114+ return $ text ;
85115 }
86116
87117
@@ -124,6 +154,8 @@ public function parseTag(TokenIterator $tokens): Ast\PhpDoc\PhpDocTagNode
124154
125155 public function parseTagValue (TokenIterator $ tokens , string $ tag ): Ast \PhpDoc \PhpDocTagValueNode
126156 {
157+ $ startLine = $ tokens ->currentTokenLine ();
158+
127159 try {
128160 $ tokens ->pushSavePoint ();
129161
@@ -251,6 +283,13 @@ public function parseTagValue(TokenIterator $tokens, string $tag): Ast\PhpDoc\Ph
251283 $ tagValue = new Ast \PhpDoc \InvalidTagValueNode ($ this ->parseOptionalDescription ($ tokens ), $ e );
252284 }
253285
286+ $ endLine = $ tokens ->currentTokenLine ();
287+
288+ if ($ this ->useLinesAttributes ) {
289+ $ tagValue ->setAttribute (Ast \Attribute::START_LINE , $ startLine );
290+ $ tagValue ->setAttribute (Ast \Attribute::END_LINE , $ endLine );
291+ }
292+
254293 return $ tagValue ;
255294 }
256295
@@ -466,7 +505,9 @@ private function parseTypeAliasTagValue(TokenIterator $tokens): Ast\PhpDoc\TypeA
466505 $ tokens ->currentTokenValue (),
467506 $ tokens ->currentTokenType (),
468507 $ tokens ->currentTokenOffset (),
469- Lexer::TOKEN_PHPDOC_EOL
508+ Lexer::TOKEN_PHPDOC_EOL ,
509+ null ,
510+ $ tokens ->currentTokenLine ()
470511 );
471512 }
472513 }
0 commit comments