Skip to content

Commit dcc8987

Browse files
tris203joerdav
andauthoredSep 6, 2024··
fix(lsp): update URI handling for non-templ files for references (#899)
Co-authored-by: Joe Davidson <joe.davidson.21111@gmail.com>
1 parent 3ac3c9d commit dcc8987

File tree

3 files changed

+146
-3
lines changed

3 files changed

+146
-3
lines changed
 

‎cmd/templ/lspcmd/lsp_test.go

+136
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,142 @@ func TestHover(t *testing.T) {
319319
}
320320
}
321321

322+
func TestReferences(t *testing.T) {
323+
if testing.Short() {
324+
return
325+
}
326+
327+
ctx, cancel := context.WithCancel(context.Background())
328+
log, _ := zap.NewProduction()
329+
330+
ctx, appDir, _, server, teardown, err := Setup(ctx, log)
331+
if err != nil {
332+
t.Fatalf("failed to setup test: %v", err)
333+
return
334+
}
335+
defer teardown(t)
336+
defer cancel()
337+
338+
templFile, err := os.ReadFile(appDir + "/templates.templ")
339+
if err != nil {
340+
t.Fatalf("failed to read file %q: %v", appDir+"/templates.templ", err)
341+
return
342+
343+
}
344+
err = server.DidOpen(ctx, &protocol.DidOpenTextDocumentParams{
345+
TextDocument: protocol.TextDocumentItem{
346+
URI: uri.URI("file://" + appDir + "/templates.templ"),
347+
LanguageID: "templ",
348+
Version: 1,
349+
Text: string(templFile),
350+
},
351+
})
352+
if err != nil {
353+
t.Errorf("failed to register open file: %v", err)
354+
return
355+
}
356+
log.Info("Calling References")
357+
358+
tests := []struct {
359+
line int
360+
character int
361+
assert func(t *testing.T, l []protocol.Location) (msg string, ok bool)
362+
}{
363+
{
364+
// this is the definition of the templ function in the templates.templ file.
365+
line: 5,
366+
character: 9,
367+
assert: func(t *testing.T, actual []protocol.Location) (msg string, ok bool) {
368+
expectedReference := []protocol.Location{
369+
{
370+
// This is the useage of the templ function in the main.go file.
371+
URI: uri.URI("file://" + appDir + "/main.go"),
372+
Range: protocol.Range{
373+
Start: protocol.Position{
374+
Line: uint32(24),
375+
Character: uint32(7),
376+
},
377+
End: protocol.Position{
378+
Line: uint32(24),
379+
Character: uint32(11),
380+
},
381+
},
382+
},
383+
}
384+
if diff := lspdiff.References(expectedReference, actual); diff != "" {
385+
return fmt.Sprintf("Expected: %+v\nActual: %+v", expectedReference, actual), false
386+
}
387+
return "", true
388+
},
389+
},
390+
{
391+
// this is the definition of the struct in the templates.templ file.
392+
line: 21,
393+
character: 9,
394+
assert: func(t *testing.T, actual []protocol.Location) (msg string, ok bool) {
395+
expectedReference := []protocol.Location{
396+
{
397+
// This is the useage of the struct in the templates.templ file.
398+
URI: uri.URI("file://" + appDir + "/templates.templ"),
399+
Range: protocol.Range{
400+
Start: protocol.Position{
401+
Line: uint32(24),
402+
Character: uint32(8),
403+
},
404+
End: protocol.Position{
405+
Line: uint32(24),
406+
Character: uint32(14),
407+
},
408+
},
409+
},
410+
}
411+
if diff := lspdiff.References(expectedReference, actual); diff != "" {
412+
return fmt.Sprintf("Expected: %+v\nActual: %+v", expectedReference, actual), false
413+
}
414+
return "", true
415+
},
416+
},
417+
}
418+
419+
for i, test := range tests {
420+
t.Run(fmt.Sprintf("test-%d", i), func(t *testing.T) {
421+
// Give CI/CD pipeline executors some time because they're often quite slow.
422+
var ok bool
423+
var msg string
424+
for i := 0; i < 3; i++ {
425+
if err != nil {
426+
t.Error(err)
427+
return
428+
}
429+
actual, err := server.References(ctx, &protocol.ReferenceParams{
430+
TextDocumentPositionParams: protocol.TextDocumentPositionParams{
431+
TextDocument: protocol.TextDocumentIdentifier{
432+
URI: uri.URI("file://" + appDir + "/templates.templ"),
433+
},
434+
// Positions are zero indexed.
435+
Position: protocol.Position{
436+
Line: uint32(test.line - 1),
437+
Character: uint32(test.character - 1),
438+
},
439+
},
440+
})
441+
if err != nil {
442+
t.Errorf("failed to get references: %v", err)
443+
return
444+
}
445+
msg, ok = test.assert(t, actual)
446+
if !ok {
447+
break
448+
}
449+
time.Sleep(time.Millisecond * 500)
450+
}
451+
if !ok {
452+
t.Error(msg)
453+
}
454+
})
455+
}
456+
}
457+
322458
func TestCodeAction(t *testing.T) {
323459
if testing.Short() {
324460
return

‎cmd/templ/lspcmd/lspdiff/lspdiff.go

+4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ func CompletionList(expected, actual *protocol.CompletionList) string {
2525
)
2626
}
2727

28+
func References(expected, actual []protocol.Location) string {
29+
return cmp.Diff(expected, actual)
30+
}
31+
2832
func CompletionListContainsText(cl *protocol.CompletionList, text string) bool {
2933
if cl == nil {
3034
return false

‎cmd/templ/lspcmd/proxy/server.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,6 @@ func (p *Server) RangeFormatting(ctx context.Context, params *lsp.DocumentRangeF
939939
func (p *Server) References(ctx context.Context, params *lsp.ReferenceParams) (result []lsp.Location, err error) {
940940
p.Log.Info("client -> server: References")
941941
defer p.Log.Info("client -> server: References end")
942-
templURI := params.TextDocument.URI
943942
// Rewrite the request.
944943
var ok bool
945944
ok, params.TextDocument.URI, params.Position = p.updatePosition(params.TextDocument.URI, params.Position)
@@ -954,8 +953,12 @@ func (p *Server) References(ctx context.Context, params *lsp.ReferenceParams) (r
954953
// Rewrite the response.
955954
for i := 0; i < len(result); i++ {
956955
r := result[i]
957-
r.URI = templURI
958-
r.Range = p.convertGoRangeToTemplRange(templURI, r.Range)
956+
isTemplURI, templURI := convertTemplGoToTemplURI(r.URI)
957+
if isTemplURI {
958+
p.Log.Info(fmt.Sprintf("references-%d - range conversion for %s", i, r.URI))
959+
r.URI, r.Range = templURI, p.convertGoRangeToTemplRange(templURI, r.Range)
960+
}
961+
p.Log.Info(fmt.Sprintf("references-%d: %+v", i, r))
959962
result[i] = r
960963
}
961964
return result, err

0 commit comments

Comments
 (0)
Please sign in to comment.