@@ -89,21 +89,30 @@ func Definition(ctx context.Context, definitionLinkSupport bool, manager *docume
8989
9090 for _ , attribute := range body .Attributes {
9191 if isInsideRange (attribute .NameRange , position ) {
92- return []protocol.Location {
93- {
94- Range : protocol.Range {
95- Start : protocol.Position {
96- Line : uint32 (attribute .NameRange .Start .Line ) - 1 ,
97- Character : uint32 (attribute .NameRange .Start .Column ) - 1 ,
98- },
99- End : protocol.Position {
100- Line : uint32 (attribute .NameRange .End .Line ) - 1 ,
101- Character : uint32 (attribute .NameRange .End .Column ) - 1 ,
102- },
92+ return createDefinitionResult (
93+ definitionLinkSupport ,
94+ protocol.Range {
95+ Start : protocol.Position {
96+ Line : uint32 (attribute .NameRange .Start .Line ) - 1 ,
97+ Character : uint32 (attribute .NameRange .Start .Column ) - 1 ,
98+ },
99+ End : protocol.Position {
100+ Line : uint32 (attribute .NameRange .End .Line ) - 1 ,
101+ Character : uint32 (attribute .NameRange .End .Column ) - 1 ,
102+ },
103+ },
104+ & protocol.Range {
105+ Start : protocol.Position {
106+ Line : uint32 (attribute .NameRange .Start .Line ) - 1 ,
107+ Character : uint32 (attribute .NameRange .Start .Column ) - 1 ,
108+ },
109+ End : protocol.Position {
110+ Line : uint32 (attribute .NameRange .End .Line ) - 1 ,
111+ Character : uint32 (attribute .NameRange .End .Column ) - 1 ,
103112 },
104- URI : string (documentURI ),
105113 },
106- }, nil
114+ string (documentURI ),
115+ ), nil
107116 }
108117
109118 if isInsideRange (attribute .SrcRange , position ) {
@@ -126,7 +135,18 @@ func ResolveAttributeValue(ctx context.Context, definitionLinkSupport bool, mana
126135 (sourceBlock .Type == "group" && attribute .Name == "targets" ) {
127136 value , _ := templateExpr .Value (& hcl.EvalContext {})
128137 target := value .AsString ()
129- return CalculateBlockLocation (input , body , documentURI , "target" , target , false )
138+ templateExprRange := templateExpr .Range ()
139+ sourceRange := hcl.Range {
140+ Start : hcl.Pos {
141+ Line : templateExprRange .Start .Line ,
142+ Column : templateExprRange .Start .Column + 1 ,
143+ },
144+ End : hcl.Pos {
145+ Line : templateExprRange .End .Line ,
146+ Column : templateExprRange .End .Column - 1 ,
147+ },
148+ }
149+ return CalculateBlockLocation (definitionLinkSupport , input , body , documentURI , sourceRange , "target" , target , false )
130150 }
131151 }
132152 }
@@ -158,32 +178,30 @@ func ResolveExpression(ctx context.Context, definitionLinkSupport bool, manager
158178 for _ , child := range nodes {
159179 if strings .EqualFold (child .Value , "FROM" ) {
160180 if child .Next != nil && child .Next .Next != nil && strings .EqualFold (child .Next .Next .Value , "AS" ) && child .Next .Next .Next != nil && child .Next .Next .Next .Value == target {
161- targetRange := protocol.Range {
162- Start : protocol.Position {Line : uint32 (child .StartLine ) - 1 , Character : 0 },
163- End : protocol.Position {Line : uint32 (child .EndLine ) - 1 , Character : uint32 (len (lines [child .EndLine - 1 ]))},
164- }
165-
166- linkURI := protocol .URI (fmt .Sprintf ("file:///%v" , strings .TrimPrefix (filepath .ToSlash (dockerfilePath ), "/" )))
167- if ! definitionLinkSupport {
168- return []protocol.Location {
169- {
170- Range : targetRange ,
171- URI : linkURI ,
181+ return createDefinitionResult (
182+ definitionLinkSupport ,
183+ protocol.Range {
184+ Start : protocol.Position {
185+ Line : uint32 (child .StartLine ) - 1 ,
186+ Character : 0 ,
172187 },
173- }
174- }
175-
176- return []protocol.LocationLink {
177- {
178- OriginSelectionRange : & protocol.Range {
179- Start : protocol.Position {Line : uint32 (literalValueExpr .Range ().Start .Line ) - 1 , Character : uint32 (literalValueExpr .Range ().Start .Column ) - 1 },
180- End : protocol.Position {Line : uint32 (literalValueExpr .Range ().End .Line ) - 1 , Character : uint32 (uint32 (literalValueExpr .Range ().End .Column ) - 1 )},
188+ End : protocol.Position {
189+ Line : uint32 (child .EndLine ) - 1 ,
190+ Character : uint32 (len (lines [child .EndLine - 1 ])),
181191 },
182- TargetRange : targetRange ,
183- TargetSelectionRange : targetRange ,
184- TargetURI : linkURI ,
185192 },
186- }
193+ & protocol.Range {
194+ Start : protocol.Position {
195+ Line : uint32 (literalValueExpr .Range ().Start .Line ) - 1 ,
196+ Character : uint32 (literalValueExpr .Range ().Start .Column ) - 1 ,
197+ },
198+ End : protocol.Position {
199+ Line : uint32 (literalValueExpr .Range ().End .Line ) - 1 ,
200+ Character : uint32 (uint32 (literalValueExpr .Range ().End .Column ) - 1 ),
201+ },
202+ },
203+ protocol .URI (fmt .Sprintf ("file:///%v" , strings .TrimPrefix (filepath .ToSlash (dockerfilePath ), "/" ))),
204+ )
187205 }
188206 }
189207 }
@@ -225,15 +243,29 @@ func ResolveExpression(ctx context.Context, definitionLinkSupport bool, manager
225243 }
226244
227245 if value == arg {
228- return []protocol.Location {
229- {
230- Range : protocol.Range {
231- Start : protocol.Position {Line : uint32 (node .StartLine ) - 1 , Character : 0 },
232- End : protocol.Position {Line : uint32 (node .EndLine ) - 1 , Character : uint32 (len (lines [node .EndLine - 1 ]))},
233- },
234- URI : protocol .URI (fmt .Sprintf ("file:///%v" , strings .TrimPrefix (filepath .ToSlash (dockerfilePath ), "/" ))),
246+ originSelectionRange := protocol.Range {
247+ Start : protocol.Position {
248+ Line : uint32 (item .KeyExpr .Range ().Start .Line ) - 1 ,
249+ Character : uint32 (item .KeyExpr .Range ().Start .Column ) - 1 ,
235250 },
251+ End : protocol.Position {
252+ Line : uint32 (item .KeyExpr .Range ().End .Line ) - 1 ,
253+ Character : uint32 (item .KeyExpr .Range ().End .Column ) - 1 ,
254+ },
255+ }
256+ if LiteralValue (item .KeyExpr ) {
257+ originSelectionRange .Start .Character = originSelectionRange .Start .Character + 1
258+ originSelectionRange .End .Character = originSelectionRange .End .Character - 1
236259 }
260+ return createDefinitionResult (
261+ definitionLinkSupport ,
262+ protocol.Range {
263+ Start : protocol.Position {Line : uint32 (node .StartLine ) - 1 , Character : 0 },
264+ End : protocol.Position {Line : uint32 (node .EndLine ) - 1 , Character : uint32 (len (lines [node .EndLine - 1 ]))},
265+ },
266+ & originSelectionRange ,
267+ protocol .URI (fmt .Sprintf ("file:///%v" , strings .TrimPrefix (filepath .ToSlash (dockerfilePath ), "/" ))),
268+ )
237269 }
238270 child = child .Next
239271 }
@@ -278,7 +310,7 @@ func ResolveExpression(ctx context.Context, definitionLinkSupport bool, manager
278310
279311 if _ , ok := expression .(* hclsyntax.ScopeTraversalExpr ); ok {
280312 name := string (input [expression .Range ().Start .Byte :expression .Range ().End .Byte ])
281- return CalculateBlockLocation (input , body , documentURI , "variable" , name , true )
313+ return CalculateBlockLocation (definitionLinkSupport , input , body , documentURI , expression . Range () , "variable" , name , true )
282314 }
283315
284316 if templateWrapExpr , ok := expression .(* hclsyntax.TemplateWrapExpr ); ok {
@@ -287,7 +319,7 @@ func ResolveExpression(ctx context.Context, definitionLinkSupport bool, manager
287319
288320 if functionCallExpr , ok := expression .(* hclsyntax.FunctionCallExpr ); ok {
289321 if isInsideRange (functionCallExpr .NameRange , position ) {
290- return CalculateBlockLocation (input , body , documentURI , "function" , functionCallExpr .Name , true )
322+ return CalculateBlockLocation (definitionLinkSupport , input , body , documentURI , functionCallExpr . NameRange , "function" , functionCallExpr .Name , true )
291323 }
292324
293325 for _ , arg := range functionCallExpr .Args {
@@ -303,7 +335,7 @@ func ResolveExpression(ctx context.Context, definitionLinkSupport bool, manager
303335// returns it. If variable is true then it will also look at the
304336// top-level attributes of the HCL file and resolve to those if the
305337// names match.
306- func CalculateBlockLocation (input []byte , body * hclsyntax.Body , documentURI uri.URI , blockName , name string , variable bool ) any {
338+ func CalculateBlockLocation (definitionLinkSupport bool , input []byte , body * hclsyntax.Body , documentURI uri.URI , sourceRange hcl. Range , blockName , name string , variable bool ) any {
307339 for _ , b := range body .Blocks {
308340 if b .Type == blockName && b .Labels [0 ] == name {
309341 startCharacter := uint32 (b .LabelRanges [0 ].Start .Column )
@@ -315,42 +347,80 @@ func CalculateBlockLocation(input []byte, body *hclsyntax.Body, documentURI uri.
315347 startCharacter --
316348 endCharacter --
317349 }
318- return []protocol.Location {
319- {
320- Range : protocol.Range {
321- Start : protocol.Position {
322- Line : uint32 (b .LabelRanges [0 ].Start .Line ) - 1 ,
323- Character : startCharacter ,
324- },
325- End : protocol.Position {
326- Line : uint32 (b .LabelRanges [0 ].End .Line ) - 1 ,
327- Character : endCharacter ,
328- },
350+ return createDefinitionResult (
351+ definitionLinkSupport ,
352+ protocol.Range {
353+ Start : protocol.Position {
354+ Line : uint32 (b .LabelRanges [0 ].Start .Line ) - 1 ,
355+ Character : startCharacter ,
356+ },
357+ End : protocol.Position {
358+ Line : uint32 (b .LabelRanges [0 ].End .Line ) - 1 ,
359+ Character : endCharacter ,
329360 },
330- URI : string (documentURI ),
331361 },
332- }
362+ & protocol.Range {
363+ Start : protocol.Position {
364+ Line : uint32 (sourceRange .Start .Line ) - 1 ,
365+ Character : uint32 (sourceRange .Start .Column ) - 1 ,
366+ },
367+ End : protocol.Position {
368+ Line : uint32 (sourceRange .End .Line ) - 1 ,
369+ Character : uint32 (sourceRange .End .Column ) - 1 ,
370+ },
371+ },
372+ string (documentURI ),
373+ )
333374 }
334375 }
335376
336377 if attribute , ok := body .Attributes [name ]; ok && variable {
378+ return createDefinitionResult (
379+ definitionLinkSupport ,
380+ protocol.Range {
381+ Start : protocol.Position {
382+ Line : uint32 (attribute .NameRange .Start .Line ) - 1 ,
383+ Character : uint32 (attribute .NameRange .Start .Column ) - 1 ,
384+ },
385+ End : protocol.Position {
386+ Line : uint32 (attribute .NameRange .End .Line ) - 1 ,
387+ Character : uint32 (attribute .NameRange .End .Column ) - 1 ,
388+ },
389+ },
390+ & protocol.Range {
391+ Start : protocol.Position {
392+ Line : uint32 (sourceRange .Start .Line ) - 1 ,
393+ Character : uint32 (sourceRange .Start .Column ) - 1 ,
394+ },
395+ End : protocol.Position {
396+ Line : uint32 (sourceRange .End .Line ) - 1 ,
397+ Character : uint32 (sourceRange .End .Column ) - 1 ,
398+ },
399+ },
400+ string (documentURI ),
401+ )
402+ }
403+ return nil
404+ }
405+
406+ func createDefinitionResult (definitionLinkSupport bool , targetRange protocol.Range , originSelectionRange * protocol.Range , linkURI protocol.URI ) any {
407+ if ! definitionLinkSupport {
337408 return []protocol.Location {
338409 {
339- Range : protocol.Range {
340- Start : protocol.Position {
341- Line : uint32 (attribute .NameRange .Start .Line ) - 1 ,
342- Character : uint32 (attribute .NameRange .Start .Column ) - 1 ,
343- },
344- End : protocol.Position {
345- Line : uint32 (attribute .NameRange .End .Line ) - 1 ,
346- Character : uint32 (attribute .NameRange .End .Column ) - 1 ,
347- },
348- },
349- URI : string (documentURI ),
410+ Range : targetRange ,
411+ URI : linkURI ,
350412 },
351413 }
352414 }
353- return nil
415+
416+ return []protocol.LocationLink {
417+ {
418+ OriginSelectionRange : originSelectionRange ,
419+ TargetRange : targetRange ,
420+ TargetSelectionRange : targetRange ,
421+ TargetURI : linkURI ,
422+ },
423+ }
354424}
355425
356426func ParseDockerfile (dockerfilePath string ) ([]byte , * parser.Result , error ) {
0 commit comments