44
55use Symfony \Lsp \Document \PositionConverter ;
66use Symfony \Lsp \Parser \TreeSitter \TreeSitterNode ;
7- use Symfony \Lsp \Parser \Twig \TwigArgumentParser ;
7+ use Symfony \Lsp \Parser \Twig \TwigCallArgumentResolver ;
88use Symfony \Lsp \Parser \Twig \TwigCommentParser ;
99use Symfony \Lsp \Parser \Twig \TwigDocument ;
1010use Symfony \Lsp \Parser \Twig \TwigDocumentParser ;
@@ -16,7 +16,7 @@ final class TwigTranslationReferenceExtractor
1616 public function __construct (
1717 private readonly PositionConverter $ converter ,
1818 private readonly TwigDocumentParser $ parser ,
19- private readonly TwigArgumentParser $ argumentParser ,
19+ private readonly TwigCallArgumentResolver $ arguments ,
2020 private readonly TwigCommentParser $ comments ,
2121 private readonly TranslationParameterAnalyzer $ parameters ,
2222 ) {
@@ -74,8 +74,8 @@ private function filterReferences(string $uri, string $text, string $masked, Twi
7474 if (null === $ key ) {
7575 continue ;
7676 }
77- $ arguments = $ this ->arguments ( $ masked , $ document , $ filter );
78- $ domain = $ this ->domain ($ document , $ this -> argument ( $ arguments , 1 , [ 'domain ' ] ), $ defaultDomain );
77+ $ arguments = $ this ->arguments -> resolve ( $ document , $ filter );
78+ $ domain = $ this ->domain ($ document , $ arguments -> get ( 1 , 'domain ' ), $ defaultDomain );
7979 if (null === $ domain ) {
8080 continue ;
8181 }
@@ -84,7 +84,7 @@ private function filterReferences(string $uri, string $text, string $masked, Twi
8484 $ domain ,
8585 $ uri ,
8686 $ text ,
87- $ this ->parameters ->twig ($ document , $ this -> argument ( $ arguments , 0 , [ 'arguments ' , 'parameters ' ] )),
87+ $ this ->parameters ->twig ($ document , $ arguments -> get ( 0 , 'arguments ' , 'parameters ' )),
8888 );
8989 }
9090
@@ -122,10 +122,10 @@ private function functionReferences(string $uri, string $text, string $masked, T
122122 if (null === $ identifier || !\in_array ($ document ->text ($ identifier ), ['trans ' , 't ' ], true )) {
123123 continue ;
124124 }
125- $ arguments = $ this ->arguments ( $ masked , $ document , $ call );
126- $ keyArgument = $ this -> argument ( $ arguments , 0 , [ 'id ' , 'message ' ] );
125+ $ arguments = $ this ->arguments -> resolve ( $ document , $ call );
126+ $ keyArgument = $ arguments -> get ( 0 , 'id ' , 'message ' );
127127 $ key = null === $ keyArgument ? null : $ document ->soleStringLiteral ($ keyArgument );
128- $ domain = $ this ->domain ($ document , $ this -> argument ( $ arguments , 2 , [ 'domain ' ] ), $ defaultDomain );
128+ $ domain = $ this ->domain ($ document , $ arguments -> get ( 2 , 'domain ' ), $ defaultDomain );
129129 if (null === $ key || null === $ domain ) {
130130 continue ;
131131 }
@@ -134,70 +134,13 @@ private function functionReferences(string $uri, string $text, string $masked, T
134134 $ domain ,
135135 $ uri ,
136136 $ text ,
137- $ this ->parameters ->twig ($ document , $ this -> argument ( $ arguments , 1 , [ 'arguments ' , 'parameters ' ] )),
137+ $ this ->parameters ->twig ($ document , $ arguments -> get ( 1 , 'arguments ' , 'parameters ' )),
138138 );
139139 }
140140
141141 return $ references ;
142142 }
143143
144- /** @return list<array{name: string|null, value: TreeSitterNode}> */
145- private function arguments (string $ masked , TwigDocument $ document , TreeSitterNode $ call ): array
146- {
147- $ container = $ document ->directChild ($ call , 'arguments ' );
148- if (null === $ container ) {
149- return [];
150- }
151-
152- $ text = substr ($ masked , $ container ->startByte , $ container ->endByte - $ container ->startByte );
153- $ offset = $ container ->startByte ;
154- if (str_starts_with ($ text , '( ' )) {
155- $ text = substr ($ text , 1 );
156- ++$ offset ;
157- }
158- if (str_ends_with ($ text , ') ' )) {
159- $ text = substr ($ text , 0 , -1 );
160- }
161-
162- $ parsed = $ this ->argumentParser ->parse ($ text , $ offset );
163- $ arguments = [];
164- foreach ($ document ->children ($ container ) as $ child ) {
165- if ('argument ' !== $ child ->type ) {
166- continue ;
167- }
168- $ value = $ document ->directChild ($ child , 'argument_value ' ) ?? $ child ;
169- $ name = null ;
170- foreach ($ parsed as $ argument ) {
171- if ($ value ->startByte >= $ argument ->offset && $ value ->startByte < $ argument ->offset + \strlen ($ argument ->text )) {
172- $ name = $ argument ->name ;
173-
174- break ;
175- }
176- }
177- $ arguments [] = ['name ' => $ name , 'value ' => $ value ];
178- }
179-
180- return $ arguments ;
181- }
182-
183- /**
184- * @param list<array{name: string|null, value: TreeSitterNode}> $arguments
185- * @param list<string> $names
186- */
187- private function argument (array $ arguments , int $ position , array $ names ): ?TreeSitterNode
188- {
189- $ positional = [];
190- foreach ($ arguments as $ argument ) {
191- if (null === $ argument ['name ' ]) {
192- $ positional [] = $ argument ['value ' ];
193- } elseif (\in_array ($ argument ['name ' ], $ names , true )) {
194- return $ argument ['value ' ];
195- }
196- }
197-
198- return $ positional [$ position ] ?? null ;
199- }
200-
201144 private function domain (TwigDocument $ document , ?TreeSitterNode $ argument , string $ defaultDomain ): ?string
202145 {
203146 return null === $ argument ? $ defaultDomain : $ document ->soleStringLiteral ($ argument )?->value;
0 commit comments