aboutsummaryrefslogtreecommitdiff
path: root/internal/lsp/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'internal/lsp/cmd')
-rw-r--r--internal/lsp/cmd/call_hierarchy.go146
-rw-r--r--internal/lsp/cmd/capabilities_test.go166
-rw-r--r--internal/lsp/cmd/check.go74
-rw-r--r--internal/lsp/cmd/cmd.go630
-rw-r--r--internal/lsp/cmd/cmd_test.go23
-rw-r--r--internal/lsp/cmd/definition.go137
-rw-r--r--internal/lsp/cmd/export_test.go11
-rw-r--r--internal/lsp/cmd/folding_range.go73
-rw-r--r--internal/lsp/cmd/format.go108
-rw-r--r--internal/lsp/cmd/help_test.go57
-rw-r--r--internal/lsp/cmd/highlight.go89
-rw-r--r--internal/lsp/cmd/implementation.go88
-rw-r--r--internal/lsp/cmd/imports.go102
-rw-r--r--internal/lsp/cmd/info.go197
-rw-r--r--internal/lsp/cmd/links.go78
-rw-r--r--internal/lsp/cmd/prepare_rename.go84
-rw-r--r--internal/lsp/cmd/references.go92
-rw-r--r--internal/lsp/cmd/remote.go164
-rw-r--r--internal/lsp/cmd/rename.go128
-rw-r--r--internal/lsp/cmd/semantictokens.go230
-rw-r--r--internal/lsp/cmd/serve.go130
-rw-r--r--internal/lsp/cmd/signature.go87
-rw-r--r--internal/lsp/cmd/subcommands.go44
-rw-r--r--internal/lsp/cmd/suggested_fix.go159
-rw-r--r--internal/lsp/cmd/symbols.go116
-rw-r--r--internal/lsp/cmd/test/call_hierarchy.go85
-rw-r--r--internal/lsp/cmd/test/check.go63
-rw-r--r--internal/lsp/cmd/test/cmdtest.go169
-rw-r--r--internal/lsp/cmd/test/definition.go61
-rw-r--r--internal/lsp/cmd/test/folding_range.go25
-rw-r--r--internal/lsp/cmd/test/format.go86
-rw-r--r--internal/lsp/cmd/test/highlight.go29
-rw-r--r--internal/lsp/cmd/test/implementation.go37
-rw-r--r--internal/lsp/cmd/test/imports.go29
-rw-r--r--internal/lsp/cmd/test/links.go30
-rw-r--r--internal/lsp/cmd/test/prepare_rename.go46
-rw-r--r--internal/lsp/cmd/test/references.go49
-rw-r--r--internal/lsp/cmd/test/rename.go29
-rw-r--r--internal/lsp/cmd/test/semanticdriver.go34
-rw-r--r--internal/lsp/cmd/test/signature.go34
-rw-r--r--internal/lsp/cmd/test/suggested_fix.go35
-rw-r--r--internal/lsp/cmd/test/symbols.go23
-rw-r--r--internal/lsp/cmd/test/workspace_symbol.go53
-rw-r--r--internal/lsp/cmd/usage/api-json.hlp4
-rw-r--r--internal/lsp/cmd/usage/bug.hlp4
-rw-r--r--internal/lsp/cmd/usage/call_hierarchy.hlp10
-rw-r--r--internal/lsp/cmd/usage/check.hlp8
-rw-r--r--internal/lsp/cmd/usage/definition.hlp15
-rw-r--r--internal/lsp/cmd/usage/fix.hlp15
-rw-r--r--internal/lsp/cmd/usage/folding_ranges.hlp8
-rw-r--r--internal/lsp/cmd/usage/format.hlp18
-rw-r--r--internal/lsp/cmd/usage/highlight.hlp10
-rw-r--r--internal/lsp/cmd/usage/implementation.hlp10
-rw-r--r--internal/lsp/cmd/usage/imports.hlp14
-rw-r--r--internal/lsp/cmd/usage/inspect.hlp8
-rw-r--r--internal/lsp/cmd/usage/licenses.hlp4
-rw-r--r--internal/lsp/cmd/usage/links.hlp12
-rw-r--r--internal/lsp/cmd/usage/prepare_rename.hlp10
-rw-r--r--internal/lsp/cmd/usage/references.hlp14
-rw-r--r--internal/lsp/cmd/usage/remote.hlp8
-rw-r--r--internal/lsp/cmd/usage/rename.hlp18
-rw-r--r--internal/lsp/cmd/usage/semtok.hlp8
-rw-r--r--internal/lsp/cmd/usage/serve.hlp30
-rw-r--r--internal/lsp/cmd/usage/signature.hlp10
-rw-r--r--internal/lsp/cmd/usage/symbols.hlp7
-rw-r--r--internal/lsp/cmd/usage/usage.hlp77
-rw-r--r--internal/lsp/cmd/usage/version.hlp6
-rw-r--r--internal/lsp/cmd/usage/vulncheck.hlp9
-rw-r--r--internal/lsp/cmd/usage/workspace.hlp7
-rw-r--r--internal/lsp/cmd/usage/workspace_symbol.hlp13
-rw-r--r--internal/lsp/cmd/vulncheck.go79
-rw-r--r--internal/lsp/cmd/workspace.go77
-rw-r--r--internal/lsp/cmd/workspace_symbol.go85
73 files changed, 0 insertions, 4728 deletions
diff --git a/internal/lsp/cmd/call_hierarchy.go b/internal/lsp/cmd/call_hierarchy.go
deleted file mode 100644
index c9f9e73e0..000000000
--- a/internal/lsp/cmd/call_hierarchy.go
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2020 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"
- "strings"
-
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/span"
- "golang.org/x/tools/internal/tool"
-)
-
-// callHierarchy implements the callHierarchy verb for gopls.
-type callHierarchy struct {
- app *Application
-}
-
-func (c *callHierarchy) Name() string { return "call_hierarchy" }
-func (c *callHierarchy) Parent() string { return c.app.Name() }
-func (c *callHierarchy) Usage() string { return "<position>" }
-func (c *callHierarchy) ShortHelp() string { return "display selected identifier's call hierarchy" }
-func (c *callHierarchy) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprint(f.Output(), `
-Example:
-
- $ # 1-indexed location (:line:column or :#offset) of the target identifier
- $ gopls call_hierarchy helper/helper.go:8:6
- $ gopls call_hierarchy helper/helper.go:#53
-`)
- printFlagDefaults(f)
-}
-
-func (c *callHierarchy) Run(ctx context.Context, args ...string) error {
- if len(args) != 1 {
- return tool.CommandLineErrorf("call_hierarchy expects 1 argument (position)")
- }
-
- conn, err := c.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.CallHierarchyPrepareParams{
- TextDocumentPositionParams: protocol.TextDocumentPositionParams{
- TextDocument: protocol.TextDocumentIdentifier{URI: loc.URI},
- Position: loc.Range.Start,
- },
- }
-
- callItems, err := conn.PrepareCallHierarchy(ctx, &p)
- if err != nil {
- return err
- }
- if len(callItems) == 0 {
- return fmt.Errorf("function declaration identifier not found at %v", args[0])
- }
-
- for _, item := range callItems {
- incomingCalls, err := conn.IncomingCalls(ctx, &protocol.CallHierarchyIncomingCallsParams{Item: item})
- if err != nil {
- return err
- }
- for i, call := range incomingCalls {
- // From the spec: CallHierarchyIncomingCall.FromRanges is relative to
- // the caller denoted by CallHierarchyIncomingCall.from.
- printString, err := callItemPrintString(ctx, conn, call.From, call.From.URI, call.FromRanges)
- if err != nil {
- return err
- }
- fmt.Printf("caller[%d]: %s\n", i, printString)
- }
-
- printString, err := callItemPrintString(ctx, conn, item, "", nil)
- if err != nil {
- return err
- }
- fmt.Printf("identifier: %s\n", printString)
-
- outgoingCalls, err := conn.OutgoingCalls(ctx, &protocol.CallHierarchyOutgoingCallsParams{Item: item})
- if err != nil {
- return err
- }
- for i, call := range outgoingCalls {
- // From the spec: CallHierarchyOutgoingCall.FromRanges is the range
- // relative to the caller, e.g the item passed to
- printString, err := callItemPrintString(ctx, conn, call.To, item.URI, call.FromRanges)
- if err != nil {
- return err
- }
- fmt.Printf("callee[%d]: %s\n", i, printString)
- }
- }
-
- return nil
-}
-
-// callItemPrintString returns a protocol.CallHierarchyItem object represented as a string.
-// item and call ranges (protocol.Range) are converted to user friendly spans (1-indexed).
-func callItemPrintString(ctx context.Context, conn *connection, item protocol.CallHierarchyItem, callsURI protocol.DocumentURI, calls []protocol.Range) (string, error) {
- itemFile := conn.AddFile(ctx, item.URI.SpanURI())
- if itemFile.err != nil {
- return "", itemFile.err
- }
- itemSpan, err := itemFile.mapper.Span(protocol.Location{URI: item.URI, Range: item.Range})
- if err != nil {
- return "", err
- }
-
- callsFile := conn.AddFile(ctx, callsURI.SpanURI())
- if callsURI != "" && callsFile.err != nil {
- return "", callsFile.err
- }
- var callRanges []string
- for _, rng := range calls {
- callSpan, err := callsFile.mapper.Span(protocol.Location{URI: item.URI, Range: rng})
- if err != nil {
- return "", err
- }
-
- spn := fmt.Sprint(callSpan)
- callRanges = append(callRanges, fmt.Sprint(spn[strings.Index(spn, ":")+1:]))
- }
-
- printString := fmt.Sprintf("function %s in %v", item.Name, itemSpan)
- if len(calls) > 0 {
- printString = fmt.Sprintf("ranges %s in %s from/to %s", strings.Join(callRanges, ", "), callsURI.SpanURI().Filename(), printString)
- }
- return printString, nil
-}
diff --git a/internal/lsp/cmd/capabilities_test.go b/internal/lsp/cmd/capabilities_test.go
deleted file mode 100644
index 70db8d7d3..000000000
--- a/internal/lsp/cmd/capabilities_test.go
+++ /dev/null
@@ -1,166 +0,0 @@
-// 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"
- "io/ioutil"
- "os"
- "path/filepath"
- "testing"
-
- "golang.org/x/tools/internal/lsp"
- "golang.org/x/tools/internal/lsp/cache"
- "golang.org/x/tools/internal/lsp/protocol"
- errors "golang.org/x/xerrors"
-)
-
-// TestCapabilities does some minimal validation of the server's adherence to the LSP.
-// The checks in the test are added as changes are made and errors noticed.
-func TestCapabilities(t *testing.T) {
- tmpDir, err := ioutil.TempDir("", "fake")
- if err != nil {
- t.Fatal(err)
- }
- tmpFile := filepath.Join(tmpDir, "fake.go")
- if err := ioutil.WriteFile(tmpFile, []byte(""), 0775); err != nil {
- t.Fatal(err)
- }
- if err := ioutil.WriteFile(filepath.Join(tmpDir, "go.mod"), []byte("module fake\n\ngo 1.12\n"), 0775); err != nil {
- t.Fatal(err)
- }
- defer os.RemoveAll(tmpDir)
-
- app := New("gopls-test", tmpDir, os.Environ(), nil)
- c := newConnection(app)
- ctx := context.Background()
- defer c.terminate(ctx)
-
- params := &protocol.ParamInitialize{}
- params.RootURI = protocol.URIFromPath(c.Client.app.wd)
- params.Capabilities.Workspace.Configuration = true
-
- // Send an initialize request to the server.
- c.Server = lsp.NewServer(cache.New(app.options).NewSession(ctx), c.Client)
- result, err := c.Server.Initialize(ctx, params)
- if err != nil {
- t.Fatal(err)
- }
- // Validate initialization result.
- if err := validateCapabilities(result); err != nil {
- t.Error(err)
- }
- // Complete initialization of server.
- if err := c.Server.Initialized(ctx, &protocol.InitializedParams{}); err != nil {
- t.Fatal(err)
- }
-
- // Open the file on the server side.
- uri := protocol.URIFromPath(tmpFile)
- if err := c.Server.DidOpen(ctx, &protocol.DidOpenTextDocumentParams{
- TextDocument: protocol.TextDocumentItem{
- URI: uri,
- LanguageID: "go",
- Version: 1,
- Text: `package main; func main() {};`,
- },
- }); err != nil {
- t.Fatal(err)
- }
-
- // If we are sending a full text change, the change.Range must be nil.
- // It is not enough for the Change to be empty, as that is ambiguous.
- if err := c.Server.DidChange(ctx, &protocol.DidChangeTextDocumentParams{
- TextDocument: protocol.VersionedTextDocumentIdentifier{
- TextDocumentIdentifier: protocol.TextDocumentIdentifier{
- URI: uri,
- },
- Version: 2,
- },
- ContentChanges: []protocol.TextDocumentContentChangeEvent{
- {
- Range: nil,
- Text: `package main; func main() { fmt.Println("") }`,
- },
- },
- }); err != nil {
- t.Fatal(err)
- }
-
- // Send a code action request to validate expected types.
- actions, err := c.Server.CodeAction(ctx, &protocol.CodeActionParams{
- TextDocument: protocol.TextDocumentIdentifier{
- URI: uri,
- },
- })
- if err != nil {
- t.Fatal(err)
- }
- for _, action := range actions {
- // Validate that an empty command is sent along with import organization responses.
- if action.Kind == protocol.SourceOrganizeImports && action.Command != nil {
- t.Errorf("unexpected command for import organization")
- }
- }
-
- if err := c.Server.DidSave(ctx, &protocol.DidSaveTextDocumentParams{
- TextDocument: protocol.TextDocumentIdentifier{
- URI: uri,
- },
- // LSP specifies that a file can be saved with optional text, so this field must be nil.
- Text: nil,
- }); err != nil {
- t.Fatal(err)
- }
-
- // Send a completion request to validate expected types.
- list, err := c.Server.Completion(ctx, &protocol.CompletionParams{
- TextDocumentPositionParams: protocol.TextDocumentPositionParams{
- TextDocument: protocol.TextDocumentIdentifier{
- URI: uri,
- },
- Position: protocol.Position{
- Line: 0,
- Character: 28,
- },
- },
- })
- if err != nil {
- t.Fatal(err)
- }
- for _, item := range list.Items {
- // All other completion items should have nil commands.
- // An empty command will be treated as a command with the name '' by VS Code.
- // This causes VS Code to report errors to users about invalid commands.
- if item.Command != nil {
- t.Errorf("unexpected command for completion item")
- }
- // The item's TextEdit must be a pointer, as VS Code considers TextEdits
- // that don't contain the cursor position to be invalid.
- var textEdit interface{} = item.TextEdit
- if _, ok := textEdit.(*protocol.TextEdit); !ok {
- t.Errorf("textEdit is not a *protocol.TextEdit, instead it is %T", textEdit)
- }
- }
- if err := c.Server.Shutdown(ctx); err != nil {
- t.Fatal(err)
- }
- if err := c.Server.Exit(ctx); err != nil {
- t.Fatal(err)
- }
-}
-
-func validateCapabilities(result *protocol.InitializeResult) error {
- // If the client sends "false" for RenameProvider.PrepareSupport,
- // the server must respond with a boolean.
- if v, ok := result.Capabilities.RenameProvider.(bool); !ok {
- return errors.Errorf("RenameProvider must be a boolean if PrepareSupport is false (got %T)", v)
- }
- // The same goes for CodeActionKind.ValueSet.
- if v, ok := result.Capabilities.CodeActionProvider.(bool); !ok {
- return errors.Errorf("CodeActionSupport must be a boolean if CodeActionKind.ValueSet has length 0 (got %T)", v)
- }
- return nil
-}
diff --git a/internal/lsp/cmd/check.go b/internal/lsp/cmd/check.go
deleted file mode 100644
index 566924aa6..000000000
--- a/internal/lsp/cmd/check.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// 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"
-
- "golang.org/x/tools/internal/span"
- errors "golang.org/x/xerrors"
-)
-
-// check implements the check verb for gopls.
-type check struct {
- app *Application
-}
-
-func (c *check) Name() string { return "check" }
-func (c *check) Parent() string { return c.app.Name() }
-func (c *check) Usage() string { return "<filename>" }
-func (c *check) ShortHelp() string { return "show diagnostic results for the specified file" }
-func (c *check) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprint(f.Output(), `
-Example: show the diagnostic results of this file:
-
- $ gopls check internal/lsp/cmd/check.go
-`)
- printFlagDefaults(f)
-}
-
-// Run performs the check on the files specified by args and prints the
-// results to stdout.
-func (c *check) Run(ctx context.Context, args ...string) error {
- if len(args) == 0 {
- // no files, so no results
- return nil
- }
- checking := map[span.URI]*cmdFile{}
- var uris []span.URI
- // now we ready to kick things off
- conn, err := c.app.connect(ctx)
- if err != nil {
- return err
- }
- defer conn.terminate(ctx)
- for _, arg := range args {
- uri := span.URIFromPath(arg)
- uris = append(uris, uri)
- file := conn.AddFile(ctx, uri)
- if file.err != nil {
- return file.err
- }
- checking[uri] = file
- }
- if err := conn.diagnoseFiles(ctx, uris); err != nil {
- return err
- }
- conn.Client.filesMu.Lock()
- defer conn.Client.filesMu.Unlock()
-
- for _, file := range checking {
- for _, d := range file.diagnostics {
- spn, err := file.mapper.RangeSpan(d.Range)
- if err != nil {
- return errors.Errorf("Could not convert position %v for %q", d.Range, d.Message)
- }
- fmt.Printf("%v: %v\n", spn, d.Message)
- }
- }
- return nil
-}
diff --git a/internal/lsp/cmd/cmd.go b/internal/lsp/cmd/cmd.go
deleted file mode 100644
index d48398d0d..000000000
--- a/internal/lsp/cmd/cmd.go
+++ /dev/null
@@ -1,630 +0,0 @@
-// Copyright 2018 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 handles the gopls command line.
-// It contains a handler for each of the modes, along with all the flag handling
-// and the command line output format.
-package cmd
-
-import (
- "context"
- "flag"
- "fmt"
- "go/token"
- "io/ioutil"
- "log"
- "os"
- "reflect"
- "sort"
- "strings"
- "sync"
- "text/tabwriter"
- "time"
-
- "golang.org/x/tools/internal/jsonrpc2"
- "golang.org/x/tools/internal/lsp"
- "golang.org/x/tools/internal/lsp/cache"
- "golang.org/x/tools/internal/lsp/debug"
- "golang.org/x/tools/internal/lsp/lsprpc"
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/lsp/source"
- "golang.org/x/tools/internal/span"
- "golang.org/x/tools/internal/tool"
- "golang.org/x/tools/internal/xcontext"
- errors "golang.org/x/xerrors"
-)
-
-// Application is the main application as passed to tool.Main
-// It handles the main command line parsing and dispatch to the sub commands.
-type Application struct {
- // Core application flags
-
- // Embed the basic profiling flags supported by the tool package
- tool.Profile
-
- // We include the server configuration directly for now, so the flags work
- // even without the verb.
- // TODO: Remove this when we stop allowing the serve verb by default.
- Serve Serve
-
- // the options configuring function to invoke when building a server
- options func(*source.Options)
-
- // The name of the binary, used in help and telemetry.
- name string
-
- // The working directory to run commands in.
- wd string
-
- // The environment variables to use.
- env []string
-
- // Support for remote LSP server.
- Remote string `flag:"remote" help:"forward all commands to a remote lsp specified by this flag. With no special prefix, this is assumed to be a TCP address. If prefixed by 'unix;', the subsequent address is assumed to be a unix domain socket. If 'auto', or prefixed by 'auto;', the remote address is automatically resolved based on the executing environment."`
-
- // Verbose enables verbose logging.
- Verbose bool `flag:"v,verbose" help:"verbose output"`
-
- // VeryVerbose enables a higher level of verbosity in logging output.
- VeryVerbose bool `flag:"vv,veryverbose" help:"very verbose output"`
-
- // Control ocagent export of telemetry
- OCAgent string `flag:"ocagent" help:"the address of the ocagent (e.g. http://localhost:55678), or off"`
-
- // PrepareOptions is called to update the options when a new view is built.
- // It is primarily to allow the behavior of gopls to be modified by hooks.
- PrepareOptions func(*source.Options)
-}
-
-func (app *Application) verbose() bool {
- return app.Verbose || app.VeryVerbose
-}
-
-// New returns a new Application ready to run.
-func New(name, wd string, env []string, options func(*source.Options)) *Application {
- if wd == "" {
- wd, _ = os.Getwd()
- }
- app := &Application{
- options: options,
- name: name,
- wd: wd,
- env: env,
- OCAgent: "off", //TODO: Remove this line to default the exporter to on
-
- Serve: Serve{
- RemoteListenTimeout: 1 * time.Minute,
- },
- }
- app.Serve.app = app
- return app
-}
-
-// Name implements tool.Application returning the binary name.
-func (app *Application) Name() string { return app.name }
-
-// Usage implements tool.Application returning empty extra argument usage.
-func (app *Application) Usage() string { return "" }
-
-// ShortHelp implements tool.Application returning the main binary help.
-func (app *Application) ShortHelp() string {
- return ""
-}
-
-// DetailedHelp implements tool.Application returning the main binary help.
-// This includes the short help for all the sub commands.
-func (app *Application) DetailedHelp(f *flag.FlagSet) {
- w := tabwriter.NewWriter(f.Output(), 0, 0, 2, ' ', 0)
- defer w.Flush()
-
- fmt.Fprint(w, `
-gopls is a Go language server.
-
-It is typically used with an editor to provide language features. When no
-command is specified, gopls will default to the 'serve' command. The language
-features can also be accessed via the gopls command-line interface.
-
-Usage:
- gopls help [<subject>]
-
-Command:
-`)
- fmt.Fprint(w, "\nMain\t\n")
- for _, c := range app.mainCommands() {
- fmt.Fprintf(w, " %s\t%s\n", c.Name(), c.ShortHelp())
- }
- fmt.Fprint(w, "\t\nFeatures\t\n")
- for _, c := range app.featureCommands() {
- fmt.Fprintf(w, " %s\t%s\n", c.Name(), c.ShortHelp())
- }
- fmt.Fprint(w, "\nflags:\n")
- printFlagDefaults(f)
-}
-
-// this is a slightly modified version of flag.PrintDefaults to give us control
-func printFlagDefaults(s *flag.FlagSet) {
- var flags [][]*flag.Flag
- seen := map[flag.Value]int{}
- s.VisitAll(func(f *flag.Flag) {
- if i, ok := seen[f.Value]; !ok {
- seen[f.Value] = len(flags)
- flags = append(flags, []*flag.Flag{f})
- } else {
- flags[i] = append(flags[i], f)
- }
- })
- for _, entry := range flags {
- sort.SliceStable(entry, func(i, j int) bool {
- return len(entry[i].Name) < len(entry[j].Name)
- })
- var b strings.Builder
- for i, f := range entry {
- switch i {
- case 0:
- b.WriteString(" -")
- default:
- b.WriteString(",-")
- }
- b.WriteString(f.Name)
- }
-
- f := entry[0]
- name, usage := flag.UnquoteUsage(f)
- if len(name) > 0 {
- b.WriteString("=")
- b.WriteString(name)
- }
- // Boolean flags of one ASCII letter are so common we
- // treat them specially, putting their usage on the same line.
- if b.Len() <= 4 { // space, space, '-', 'x'.
- b.WriteString("\t")
- } else {
- // Four spaces before the tab triggers good alignment
- // for both 4- and 8-space tab stops.
- b.WriteString("\n \t")
- }
- b.WriteString(strings.ReplaceAll(usage, "\n", "\n \t"))
- if !isZeroValue(f, f.DefValue) {
- if reflect.TypeOf(f.Value).Elem().Name() == "stringValue" {
- fmt.Fprintf(&b, " (default %q)", f.DefValue)
- } else {
- fmt.Fprintf(&b, " (default %v)", f.DefValue)
- }
- }
- fmt.Fprint(s.Output(), b.String(), "\n")
- }
-}
-
-// isZeroValue is copied from the flags package
-func isZeroValue(f *flag.Flag, value string) bool {
- // Build a zero value of the flag's Value type, and see if the
- // result of calling its String method equals the value passed in.
- // This works unless the Value type is itself an interface type.
- typ := reflect.TypeOf(f.Value)
- var z reflect.Value
- if typ.Kind() == reflect.Ptr {
- z = reflect.New(typ.Elem())
- } else {
- z = reflect.Zero(typ)
- }
- return value == z.Interface().(flag.Value).String()
-}
-
-// Run takes the args after top level flag processing, and invokes the correct
-// sub command as specified by the first argument.
-// If no arguments are passed it will invoke the server sub command, as a
-// temporary measure for compatibility.
-func (app *Application) Run(ctx context.Context, args ...string) error {
- ctx = debug.WithInstance(ctx, app.wd, app.OCAgent)
- if len(args) == 0 {
- s := flag.NewFlagSet(app.Name(), flag.ExitOnError)
- return tool.Run(ctx, s, &app.Serve, args)
- }
- command, args := args[0], args[1:]
- for _, c := range app.Commands() {
- if c.Name() == command {
- s := flag.NewFlagSet(app.Name(), flag.ExitOnError)
- return tool.Run(ctx, s, c, args)
- }
- }
- return tool.CommandLineErrorf("Unknown command %v", command)
-}
-
-// commands returns the set of commands supported by the gopls tool on the
-// command line.
-// The command is specified by the first non flag argument.
-func (app *Application) Commands() []tool.Application {
- var commands []tool.Application
- commands = append(commands, app.mainCommands()...)
- commands = append(commands, app.featureCommands()...)
- return commands
-}
-
-func (app *Application) mainCommands() []tool.Application {
- return []tool.Application{
- &app.Serve,
- &version{app: app},
- &bug{app: app},
- &apiJSON{app: app},
- &licenses{app: app},
- }
-}
-
-func (app *Application) featureCommands() []tool.Application {
- return []tool.Application{
- &callHierarchy{app: app},
- &check{app: app},
- &definition{app: app},
- &foldingRanges{app: app},
- &format{app: app},
- &highlight{app: app},
- &implementation{app: app},
- &imports{app: app},
- newRemote(app, ""),
- newRemote(app, "inspect"),
- &links{app: app},
- &prepareRename{app: app},
- &references{app: app},
- &rename{app: app},
- &semtok{app: app},
- &signature{app: app},
- &suggestedFix{app: app},
- &symbols{app: app},
- newWorkspace(app),
- &workspaceSymbol{app: app},
- &vulncheck{app: app},
- }
-}
-
-var (
- internalMu sync.Mutex
- internalConnections = make(map[string]*connection)
-)
-
-func (app *Application) connect(ctx context.Context) (*connection, error) {
- switch {
- case app.Remote == "":
- connection := newConnection(app)
- connection.Server = lsp.NewServer(cache.New(app.options).NewSession(ctx), connection.Client)
- ctx = protocol.WithClient(ctx, connection.Client)
- return connection, connection.initialize(ctx, app.options)
- case strings.HasPrefix(app.Remote, "internal@"):
- internalMu.Lock()
- defer internalMu.Unlock()
- opts := source.DefaultOptions().Clone()
- if app.options != nil {
- app.options(opts)
- }
- key := fmt.Sprintf("%s %v %v %v", app.wd, opts.PreferredContentFormat, opts.HierarchicalDocumentSymbolSupport, opts.SymbolMatcher)
- if c := internalConnections[key]; c != nil {
- return c, nil
- }
- remote := app.Remote[len("internal@"):]
- ctx := xcontext.Detach(ctx) //TODO:a way of shutting down the internal server
- connection, err := app.connectRemote(ctx, remote)
- if err != nil {
- return nil, err
- }
- internalConnections[key] = connection
- return connection, nil
- default:
- return app.connectRemote(ctx, app.Remote)
- }
-}
-
-// CloseTestConnections terminates shared connections used in command tests. It
-// should only be called from tests.
-func CloseTestConnections(ctx context.Context) {
- for _, c := range internalConnections {
- c.Shutdown(ctx)
- c.Exit(ctx)
- }
-}
-
-func (app *Application) connectRemote(ctx context.Context, remote string) (*connection, error) {
- connection := newConnection(app)
- conn, err := lsprpc.ConnectToRemote(ctx, remote)
- if err != nil {
- return nil, err
- }
- stream := jsonrpc2.NewHeaderStream(conn)
- cc := jsonrpc2.NewConn(stream)
- connection.Server = protocol.ServerDispatcher(cc)
- ctx = protocol.WithClient(ctx, connection.Client)
- cc.Go(ctx,
- protocol.Handlers(
- protocol.ClientHandler(connection.Client,
- jsonrpc2.MethodNotFound)))
- return connection, connection.initialize(ctx, app.options)
-}
-
-var matcherString = map[source.SymbolMatcher]string{
- source.SymbolFuzzy: "fuzzy",
- source.SymbolCaseSensitive: "caseSensitive",
- source.SymbolCaseInsensitive: "caseInsensitive",
-}
-
-func (c *connection) initialize(ctx context.Context, options func(*source.Options)) error {
- params := &protocol.ParamInitialize{}
- params.RootURI = protocol.URIFromPath(c.Client.app.wd)
- params.Capabilities.Workspace.Configuration = true
-
- // Make sure to respect configured options when sending initialize request.
- opts := source.DefaultOptions().Clone()
- if options != nil {
- options(opts)
- }
- // If you add an additional option here, you must update the map key in connect.
- params.Capabilities.TextDocument.Hover = protocol.HoverClientCapabilities{
- ContentFormat: []protocol.MarkupKind{opts.PreferredContentFormat},
- }
- params.Capabilities.TextDocument.DocumentSymbol.HierarchicalDocumentSymbolSupport = opts.HierarchicalDocumentSymbolSupport
- params.Capabilities.TextDocument.SemanticTokens = protocol.SemanticTokensClientCapabilities{}
- params.Capabilities.TextDocument.SemanticTokens.Formats = []string{"relative"}
- params.Capabilities.TextDocument.SemanticTokens.Requests.Range = true
- params.Capabilities.TextDocument.SemanticTokens.Requests.Full = true
- params.Capabilities.TextDocument.SemanticTokens.TokenTypes = lsp.SemanticTypes()
- params.Capabilities.TextDocument.SemanticTokens.TokenModifiers = lsp.SemanticModifiers()
- params.InitializationOptions = map[string]interface{}{
- "symbolMatcher": matcherString[opts.SymbolMatcher],
- }
- if _, err := c.Server.Initialize(ctx, params); err != nil {
- return err
- }
- if err := c.Server.Initialized(ctx, &protocol.InitializedParams{}); err != nil {
- return err
- }
- return nil
-}
-
-type connection struct {
- protocol.Server
- Client *cmdClient
-}
-
-type cmdClient struct {
- protocol.Server
- app *Application
- fset *token.FileSet
-
- diagnosticsMu sync.Mutex
- diagnosticsDone chan struct{}
-
- filesMu sync.Mutex
- files map[span.URI]*cmdFile
-}
-
-type cmdFile struct {
- uri span.URI
- mapper *protocol.ColumnMapper
- err error
- added bool
- diagnostics []protocol.Diagnostic
-}
-
-func newConnection(app *Application) *connection {
- return &connection{
- Client: &cmdClient{
- app: app,
- fset: token.NewFileSet(),
- files: make(map[span.URI]*cmdFile),
- },
- }
-}
-
-// fileURI converts a DocumentURI to a file:// span.URI, panicking if it's not a file.
-func fileURI(uri protocol.DocumentURI) span.URI {
- sURI := uri.SpanURI()
- if !sURI.IsFile() {
- panic(fmt.Sprintf("%q is not a file URI", uri))
- }
- return sURI
-}
-
-func (c *cmdClient) ShowMessage(ctx context.Context, p *protocol.ShowMessageParams) error { return nil }
-
-func (c *cmdClient) ShowMessageRequest(ctx context.Context, p *protocol.ShowMessageRequestParams) (*protocol.MessageActionItem, error) {
- return nil, nil
-}
-
-func (c *cmdClient) LogMessage(ctx context.Context, p *protocol.LogMessageParams) error {
- switch p.Type {
- case protocol.Error:
- log.Print("Error:", p.Message)
- case protocol.Warning:
- log.Print("Warning:", p.Message)
- case protocol.Info:
- if c.app.verbose() {
- log.Print("Info:", p.Message)
- }
- case protocol.Log:
- if c.app.verbose() {
- log.Print("Log:", p.Message)
- }
- default:
- if c.app.verbose() {
- log.Print(p.Message)
- }
- }
- return nil
-}
-
-func (c *cmdClient) Event(ctx context.Context, t *interface{}) error { return nil }
-
-func (c *cmdClient) RegisterCapability(ctx context.Context, p *protocol.RegistrationParams) error {
- return nil
-}
-
-func (c *cmdClient) UnregisterCapability(ctx context.Context, p *protocol.UnregistrationParams) error {
- return nil
-}
-
-func (c *cmdClient) WorkspaceFolders(ctx context.Context) ([]protocol.WorkspaceFolder, error) {
- return nil, nil
-}
-
-func (c *cmdClient) Configuration(ctx context.Context, p *protocol.ParamConfiguration) ([]interface{}, error) {
- results := make([]interface{}, len(p.Items))
- for i, item := range p.Items {
- if item.Section != "gopls" {
- continue
- }
- env := map[string]interface{}{}
- for _, value := range c.app.env {
- l := strings.SplitN(value, "=", 2)
- if len(l) != 2 {
- continue
- }
- env[l[0]] = l[1]
- }
- m := map[string]interface{}{
- "env": env,
- "analyses": map[string]bool{
- "fillreturns": true,
- "nonewvars": true,
- "noresultvalues": true,
- "undeclaredname": true,
- },
- }
- if c.app.VeryVerbose {
- m["verboseOutput"] = true
- }
- results[i] = m
- }
- return results, nil
-}
-
-func (c *cmdClient) ApplyEdit(ctx context.Context, p *protocol.ApplyWorkspaceEditParams) (*protocol.ApplyWorkspaceEditResult, error) {
- return &protocol.ApplyWorkspaceEditResult{Applied: false, FailureReason: "not implemented"}, nil
-}
-
-func (c *cmdClient) PublishDiagnostics(ctx context.Context, p *protocol.PublishDiagnosticsParams) error {
- if p.URI == "gopls://diagnostics-done" {
- close(c.diagnosticsDone)
- }
- // Don't worry about diagnostics without versions.
- if p.Version == 0 {
- return nil
- }
-
- c.filesMu.Lock()
- defer c.filesMu.Unlock()
-
- file := c.getFile(ctx, fileURI(p.URI))
- file.diagnostics = p.Diagnostics
- return nil
-}
-
-func (c *cmdClient) Progress(context.Context, *protocol.ProgressParams) error {
- return nil
-}
-
-func (c *cmdClient) ShowDocument(context.Context, *protocol.ShowDocumentParams) (*protocol.ShowDocumentResult, error) {
- return nil, nil
-}
-
-func (c *cmdClient) WorkDoneProgressCreate(context.Context, *protocol.WorkDoneProgressCreateParams) error {
- return nil
-}
-
-func (c *cmdClient) getFile(ctx context.Context, uri span.URI) *cmdFile {
- file, found := c.files[uri]
- if !found || file.err != nil {
- file = &cmdFile{
- uri: uri,
- }
- c.files[uri] = file
- }
- if file.mapper == nil {
- fname := uri.Filename()
- content, err := ioutil.ReadFile(fname)
- if err != nil {
- file.err = errors.Errorf("getFile: %v: %v", uri, err)
- return file
- }
- f := c.fset.AddFile(fname, -1, len(content))
- f.SetLinesForContent(content)
- converter := span.NewContentConverter(fname, content)
- file.mapper = &protocol.ColumnMapper{
- URI: uri,
- Converter: converter,
- Content: content,
- }
- }
- return file
-}
-
-func (c *connection) AddFile(ctx context.Context, uri span.URI) *cmdFile {
- c.Client.filesMu.Lock()
- defer c.Client.filesMu.Unlock()
-
- file := c.Client.getFile(ctx, uri)
- // This should never happen.
- if file == nil {
- return &cmdFile{
- uri: uri,
- err: fmt.Errorf("no file found for %s", uri),
- }
- }
- if file.err != nil || file.added {
- return file
- }
- file.added = true
- p := &protocol.DidOpenTextDocumentParams{
- TextDocument: protocol.TextDocumentItem{
- URI: protocol.URIFromSpanURI(uri),
- LanguageID: "go",
- Version: 1,
- Text: string(file.mapper.Content),
- },
- }
- if err := c.Server.DidOpen(ctx, p); err != nil {
- file.err = errors.Errorf("%v: %v", uri, err)
- }
- return file
-}
-
-func (c *connection) semanticTokens(ctx context.Context, p *protocol.SemanticTokensRangeParams) (*protocol.SemanticTokens, error) {
- // use range to avoid limits on full
- resp, err := c.Server.SemanticTokensRange(ctx, p)
- if err != nil {
- return nil, err
- }
- return resp, nil
-}
-
-func (c *connection) diagnoseFiles(ctx context.Context, files []span.URI) error {
- var untypedFiles []interface{}
- for _, file := range files {
- untypedFiles = append(untypedFiles, string(file))
- }
- c.Client.diagnosticsMu.Lock()
- defer c.Client.diagnosticsMu.Unlock()
-
- c.Client.diagnosticsDone = make(chan struct{})
- _, err := c.Server.NonstandardRequest(ctx, "gopls/diagnoseFiles", map[string]interface{}{"files": untypedFiles})
- if err != nil {
- close(c.Client.diagnosticsDone)
- return err
- }
-
- <-c.Client.diagnosticsDone
- return nil
-}
-
-func (c *connection) terminate(ctx context.Context) {
- if strings.HasPrefix(c.Client.app.Remote, "internal@") {
- // internal connections need to be left alive for the next test
- return
- }
- //TODO: do we need to handle errors on these calls?
- c.Shutdown(ctx)
- //TODO: right now calling exit terminates the process, we should rethink that
- //server.Exit(ctx)
-}
-
-// Implement io.Closer.
-func (c *cmdClient) Close() error {
- return nil
-}
diff --git a/internal/lsp/cmd/cmd_test.go b/internal/lsp/cmd/cmd_test.go
deleted file mode 100644
index 29816c83e..000000000
--- a/internal/lsp/cmd/cmd_test.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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_test
-
-import (
- "os"
- "testing"
-
- cmdtest "golang.org/x/tools/internal/lsp/cmd/test"
- "golang.org/x/tools/internal/lsp/tests"
- "golang.org/x/tools/internal/testenv"
-)
-
-func TestMain(m *testing.M) {
- testenv.ExitIfSmallMachine()
- os.Exit(m.Run())
-}
-
-func TestCommandLine(t *testing.T) {
- cmdtest.TestCommandLine(t, "../testdata", tests.DefaultOptions)
-}
diff --git a/internal/lsp/cmd/definition.go b/internal/lsp/cmd/definition.go
deleted file mode 100644
index f3c71b671..000000000
--- a/internal/lsp/cmd/definition.go
+++ /dev/null
@@ -1,137 +0,0 @@
-// 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"
- "encoding/json"
- "flag"
- "fmt"
- "os"
- "strings"
-
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/lsp/source"
- "golang.org/x/tools/internal/span"
- "golang.org/x/tools/internal/tool"
- errors "golang.org/x/xerrors"
-)
-
-// A Definition is the result of a 'definition' query.
-type Definition struct {
- Span span.Span `json:"span"` // span of the definition
- Description string `json:"description"` // description of the denoted object
-}
-
-// These constant is printed in the help, and then used in a test to verify the
-// help is still valid.
-// They refer to "Set" in "flag.FlagSet" from the DetailedHelp method below.
-const (
- exampleLine = 44
- exampleColumn = 47
- exampleOffset = 1270
-)
-
-// definition implements the definition verb for gopls.
-type definition struct {
- app *Application
-
- JSON bool `flag:"json" help:"emit output in JSON format"`
- MarkdownSupported bool `flag:"markdown" help:"support markdown in responses"`
-}
-
-func (d *definition) Name() string { return "definition" }
-func (d *definition) Parent() string { return d.app.Name() }
-func (d *definition) Usage() string { return "[definition-flags] <position>" }
-func (d *definition) ShortHelp() string { return "show declaration of selected identifier" }
-func (d *definition) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprintf(f.Output(), `
-Example: show the definition of the identifier at syntax at offset %[1]v in this file (flag.FlagSet):
-
- $ gopls definition internal/lsp/cmd/definition.go:%[1]v:%[2]v
- $ gopls definition internal/lsp/cmd/definition.go:#%[3]v
-
-definition-flags:
-`, exampleLine, exampleColumn, exampleOffset)
- printFlagDefaults(f)
-}
-
-// Run performs the definition query as specified by args and prints the
-// results to stdout.
-func (d *definition) Run(ctx context.Context, args ...string) error {
- if len(args) != 1 {
- return tool.CommandLineErrorf("definition expects 1 argument")
- }
- // Plaintext makes more sense for the command line.
- opts := d.app.options
- d.app.options = func(o *source.Options) {
- if opts != nil {
- opts(o)
- }
- o.PreferredContentFormat = protocol.PlainText
- if d.MarkdownSupported {
- o.PreferredContentFormat = protocol.Markdown
- }
- }
- conn, err := d.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
- }
- tdpp := protocol.TextDocumentPositionParams{
- TextDocument: protocol.TextDocumentIdentifier{URI: loc.URI},
- Position: loc.Range.Start,
- }
- p := protocol.DefinitionParams{
- TextDocumentPositionParams: tdpp,
- }
- locs, err := conn.Definition(ctx, &p)
- if err != nil {
- return errors.Errorf("%v: %v", from, err)
- }
-
- if len(locs) == 0 {
- return errors.Errorf("%v: not an identifier", from)
- }
- q := protocol.HoverParams{
- TextDocumentPositionParams: tdpp,
- }
- hover, err := conn.Hover(ctx, &q)
- if err != nil {
- return errors.Errorf("%v: %v", from, err)
- }
- if hover == nil {
- return errors.Errorf("%v: not an identifier", from)
- }
- file = conn.AddFile(ctx, fileURI(locs[0].URI))
- if file.err != nil {
- return errors.Errorf("%v: %v", from, file.err)
- }
- definition, err := file.mapper.Span(locs[0])
- if err != nil {
- return errors.Errorf("%v: %v", from, err)
- }
- description := strings.TrimSpace(hover.Contents.Value)
- result := &Definition{
- Span: definition,
- Description: description,
- }
- if d.JSON {
- enc := json.NewEncoder(os.Stdout)
- enc.SetIndent("", "\t")
- return enc.Encode(result)
- }
- fmt.Printf("%v: defined here as %s", result.Span, result.Description)
- return nil
-}
diff --git a/internal/lsp/cmd/export_test.go b/internal/lsp/cmd/export_test.go
deleted file mode 100644
index 05b3cd312..000000000
--- a/internal/lsp/cmd/export_test.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// 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
-
-const (
- ExampleLine = exampleLine
- ExampleColumn = exampleColumn
- ExampleOffset = exampleOffset
-)
diff --git a/internal/lsp/cmd/folding_range.go b/internal/lsp/cmd/folding_range.go
deleted file mode 100644
index 513c9bdd2..000000000
--- a/internal/lsp/cmd/folding_range.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// 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"
-
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/span"
- "golang.org/x/tools/internal/tool"
-)
-
-// foldingRanges implements the folding_ranges verb for gopls
-type foldingRanges struct {
- app *Application
-}
-
-func (r *foldingRanges) Name() string { return "folding_ranges" }
-func (r *foldingRanges) Parent() string { return r.app.Name() }
-func (r *foldingRanges) Usage() string { return "<file>" }
-func (r *foldingRanges) ShortHelp() string { return "display selected file's folding ranges" }
-func (r *foldingRanges) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprint(f.Output(), `
-Example:
-
- $ gopls folding_ranges helper/helper.go
-`)
- printFlagDefaults(f)
-}
-
-func (r *foldingRanges) Run(ctx context.Context, args ...string) error {
- if len(args) != 1 {
- return tool.CommandLineErrorf("folding_ranges expects 1 argument (file)")
- }
-
- 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
- }
-
- p := protocol.FoldingRangeParams{
- TextDocument: protocol.TextDocumentIdentifier{
- URI: protocol.URIFromSpanURI(from.URI()),
- },
- }
-
- ranges, err := conn.FoldingRange(ctx, &p)
- if err != nil {
- return err
- }
-
- for _, r := range ranges {
- fmt.Printf("%v:%v-%v:%v\n",
- r.StartLine+1,
- r.StartCharacter+1,
- r.EndLine+1,
- r.EndCharacter,
- )
- }
-
- return nil
-}
diff --git a/internal/lsp/cmd/format.go b/internal/lsp/cmd/format.go
deleted file mode 100644
index 2d0f3f7c3..000000000
--- a/internal/lsp/cmd/format.go
+++ /dev/null
@@ -1,108 +0,0 @@
-// 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"
- "io/ioutil"
-
- "golang.org/x/tools/internal/lsp/diff"
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/lsp/source"
- "golang.org/x/tools/internal/span"
- errors "golang.org/x/xerrors"
-)
-
-// format implements the format verb for gopls.
-type format struct {
- Diff bool `flag:"d,diff" help:"display diffs instead of rewriting files"`
- Write bool `flag:"w,write" help:"write result to (source) file instead of stdout"`
- List bool `flag:"l,list" help:"list files whose formatting differs from gofmt's"`
-
- app *Application
-}
-
-func (c *format) Name() string { return "format" }
-func (c *format) Parent() string { return c.app.Name() }
-func (c *format) Usage() string { return "[format-flags] <filerange>" }
-func (c *format) ShortHelp() string { return "format the code according to the go standard" }
-func (c *format) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprint(f.Output(), `
-The arguments supplied may be simple file names, or ranges within files.
-
-Example: reformat this file:
-
- $ gopls format -w internal/lsp/cmd/check.go
-
-format-flags:
-`)
- printFlagDefaults(f)
-}
-
-// Run performs the check on the files specified by args and prints the
-// results to stdout.
-func (c *format) Run(ctx context.Context, args ...string) error {
- if len(args) == 0 {
- // no files, so no results
- return nil
- }
- // now we ready to kick things off
- conn, err := c.app.connect(ctx)
- if err != nil {
- return err
- }
- defer conn.terminate(ctx)
- for _, arg := range args {
- spn := span.Parse(arg)
- file := conn.AddFile(ctx, spn.URI())
- if file.err != nil {
- return file.err
- }
- filename := spn.URI().Filename()
- loc, err := file.mapper.Location(spn)
- if err != nil {
- return err
- }
- if loc.Range.Start != loc.Range.End {
- return errors.Errorf("only full file formatting supported")
- }
- p := protocol.DocumentFormattingParams{
- TextDocument: protocol.TextDocumentIdentifier{URI: loc.URI},
- }
- edits, err := conn.Formatting(ctx, &p)
- if err != nil {
- return errors.Errorf("%v: %v", spn, err)
- }
- sedits, err := source.FromProtocolEdits(file.mapper, edits)
- if err != nil {
- return errors.Errorf("%v: %v", spn, err)
- }
- formatted := diff.ApplyEdits(string(file.mapper.Content), sedits)
- printIt := true
- if c.List {
- printIt = false
- if len(edits) > 0 {
- fmt.Println(filename)
- }
- }
- if c.Write {
- printIt = false
- if len(edits) > 0 {
- ioutil.WriteFile(filename, []byte(formatted), 0644)
- }
- }
- if c.Diff {
- printIt = false
- u := diff.ToUnified(filename+".orig", filename, string(file.mapper.Content), sedits)
- fmt.Print(u)
- }
- if printIt {
- fmt.Print(formatted)
- }
- }
- return nil
-}
diff --git a/internal/lsp/cmd/help_test.go b/internal/lsp/cmd/help_test.go
deleted file mode 100644
index 536d19dc2..000000000
--- a/internal/lsp/cmd/help_test.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// 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_test
-
-import (
- "bytes"
- "context"
- "flag"
- "io/ioutil"
- "path/filepath"
- "testing"
-
- "golang.org/x/tools/internal/lsp/cmd"
- "golang.org/x/tools/internal/testenv"
- "golang.org/x/tools/internal/tool"
-)
-
-//go:generate go test -run Help -update-help-files
-
-var updateHelpFiles = flag.Bool("update-help-files", false, "Write out the help files instead of checking them")
-
-const appName = "gopls"
-
-func TestHelpFiles(t *testing.T) {
- testenv.NeedsGoBuild(t) // This is a lie. We actually need the source code.
- app := cmd.New(appName, "", nil, nil)
- ctx := context.Background()
- for _, page := range append(app.Commands(), app) {
- t.Run(page.Name(), func(t *testing.T) {
- var buf bytes.Buffer
- s := flag.NewFlagSet(page.Name(), flag.ContinueOnError)
- s.SetOutput(&buf)
- tool.Run(ctx, s, page, []string{"-h"})
- name := page.Name()
- if name == appName {
- name = "usage"
- }
- helpFile := filepath.Join("usage", name+".hlp")
- got := buf.Bytes()
- if *updateHelpFiles {
- if err := ioutil.WriteFile(helpFile, got, 0666); err != nil {
- t.Errorf("Failed writing %v: %v", helpFile, err)
- }
- return
- }
- expect, err := ioutil.ReadFile(helpFile)
- switch {
- case err != nil:
- t.Errorf("Missing help file %q", helpFile)
- case !bytes.Equal(expect, got):
- t.Errorf("Help file %q did not match, got:\n%q\nwant:\n%q", helpFile, string(got), string(expect))
- }
- })
- }
-}
diff --git a/internal/lsp/cmd/highlight.go b/internal/lsp/cmd/highlight.go
deleted file mode 100644
index a325a2d53..000000000
--- a/internal/lsp/cmd/highlight.go
+++ /dev/null
@@ -1,89 +0,0 @@
-// 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"
-)
-
-// highlight implements the highlight verb for gopls.
-type highlight struct {
- app *Application
-}
-
-func (r *highlight) Name() string { return "highlight" }
-func (r *highlight) Parent() string { return r.app.Name() }
-func (r *highlight) Usage() string { return "<position>" }
-func (r *highlight) ShortHelp() string { return "display selected identifier's highlights" }
-func (r *highlight) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprint(f.Output(), `
-Example:
-
- $ # 1-indexed location (:line:column or :#offset) of the target identifier
- $ gopls highlight helper/helper.go:8:6
- $ gopls highlight helper/helper.go:#53
-`)
- printFlagDefaults(f)
-}
-
-func (r *highlight) Run(ctx context.Context, args ...string) error {
- if len(args) != 1 {
- return tool.CommandLineErrorf("highlight 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.DocumentHighlightParams{
- TextDocumentPositionParams: protocol.TextDocumentPositionParams{
- TextDocument: protocol.TextDocumentIdentifier{URI: loc.URI},
- Position: loc.Range.Start,
- },
- }
- highlights, err := conn.DocumentHighlight(ctx, &p)
- if err != nil {
- return err
- }
-
- var results []span.Span
- for _, h := range highlights {
- l := protocol.Location{Range: h.Range}
- s, err := file.mapper.Span(l)
- if err != nil {
- return err
- }
- results = append(results, s)
- }
- // Sort results to make tests deterministic since DocumentHighlight uses a map.
- sort.SliceStable(results, func(i, j int) bool {
- return span.Compare(results[i], results[j]) == -1
- })
-
- for _, s := range results {
- fmt.Println(s)
- }
- return nil
-}
diff --git a/internal/lsp/cmd/implementation.go b/internal/lsp/cmd/implementation.go
deleted file mode 100644
index 7b42d9943..000000000
--- a/internal/lsp/cmd/implementation.go
+++ /dev/null
@@ -1,88 +0,0 @@
-// 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"
-)
-
-// implementation implements the implementation verb for gopls
-type implementation struct {
- app *Application
-}
-
-func (i *implementation) Name() string { return "implementation" }
-func (i *implementation) Parent() string { return i.app.Name() }
-func (i *implementation) Usage() string { return "<position>" }
-func (i *implementation) ShortHelp() string { return "display selected identifier's implementation" }
-func (i *implementation) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprint(f.Output(), `
-Example:
-
- $ # 1-indexed location (:line:column or :#offset) of the target identifier
- $ gopls implementation helper/helper.go:8:6
- $ gopls implementation helper/helper.go:#53
-`)
- printFlagDefaults(f)
-}
-
-func (i *implementation) Run(ctx context.Context, args ...string) error {
- if len(args) != 1 {
- return tool.CommandLineErrorf("implementation expects 1 argument (position)")
- }
-
- conn, err := i.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.ImplementationParams{
- TextDocumentPositionParams: protocol.TextDocumentPositionParams{
- TextDocument: protocol.TextDocumentIdentifier{URI: loc.URI},
- Position: loc.Range.Start,
- },
- }
-
- implementations, err := conn.Implementation(ctx, &p)
- if err != nil {
- return err
- }
-
- var spans []string
- for _, impl := range implementations {
- f := conn.AddFile(ctx, fileURI(impl.URI))
- span, err := f.mapper.Span(impl)
- if err != nil {
- return err
- }
- spans = append(spans, fmt.Sprint(span))
- }
- sort.Strings(spans)
-
- for _, s := range spans {
- fmt.Println(s)
- }
-
- return nil
-}
diff --git a/internal/lsp/cmd/imports.go b/internal/lsp/cmd/imports.go
deleted file mode 100644
index 215c57f11..000000000
--- a/internal/lsp/cmd/imports.go
+++ /dev/null
@@ -1,102 +0,0 @@
-// 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"
- "io/ioutil"
-
- "golang.org/x/tools/internal/lsp/diff"
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/lsp/source"
- "golang.org/x/tools/internal/span"
- "golang.org/x/tools/internal/tool"
- errors "golang.org/x/xerrors"
-)
-
-// imports implements the import verb for gopls.
-type imports struct {
- Diff bool `flag:"d,diff" help:"display diffs instead of rewriting files"`
- Write bool `flag:"w,write" help:"write result to (source) file instead of stdout"`
-
- app *Application
-}
-
-func (t *imports) Name() string { return "imports" }
-func (t *imports) Parent() string { return t.app.Name() }
-func (t *imports) Usage() string { return "[imports-flags] <filename>" }
-func (t *imports) ShortHelp() string { return "updates import statements" }
-func (t *imports) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprintf(f.Output(), `
-Example: update imports statements in a file:
-
- $ gopls imports -w internal/lsp/cmd/check.go
-
-imports-flags:
-`)
- printFlagDefaults(f)
-}
-
-// Run performs diagnostic checks on the file specified and either;
-// - if -w is specified, updates the file in place;
-// - if -d is specified, prints out unified diffs of the changes; or
-// - otherwise, prints the new versions to stdout.
-func (t *imports) Run(ctx context.Context, args ...string) error {
- if len(args) != 1 {
- return tool.CommandLineErrorf("imports expects 1 argument")
- }
- conn, err := t.app.connect(ctx)
- if err != nil {
- return err
- }
- defer conn.terminate(ctx)
-
- from := span.Parse(args[0])
- uri := from.URI()
- file := conn.AddFile(ctx, uri)
- if file.err != nil {
- return file.err
- }
- actions, err := conn.CodeAction(ctx, &protocol.CodeActionParams{
- TextDocument: protocol.TextDocumentIdentifier{
- URI: protocol.URIFromSpanURI(uri),
- },
- })
- if err != nil {
- return errors.Errorf("%v: %v", from, err)
- }
- var edits []protocol.TextEdit
- for _, a := range actions {
- if a.Title != "Organize Imports" {
- continue
- }
- for _, c := range a.Edit.DocumentChanges {
- if fileURI(c.TextDocument.URI) == uri {
- edits = append(edits, c.Edits...)
- }
- }
- }
- sedits, err := source.FromProtocolEdits(file.mapper, edits)
- if err != nil {
- return errors.Errorf("%v: %v", edits, err)
- }
- newContent := diff.ApplyEdits(string(file.mapper.Content), sedits)
-
- filename := file.uri.Filename()
- switch {
- case t.Write:
- if len(edits) > 0 {
- ioutil.WriteFile(filename, []byte(newContent), 0644)
- }
- case t.Diff:
- diffs := diff.ToUnified(filename+".orig", filename, string(file.mapper.Content), sedits)
- fmt.Print(diffs)
- default:
- fmt.Print(string(newContent))
- }
- return nil
-}
diff --git a/internal/lsp/cmd/info.go b/internal/lsp/cmd/info.go
deleted file mode 100644
index 09f453e1a..000000000
--- a/internal/lsp/cmd/info.go
+++ /dev/null
@@ -1,197 +0,0 @@
-// 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 (
- "bytes"
- "context"
- "encoding/json"
- "flag"
- "fmt"
- "net/url"
- "os"
- "strings"
-
- "golang.org/x/tools/internal/lsp/browser"
- "golang.org/x/tools/internal/lsp/debug"
- "golang.org/x/tools/internal/lsp/source"
-)
-
-// version implements the version command.
-type version struct {
- JSON bool `flag:"json" help:"outputs in json format."`
-
- app *Application
-}
-
-func (v *version) Name() string { return "version" }
-func (v *version) Parent() string { return v.app.Name() }
-func (v *version) Usage() string { return "" }
-func (v *version) ShortHelp() string { return "print the gopls version information" }
-func (v *version) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprint(f.Output(), ``)
- printFlagDefaults(f)
-}
-
-// Run prints version information to stdout.
-func (v *version) Run(ctx context.Context, args ...string) error {
- var mode = debug.PlainText
- if v.JSON {
- mode = debug.JSON
- }
-
- return debug.PrintVersionInfo(ctx, os.Stdout, v.app.verbose(), mode)
-}
-
-// bug implements the bug command.
-type bug struct {
- app *Application
-}
-
-func (b *bug) Name() string { return "bug" }
-func (b *bug) Parent() string { return b.app.Name() }
-func (b *bug) Usage() string { return "" }
-func (b *bug) ShortHelp() string { return "report a bug in gopls" }
-func (b *bug) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprint(f.Output(), ``)
- printFlagDefaults(f)
-}
-
-const goplsBugPrefix = "x/tools/gopls: <DESCRIBE THE PROBLEM>"
-const goplsBugHeader = `ATTENTION: Please answer these questions BEFORE submitting your issue. Thanks!
-
-#### What did you do?
-If possible, provide a recipe for reproducing the error.
-A complete runnable program is good.
-A link on play.golang.org is better.
-A failing unit test is the best.
-
-#### What did you expect to see?
-
-
-#### What did you see instead?
-
-
-`
-
-// Run collects some basic information and then prepares an issue ready to
-// be reported.
-func (b *bug) Run(ctx context.Context, args ...string) error {
- buf := &bytes.Buffer{}
- fmt.Fprint(buf, goplsBugHeader)
- debug.PrintVersionInfo(ctx, buf, true, debug.Markdown)
- body := buf.String()
- title := strings.Join(args, " ")
- if !strings.HasPrefix(title, goplsBugPrefix) {
- title = goplsBugPrefix + title
- }
- if !browser.Open("https://github.com/golang/go/issues/new?title=" + url.QueryEscape(title) + "&body=" + url.QueryEscape(body)) {
- fmt.Print("Please file a new issue at golang.org/issue/new using this template:\n\n")
- fmt.Print(body)
- }
- return nil
-}
-
-type apiJSON struct {
- app *Application
-}
-
-func (j *apiJSON) Name() string { return "api-json" }
-func (j *apiJSON) Parent() string { return j.app.Name() }
-func (j *apiJSON) Usage() string { return "" }
-func (j *apiJSON) ShortHelp() string { return "print json describing gopls API" }
-func (j *apiJSON) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprint(f.Output(), ``)
- printFlagDefaults(f)
-}
-
-func (j *apiJSON) Run(ctx context.Context, args ...string) error {
- js, err := json.MarshalIndent(source.GeneratedAPIJSON, "", "\t")
- if err != nil {
- return err
- }
- fmt.Fprint(os.Stdout, string(js))
- return nil
-}
-
-type licenses struct {
- app *Application
-}
-
-func (l *licenses) Name() string { return "licenses" }
-func (l *licenses) Parent() string { return l.app.Name() }
-func (l *licenses) Usage() string { return "" }
-func (l *licenses) ShortHelp() string { return "print licenses of included software" }
-func (l *licenses) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprint(f.Output(), ``)
- printFlagDefaults(f)
-}
-
-const licensePreamble = `
-gopls is made available under the following BSD-style license:
-
-Copyright (c) 2009 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-gopls implements the LSP specification, which is made available under the following license:
-
-Copyright (c) Microsoft Corporation
-
-All rights reserved.
-
-MIT License
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
-modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
-OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-gopls also includes software made available under these licenses:
-`
-
-func (l *licenses) Run(ctx context.Context, args ...string) error {
- opts := source.DefaultOptions()
- l.app.options(opts)
- txt := licensePreamble
- if opts.LicensesText == "" {
- txt += "(development gopls, license information not available)"
- } else {
- txt += opts.LicensesText
- }
- fmt.Fprint(os.Stdout, txt)
- return nil
-}
diff --git a/internal/lsp/cmd/links.go b/internal/lsp/cmd/links.go
deleted file mode 100644
index d49aabb6f..000000000
--- a/internal/lsp/cmd/links.go
+++ /dev/null
@@ -1,78 +0,0 @@
-// 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"
- "encoding/json"
- "flag"
- "fmt"
- "os"
-
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/span"
- "golang.org/x/tools/internal/tool"
- errors "golang.org/x/xerrors"
-)
-
-// links implements the links verb for gopls.
-type links struct {
- JSON bool `flag:"json" help:"emit document links in JSON format"`
-
- app *Application
-}
-
-func (l *links) Name() string { return "links" }
-func (l *links) Parent() string { return l.app.Name() }
-func (l *links) Usage() string { return "[links-flags] <filename>" }
-func (l *links) ShortHelp() string { return "list links in a file" }
-func (l *links) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprintf(f.Output(), `
-Example: list links contained within a file:
-
- $ gopls links internal/lsp/cmd/check.go
-
-links-flags:
-`)
- printFlagDefaults(f)
-}
-
-// Run finds all the links within a document
-// - if -json is specified, outputs location range and uri
-// - otherwise, prints the a list of unique links
-func (l *links) Run(ctx context.Context, args ...string) error {
- if len(args) != 1 {
- return tool.CommandLineErrorf("links expects 1 argument")
- }
- conn, err := l.app.connect(ctx)
- if err != nil {
- return err
- }
- defer conn.terminate(ctx)
-
- from := span.Parse(args[0])
- uri := from.URI()
- file := conn.AddFile(ctx, uri)
- if file.err != nil {
- return file.err
- }
- results, err := conn.DocumentLink(ctx, &protocol.DocumentLinkParams{
- TextDocument: protocol.TextDocumentIdentifier{
- URI: protocol.URIFromSpanURI(uri),
- },
- })
- if err != nil {
- return errors.Errorf("%v: %v", from, err)
- }
- if l.JSON {
- enc := json.NewEncoder(os.Stdout)
- enc.SetIndent("", "\t")
- return enc.Encode(results)
- }
- for _, v := range results {
- fmt.Println(v.Target)
- }
- return nil
-}
diff --git a/internal/lsp/cmd/prepare_rename.go b/internal/lsp/cmd/prepare_rename.go
deleted file mode 100644
index aef0477e8..000000000
--- a/internal/lsp/cmd/prepare_rename.go
+++ /dev/null
@@ -1,84 +0,0 @@
-// 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"
-
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/span"
- "golang.org/x/tools/internal/tool"
- errors "golang.org/x/xerrors"
-)
-
-// prepareRename implements the prepare_rename verb for gopls.
-type prepareRename struct {
- app *Application
-}
-
-func (r *prepareRename) Name() string { return "prepare_rename" }
-func (r *prepareRename) Parent() string { return r.app.Name() }
-func (r *prepareRename) Usage() string { return "<position>" }
-func (r *prepareRename) ShortHelp() string { return "test validity of a rename operation at location" }
-func (r *prepareRename) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprint(f.Output(), `
-Example:
-
- $ # 1-indexed location (:line:column or :#offset) of the target identifier
- $ gopls prepare_rename helper/helper.go:8:6
- $ gopls prepare_rename helper/helper.go:#53
-`)
- printFlagDefaults(f)
-}
-
-// ErrInvalidRenamePosition is returned when prepareRename is run at a position that
-// is not a candidate for renaming.
-var ErrInvalidRenamePosition = errors.New("request is not valid at the given position")
-
-func (r *prepareRename) Run(ctx context.Context, args ...string) error {
- if len(args) != 1 {
- return tool.CommandLineErrorf("prepare_rename expects 1 argument (file)")
- }
-
- 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.PrepareRenameParams{
- TextDocumentPositionParams: protocol.TextDocumentPositionParams{
- TextDocument: protocol.TextDocumentIdentifier{URI: loc.URI},
- Position: loc.Range.Start,
- },
- }
- result, err := conn.PrepareRename(ctx, &p)
- if err != nil {
- return errors.Errorf("prepare_rename failed: %w", err)
- }
- if result == nil {
- return ErrInvalidRenamePosition
- }
-
- l := protocol.Location{Range: result.Range}
- s, err := file.mapper.Span(l)
- if err != nil {
- return err
- }
-
- fmt.Println(s)
- return nil
-}
diff --git a/internal/lsp/cmd/references.go b/internal/lsp/cmd/references.go
deleted file mode 100644
index 0697d2e11..000000000
--- a/internal/lsp/cmd/references.go
+++ /dev/null
@@ -1,92 +0,0 @@
-// 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,declaration" help:"include the declaration of the specified identifier in the results"`
-
- app *Application
-}
-
-func (r *references) Name() string { return "references" }
-func (r *references) Parent() string { return r.app.Name() }
-func (r *references) Usage() string { return "[references-flags] <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
-
-references-flags:
-`)
- printFlagDefaults(f)
-}
-
-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
- }
- var spans []string
- for _, l := range locations {
- f := conn.AddFile(ctx, fileURI(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
-}
diff --git a/internal/lsp/cmd/remote.go b/internal/lsp/cmd/remote.go
deleted file mode 100644
index f71113576..000000000
--- a/internal/lsp/cmd/remote.go
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright 2020 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"
- "encoding/json"
- "flag"
- "fmt"
- "log"
- "os"
-
- "golang.org/x/tools/internal/lsp/command"
- "golang.org/x/tools/internal/lsp/lsprpc"
- errors "golang.org/x/xerrors"
-)
-
-type remote struct {
- app *Application
- subcommands
-
- // For backward compatibility, allow aliasing this command (it was previously
- // called 'inspect').
- //
- // TODO(rFindley): delete this after allowing some transition time in case
- // there were any users of 'inspect' (I suspect not).
- alias string
-}
-
-func newRemote(app *Application, alias string) *remote {
- return &remote{
- app: app,
- subcommands: subcommands{
- &listSessions{app: app},
- &startDebugging{app: app},
- },
- alias: alias,
- }
-}
-
-func (r *remote) Name() string {
- if r.alias != "" {
- return r.alias
- }
- return "remote"
-}
-
-func (r *remote) Parent() string { return r.app.Name() }
-
-func (r *remote) ShortHelp() string {
- short := "interact with the gopls daemon"
- if r.alias != "" {
- short += " (deprecated: use 'remote')"
- }
- return short
-}
-
-// listSessions is an inspect subcommand to list current sessions.
-type listSessions struct {
- app *Application
-}
-
-func (c *listSessions) Name() string { return "sessions" }
-func (c *listSessions) Parent() string { return c.app.Name() }
-func (c *listSessions) Usage() string { return "" }
-func (c *listSessions) ShortHelp() string {
- return "print information about current gopls sessions"
-}
-
-const listSessionsExamples = `
-Examples:
-
-1) list sessions for the default daemon:
-
-$ gopls -remote=auto remote sessions
-or just
-$ gopls remote sessions
-
-2) list sessions for a specific daemon:
-
-$ gopls -remote=localhost:8082 remote sessions
-`
-
-func (c *listSessions) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprint(f.Output(), listSessionsExamples)
- printFlagDefaults(f)
-}
-
-func (c *listSessions) Run(ctx context.Context, args ...string) error {
- remote := c.app.Remote
- if remote == "" {
- remote = "auto"
- }
- state, err := lsprpc.QueryServerState(ctx, remote)
- if err != nil {
- return err
- }
- v, err := json.MarshalIndent(state, "", "\t")
- if err != nil {
- log.Fatal(err)
- }
- os.Stdout.Write(v)
- return nil
-}
-
-type startDebugging struct {
- app *Application
-}
-
-func (c *startDebugging) Name() string { return "debug" }
-func (c *startDebugging) Usage() string { return "[host:port]" }
-func (c *startDebugging) ShortHelp() string {
- return "start the debug server"
-}
-
-const startDebuggingExamples = `
-Examples:
-
-1) start a debug server for the default daemon, on an arbitrary port:
-
-$ gopls -remote=auto remote debug
-or just
-$ gopls remote debug
-
-2) start for a specific daemon, on a specific port:
-
-$ gopls -remote=localhost:8082 remote debug localhost:8083
-`
-
-func (c *startDebugging) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprint(f.Output(), startDebuggingExamples)
- printFlagDefaults(f)
-}
-
-func (c *startDebugging) Run(ctx context.Context, args ...string) error {
- if len(args) > 1 {
- fmt.Fprintln(os.Stderr, c.Usage())
- return errors.New("invalid usage")
- }
- remote := c.app.Remote
- if remote == "" {
- remote = "auto"
- }
- debugAddr := ""
- if len(args) > 0 {
- debugAddr = args[0]
- }
- debugArgs := command.DebuggingArgs{
- Addr: debugAddr,
- }
- var result command.DebuggingResult
- if err := lsprpc.ExecuteCommand(ctx, remote, command.StartDebugging.ID(), debugArgs, &result); err != nil {
- return err
- }
- if len(result.URLs) == 0 {
- return errors.New("no debugging URLs")
- }
- for _, url := range result.URLs {
- fmt.Printf("debugging on %s\n", url)
- }
- return nil
-}
diff --git a/internal/lsp/cmd/rename.go b/internal/lsp/cmd/rename.go
deleted file mode 100644
index b0a22a1b4..000000000
--- a/internal/lsp/cmd/rename.go
+++ /dev/null
@@ -1,128 +0,0 @@
-// 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"
- "io/ioutil"
- "os"
- "path/filepath"
- "sort"
-
- "golang.org/x/tools/internal/lsp/diff"
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/lsp/source"
- "golang.org/x/tools/internal/span"
- "golang.org/x/tools/internal/tool"
- errors "golang.org/x/xerrors"
-)
-
-// rename implements the rename verb for gopls.
-type rename struct {
- Diff bool `flag:"d,diff" help:"display diffs instead of rewriting files"`
- Write bool `flag:"w,write" help:"write result to (source) file instead of stdout"`
- Preserve bool `flag:"preserve" help:"preserve original files"`
-
- app *Application
-}
-
-func (r *rename) Name() string { return "rename" }
-func (r *rename) Parent() string { return r.app.Name() }
-func (r *rename) Usage() string { return "[rename-flags] <position> <name>" }
-func (r *rename) ShortHelp() string { return "rename selected identifier" }
-func (r *rename) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprint(f.Output(), `
-Example:
-
- $ # 1-based location (:line:column or :#position) of the thing to change
- $ gopls rename helper/helper.go:8:6 Foo
- $ gopls rename helper/helper.go:#53 Foo
-
-rename-flags:
-`)
- printFlagDefaults(f)
-}
-
-// Run renames the specified identifier and either;
-// - if -w is specified, updates the file(s) in place;
-// - if -d is specified, prints out unified diffs of the changes; or
-// - otherwise, prints the new versions to stdout.
-func (r *rename) Run(ctx context.Context, args ...string) error {
- if len(args) != 2 {
- return tool.CommandLineErrorf("definition expects 2 arguments (position, new name)")
- }
- 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.RenameParams{
- TextDocument: protocol.TextDocumentIdentifier{URI: loc.URI},
- Position: loc.Range.Start,
- NewName: args[1],
- }
- edit, err := conn.Rename(ctx, &p)
- if err != nil {
- return err
- }
- var orderedURIs []string
- edits := map[span.URI][]protocol.TextEdit{}
- for _, c := range edit.DocumentChanges {
- uri := fileURI(c.TextDocument.URI)
- edits[uri] = append(edits[uri], c.Edits...)
- orderedURIs = append(orderedURIs, string(uri))
- }
- sort.Strings(orderedURIs)
- changeCount := len(orderedURIs)
-
- for _, u := range orderedURIs {
- uri := span.URIFromURI(u)
- cmdFile := conn.AddFile(ctx, uri)
- filename := cmdFile.uri.Filename()
-
- // convert LSP-style edits to []diff.TextEdit cuz Spans are handy
- renameEdits, err := source.FromProtocolEdits(cmdFile.mapper, edits[uri])
- if err != nil {
- return errors.Errorf("%v: %v", edits, err)
- }
- newContent := diff.ApplyEdits(string(cmdFile.mapper.Content), renameEdits)
-
- switch {
- case r.Write:
- fmt.Fprintln(os.Stderr, filename)
- if r.Preserve {
- if err := os.Rename(filename, filename+".orig"); err != nil {
- return errors.Errorf("%v: %v", edits, err)
- }
- }
- ioutil.WriteFile(filename, []byte(newContent), 0644)
- case r.Diff:
- diffs := diff.ToUnified(filename+".orig", filename, string(cmdFile.mapper.Content), renameEdits)
- fmt.Print(diffs)
- default:
- if len(orderedURIs) > 1 {
- fmt.Printf("%s:\n", filepath.Base(filename))
- }
- fmt.Print(string(newContent))
- if changeCount > 1 { // if this wasn't last change, print newline
- fmt.Println()
- }
- changeCount -= 1
- }
- }
- return nil
-}
diff --git a/internal/lsp/cmd/semantictokens.go b/internal/lsp/cmd/semantictokens.go
deleted file mode 100644
index 120f91d36..000000000
--- a/internal/lsp/cmd/semantictokens.go
+++ /dev/null
@@ -1,230 +0,0 @@
-// Copyright 2020 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 (
- "bytes"
- "context"
- "flag"
- "fmt"
- "go/parser"
- "go/token"
- "io/ioutil"
- "log"
- "os"
- "unicode/utf8"
-
- "golang.org/x/tools/internal/lsp"
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/lsp/source"
- "golang.org/x/tools/internal/span"
-)
-
-// generate semantic tokens and interpolate them in the file
-
-// The output is the input file decorated with comments showing the
-// syntactic tokens. The comments are stylized:
-// /*<arrow><length>,<token type>,[<modifiers]*/
-// For most occurrences, the comment comes just before the token it
-// describes, and arrow is a right arrow. If the token is inside a string
-// the comment comes just after the string, and the arrow is a left arrow.
-// <length> is the length of the token in runes, <token type> is one
-// of the supported semantic token types, and <modifiers. is a
-// (possibly empty) list of token type modifiers.
-
-// There are 3 coordinate systems for lines and character offsets in lines
-// LSP (what's returned from semanticTokens()):
-// 0-based: the first line is line 0, the first character of a line
-// is character 0, and characters are counted as UTF-16 code points
-// gopls (and Go error messages):
-// 1-based: the first line is line1, the first chararcter of a line
-// is character 0, and characters are counted as bytes
-// internal (as used in marks, and lines:=bytes.Split(buf, '\n'))
-// 0-based: lines and character positions are 1 less than in
-// the gopls coordinate system
-
-type semtok struct {
- app *Application
-}
-
-var colmap *protocol.ColumnMapper
-
-func (c *semtok) Name() string { return "semtok" }
-func (c *semtok) Parent() string { return c.app.Name() }
-func (c *semtok) Usage() string { return "<filename>" }
-func (c *semtok) ShortHelp() string { return "show semantic tokens for the specified file" }
-func (c *semtok) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprint(f.Output(), `
-Example: show the semantic tokens for this file:
-
- $ gopls semtok internal/lsp/cmd/semtok.go
-`)
- printFlagDefaults(f)
-}
-
-// Run performs the semtok on the files specified by args and prints the
-// results to stdout in the format described above.
-func (c *semtok) Run(ctx context.Context, args ...string) error {
- if len(args) != 1 {
- return fmt.Errorf("expected one file name, got %d", len(args))
- }
- // perhaps simpler if app had just had a FlagSet member
- origOptions := c.app.options
- c.app.options = func(opts *source.Options) {
- origOptions(opts)
- opts.SemanticTokens = true
- }
- conn, err := c.app.connect(ctx)
- if err != nil {
- return err
- }
- defer conn.terminate(ctx)
- uri := span.URIFromPath(args[0])
- file := conn.AddFile(ctx, uri)
- if file.err != nil {
- return file.err
- }
-
- buf, err := ioutil.ReadFile(args[0])
- if err != nil {
- return err
- }
- lines := bytes.Split(buf, []byte{'\n'})
- p := &protocol.SemanticTokensRangeParams{
- TextDocument: protocol.TextDocumentIdentifier{
- URI: protocol.URIFromSpanURI(uri),
- },
- Range: protocol.Range{Start: protocol.Position{Line: 0, Character: 0},
- End: protocol.Position{
- Line: uint32(len(lines) - 1),
- Character: uint32(len(lines[len(lines)-1]))},
- },
- }
- resp, err := conn.semanticTokens(ctx, p)
- if err != nil {
- return err
- }
- fset := token.NewFileSet()
- f, err := parser.ParseFile(fset, args[0], buf, 0)
- if err != nil {
- log.Printf("parsing %s failed %v", args[0], err)
- return err
- }
- tok := fset.File(f.Pos())
- if tok == nil {
- // can't happen; just parsed this file
- return fmt.Errorf("can't find %s in fset", args[0])
- }
- tc := span.NewContentConverter(args[0], buf)
- colmap = &protocol.ColumnMapper{
- URI: span.URI(args[0]),
- Content: buf,
- Converter: tc,
- }
- err = decorate(file.uri.Filename(), resp.Data)
- if err != nil {
- return err
- }
- return nil
-}
-
-type mark struct {
- line, offset int // 1-based, from RangeSpan
- len int // bytes, not runes
- typ string
- mods []string
-}
-
-// prefixes for semantic token comments
-const (
- SemanticLeft = "/*⇐"
- SemanticRight = "/*⇒"
-)
-
-func markLine(m mark, lines [][]byte) {
- l := lines[m.line-1] // mx is 1-based
- length := utf8.RuneCount(l[m.offset-1 : m.offset-1+m.len])
- splitAt := m.offset - 1
- insert := ""
- if m.typ == "namespace" && m.offset-1+m.len < len(l) && l[m.offset-1+m.len] == '"' {
- // it is the last component of an import spec
- // cannot put a comment inside a string
- insert = fmt.Sprintf("%s%d,namespace,[]*/", SemanticLeft, length)
- splitAt = m.offset + m.len
- } else {
- // be careful not to generate //*
- spacer := ""
- if splitAt-1 >= 0 && l[splitAt-1] == '/' {
- spacer = " "
- }
- insert = fmt.Sprintf("%s%s%d,%s,%v*/", spacer, SemanticRight, length, m.typ, m.mods)
- }
- x := append([]byte(insert), l[splitAt:]...)
- l = append(l[:splitAt], x...)
- lines[m.line-1] = l
-}
-
-func decorate(file string, result []uint32) error {
- buf, err := ioutil.ReadFile(file)
- if err != nil {
- return err
- }
- marks := newMarks(result)
- if len(marks) == 0 {
- return nil
- }
- lines := bytes.Split(buf, []byte{'\n'})
- for i := len(marks) - 1; i >= 0; i-- {
- mx := marks[i]
- markLine(mx, lines)
- }
- os.Stdout.Write(bytes.Join(lines, []byte{'\n'}))
- return nil
-}
-
-func newMarks(d []uint32) []mark {
- ans := []mark{}
- // the following two loops could be merged, at the cost
- // of making the logic slightly more complicated to understand
- // first, convert from deltas to absolute, in LSP coordinates
- lspLine := make([]uint32, len(d)/5)
- lspChar := make([]uint32, len(d)/5)
- var line, char uint32
- for i := 0; 5*i < len(d); i++ {
- lspLine[i] = line + d[5*i+0]
- if d[5*i+0] > 0 {
- char = 0
- }
- lspChar[i] = char + d[5*i+1]
- char = lspChar[i]
- line = lspLine[i]
- }
- // second, convert to gopls coordinates
- for i := 0; 5*i < len(d); i++ {
- pr := protocol.Range{
- Start: protocol.Position{
- Line: lspLine[i],
- Character: lspChar[i],
- },
- End: protocol.Position{
- Line: lspLine[i],
- Character: lspChar[i] + d[5*i+2],
- },
- }
- spn, err := colmap.RangeSpan(pr)
- if err != nil {
- log.Fatal(err)
- }
- m := mark{
- line: spn.Start().Line(),
- offset: spn.Start().Column(),
- len: spn.End().Column() - spn.Start().Column(),
- typ: lsp.SemType(int(d[5*i+3])),
- mods: lsp.SemMods(int(d[5*i+4])),
- }
- ans = append(ans, m)
- }
- return ans
-}
diff --git a/internal/lsp/cmd/serve.go b/internal/lsp/cmd/serve.go
deleted file mode 100644
index f6e268397..000000000
--- a/internal/lsp/cmd/serve.go
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2018 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"
- "io"
- "log"
- "os"
- "time"
-
- "golang.org/x/tools/internal/fakenet"
- "golang.org/x/tools/internal/jsonrpc2"
- "golang.org/x/tools/internal/lsp/cache"
- "golang.org/x/tools/internal/lsp/debug"
- "golang.org/x/tools/internal/lsp/lsprpc"
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/tool"
- errors "golang.org/x/xerrors"
-)
-
-// Serve is a struct that exposes the configurable parts of the LSP server as
-// flags, in the right form for tool.Main to consume.
-type Serve struct {
- Logfile string `flag:"logfile" help:"filename to log to. if value is \"auto\", then logging to a default output file is enabled"`
- Mode string `flag:"mode" help:"no effect"`
- Port int `flag:"port" help:"port on which to run gopls for debugging purposes"`
- Address string `flag:"listen" help:"address on which to listen for remote connections. If prefixed by 'unix;', the subsequent address is assumed to be a unix domain socket. Otherwise, TCP is used."`
- IdleTimeout time.Duration `flag:"listen.timeout" help:"when used with -listen, shut down the server when there are no connected clients for this duration"`
- Trace bool `flag:"rpc.trace" help:"print the full rpc trace in lsp inspector format"`
- Debug string `flag:"debug" help:"serve debug information on the supplied address"`
-
- RemoteListenTimeout time.Duration `flag:"remote.listen.timeout" help:"when used with -remote=auto, the -listen.timeout value used to start the daemon"`
- RemoteDebug string `flag:"remote.debug" help:"when used with -remote=auto, the -debug value used to start the daemon"`
- RemoteLogfile string `flag:"remote.logfile" help:"when used with -remote=auto, the -logfile value used to start the daemon"`
-
- app *Application
-}
-
-func (s *Serve) Name() string { return "serve" }
-func (s *Serve) Parent() string { return s.app.Name() }
-func (s *Serve) Usage() string { return "[server-flags]" }
-func (s *Serve) ShortHelp() string {
- return "run a server for Go code using the Language Server Protocol"
-}
-func (s *Serve) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprint(f.Output(), ` gopls [flags] [server-flags]
-
-The server communicates using JSONRPC2 on stdin and stdout, and is intended to be run directly as
-a child of an editor process.
-
-server-flags:
-`)
- printFlagDefaults(f)
-}
-
-func (s *Serve) remoteArgs(network, address string) []string {
- args := []string{"serve",
- "-listen", fmt.Sprintf(`%s;%s`, network, address),
- }
- if s.RemoteDebug != "" {
- args = append(args, "-debug", s.RemoteDebug)
- }
- if s.RemoteListenTimeout != 0 {
- args = append(args, "-listen.timeout", s.RemoteListenTimeout.String())
- }
- if s.RemoteLogfile != "" {
- args = append(args, "-logfile", s.RemoteLogfile)
- }
- return args
-}
-
-// Run configures a server based on the flags, and then runs it.
-// It blocks until the server shuts down.
-func (s *Serve) Run(ctx context.Context, args ...string) error {
- if len(args) > 0 {
- return tool.CommandLineErrorf("server does not take arguments, got %v", args)
- }
-
- di := debug.GetInstance(ctx)
- isDaemon := s.Address != "" || s.Port != 0
- if di != nil {
- closeLog, err := di.SetLogFile(s.Logfile, isDaemon)
- if err != nil {
- return err
- }
- defer closeLog()
- di.ServerAddress = s.Address
- di.MonitorMemory(ctx)
- di.Serve(ctx, s.Debug)
- }
- var ss jsonrpc2.StreamServer
- if s.app.Remote != "" {
- var err error
- ss, err = lsprpc.NewForwarder(s.app.Remote, s.remoteArgs)
- if err != nil {
- return errors.Errorf("creating forwarder: %w", err)
- }
- } else {
- ss = lsprpc.NewStreamServer(cache.New(s.app.options), isDaemon)
- }
-
- var network, addr string
- if s.Address != "" {
- network, addr = lsprpc.ParseAddr(s.Address)
- }
- if s.Port != 0 {
- network = "tcp"
- addr = fmt.Sprintf(":%v", s.Port)
- }
- if addr != "" {
- log.Printf("Gopls daemon: listening on %s network, address %s...", network, addr)
- defer log.Printf("Gopls daemon: exiting")
- return jsonrpc2.ListenAndServe(ctx, network, addr, ss, s.IdleTimeout)
- }
- stream := jsonrpc2.NewHeaderStream(fakenet.NewConn("stdio", os.Stdin, os.Stdout))
- if s.Trace && di != nil {
- stream = protocol.LoggingStream(stream, di.LogWriter)
- }
- conn := jsonrpc2.NewConn(stream)
- err := ss.ServeStream(ctx, conn)
- if errors.Is(err, io.EOF) {
- return nil
- }
- return err
-}
diff --git a/internal/lsp/cmd/signature.go b/internal/lsp/cmd/signature.go
deleted file mode 100644
index db9484301..000000000
--- a/internal/lsp/cmd/signature.go
+++ /dev/null
@@ -1,87 +0,0 @@
-// 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"
-
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/span"
- "golang.org/x/tools/internal/tool"
-)
-
-// signature implements the signature verb for gopls
-type signature struct {
- app *Application
-}
-
-func (r *signature) Name() string { return "signature" }
-func (r *signature) Parent() string { return r.app.Name() }
-func (r *signature) Usage() string { return "<position>" }
-func (r *signature) ShortHelp() string { return "display selected identifier's signature" }
-func (r *signature) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprint(f.Output(), `
-Example:
-
- $ # 1-indexed location (:line:column or :#offset) of the target identifier
- $ gopls signature helper/helper.go:8:6
- $ gopls signature helper/helper.go:#53
-`)
- printFlagDefaults(f)
-}
-
-func (r *signature) Run(ctx context.Context, args ...string) error {
- if len(args) != 1 {
- return tool.CommandLineErrorf("signature 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
- }
-
- tdpp := protocol.TextDocumentPositionParams{
- TextDocument: protocol.TextDocumentIdentifier{
- URI: protocol.URIFromSpanURI(from.URI()),
- },
- Position: loc.Range.Start,
- }
- p := protocol.SignatureHelpParams{
- TextDocumentPositionParams: tdpp,
- }
-
- s, err := conn.SignatureHelp(ctx, &p)
- if err != nil {
- return err
- }
-
- if s == nil || len(s.Signatures) == 0 {
- return tool.CommandLineErrorf("%v: not a function", from)
- }
-
- // there is only ever one possible signature,
- // see toProtocolSignatureHelp in lsp/signature_help.go
- signature := s.Signatures[0]
- fmt.Printf("%s\n", signature.Label)
- if signature.Documentation != "" {
- fmt.Printf("\n%s\n", signature.Documentation)
- }
-
- return nil
-}
diff --git a/internal/lsp/cmd/subcommands.go b/internal/lsp/cmd/subcommands.go
deleted file mode 100644
index deac5c822..000000000
--- a/internal/lsp/cmd/subcommands.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2021 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"
- "text/tabwriter"
-
- "golang.org/x/tools/internal/tool"
-)
-
-// subcommands is a helper that may be embedded for commands that delegate to
-// subcommands.
-type subcommands []tool.Application
-
-func (s subcommands) DetailedHelp(f *flag.FlagSet) {
- w := tabwriter.NewWriter(f.Output(), 0, 0, 2, ' ', 0)
- defer w.Flush()
- fmt.Fprint(w, "\nSubcommand:\n")
- for _, c := range s {
- fmt.Fprintf(w, " %s\t%s\n", c.Name(), c.ShortHelp())
- }
- printFlagDefaults(f)
-}
-
-func (s subcommands) Usage() string { return "<subcommand> [arg]..." }
-
-func (s subcommands) Run(ctx context.Context, args ...string) error {
- if len(args) == 0 {
- return tool.CommandLineErrorf("must provide subcommand")
- }
- command, args := args[0], args[1:]
- for _, c := range s {
- if c.Name() == command {
- s := flag.NewFlagSet(c.Name(), flag.ExitOnError)
- return tool.Run(ctx, s, c, args)
- }
- }
- return tool.CommandLineErrorf("unknown subcommand %v", command)
-}
diff --git a/internal/lsp/cmd/suggested_fix.go b/internal/lsp/cmd/suggested_fix.go
deleted file mode 100644
index df14631da..000000000
--- a/internal/lsp/cmd/suggested_fix.go
+++ /dev/null
@@ -1,159 +0,0 @@
-// 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"
- "io/ioutil"
-
- "golang.org/x/tools/internal/lsp/diff"
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/lsp/source"
- "golang.org/x/tools/internal/span"
- "golang.org/x/tools/internal/tool"
- errors "golang.org/x/xerrors"
-)
-
-// suggestedFix implements the fix verb for gopls.
-type suggestedFix struct {
- Diff bool `flag:"d,diff" help:"display diffs instead of rewriting files"`
- Write bool `flag:"w,write" help:"write result to (source) file instead of stdout"`
- All bool `flag:"a,all" help:"apply all fixes, not just preferred fixes"`
-
- app *Application
-}
-
-func (s *suggestedFix) Name() string { return "fix" }
-func (s *suggestedFix) Parent() string { return s.app.Name() }
-func (s *suggestedFix) Usage() string { return "[fix-flags] <filename>" }
-func (s *suggestedFix) ShortHelp() string { return "apply suggested fixes" }
-func (s *suggestedFix) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprintf(f.Output(), `
-Example: apply suggested fixes for this file
- $ gopls fix -w internal/lsp/cmd/check.go
-
-fix-flags:
-`)
- printFlagDefaults(f)
-}
-
-// Run performs diagnostic checks on the file specified and either;
-// - if -w is specified, updates the file in place;
-// - if -d is specified, prints out unified diffs of the changes; or
-// - otherwise, prints the new versions to stdout.
-func (s *suggestedFix) Run(ctx context.Context, args ...string) error {
- if len(args) < 1 {
- return tool.CommandLineErrorf("fix expects at least 1 argument")
- }
- conn, err := s.app.connect(ctx)
- if err != nil {
- return err
- }
- defer conn.terminate(ctx)
-
- from := span.Parse(args[0])
- uri := from.URI()
- file := conn.AddFile(ctx, uri)
- if file.err != nil {
- return file.err
- }
-
- if err := conn.diagnoseFiles(ctx, []span.URI{uri}); err != nil {
- return err
- }
- conn.Client.filesMu.Lock()
- defer conn.Client.filesMu.Unlock()
-
- codeActionKinds := []protocol.CodeActionKind{protocol.QuickFix}
- if len(args) > 1 {
- codeActionKinds = []protocol.CodeActionKind{}
- for _, k := range args[1:] {
- codeActionKinds = append(codeActionKinds, protocol.CodeActionKind(k))
- }
- }
-
- rng, err := file.mapper.Range(from)
- if err != nil {
- return err
- }
- p := protocol.CodeActionParams{
- TextDocument: protocol.TextDocumentIdentifier{
- URI: protocol.URIFromSpanURI(uri),
- },
- Context: protocol.CodeActionContext{
- Only: codeActionKinds,
- Diagnostics: file.diagnostics,
- },
- Range: rng,
- }
- actions, err := conn.CodeAction(ctx, &p)
- if err != nil {
- return errors.Errorf("%v: %v", from, err)
- }
- var edits []protocol.TextEdit
- for _, a := range actions {
- if a.Command != nil {
- return fmt.Errorf("ExecuteCommand is not yet supported on the command line")
- }
- if !a.IsPreferred && !s.All {
- continue
- }
- if !from.HasPosition() {
- for _, c := range a.Edit.DocumentChanges {
- if fileURI(c.TextDocument.URI) == uri {
- edits = append(edits, c.Edits...)
- }
- }
- continue
- }
- // If the span passed in has a position, then we need to find
- // the codeaction that has the same range as the passed in span.
- for _, diag := range a.Diagnostics {
- spn, err := file.mapper.RangeSpan(diag.Range)
- if err != nil {
- continue
- }
- if span.ComparePoint(from.Start(), spn.Start()) == 0 {
- for _, c := range a.Edit.DocumentChanges {
- if fileURI(c.TextDocument.URI) == uri {
- edits = append(edits, c.Edits...)
- }
- }
- break
- }
- }
-
- // If suggested fix is not a diagnostic, still must collect edits.
- if len(a.Diagnostics) == 0 {
- for _, c := range a.Edit.DocumentChanges {
- if fileURI(c.TextDocument.URI) == uri {
- edits = append(edits, c.Edits...)
- }
- }
- }
- }
-
- sedits, err := source.FromProtocolEdits(file.mapper, edits)
- if err != nil {
- return errors.Errorf("%v: %v", edits, err)
- }
- newContent := diff.ApplyEdits(string(file.mapper.Content), sedits)
-
- filename := file.uri.Filename()
- switch {
- case s.Write:
- if len(edits) > 0 {
- ioutil.WriteFile(filename, []byte(newContent), 0644)
- }
- case s.Diff:
- diffs := diff.ToUnified(filename+".orig", filename, string(file.mapper.Content), sedits)
- fmt.Print(diffs)
- default:
- fmt.Print(string(newContent))
- }
- return nil
-}
diff --git a/internal/lsp/cmd/symbols.go b/internal/lsp/cmd/symbols.go
deleted file mode 100644
index b43a6dcd1..000000000
--- a/internal/lsp/cmd/symbols.go
+++ /dev/null
@@ -1,116 +0,0 @@
-// 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"
- "encoding/json"
- "flag"
- "fmt"
- "sort"
-
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/span"
- "golang.org/x/tools/internal/tool"
-)
-
-// symbols implements the symbols verb for gopls
-type symbols struct {
- app *Application
-}
-
-func (r *symbols) Name() string { return "symbols" }
-func (r *symbols) Parent() string { return r.app.Name() }
-func (r *symbols) Usage() string { return "<file>" }
-func (r *symbols) ShortHelp() string { return "display selected file's symbols" }
-func (r *symbols) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprint(f.Output(), `
-Example:
- $ gopls symbols helper/helper.go
-`)
- printFlagDefaults(f)
-}
-func (r *symbols) Run(ctx context.Context, args ...string) error {
- if len(args) != 1 {
- return tool.CommandLineErrorf("symbols expects 1 argument (position)")
- }
-
- conn, err := r.app.connect(ctx)
- if err != nil {
- return err
- }
- defer conn.terminate(ctx)
-
- from := span.Parse(args[0])
- p := protocol.DocumentSymbolParams{
- TextDocument: protocol.TextDocumentIdentifier{
- URI: protocol.URIFromSpanURI(from.URI()),
- },
- }
- symbols, err := conn.DocumentSymbol(ctx, &p)
- if err != nil {
- return err
- }
- for _, s := range symbols {
- if m, ok := s.(map[string]interface{}); ok {
- s, err = mapToSymbol(m)
- if err != nil {
- return err
- }
- }
- switch t := s.(type) {
- case protocol.DocumentSymbol:
- printDocumentSymbol(t)
- case protocol.SymbolInformation:
- printSymbolInformation(t)
- }
- }
- return nil
-}
-
-func mapToSymbol(m map[string]interface{}) (interface{}, error) {
- b, err := json.Marshal(m)
- if err != nil {
- return nil, err
- }
-
- if _, ok := m["selectionRange"]; ok {
- var s protocol.DocumentSymbol
- if err := json.Unmarshal(b, &s); err != nil {
- return nil, err
- }
- return s, nil
- }
-
- var s protocol.SymbolInformation
- if err := json.Unmarshal(b, &s); err != nil {
- return nil, err
- }
- return s, nil
-}
-
-func printDocumentSymbol(s protocol.DocumentSymbol) {
- fmt.Printf("%s %s %s\n", s.Name, s.Kind, positionToString(s.SelectionRange))
- // Sort children for consistency
- sort.Slice(s.Children, func(i, j int) bool {
- return s.Children[i].Name < s.Children[j].Name
- })
- for _, c := range s.Children {
- fmt.Printf("\t%s %s %s\n", c.Name, c.Kind, positionToString(c.SelectionRange))
- }
-}
-
-func printSymbolInformation(s protocol.SymbolInformation) {
- fmt.Printf("%s %s %s\n", s.Name, s.Kind, positionToString(s.Location.Range))
-}
-
-func positionToString(r protocol.Range) string {
- return fmt.Sprintf("%v:%v-%v:%v",
- r.Start.Line+1,
- r.Start.Character+1,
- r.End.Line+1,
- r.End.Character+1,
- )
-}
diff --git a/internal/lsp/cmd/test/call_hierarchy.go b/internal/lsp/cmd/test/call_hierarchy.go
deleted file mode 100644
index 38f8ed707..000000000
--- a/internal/lsp/cmd/test/call_hierarchy.go
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2020 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 cmdtest
-
-import (
- "fmt"
- "sort"
- "strings"
- "testing"
-
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/lsp/tests"
- "golang.org/x/tools/internal/span"
-)
-
-func (r *runner) CallHierarchy(t *testing.T, spn span.Span, expectedCalls *tests.CallHierarchyResult) {
- collectCallSpansString := func(callItems []protocol.CallHierarchyItem) string {
- var callSpans []string
- for _, call := range callItems {
- mapper, err := r.data.Mapper(call.URI.SpanURI())
- if err != nil {
- t.Fatal(err)
- }
- callSpan, err := mapper.Span(protocol.Location{URI: call.URI, Range: call.Range})
- if err != nil {
- t.Fatal(err)
- }
- callSpans = append(callSpans, fmt.Sprint(callSpan))
- }
- // to make tests deterministic
- sort.Strings(callSpans)
- return r.Normalize(strings.Join(callSpans, "\n"))
- }
-
- expectIn, expectOut := collectCallSpansString(expectedCalls.IncomingCalls), collectCallSpansString(expectedCalls.OutgoingCalls)
- expectIdent := r.Normalize(fmt.Sprint(spn))
-
- uri := spn.URI()
- filename := uri.Filename()
- target := filename + fmt.Sprintf(":%v:%v", spn.Start().Line(), spn.Start().Column())
-
- got, stderr := r.NormalizeGoplsCmd(t, "call_hierarchy", target)
- if stderr != "" {
- t.Fatalf("call_hierarchy failed for %s: %s", target, stderr)
- }
-
- gotIn, gotIdent, gotOut := cleanCallHierarchyCmdResult(got)
- if expectIn != gotIn {
- t.Errorf("incoming calls call_hierarchy failed for %s expected:\n%s\ngot:\n%s", target, expectIn, gotIn)
- }
- if expectIdent != gotIdent {
- t.Errorf("call_hierarchy failed for %s expected:\n%s\ngot:\n%s", target, expectIdent, gotIdent)
- }
- if expectOut != gotOut {
- t.Errorf("outgoing calls call_hierarchy failed for %s expected:\n%s\ngot:\n%s", target, expectOut, gotOut)
- }
-
-}
-
-// parses function URI and Range from call hierarchy cmd output to
-// incoming, identifier and outgoing calls (returned in that order)
-// ex: "identifier: function d at .../callhierarchy/callhierarchy.go:19:6-7" -> ".../callhierarchy/callhierarchy.go:19:6-7"
-func cleanCallHierarchyCmdResult(output string) (incoming, ident, outgoing string) {
- var incomingCalls, outgoingCalls []string
- for _, out := range strings.Split(output, "\n") {
- if out == "" {
- continue
- }
-
- callLocation := out[strings.LastIndex(out, " ")+1:]
- if strings.HasPrefix(out, "caller") {
- incomingCalls = append(incomingCalls, callLocation)
- } else if strings.HasPrefix(out, "callee") {
- outgoingCalls = append(outgoingCalls, callLocation)
- } else {
- ident = callLocation
- }
- }
- sort.Strings(incomingCalls)
- sort.Strings(outgoingCalls)
- incoming, outgoing = strings.Join(incomingCalls, "\n"), strings.Join(outgoingCalls, "\n")
- return
-}
diff --git a/internal/lsp/cmd/test/check.go b/internal/lsp/cmd/test/check.go
deleted file mode 100644
index f0e6d8fef..000000000
--- a/internal/lsp/cmd/test/check.go
+++ /dev/null
@@ -1,63 +0,0 @@
-// 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 cmdtest
-
-import (
- "fmt"
- "io/ioutil"
- "strings"
- "testing"
-
- "golang.org/x/tools/internal/lsp/source"
- "golang.org/x/tools/internal/span"
-)
-
-func (r *runner) Diagnostics(t *testing.T, uri span.URI, want []*source.Diagnostic) {
- if len(want) == 1 && want[0].Message == "" {
- return
- }
- fname := uri.Filename()
- out, _ := r.runGoplsCmd(t, "check", fname)
- // parse got into a collection of reports
- got := map[string]struct{}{}
- for _, l := range strings.Split(out, "\n") {
- if len(l) == 0 {
- continue
- }
- // parse and reprint to normalize the span
- bits := strings.SplitN(l, ": ", 2)
- if len(bits) == 2 {
- spn := span.Parse(strings.TrimSpace(bits[0]))
- spn = span.New(spn.URI(), spn.Start(), span.Point{})
- data, err := ioutil.ReadFile(fname)
- if err != nil {
- t.Fatal(err)
- }
- converter := span.NewContentConverter(fname, data)
- s, err := spn.WithPosition(converter)
- if err != nil {
- t.Fatal(err)
- }
- l = fmt.Sprintf("%s: %s", s, strings.TrimSpace(bits[1]))
- }
- got[r.NormalizePrefix(l)] = struct{}{}
- }
- for _, diag := range want {
- expect := fmt.Sprintf("%v:%v:%v: %v", uri.Filename(), diag.Range.Start.Line+1, diag.Range.Start.Character+1, diag.Message)
- if diag.Range.Start.Character == 0 {
- expect = fmt.Sprintf("%v:%v: %v", uri.Filename(), diag.Range.Start.Line+1, diag.Message)
- }
- expect = r.NormalizePrefix(expect)
- _, found := got[expect]
- if !found {
- t.Errorf("missing diagnostic %q, %v", expect, got)
- } else {
- delete(got, expect)
- }
- }
- for extra := range got {
- t.Errorf("extra diagnostic %q", extra)
- }
-}
diff --git a/internal/lsp/cmd/test/cmdtest.go b/internal/lsp/cmd/test/cmdtest.go
deleted file mode 100644
index 312f7b8b4..000000000
--- a/internal/lsp/cmd/test/cmdtest.go
+++ /dev/null
@@ -1,169 +0,0 @@
-// 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 cmdtest contains the test suite for the command line behavior of gopls.
-package cmdtest
-
-import (
- "bytes"
- "context"
- "flag"
- "fmt"
- "io"
- "os"
- "sync"
- "testing"
-
- "golang.org/x/tools/internal/jsonrpc2/servertest"
- "golang.org/x/tools/internal/lsp/cache"
- "golang.org/x/tools/internal/lsp/cmd"
- "golang.org/x/tools/internal/lsp/debug"
- "golang.org/x/tools/internal/lsp/lsprpc"
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/lsp/source"
- "golang.org/x/tools/internal/lsp/tests"
- "golang.org/x/tools/internal/span"
- "golang.org/x/tools/internal/tool"
-)
-
-type runner struct {
- data *tests.Data
- ctx context.Context
- options func(*source.Options)
- normalizers []tests.Normalizer
- remote string
-}
-
-func TestCommandLine(t *testing.T, testdata string, options func(*source.Options)) {
- // On Android, the testdata directory is not copied to the runner.
- if stat, err := os.Stat(testdata); err != nil || !stat.IsDir() {
- t.Skip("testdata directory not present")
- }
- tests.RunTests(t, testdata, false, func(t *testing.T, datum *tests.Data) {
- ctx := tests.Context(t)
- ts := NewTestServer(ctx, options)
- tests.Run(t, NewRunner(datum, ctx, ts.Addr, options), datum)
- cmd.CloseTestConnections(ctx)
- })
-}
-
-func NewTestServer(ctx context.Context, options func(*source.Options)) *servertest.TCPServer {
- ctx = debug.WithInstance(ctx, "", "")
- cache := cache.New(options)
- ss := lsprpc.NewStreamServer(cache, false)
- return servertest.NewTCPServer(ctx, ss, nil)
-}
-
-func NewRunner(data *tests.Data, ctx context.Context, remote string, options func(*source.Options)) *runner {
- return &runner{
- data: data,
- ctx: ctx,
- options: options,
- normalizers: tests.CollectNormalizers(data.Exported),
- remote: remote,
- }
-}
-
-func (r *runner) CodeLens(t *testing.T, uri span.URI, want []protocol.CodeLens) {
- //TODO: add command line completions tests when it works
-}
-
-func (r *runner) Completion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
- //TODO: add command line completions tests when it works
-}
-
-func (r *runner) CompletionSnippet(t *testing.T, src span.Span, expected tests.CompletionSnippet, placeholders bool, items tests.CompletionItems) {
- //TODO: add command line completions tests when it works
-}
-
-func (r *runner) UnimportedCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
- //TODO: add command line completions tests when it works
-}
-
-func (r *runner) DeepCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
- //TODO: add command line completions tests when it works
-}
-
-func (r *runner) FuzzyCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
- //TODO: add command line completions tests when it works
-}
-
-func (r *runner) CaseSensitiveCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
- //TODO: add command line completions tests when it works
-}
-
-func (r *runner) RankCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
- //TODO: add command line completions tests when it works
-}
-
-func (r *runner) FunctionExtraction(t *testing.T, start span.Span, end span.Span) {
- //TODO: function extraction not supported on command line
-}
-
-func (r *runner) MethodExtraction(t *testing.T, start span.Span, end span.Span) {
- //TODO: function extraction not supported on command line
-}
-
-func (r *runner) AddImport(t *testing.T, uri span.URI, expectedImport string) {
- //TODO: import addition not supported on command line
-}
-
-func (r *runner) Hover(t *testing.T, spn span.Span, info string) {
- //TODO: hovering not supported on command line
-}
-
-func (r *runner) runGoplsCmd(t testing.TB, args ...string) (string, string) {
- rStdout, wStdout, err := os.Pipe()
- if err != nil {
- t.Fatal(err)
- }
- oldStdout := os.Stdout
- rStderr, wStderr, err := os.Pipe()
- if err != nil {
- t.Fatal(err)
- }
- oldStderr := os.Stderr
- stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}
- var wg sync.WaitGroup
- wg.Add(2)
- go func() {
- io.Copy(stdout, rStdout)
- wg.Done()
- }()
- go func() {
- io.Copy(stderr, rStderr)
- wg.Done()
- }()
- os.Stdout, os.Stderr = wStdout, wStderr
- app := cmd.New("gopls-test", r.data.Config.Dir, r.data.Exported.Config.Env, r.options)
- remote := r.remote
- s := flag.NewFlagSet(app.Name(), flag.ExitOnError)
- err = tool.Run(tests.Context(t), s,
- app,
- append([]string{fmt.Sprintf("-remote=internal@%s", remote)}, args...))
- if err != nil {
- fmt.Fprint(os.Stderr, err)
- }
- wStdout.Close()
- wStderr.Close()
- wg.Wait()
- os.Stdout, os.Stderr = oldStdout, oldStderr
- rStdout.Close()
- rStderr.Close()
- return stdout.String(), stderr.String()
-}
-
-// NormalizeGoplsCmd runs the gopls command and normalizes its output.
-func (r *runner) NormalizeGoplsCmd(t testing.TB, args ...string) (string, string) {
- stdout, stderr := r.runGoplsCmd(t, args...)
- return r.Normalize(stdout), r.Normalize(stderr)
-}
-
-func (r *runner) Normalize(s string) string {
- return tests.Normalize(s, r.normalizers)
-}
-
-func (r *runner) NormalizePrefix(s string) string {
- return tests.NormalizePrefix(s, r.normalizers)
-}
diff --git a/internal/lsp/cmd/test/definition.go b/internal/lsp/cmd/test/definition.go
deleted file mode 100644
index c82d9a6c1..000000000
--- a/internal/lsp/cmd/test/definition.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// 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 cmdtest
-
-import (
- "fmt"
- "runtime"
- "strings"
- "testing"
-
- "golang.org/x/tools/internal/lsp/diff"
- "golang.org/x/tools/internal/lsp/diff/myers"
- "golang.org/x/tools/internal/lsp/tests"
- "golang.org/x/tools/internal/span"
-)
-
-type godefMode int
-
-const (
- plainGodef = godefMode(1 << iota)
- jsonGoDef
-)
-
-var godefModes = []godefMode{
- plainGodef,
- jsonGoDef,
-}
-
-func (r *runner) Definition(t *testing.T, spn span.Span, d tests.Definition) {
- if d.IsType || d.OnlyHover {
- // TODO: support type definition, hover queries
- return
- }
- d.Src = span.New(d.Src.URI(), span.NewPoint(0, 0, d.Src.Start().Offset()), span.Point{})
- for _, mode := range godefModes {
- args := []string{"definition", "-markdown"}
- tag := d.Name + "-definition"
- if mode&jsonGoDef != 0 {
- tag += "-json"
- args = append(args, "-json")
- }
- uri := d.Src.URI()
- args = append(args, fmt.Sprint(d.Src))
- got, _ := r.NormalizeGoplsCmd(t, args...)
- if mode&jsonGoDef != 0 && runtime.GOOS == "windows" {
- got = strings.Replace(got, "file:///", "file://", -1)
- }
- expect := strings.TrimSpace(string(r.data.Golden(tag, uri.Filename(), func() ([]byte, error) {
- return []byte(got), nil
- })))
- if expect != "" && !strings.HasPrefix(got, expect) {
- d, err := myers.ComputeEdits("", expect, got)
- if err != nil {
- t.Fatal(err)
- }
- t.Errorf("definition %v failed with %#v\n%s", tag, args, diff.ToUnified("expect", "got", expect, d))
- }
- }
-}
diff --git a/internal/lsp/cmd/test/folding_range.go b/internal/lsp/cmd/test/folding_range.go
deleted file mode 100644
index 4478687b5..000000000
--- a/internal/lsp/cmd/test/folding_range.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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 cmdtest
-
-import (
- "testing"
-
- "golang.org/x/tools/internal/span"
-)
-
-func (r *runner) FoldingRanges(t *testing.T, spn span.Span) {
- goldenTag := "foldingRange-cmd"
- uri := spn.URI()
- filename := uri.Filename()
- got, _ := r.NormalizeGoplsCmd(t, "folding_ranges", filename)
- expect := string(r.data.Golden(goldenTag, filename, func() ([]byte, error) {
- return []byte(got), nil
- }))
-
- if expect != got {
- t.Errorf("folding_ranges failed failed for %s expected:\n%s\ngot:\n%s", filename, expect, got)
- }
-}
diff --git a/internal/lsp/cmd/test/format.go b/internal/lsp/cmd/test/format.go
deleted file mode 100644
index 77eedd440..000000000
--- a/internal/lsp/cmd/test/format.go
+++ /dev/null
@@ -1,86 +0,0 @@
-// 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 cmdtest
-
-import (
- "bytes"
- exec "golang.org/x/sys/execabs"
- "io/ioutil"
- "os"
- "regexp"
- "strings"
- "testing"
-
- "golang.org/x/tools/internal/span"
- "golang.org/x/tools/internal/testenv"
-)
-
-func (r *runner) Format(t *testing.T, spn span.Span) {
- tag := "gofmt"
- uri := spn.URI()
- filename := uri.Filename()
- expect := string(r.data.Golden(tag, filename, func() ([]byte, error) {
- cmd := exec.Command("gofmt", filename)
- contents, _ := cmd.Output() // ignore error, sometimes we have intentionally ungofmt-able files
- contents = []byte(r.Normalize(fixFileHeader(string(contents))))
- return contents, nil
- }))
- if expect == "" {
- //TODO: our error handling differs, for now just skip unformattable files
- t.Skip("Unformattable file")
- }
- got, _ := r.NormalizeGoplsCmd(t, "format", filename)
- if expect != got {
- t.Errorf("format failed for %s expected:\n%s\ngot:\n%s", filename, expect, got)
- }
- // now check we can build a valid unified diff
- unified, _ := r.NormalizeGoplsCmd(t, "format", "-d", filename)
- checkUnified(t, filename, expect, unified)
-}
-
-var unifiedHeader = regexp.MustCompile(`^diff -u.*\n(---\s+\S+\.go\.orig)\s+[\d-:. ]+(\n\+\+\+\s+\S+\.go)\s+[\d-:. ]+(\n@@)`)
-
-func fixFileHeader(s string) string {
- match := unifiedHeader.FindStringSubmatch(s)
- if match == nil {
- return s
- }
- return strings.Join(append(match[1:], s[len(match[0]):]), "")
-}
-
-func checkUnified(t *testing.T, filename string, expect string, patch string) {
- testenv.NeedsTool(t, "patch")
- if strings.Count(patch, "\n+++ ") > 1 {
- // TODO(golang/go/#34580)
- t.Skip("multi-file patch tests not supported yet")
- }
- applied := ""
- if patch == "" {
- applied = expect
- } else {
- temp, err := ioutil.TempFile("", "applied")
- if err != nil {
- t.Fatal(err)
- }
- temp.Close()
- defer os.Remove(temp.Name())
- cmd := exec.Command("patch", "-u", "-p0", "-o", temp.Name(), filename)
- cmd.Stdin = bytes.NewBuffer([]byte(patch))
- msg, err := cmd.CombinedOutput()
- if err != nil {
- t.Errorf("failed applying patch to %s: %v\ngot:\n%s\npatch:\n%s", filename, err, msg, patch)
- return
- }
- out, err := ioutil.ReadFile(temp.Name())
- if err != nil {
- t.Errorf("failed reading patched output for %s: %v\n", filename, err)
- return
- }
- applied = string(out)
- }
- if expect != applied {
- t.Errorf("apply unified gave wrong result for %s expected:\n%s\ngot:\n%s\npatch:\n%s", filename, expect, applied, patch)
- }
-}
diff --git a/internal/lsp/cmd/test/highlight.go b/internal/lsp/cmd/test/highlight.go
deleted file mode 100644
index 99e8b2c3f..000000000
--- a/internal/lsp/cmd/test/highlight.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// 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 cmdtest
-
-import (
- "testing"
-
- "fmt"
-
- "golang.org/x/tools/internal/span"
-)
-
-func (r *runner) Highlight(t *testing.T, spn span.Span, spans []span.Span) {
- var expect string
- for _, l := range spans {
- expect += fmt.Sprintln(l)
- }
- expect = r.Normalize(expect)
-
- uri := spn.URI()
- filename := uri.Filename()
- target := filename + ":" + fmt.Sprint(spn.Start().Line()) + ":" + fmt.Sprint(spn.Start().Column())
- got, _ := r.NormalizeGoplsCmd(t, "highlight", target)
- if expect != got {
- t.Errorf("highlight failed for %s expected:\n%s\ngot:\n%s", target, expect, got)
- }
-}
diff --git a/internal/lsp/cmd/test/implementation.go b/internal/lsp/cmd/test/implementation.go
deleted file mode 100644
index 189452466..000000000
--- a/internal/lsp/cmd/test/implementation.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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 cmdtest
-
-import (
- "fmt"
- "sort"
- "testing"
-
- "golang.org/x/tools/internal/span"
-)
-
-func (r *runner) Implementation(t *testing.T, spn span.Span, imps []span.Span) {
- var itemStrings []string
- for _, i := range imps {
- itemStrings = append(itemStrings, fmt.Sprint(i))
- }
- sort.Strings(itemStrings)
- var expect string
- for _, i := range itemStrings {
- expect += i + "\n"
- }
- expect = r.Normalize(expect)
-
- uri := spn.URI()
- filename := uri.Filename()
- target := filename + fmt.Sprintf(":%v:%v", spn.Start().Line(), spn.Start().Column())
-
- got, stderr := r.NormalizeGoplsCmd(t, "implementation", target)
- if stderr != "" {
- t.Errorf("implementation failed for %s: %s", target, stderr)
- } else if expect != got {
- t.Errorf("implementation failed for %s expected:\n%s\ngot:\n%s", target, expect, got)
- }
-}
diff --git a/internal/lsp/cmd/test/imports.go b/internal/lsp/cmd/test/imports.go
deleted file mode 100644
index ce8aee55d..000000000
--- a/internal/lsp/cmd/test/imports.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// 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 cmdtest
-
-import (
- "testing"
-
- "golang.org/x/tools/internal/lsp/diff"
- "golang.org/x/tools/internal/lsp/diff/myers"
- "golang.org/x/tools/internal/span"
-)
-
-func (r *runner) Import(t *testing.T, spn span.Span) {
- uri := spn.URI()
- filename := uri.Filename()
- got, _ := r.NormalizeGoplsCmd(t, "imports", filename)
- want := string(r.data.Golden("goimports", filename, func() ([]byte, error) {
- return []byte(got), nil
- }))
- if want != got {
- d, err := myers.ComputeEdits(uri, want, got)
- if err != nil {
- t.Fatal(err)
- }
- t.Errorf("imports failed for %s, expected:\n%s", filename, diff.ToUnified("want", "got", want, d))
- }
-}
diff --git a/internal/lsp/cmd/test/links.go b/internal/lsp/cmd/test/links.go
deleted file mode 100644
index 88df76832..000000000
--- a/internal/lsp/cmd/test/links.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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 cmdtest
-
-import (
- "encoding/json"
- "testing"
-
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/lsp/tests"
- "golang.org/x/tools/internal/span"
-)
-
-func (r *runner) Link(t *testing.T, uri span.URI, wantLinks []tests.Link) {
- m, err := r.data.Mapper(uri)
- if err != nil {
- t.Fatal(err)
- }
- out, _ := r.NormalizeGoplsCmd(t, "links", "-json", uri.Filename())
- var got []protocol.DocumentLink
- err = json.Unmarshal([]byte(out), &got)
- if err != nil {
- t.Fatal(err)
- }
- if diff := tests.DiffLinks(m, wantLinks, got); diff != "" {
- t.Error(diff)
- }
-}
diff --git a/internal/lsp/cmd/test/prepare_rename.go b/internal/lsp/cmd/test/prepare_rename.go
deleted file mode 100644
index b5359e57b..000000000
--- a/internal/lsp/cmd/test/prepare_rename.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// 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 cmdtest
-
-import (
- "fmt"
- "testing"
-
- "golang.org/x/tools/internal/lsp/cmd"
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/lsp/source"
- "golang.org/x/tools/internal/span"
-)
-
-func (r *runner) PrepareRename(t *testing.T, src span.Span, want *source.PrepareItem) {
- m, err := r.data.Mapper(src.URI())
- if err != nil {
- t.Errorf("prepare_rename failed: %v", err)
- }
-
- var (
- target = fmt.Sprintf("%v", src)
- args = []string{"prepare_rename", target}
- stdOut, stdErr = r.NormalizeGoplsCmd(t, args...)
- expect string
- )
-
- if want.Text == "" {
- if stdErr != "" && stdErr != cmd.ErrInvalidRenamePosition.Error() {
- t.Errorf("prepare_rename failed for %s,\nexpected:\n`%v`\ngot:\n`%v`", target, expect, stdErr)
- }
- return
- }
-
- ws, err := m.Span(protocol.Location{Range: want.Range})
- if err != nil {
- t.Errorf("prepare_rename failed: %v", err)
- }
-
- expect = r.Normalize(fmt.Sprintln(ws))
- if expect != stdOut {
- t.Errorf("prepare_rename failed for %s expected:\n`%s`\ngot:\n`%s`\n", target, expect, stdOut)
- }
-}
diff --git a/internal/lsp/cmd/test/references.go b/internal/lsp/cmd/test/references.go
deleted file mode 100644
index 66d0d0662..000000000
--- a/internal/lsp/cmd/test/references.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// 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 cmdtest
-
-import (
- "fmt"
- "sort"
- "testing"
-
- "golang.org/x/tools/internal/span"
-)
-
-func (r *runner) References(t *testing.T, spn span.Span, itemList []span.Span) {
- for _, includeDeclaration := range []bool{true, false} {
- t.Run(fmt.Sprintf("refs-declaration-%v", includeDeclaration), func(t *testing.T) {
- var itemStrings []string
- for i, s := range itemList {
- // We don't want the first result if we aren't including the declaration.
- if i == 0 && !includeDeclaration {
- continue
- }
- itemStrings = append(itemStrings, fmt.Sprint(s))
- }
- sort.Strings(itemStrings)
- var expect string
- for _, s := range itemStrings {
- expect += s + "\n"
- }
- expect = r.Normalize(expect)
-
- uri := spn.URI()
- filename := uri.Filename()
- target := filename + fmt.Sprintf(":%v:%v", spn.Start().Line(), spn.Start().Column())
- args := []string{"references"}
- if includeDeclaration {
- args = append(args, "-d")
- }
- args = append(args, target)
- got, stderr := r.NormalizeGoplsCmd(t, args...)
- if stderr != "" {
- t.Errorf("references failed for %s: %s", target, stderr)
- } else if expect != got {
- t.Errorf("references failed for %s expected:\n%s\ngot:\n%s", target, expect, got)
- }
- })
- }
-}
diff --git a/internal/lsp/cmd/test/rename.go b/internal/lsp/cmd/test/rename.go
deleted file mode 100644
index 0fe2d1e18..000000000
--- a/internal/lsp/cmd/test/rename.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// 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 cmdtest
-
-import (
- "fmt"
- "testing"
-
- "golang.org/x/tools/internal/span"
-)
-
-func (r *runner) Rename(t *testing.T, spn span.Span, newText string) {
- filename := spn.URI().Filename()
- goldenTag := newText + "-rename"
- loc := fmt.Sprintf("%v", spn)
- got, err := r.NormalizeGoplsCmd(t, "rename", loc, newText)
- got += err
- expect := string(r.data.Golden(goldenTag, filename, func() ([]byte, error) {
- return []byte(got), nil
- }))
- if expect != got {
- t.Errorf("rename failed with %v %v\nexpected:\n%s\ngot:\n%s", loc, newText, expect, got)
- }
- // now check we can build a valid unified diff
- unified, _ := r.NormalizeGoplsCmd(t, "rename", "-d", loc, newText)
- checkUnified(t, filename, expect, unified)
-}
diff --git a/internal/lsp/cmd/test/semanticdriver.go b/internal/lsp/cmd/test/semanticdriver.go
deleted file mode 100644
index 80dc61e3d..000000000
--- a/internal/lsp/cmd/test/semanticdriver.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2020 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 cmdtest
-
-import (
- "strings"
- "testing"
-
- "golang.org/x/tools/internal/span"
-)
-
-func (r *runner) SemanticTokens(t *testing.T, spn span.Span) {
- uri := spn.URI()
- filename := uri.Filename()
- got, stderr := r.NormalizeGoplsCmd(t, "semtok", filename)
- if stderr != "" {
- t.Fatalf("%s: %q", filename, stderr)
- }
- want := string(r.data.Golden("semantic", filename, func() ([]byte, error) {
- return []byte(got), nil
- }))
- if want != got {
- lwant := strings.Split(want, "\n")
- lgot := strings.Split(got, "\n")
- t.Errorf("want(%d-%d) != got(%d-%d) for %s", len(want), len(lwant), len(got), len(lgot), r.Normalize(filename))
- for i := 0; i < len(lwant) && i < len(lgot); i++ {
- if lwant[i] != lgot[i] {
- t.Errorf("line %d:\nwant%q\ngot %q\n", i, lwant[i], lgot[i])
- }
- }
- }
-}
diff --git a/internal/lsp/cmd/test/signature.go b/internal/lsp/cmd/test/signature.go
deleted file mode 100644
index f6bdaebf3..000000000
--- a/internal/lsp/cmd/test/signature.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// 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 cmdtest
-
-import (
- "fmt"
- "testing"
-
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/lsp/tests"
- "golang.org/x/tools/internal/span"
-)
-
-func (r *runner) SignatureHelp(t *testing.T, spn span.Span, want *protocol.SignatureHelp) {
- uri := spn.URI()
- filename := uri.Filename()
- target := filename + fmt.Sprintf(":%v:%v", spn.Start().Line(), spn.Start().Column())
- got, _ := r.NormalizeGoplsCmd(t, "signature", target)
- if want == nil {
- if got != "" {
- t.Fatalf("want nil, but got %s", got)
- }
- return
- }
- goldenTag := want.Signatures[0].Label + "-signature"
- expect := string(r.data.Golden(goldenTag, filename, func() ([]byte, error) {
- return []byte(got), nil
- }))
- if tests.NormalizeAny(expect) != tests.NormalizeAny(got) {
- t.Errorf("signature failed for %s expected:\n%q\ngot:\n%q'", filename, expect, got)
- }
-}
diff --git a/internal/lsp/cmd/test/suggested_fix.go b/internal/lsp/cmd/test/suggested_fix.go
deleted file mode 100644
index c819e0517..000000000
--- a/internal/lsp/cmd/test/suggested_fix.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// 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 cmdtest
-
-import (
- "fmt"
- "testing"
-
- "golang.org/x/tools/internal/lsp/tests"
- "golang.org/x/tools/internal/span"
-)
-
-func (r *runner) SuggestedFix(t *testing.T, spn span.Span, actionKinds []string, expectedActions int) {
- uri := spn.URI()
- filename := uri.Filename()
- args := []string{"fix", "-a", fmt.Sprintf("%s", spn)}
- for _, kind := range actionKinds {
- if kind == "refactor.rewrite" {
- t.Skip("refactor.rewrite is not yet supported on the command line")
- }
- }
- args = append(args, actionKinds...)
- got, stderr := r.NormalizeGoplsCmd(t, args...)
- if stderr == "ExecuteCommand is not yet supported on the command line" {
- return // don't skip to keep the summary counts correct
- }
- want := string(r.data.Golden("suggestedfix_"+tests.SpanName(spn), filename, func() ([]byte, error) {
- return []byte(got), nil
- }))
- if want != got {
- t.Errorf("suggested fixes failed for %s:\n%s", filename, tests.Diff(t, want, got))
- }
-}
diff --git a/internal/lsp/cmd/test/symbols.go b/internal/lsp/cmd/test/symbols.go
deleted file mode 100644
index 055be0308..000000000
--- a/internal/lsp/cmd/test/symbols.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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 cmdtest
-
-import (
- "testing"
-
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/span"
-)
-
-func (r *runner) Symbols(t *testing.T, uri span.URI, expectedSymbols []protocol.DocumentSymbol) {
- filename := uri.Filename()
- got, _ := r.NormalizeGoplsCmd(t, "symbols", filename)
- expect := string(r.data.Golden("symbols", filename, func() ([]byte, error) {
- return []byte(got), nil
- }))
- if expect != got {
- t.Errorf("symbols failed for %s expected:\n%s\ngot:\n%s", filename, expect, got)
- }
-}
diff --git a/internal/lsp/cmd/test/workspace_symbol.go b/internal/lsp/cmd/test/workspace_symbol.go
deleted file mode 100644
index ce965f03a..000000000
--- a/internal/lsp/cmd/test/workspace_symbol.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2020 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 cmdtest
-
-import (
- "fmt"
- "path/filepath"
- "sort"
- "strings"
- "testing"
-
- "golang.org/x/tools/internal/lsp/source"
- "golang.org/x/tools/internal/lsp/tests"
- "golang.org/x/tools/internal/span"
-)
-
-func (r *runner) WorkspaceSymbols(t *testing.T, uri span.URI, query string, typ tests.WorkspaceSymbolsTestType) {
- var matcher string
- switch typ {
- case tests.WorkspaceSymbolsFuzzy:
- matcher = "fuzzy"
- case tests.WorkspaceSymbolsCaseSensitive:
- matcher = "caseSensitive"
- case tests.WorkspaceSymbolsDefault:
- matcher = "caseInsensitive"
- }
- r.runWorkspaceSymbols(t, uri, matcher, query)
-}
-
-func (r *runner) runWorkspaceSymbols(t *testing.T, uri span.URI, matcher, query string) {
- t.Helper()
-
- out, _ := r.runGoplsCmd(t, "workspace_symbol", "-matcher", matcher, query)
- var filtered []string
- dir := filepath.Dir(uri.Filename())
- for _, line := range strings.Split(out, "\n") {
- if source.InDir(dir, line) {
- filtered = append(filtered, filepath.ToSlash(line))
- }
- }
- sort.Strings(filtered)
- got := r.Normalize(strings.Join(filtered, "\n") + "\n")
-
- expect := string(r.data.Golden(fmt.Sprintf("workspace_symbol-%s-%s", strings.ToLower(string(matcher)), query), uri.Filename(), func() ([]byte, error) {
- return []byte(got), nil
- }))
-
- if expect != got {
- t.Errorf("workspace_symbol failed for %s:\n%s", query, tests.Diff(t, expect, got))
- }
-}
diff --git a/internal/lsp/cmd/usage/api-json.hlp b/internal/lsp/cmd/usage/api-json.hlp
deleted file mode 100644
index cb9fbfbea..000000000
--- a/internal/lsp/cmd/usage/api-json.hlp
+++ /dev/null
@@ -1,4 +0,0 @@
-print json describing gopls API
-
-Usage:
- gopls [flags] api-json
diff --git a/internal/lsp/cmd/usage/bug.hlp b/internal/lsp/cmd/usage/bug.hlp
deleted file mode 100644
index 772d54d5f..000000000
--- a/internal/lsp/cmd/usage/bug.hlp
+++ /dev/null
@@ -1,4 +0,0 @@
-report a bug in gopls
-
-Usage:
- gopls [flags] bug
diff --git a/internal/lsp/cmd/usage/call_hierarchy.hlp b/internal/lsp/cmd/usage/call_hierarchy.hlp
deleted file mode 100644
index 07fccc828..000000000
--- a/internal/lsp/cmd/usage/call_hierarchy.hlp
+++ /dev/null
@@ -1,10 +0,0 @@
-display selected identifier's call hierarchy
-
-Usage:
- gopls [flags] call_hierarchy <position>
-
-Example:
-
- $ # 1-indexed location (:line:column or :#offset) of the target identifier
- $ gopls call_hierarchy helper/helper.go:8:6
- $ gopls call_hierarchy helper/helper.go:#53
diff --git a/internal/lsp/cmd/usage/check.hlp b/internal/lsp/cmd/usage/check.hlp
deleted file mode 100644
index ba89588d5..000000000
--- a/internal/lsp/cmd/usage/check.hlp
+++ /dev/null
@@ -1,8 +0,0 @@
-show diagnostic results for the specified file
-
-Usage:
- gopls [flags] check <filename>
-
-Example: show the diagnostic results of this file:
-
- $ gopls check internal/lsp/cmd/check.go
diff --git a/internal/lsp/cmd/usage/definition.hlp b/internal/lsp/cmd/usage/definition.hlp
deleted file mode 100644
index 500e6c9a4..000000000
--- a/internal/lsp/cmd/usage/definition.hlp
+++ /dev/null
@@ -1,15 +0,0 @@
-show declaration of selected identifier
-
-Usage:
- gopls [flags] definition [definition-flags] <position>
-
-Example: show the definition of the identifier at syntax at offset 44 in this file (flag.FlagSet):
-
- $ gopls definition internal/lsp/cmd/definition.go:44:47
- $ gopls definition internal/lsp/cmd/definition.go:#1270
-
-definition-flags:
- -json
- emit output in JSON format
- -markdown
- support markdown in responses
diff --git a/internal/lsp/cmd/usage/fix.hlp b/internal/lsp/cmd/usage/fix.hlp
deleted file mode 100644
index 4789a6c5b..000000000
--- a/internal/lsp/cmd/usage/fix.hlp
+++ /dev/null
@@ -1,15 +0,0 @@
-apply suggested fixes
-
-Usage:
- gopls [flags] fix [fix-flags] <filename>
-
-Example: apply suggested fixes for this file
- $ gopls fix -w internal/lsp/cmd/check.go
-
-fix-flags:
- -a,-all
- apply all fixes, not just preferred fixes
- -d,-diff
- display diffs instead of rewriting files
- -w,-write
- write result to (source) file instead of stdout
diff --git a/internal/lsp/cmd/usage/folding_ranges.hlp b/internal/lsp/cmd/usage/folding_ranges.hlp
deleted file mode 100644
index 4af2da615..000000000
--- a/internal/lsp/cmd/usage/folding_ranges.hlp
+++ /dev/null
@@ -1,8 +0,0 @@
-display selected file's folding ranges
-
-Usage:
- gopls [flags] folding_ranges <file>
-
-Example:
-
- $ gopls folding_ranges helper/helper.go
diff --git a/internal/lsp/cmd/usage/format.hlp b/internal/lsp/cmd/usage/format.hlp
deleted file mode 100644
index 7ef0bbe43..000000000
--- a/internal/lsp/cmd/usage/format.hlp
+++ /dev/null
@@ -1,18 +0,0 @@
-format the code according to the go standard
-
-Usage:
- gopls [flags] format [format-flags] <filerange>
-
-The arguments supplied may be simple file names, or ranges within files.
-
-Example: reformat this file:
-
- $ gopls format -w internal/lsp/cmd/check.go
-
-format-flags:
- -d,-diff
- display diffs instead of rewriting files
- -l,-list
- list files whose formatting differs from gofmt's
- -w,-write
- write result to (source) file instead of stdout
diff --git a/internal/lsp/cmd/usage/highlight.hlp b/internal/lsp/cmd/usage/highlight.hlp
deleted file mode 100644
index e128eb7de..000000000
--- a/internal/lsp/cmd/usage/highlight.hlp
+++ /dev/null
@@ -1,10 +0,0 @@
-display selected identifier's highlights
-
-Usage:
- gopls [flags] highlight <position>
-
-Example:
-
- $ # 1-indexed location (:line:column or :#offset) of the target identifier
- $ gopls highlight helper/helper.go:8:6
- $ gopls highlight helper/helper.go:#53
diff --git a/internal/lsp/cmd/usage/implementation.hlp b/internal/lsp/cmd/usage/implementation.hlp
deleted file mode 100644
index 09414f190..000000000
--- a/internal/lsp/cmd/usage/implementation.hlp
+++ /dev/null
@@ -1,10 +0,0 @@
-display selected identifier's implementation
-
-Usage:
- gopls [flags] implementation <position>
-
-Example:
-
- $ # 1-indexed location (:line:column or :#offset) of the target identifier
- $ gopls implementation helper/helper.go:8:6
- $ gopls implementation helper/helper.go:#53
diff --git a/internal/lsp/cmd/usage/imports.hlp b/internal/lsp/cmd/usage/imports.hlp
deleted file mode 100644
index 295f4daa2..000000000
--- a/internal/lsp/cmd/usage/imports.hlp
+++ /dev/null
@@ -1,14 +0,0 @@
-updates import statements
-
-Usage:
- gopls [flags] imports [imports-flags] <filename>
-
-Example: update imports statements in a file:
-
- $ gopls imports -w internal/lsp/cmd/check.go
-
-imports-flags:
- -d,-diff
- display diffs instead of rewriting files
- -w,-write
- write result to (source) file instead of stdout
diff --git a/internal/lsp/cmd/usage/inspect.hlp b/internal/lsp/cmd/usage/inspect.hlp
deleted file mode 100644
index 3d0a0f3c4..000000000
--- a/internal/lsp/cmd/usage/inspect.hlp
+++ /dev/null
@@ -1,8 +0,0 @@
-interact with the gopls daemon (deprecated: use 'remote')
-
-Usage:
- gopls [flags] inspect <subcommand> [arg]...
-
-Subcommand:
- sessions print information about current gopls sessions
- debug start the debug server
diff --git a/internal/lsp/cmd/usage/licenses.hlp b/internal/lsp/cmd/usage/licenses.hlp
deleted file mode 100644
index ab60ebc2f..000000000
--- a/internal/lsp/cmd/usage/licenses.hlp
+++ /dev/null
@@ -1,4 +0,0 @@
-print licenses of included software
-
-Usage:
- gopls [flags] licenses
diff --git a/internal/lsp/cmd/usage/links.hlp b/internal/lsp/cmd/usage/links.hlp
deleted file mode 100644
index 7f7612ce7..000000000
--- a/internal/lsp/cmd/usage/links.hlp
+++ /dev/null
@@ -1,12 +0,0 @@
-list links in a file
-
-Usage:
- gopls [flags] links [links-flags] <filename>
-
-Example: list links contained within a file:
-
- $ gopls links internal/lsp/cmd/check.go
-
-links-flags:
- -json
- emit document links in JSON format
diff --git a/internal/lsp/cmd/usage/prepare_rename.hlp b/internal/lsp/cmd/usage/prepare_rename.hlp
deleted file mode 100644
index 7f8a6f32d..000000000
--- a/internal/lsp/cmd/usage/prepare_rename.hlp
+++ /dev/null
@@ -1,10 +0,0 @@
-test validity of a rename operation at location
-
-Usage:
- gopls [flags] prepare_rename <position>
-
-Example:
-
- $ # 1-indexed location (:line:column or :#offset) of the target identifier
- $ gopls prepare_rename helper/helper.go:8:6
- $ gopls prepare_rename helper/helper.go:#53
diff --git a/internal/lsp/cmd/usage/references.hlp b/internal/lsp/cmd/usage/references.hlp
deleted file mode 100644
index c55ef0337..000000000
--- a/internal/lsp/cmd/usage/references.hlp
+++ /dev/null
@@ -1,14 +0,0 @@
-display selected identifier's references
-
-Usage:
- gopls [flags] references [references-flags] <position>
-
-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
-
-references-flags:
- -d,-declaration
- include the declaration of the specified identifier in the results
diff --git a/internal/lsp/cmd/usage/remote.hlp b/internal/lsp/cmd/usage/remote.hlp
deleted file mode 100644
index dd6034f46..000000000
--- a/internal/lsp/cmd/usage/remote.hlp
+++ /dev/null
@@ -1,8 +0,0 @@
-interact with the gopls daemon
-
-Usage:
- gopls [flags] remote <subcommand> [arg]...
-
-Subcommand:
- sessions print information about current gopls sessions
- debug start the debug server
diff --git a/internal/lsp/cmd/usage/rename.hlp b/internal/lsp/cmd/usage/rename.hlp
deleted file mode 100644
index ae58cbf60..000000000
--- a/internal/lsp/cmd/usage/rename.hlp
+++ /dev/null
@@ -1,18 +0,0 @@
-rename selected identifier
-
-Usage:
- gopls [flags] rename [rename-flags] <position> <name>
-
-Example:
-
- $ # 1-based location (:line:column or :#position) of the thing to change
- $ gopls rename helper/helper.go:8:6 Foo
- $ gopls rename helper/helper.go:#53 Foo
-
-rename-flags:
- -d,-diff
- display diffs instead of rewriting files
- -preserve
- preserve original files
- -w,-write
- write result to (source) file instead of stdout
diff --git a/internal/lsp/cmd/usage/semtok.hlp b/internal/lsp/cmd/usage/semtok.hlp
deleted file mode 100644
index 459ed596c..000000000
--- a/internal/lsp/cmd/usage/semtok.hlp
+++ /dev/null
@@ -1,8 +0,0 @@
-show semantic tokens for the specified file
-
-Usage:
- gopls [flags] semtok <filename>
-
-Example: show the semantic tokens for this file:
-
- $ gopls semtok internal/lsp/cmd/semtok.go
diff --git a/internal/lsp/cmd/usage/serve.hlp b/internal/lsp/cmd/usage/serve.hlp
deleted file mode 100644
index 370cbce83..000000000
--- a/internal/lsp/cmd/usage/serve.hlp
+++ /dev/null
@@ -1,30 +0,0 @@
-run a server for Go code using the Language Server Protocol
-
-Usage:
- gopls [flags] serve [server-flags]
- gopls [flags] [server-flags]
-
-The server communicates using JSONRPC2 on stdin and stdout, and is intended to be run directly as
-a child of an editor process.
-
-server-flags:
- -debug=string
- serve debug information on the supplied address
- -listen=string
- address on which to listen for remote connections. If prefixed by 'unix;', the subsequent address is assumed to be a unix domain socket. Otherwise, TCP is used.
- -listen.timeout=duration
- when used with -listen, shut down the server when there are no connected clients for this duration
- -logfile=string
- filename to log to. if value is "auto", then logging to a default output file is enabled
- -mode=string
- no effect
- -port=int
- port on which to run gopls for debugging purposes
- -remote.debug=string
- when used with -remote=auto, the -debug value used to start the daemon
- -remote.listen.timeout=duration
- when used with -remote=auto, the -listen.timeout value used to start the daemon (default 1m0s)
- -remote.logfile=string
- when used with -remote=auto, the -logfile value used to start the daemon
- -rpc.trace
- print the full rpc trace in lsp inspector format
diff --git a/internal/lsp/cmd/usage/signature.hlp b/internal/lsp/cmd/usage/signature.hlp
deleted file mode 100644
index f9fd0bfb7..000000000
--- a/internal/lsp/cmd/usage/signature.hlp
+++ /dev/null
@@ -1,10 +0,0 @@
-display selected identifier's signature
-
-Usage:
- gopls [flags] signature <position>
-
-Example:
-
- $ # 1-indexed location (:line:column or :#offset) of the target identifier
- $ gopls signature helper/helper.go:8:6
- $ gopls signature helper/helper.go:#53
diff --git a/internal/lsp/cmd/usage/symbols.hlp b/internal/lsp/cmd/usage/symbols.hlp
deleted file mode 100644
index 2aa36aa84..000000000
--- a/internal/lsp/cmd/usage/symbols.hlp
+++ /dev/null
@@ -1,7 +0,0 @@
-display selected file's symbols
-
-Usage:
- gopls [flags] symbols <file>
-
-Example:
- $ gopls symbols helper/helper.go
diff --git a/internal/lsp/cmd/usage/usage.hlp b/internal/lsp/cmd/usage/usage.hlp
deleted file mode 100644
index 1d0fb8d4c..000000000
--- a/internal/lsp/cmd/usage/usage.hlp
+++ /dev/null
@@ -1,77 +0,0 @@
-
-gopls is a Go language server.
-
-It is typically used with an editor to provide language features. When no
-command is specified, gopls will default to the 'serve' command. The language
-features can also be accessed via the gopls command-line interface.
-
-Usage:
- gopls help [<subject>]
-
-Command:
-
-Main
- serve run a server for Go code using the Language Server Protocol
- version print the gopls version information
- bug report a bug in gopls
- api-json print json describing gopls API
- licenses print licenses of included software
-
-Features
- call_hierarchy display selected identifier's call hierarchy
- check show diagnostic results for the specified file
- definition show declaration of selected identifier
- folding_ranges display selected file's folding ranges
- format format the code according to the go standard
- highlight display selected identifier's highlights
- implementation display selected identifier's implementation
- imports updates import statements
- remote interact with the gopls daemon
- inspect interact with the gopls daemon (deprecated: use 'remote')
- links list links in a file
- prepare_rename test validity of a rename operation at location
- references display selected identifier's references
- rename rename selected identifier
- semtok show semantic tokens for the specified file
- signature display selected identifier's signature
- fix apply suggested fixes
- symbols display selected file's symbols
- workspace manage the gopls workspace (experimental: under development)
- workspace_symbol search symbols in workspace
- vulncheck run experimental vulncheck analysis (experimental: under development)
-
-flags:
- -debug=string
- serve debug information on the supplied address
- -listen=string
- address on which to listen for remote connections. If prefixed by 'unix;', the subsequent address is assumed to be a unix domain socket. Otherwise, TCP is used.
- -listen.timeout=duration
- when used with -listen, shut down the server when there are no connected clients for this duration
- -logfile=string
- filename to log to. if value is "auto", then logging to a default output file is enabled
- -mode=string
- no effect
- -ocagent=string
- the address of the ocagent (e.g. http://localhost:55678), or off (default "off")
- -port=int
- port on which to run gopls for debugging purposes
- -profile.cpu=string
- write CPU profile to this file
- -profile.mem=string
- write memory profile to this file
- -profile.trace=string
- write trace log to this file
- -remote=string
- forward all commands to a remote lsp specified by this flag. With no special prefix, this is assumed to be a TCP address. If prefixed by 'unix;', the subsequent address is assumed to be a unix domain socket. If 'auto', or prefixed by 'auto;', the remote address is automatically resolved based on the executing environment.
- -remote.debug=string
- when used with -remote=auto, the -debug value used to start the daemon
- -remote.listen.timeout=duration
- when used with -remote=auto, the -listen.timeout value used to start the daemon (default 1m0s)
- -remote.logfile=string
- when used with -remote=auto, the -logfile value used to start the daemon
- -rpc.trace
- print the full rpc trace in lsp inspector format
- -v,-verbose
- verbose output
- -vv,-veryverbose
- very verbose output
diff --git a/internal/lsp/cmd/usage/version.hlp b/internal/lsp/cmd/usage/version.hlp
deleted file mode 100644
index 3a09ddedf..000000000
--- a/internal/lsp/cmd/usage/version.hlp
+++ /dev/null
@@ -1,6 +0,0 @@
-print the gopls version information
-
-Usage:
- gopls [flags] version
- -json
- outputs in json format.
diff --git a/internal/lsp/cmd/usage/vulncheck.hlp b/internal/lsp/cmd/usage/vulncheck.hlp
deleted file mode 100644
index 4bfdc4b47..000000000
--- a/internal/lsp/cmd/usage/vulncheck.hlp
+++ /dev/null
@@ -1,9 +0,0 @@
-run experimental vulncheck analysis (experimental: under development)
-
-Usage:
- gopls [flags] vulncheck
-
- WARNING: this command is experimental.
-
- Example:
- $ gopls vulncheck <packages>
diff --git a/internal/lsp/cmd/usage/workspace.hlp b/internal/lsp/cmd/usage/workspace.hlp
deleted file mode 100644
index 912cf2946..000000000
--- a/internal/lsp/cmd/usage/workspace.hlp
+++ /dev/null
@@ -1,7 +0,0 @@
-manage the gopls workspace (experimental: under development)
-
-Usage:
- gopls [flags] workspace <subcommand> [arg]...
-
-Subcommand:
- generate generate a gopls.mod file for a workspace
diff --git a/internal/lsp/cmd/usage/workspace_symbol.hlp b/internal/lsp/cmd/usage/workspace_symbol.hlp
deleted file mode 100644
index a61b47b33..000000000
--- a/internal/lsp/cmd/usage/workspace_symbol.hlp
+++ /dev/null
@@ -1,13 +0,0 @@
-search symbols in workspace
-
-Usage:
- gopls [flags] workspace_symbol [workspace_symbol-flags] <query>
-
-Example:
-
- $ gopls workspace_symbol -matcher fuzzy 'wsymbols'
-
-workspace_symbol-flags:
- -matcher=string
- specifies the type of matcher: fuzzy, caseSensitive, or caseInsensitive.
- The default is caseInsensitive.
diff --git a/internal/lsp/cmd/vulncheck.go b/internal/lsp/cmd/vulncheck.go
deleted file mode 100644
index adf59cecb..000000000
--- a/internal/lsp/cmd/vulncheck.go
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2022 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"
- "encoding/json"
- "flag"
- "fmt"
- "os"
-
- "golang.org/x/tools/internal/lsp/command"
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/tool"
-)
-
-// vulncheck implements the vulncheck command.
-type vulncheck struct {
- app *Application
-}
-
-func (v *vulncheck) Name() string { return "vulncheck" }
-func (v *vulncheck) Parent() string { return v.app.Name() }
-func (v *vulncheck) Usage() string { return "" }
-func (v *vulncheck) ShortHelp() string {
- return "run experimental vulncheck analysis (experimental: under development)"
-}
-func (v *vulncheck) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprint(f.Output(), `
- WARNING: this command is experimental.
-
- Example:
- $ gopls vulncheck <packages>
-`)
- printFlagDefaults(f)
-}
-
-func (v *vulncheck) Run(ctx context.Context, args ...string) error {
- if len(args) > 1 {
- return tool.CommandLineErrorf("vulncheck accepts at most one package pattern")
- }
- pattern := "."
- if len(args) == 1 {
- pattern = args[0]
- }
-
- conn, err := v.app.connect(ctx)
- if err != nil {
- return err
- }
- defer conn.terminate(ctx)
-
- cwd, err := os.Getwd()
- if err != nil {
- return err
- }
-
- cmd, err := command.NewRunVulncheckExpCommand("", command.VulncheckArgs{
- Dir: protocol.URIFromPath(cwd),
- Pattern: pattern,
- })
- if err != nil {
- return err
- }
-
- params := &protocol.ExecuteCommandParams{Command: cmd.Command, Arguments: cmd.Arguments}
- res, err := conn.ExecuteCommand(ctx, params)
- if err != nil {
- return fmt.Errorf("executing server command: %v", err)
- }
- data, err := json.MarshalIndent(res, " ", " ")
- if err != nil {
- return fmt.Errorf("failed to decode results: %v", err)
- }
- fmt.Printf("%s\n", data)
- return nil
-}
diff --git a/internal/lsp/cmd/workspace.go b/internal/lsp/cmd/workspace.go
deleted file mode 100644
index c0ddd9eb4..000000000
--- a/internal/lsp/cmd/workspace.go
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2020 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"
-
- "golang.org/x/tools/internal/lsp/command"
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/lsp/source"
-)
-
-// workspace is a top-level command for working with the gopls workspace. This
-// is experimental and subject to change. The idea is that subcommands could be
-// used for manipulating the workspace mod file, rather than editing it
-// manually.
-type workspace struct {
- app *Application
- subcommands
-}
-
-func newWorkspace(app *Application) *workspace {
- return &workspace{
- app: app,
- subcommands: subcommands{
- &generateWorkspaceMod{app: app},
- },
- }
-}
-
-func (w *workspace) Name() string { return "workspace" }
-func (w *workspace) Parent() string { return w.app.Name() }
-func (w *workspace) ShortHelp() string {
- return "manage the gopls workspace (experimental: under development)"
-}
-
-// generateWorkspaceMod (re)generates the gopls.mod file for the current
-// workspace.
-type generateWorkspaceMod struct {
- app *Application
-}
-
-func (c *generateWorkspaceMod) Name() string { return "generate" }
-func (c *generateWorkspaceMod) Usage() string { return "" }
-func (c *generateWorkspaceMod) ShortHelp() string {
- return "generate a gopls.mod file for a workspace"
-}
-
-func (c *generateWorkspaceMod) DetailedHelp(f *flag.FlagSet) {
- printFlagDefaults(f)
-}
-
-func (c *generateWorkspaceMod) Run(ctx context.Context, args ...string) error {
- origOptions := c.app.options
- c.app.options = func(opts *source.Options) {
- origOptions(opts)
- opts.ExperimentalWorkspaceModule = true
- }
- conn, err := c.app.connect(ctx)
- if err != nil {
- return err
- }
- defer conn.terminate(ctx)
- cmd, err := command.NewGenerateGoplsModCommand("", command.URIArg{})
- if err != nil {
- return err
- }
- params := &protocol.ExecuteCommandParams{Command: cmd.Command, Arguments: cmd.Arguments}
- if _, err := conn.ExecuteCommand(ctx, params); err != nil {
- return fmt.Errorf("executing server command: %v", err)
- }
- return nil
-}
diff --git a/internal/lsp/cmd/workspace_symbol.go b/internal/lsp/cmd/workspace_symbol.go
deleted file mode 100644
index 38fe5decf..000000000
--- a/internal/lsp/cmd/workspace_symbol.go
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2020 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"
-
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/lsp/source"
- "golang.org/x/tools/internal/tool"
-)
-
-// workspaceSymbol implements the workspace_symbol verb for gopls.
-type workspaceSymbol struct {
- Matcher string `flag:"matcher" help:"specifies the type of matcher: fuzzy, caseSensitive, or caseInsensitive.\nThe default is caseInsensitive."`
-
- app *Application
-}
-
-func (r *workspaceSymbol) Name() string { return "workspace_symbol" }
-func (r *workspaceSymbol) Parent() string { return r.app.Name() }
-func (r *workspaceSymbol) Usage() string { return "[workspace_symbol-flags] <query>" }
-func (r *workspaceSymbol) ShortHelp() string { return "search symbols in workspace" }
-func (r *workspaceSymbol) DetailedHelp(f *flag.FlagSet) {
- fmt.Fprint(f.Output(), `
-Example:
-
- $ gopls workspace_symbol -matcher fuzzy 'wsymbols'
-
-workspace_symbol-flags:
-`)
- printFlagDefaults(f)
-}
-
-func (r *workspaceSymbol) Run(ctx context.Context, args ...string) error {
- if len(args) != 1 {
- return tool.CommandLineErrorf("workspace_symbol expects 1 argument")
- }
-
- opts := r.app.options
- r.app.options = func(o *source.Options) {
- if opts != nil {
- opts(o)
- }
- switch r.Matcher {
- case "fuzzy":
- o.SymbolMatcher = source.SymbolFuzzy
- case "caseSensitive":
- o.SymbolMatcher = source.SymbolCaseSensitive
- case "fastfuzzy":
- o.SymbolMatcher = source.SymbolFastFuzzy
- default:
- o.SymbolMatcher = source.SymbolCaseInsensitive
- }
- }
-
- conn, err := r.app.connect(ctx)
- if err != nil {
- return err
- }
- defer conn.terminate(ctx)
-
- p := protocol.WorkspaceSymbolParams{
- Query: args[0],
- }
-
- symbols, err := conn.Symbol(ctx, &p)
- if err != nil {
- return err
- }
- for _, s := range symbols {
- f := conn.AddFile(ctx, fileURI(s.Location.URI))
- span, err := f.mapper.Span(s.Location)
- if err != nil {
- return err
- }
- fmt.Printf("%s %s %s\n", span, s.Name, s.Kind)
- }
-
- return nil
-}