github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/internal/lsp/cmd/references.go (about) 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 "github.com/powerman/golang-tools/internal/lsp/protocol" 14 "github.com/powerman/golang-tools/internal/span" 15 "github.com/powerman/golang-tools/internal/tool" 16 ) 17 18 // references implements the references verb for gopls 19 type references struct { 20 IncludeDeclaration bool `flag:"d,declaration" help:"include the declaration of the specified identifier in the results"` 21 22 app *Application 23 } 24 25 func (r *references) Name() string { return "references" } 26 func (r *references) Parent() string { return r.app.Name() } 27 func (r *references) Usage() string { return "[references-flags] <position>" } 28 func (r *references) ShortHelp() string { return "display selected identifier's references" } 29 func (r *references) DetailedHelp(f *flag.FlagSet) { 30 fmt.Fprint(f.Output(), ` 31 Example: 32 33 $ # 1-indexed location (:line:column or :#offset) of the target identifier 34 $ gopls references helper/helper.go:8:6 35 $ gopls references helper/helper.go:#53 36 37 references-flags: 38 `) 39 printFlagDefaults(f) 40 } 41 42 func (r *references) Run(ctx context.Context, args ...string) error { 43 if len(args) != 1 { 44 return tool.CommandLineErrorf("references expects 1 argument (position)") 45 } 46 47 conn, err := r.app.connect(ctx) 48 if err != nil { 49 return err 50 } 51 defer conn.terminate(ctx) 52 53 from := span.Parse(args[0]) 54 file := conn.AddFile(ctx, from.URI()) 55 if file.err != nil { 56 return file.err 57 } 58 loc, err := file.mapper.Location(from) 59 if err != nil { 60 return err 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 var spans []string 76 for _, l := range locations { 77 f := conn.AddFile(ctx, fileURI(l.URI)) 78 // convert location to span for user-friendly 1-indexed line 79 // and column numbers 80 span, err := f.mapper.Span(l) 81 if err != nil { 82 return err 83 } 84 spans = append(spans, fmt.Sprint(span)) 85 } 86 87 sort.Strings(spans) 88 for _, s := range spans { 89 fmt.Println(s) 90 } 91 return nil 92 }