Skip to content

Commit 59b2cd7

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

File tree

4 files changed

+126
-4
lines changed

4 files changed

+126
-4
lines changed

internal/lsp/cmd/cmd.go

+1
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ func (app *Application) commands() []tool.Application {
145145
&foldingRanges{app: app},
146146
&format{app: app},
147147
&links{app: app},
148+
&implementation{app: app},
148149
&imports{app: app},
149150
&query{app: app},
150151
&references{app: app},

internal/lsp/cmd/implementation.go

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
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+
"sort"
12+
13+
"golang.org/x/tools/internal/lsp/protocol"
14+
"golang.org/x/tools/internal/span"
15+
"golang.org/x/tools/internal/tool"
16+
)
17+
18+
// implementation implements the implementation verb for gopls
19+
type implementation struct {
20+
app *Application
21+
}
22+
23+
func (i *implementation) Name() string { return "implementation" }
24+
func (i *implementation) Usage() string { return "<position>" }
25+
func (i *implementation) ShortHelp() string { return "display selected identifier's implementation" }
26+
func (i *implementation) DetailedHelp(f *flag.FlagSet) {
27+
fmt.Fprint(f.Output(), `
28+
Example:
29+
30+
$ # 1-indexed location (:line:column or :#offset) of the target identifier
31+
$ gopls implementation helper/helper.go:8:6
32+
$ gopls implementation helper/helper.go:#53
33+
34+
gopls implementation flags are:
35+
`)
36+
f.PrintDefaults()
37+
}
38+
39+
func (i *implementation) Run(ctx context.Context, args ...string) error {
40+
if len(args) != 1 {
41+
return tool.CommandLineErrorf("implementation expects 1 argument (position)")
42+
}
43+
44+
conn, err := i.app.connect(ctx)
45+
if err != nil {
46+
return err
47+
}
48+
defer conn.terminate(ctx)
49+
50+
from := span.Parse(args[0])
51+
file := conn.AddFile(ctx, from.URI())
52+
if file.err != nil {
53+
return file.err
54+
}
55+
56+
loc, err := file.mapper.Location(from)
57+
if err != nil {
58+
return err
59+
}
60+
61+
p := protocol.ImplementationParams{
62+
TextDocumentPositionParams: protocol.TextDocumentPositionParams{
63+
TextDocument: protocol.TextDocumentIdentifier{URI: loc.URI},
64+
Position: loc.Range.Start,
65+
},
66+
}
67+
68+
implementations, err := conn.Implementation(ctx, &p)
69+
if err != nil {
70+
return err
71+
}
72+
73+
var spans []string
74+
for _, impl := range implementations {
75+
f := conn.AddFile(ctx, span.NewURI(impl.URI))
76+
span, err := f.mapper.Span(impl)
77+
if err != nil {
78+
return err
79+
}
80+
spans = append(spans, fmt.Sprint(span))
81+
}
82+
sort.Strings(spans)
83+
84+
for _, s := range spans {
85+
fmt.Println(s)
86+
}
87+
88+
return nil
89+
}

internal/lsp/cmd/test/cmdtest.go

-4
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,6 @@ func (r *runner) PrepareRename(t *testing.T, src span.Span, want *source.Prepare
103103
//TODO: add command line prepare rename tests when it works
104104
}
105105

106-
func (r *runner) Implementation(t *testing.T, spn span.Span, imp tests.Implementations) {
107-
//TODO: add implements tests when it works
108-
}
109-
110106
func (r *runner) RunGoplsCmd(t testing.TB, args ...string) (string, string) {
111107
rStdout, wStdout, err := os.Pipe()
112108
if err != nil {
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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+
"sort"
10+
"testing"
11+
12+
"golang.org/x/tools/internal/lsp/tests"
13+
"golang.org/x/tools/internal/span"
14+
)
15+
16+
func (r *runner) Implementation(t *testing.T, spn span.Span, imp tests.Implementations) {
17+
var itemStrings []string
18+
for _, i := range imp.Implementations {
19+
itemStrings = append(itemStrings, fmt.Sprint(i))
20+
}
21+
sort.Strings(itemStrings)
22+
var expect string
23+
for _, i := range itemStrings {
24+
expect += i + "\n"
25+
}
26+
expect = r.Normalize(expect)
27+
28+
uri := spn.URI()
29+
filename := uri.Filename()
30+
target := filename + fmt.Sprintf(":%v:%v", spn.Start().Line(), spn.Start().Column())
31+
32+
got, _ := r.NormalizeGoplsCmd(t, "implementation", target)
33+
if expect != got {
34+
t.Errorf("implementation failed for %s expected:\n%s\ngot:\n%s", target, expect, got)
35+
}
36+
}

0 commit comments

Comments
 (0)