mirror of
https://github.com/golang/go
synced 2024-11-19 06:04:39 -07:00
caa0b0f7d5
When looking for references, look in the entire workspace rather than the same package. This makes the references query more expensive because it needs to look at every package in the workspace, but hopefully it shouln't be user-noticable. This can be made more efficient by only checking packages that are transitive reverse dependencies. I don't think a mechanism to get all transitive reverse dependencies exists yet. One of the references test have been changed: it looked up references of the builtin int type, but now there are so many refererences that the test too slow and doesn't make sense any more. Instead look up references of the type "i" in that file. Change-Id: I93b3bd3795386f06ce488e76e6c7c8c1b1074e22 Reviewed-on: https://go-review.googlesource.com/c/tools/+/206883 Run-TryBot: Michael Matloob <matloob@golang.org> Reviewed-by: Rebecca Stambler <rstambler@golang.org>
100 lines
2.3 KiB
Go
100 lines
2.3 KiB
Go
// Copyright 2019 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"flag"
|
|
"fmt"
|
|
"sort"
|
|
|
|
"golang.org/x/tools/internal/lsp/protocol"
|
|
"golang.org/x/tools/internal/span"
|
|
"golang.org/x/tools/internal/tool"
|
|
)
|
|
|
|
// references implements the references verb for gopls
|
|
type references struct {
|
|
IncludeDeclaration bool `flag:"d" help:"include the declaration of the specified identifier in the results"`
|
|
|
|
app *Application
|
|
}
|
|
|
|
func (r *references) Name() string { return "references" }
|
|
func (r *references) Usage() string { return "<position>" }
|
|
func (r *references) ShortHelp() string { return "display selected identifier's references" }
|
|
func (r *references) DetailedHelp(f *flag.FlagSet) {
|
|
fmt.Fprint(f.Output(), `
|
|
Example:
|
|
|
|
$ # 1-indexed location (:line:column or :#offset) of the target identifier
|
|
$ gopls references helper/helper.go:8:6
|
|
$ gopls references helper/helper.go:#53
|
|
|
|
gopls references flags are:
|
|
`)
|
|
f.PrintDefaults()
|
|
}
|
|
|
|
func (r *references) Run(ctx context.Context, args ...string) error {
|
|
if len(args) != 1 {
|
|
return tool.CommandLineErrorf("references expects 1 argument (position)")
|
|
}
|
|
|
|
conn, err := r.app.connect(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer conn.terminate(ctx)
|
|
|
|
from := span.Parse(args[0])
|
|
file := conn.AddFile(ctx, from.URI())
|
|
if file.err != nil {
|
|
return file.err
|
|
}
|
|
|
|
loc, err := file.mapper.Location(from)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
p := protocol.ReferenceParams{
|
|
Context: protocol.ReferenceContext{
|
|
IncludeDeclaration: r.IncludeDeclaration,
|
|
},
|
|
TextDocumentPositionParams: protocol.TextDocumentPositionParams{
|
|
TextDocument: protocol.TextDocumentIdentifier{URI: loc.URI},
|
|
Position: loc.Range.Start,
|
|
},
|
|
}
|
|
locations, err := conn.References(ctx, &p)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(locations) == 0 {
|
|
return tool.CommandLineErrorf("%v: not an identifier", from)
|
|
}
|
|
|
|
var spans []string
|
|
for _, l := range locations {
|
|
f := conn.AddFile(ctx, span.NewURI(l.URI))
|
|
// convert location to span for user-friendly 1-indexed line
|
|
// and column numbers
|
|
span, err := f.mapper.Span(l)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
spans = append(spans, fmt.Sprint(span))
|
|
}
|
|
|
|
sort.Strings(spans)
|
|
for _, s := range spans {
|
|
fmt.Println(s)
|
|
}
|
|
|
|
return nil
|
|
}
|