Skip to content

Commit 2b544e3

Browse files
rentziassstamblerre
authored andcommitted
tools/gopls: add cmd support for references
This change adds command line support for references. Example: $ gopls references ~/tmp/foo/main.go:8:6 $ gopls references ~/tmp/foo/main.go:#53 Updates golang/go#32875 Change-Id: I9a0cf6ae8ba0a5c3d4ffc829b96fe3b42297c192 Reviewed-on: https://go-review.googlesource.com/c/tools/+/202178 Run-TryBot: Rebecca Stambler <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Rebecca Stambler <[email protected]>
1 parent cf891b7 commit 2b544e3

File tree

7 files changed

+141
-8
lines changed

7 files changed

+141
-8
lines changed

internal/lsp/cmd/cmd.go

+1
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ func (app *Application) commands() []tool.Application {
144144
&check{app: app},
145145
&format{app: app},
146146
&query{app: app},
147+
&references{app: app},
147148
&rename{app: app},
148149
&version{app: app},
149150
}

internal/lsp/cmd/references.go

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Copyright 2019 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package cmd
6+
7+
import (
8+
"context"
9+
"flag"
10+
"fmt"
11+
"golang.org/x/tools/internal/lsp/protocol"
12+
"golang.org/x/tools/internal/span"
13+
"golang.org/x/tools/internal/tool"
14+
"sort"
15+
)
16+
17+
// references implements the references verb for gopls
18+
type references struct {
19+
IncludeDeclaration bool `flag:"d" help:"include the declaration of the specified identifier in the results"`
20+
21+
app *Application
22+
}
23+
24+
func (r *references) Name() string { return "references" }
25+
func (r *references) Usage() string { return "<position>" }
26+
func (r *references) ShortHelp() string { return "display selected identifier's references" }
27+
func (r *references) DetailedHelp(f *flag.FlagSet) {
28+
fmt.Fprint(f.Output(), `
29+
Example:
30+
31+
$ # 1-indexed location (:line:column or :#offset) of the target identifier
32+
$ gopls references helper/helper.go:8:6
33+
$ gopls references helper/helper.go:#53
34+
35+
gopls references flags are:
36+
`)
37+
f.PrintDefaults()
38+
}
39+
40+
func (r *references) Run(ctx context.Context, args ...string) error {
41+
if len(args) != 1 {
42+
return tool.CommandLineErrorf("references expects 1 argument (position)")
43+
}
44+
45+
conn, err := r.app.connect(ctx)
46+
if err != nil {
47+
return err
48+
}
49+
defer conn.terminate(ctx)
50+
51+
from := span.Parse(args[0])
52+
file := conn.AddFile(ctx, from.URI())
53+
if file.err != nil {
54+
return file.err
55+
}
56+
57+
loc, err := file.mapper.Location(from)
58+
if err != nil {
59+
return err
60+
}
61+
62+
p := protocol.ReferenceParams{
63+
Context: protocol.ReferenceContext{
64+
IncludeDeclaration: r.IncludeDeclaration,
65+
},
66+
TextDocumentPositionParams: protocol.TextDocumentPositionParams{
67+
TextDocument: protocol.TextDocumentIdentifier{URI: loc.URI},
68+
Position: loc.Range.Start,
69+
},
70+
}
71+
locations, err := conn.References(ctx, &p)
72+
if err != nil {
73+
return err
74+
}
75+
76+
if len(locations) == 0 {
77+
return tool.CommandLineErrorf("%v: not an identifier", from)
78+
}
79+
80+
var spans []string
81+
for _, l := range locations {
82+
f := conn.AddFile(ctx, span.NewURI(l.URI))
83+
// convert location to span for user-friendly 1-indexed line
84+
// and column numbers
85+
span, err := f.mapper.Span(l)
86+
if err != nil {
87+
return err
88+
}
89+
spans = append(spans, fmt.Sprint(span))
90+
}
91+
92+
sort.Strings(spans)
93+
for _, s := range spans {
94+
fmt.Println(s)
95+
}
96+
97+
return nil
98+
}

internal/lsp/cmd/test/cmdtest.go

-4
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,6 @@ func (r *runner) Highlight(t *testing.T, name string, locations []span.Span) {
7474
//TODO: add command line highlight tests when it works
7575
}
7676

77-
func (r *runner) Reference(t *testing.T, src span.Span, itemList []span.Span) {
78-
//TODO: add command line references tests when it works
79-
}
80-
8177
func (r *runner) PrepareRename(t *testing.T, src span.Span, want *source.PrepareItem) {
8278
//TODO: add command line prepare rename tests when it works
8379
}

internal/lsp/cmd/test/references.go

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2019 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package cmdtest
6+
7+
import (
8+
"fmt"
9+
"golang.org/x/tools/internal/lsp/cmd"
10+
"golang.org/x/tools/internal/tool"
11+
"testing"
12+
13+
"golang.org/x/tools/internal/span"
14+
)
15+
16+
func (r *runner) References(t *testing.T, spn span.Span, itemList []span.Span) {
17+
var expect string
18+
for _, i := range itemList {
19+
expect += fmt.Sprintln(i)
20+
}
21+
22+
uri := spn.URI()
23+
filename := uri.Filename()
24+
target := filename + fmt.Sprintf(":%v:%v", spn.Start().Line(), spn.Start().Column())
25+
26+
app := cmd.New("gopls-test", r.data.Config.Dir, r.data.Config.Env, r.options)
27+
got := CaptureStdOut(t, func() {
28+
err := tool.Run(r.ctx, app, append([]string{"-remote=internal", "references"}, target))
29+
if err != nil {
30+
fmt.Println(spn.Start().Line())
31+
fmt.Println(err)
32+
}
33+
})
34+
35+
if expect != got {
36+
t.Errorf("references failed for %s expected:\n%s\ngot:\n%s", target, expect, got)
37+
}
38+
}

internal/lsp/lsp_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ func (r *runner) Highlight(t *testing.T, name string, locations []span.Span) {
458458
}
459459
}
460460

461-
func (r *runner) Reference(t *testing.T, src span.Span, itemList []span.Span) {
461+
func (r *runner) References(t *testing.T, src span.Span, itemList []span.Span) {
462462
sm, err := r.data.Mapper(src.URI())
463463
if err != nil {
464464
t.Fatal(err)

internal/lsp/source/source_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,7 @@ func (r *runner) Highlight(t *testing.T, name string, locations []span.Span) {
566566
}
567567
}
568568

569-
func (r *runner) Reference(t *testing.T, src span.Span, itemList []span.Span) {
569+
func (r *runner) References(t *testing.T, src span.Span, itemList []span.Span) {
570570
ctx := r.ctx
571571
f, err := r.view.GetFile(ctx, src.URI())
572572
if err != nil {

internal/lsp/tests/tests.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ type Tests interface {
110110
SuggestedFix(*testing.T, span.Span)
111111
Definition(*testing.T, span.Span, Definition)
112112
Highlight(*testing.T, string, []span.Span)
113-
Reference(*testing.T, span.Span, []span.Span)
113+
References(*testing.T, span.Span, []span.Span)
114114
Rename(*testing.T, span.Span, string)
115115
PrepareRename(*testing.T, span.Span, *source.PrepareItem)
116116
Symbol(*testing.T, span.URI, []protocol.DocumentSymbol)
@@ -484,7 +484,7 @@ func Run(t *testing.T, tests Tests, data *Data) {
484484
for src, itemList := range data.References {
485485
t.Run(spanName(src), func(t *testing.T) {
486486
t.Helper()
487-
tests.Reference(t, src, itemList)
487+
tests.References(t, src, itemList)
488488
})
489489
}
490490
})

0 commit comments

Comments
 (0)