From df83f4e7c16e8d791bddd50b4a5f48cd02bf068e Mon Sep 17 00:00:00 2001 From: Rob Findley Date: Wed, 26 Aug 2020 17:41:45 -0400 Subject: [PATCH] internal/lsp: fix builds and tests for go1.12+ Seems we've drifted a bit from go1.12 support, mostly due to error wrapping. Fix this, as well as some assorted other failures. I haven't tested 1.12 interactively. For golang/go#39146 Change-Id: Id347ead2a13e89b76d2ae0047750e6b6b49911eb Reviewed-on: https://go-review.googlesource.com/c/tools/+/250941 Run-TryBot: Robert Findley TryBot-Result: Gobot Gobot Reviewed-by: Rebecca Stambler --- internal/lsp/cache/view.go | 2 +- internal/lsp/cmd/prepare_rename.go | 4 +- internal/lsp/cmd/serve.go | 2 +- internal/lsp/debug/serve.go | 8 ++-- internal/lsp/fake/editor.go | 46 +++++++++---------- internal/lsp/fake/sandbox.go | 7 ++- internal/lsp/fake/workdir.go | 16 +++---- internal/lsp/general.go | 5 +- internal/lsp/lsprpc/autostart_default.go | 5 +- internal/lsp/lsprpc/autostart_posix.go | 10 ++-- internal/lsp/lsprpc/lsprpc.go | 17 +++---- internal/lsp/lsprpc/lsprpc_test.go | 2 + internal/lsp/mod/code_lens.go | 2 +- internal/lsp/mod/hover.go | 7 +-- internal/lsp/protocol/protocol.go | 3 +- internal/lsp/protocol/tsclient.go | 6 +-- internal/lsp/protocol/tsprotocol.go | 2 +- internal/lsp/protocol/tsserver.go | 6 +-- internal/lsp/protocol/typescript/code.ts | 4 +- internal/lsp/regtest/codelens_test.go | 1 + internal/lsp/regtest/link_test.go | 3 ++ internal/lsp/regtest/reg_test.go | 9 +++- internal/lsp/regtest/wrappers.go | 4 +- internal/lsp/server.go | 3 +- internal/lsp/source/command.go | 3 +- internal/lsp/source/completion.go | 3 +- internal/lsp/source/highlight.go | 2 +- internal/lsp/source/implementation.go | 7 +-- internal/lsp/source/signature_help.go | 3 +- internal/lsp/source/symbols.go | 3 +- .../lsp/primarymod/rename/b/b.go.golden | 2 +- internal/lsp/text_synchronization.go | 10 ++-- 32 files changed, 114 insertions(+), 93 deletions(-) diff --git a/internal/lsp/cache/view.go b/internal/lsp/cache/view.go index 52390471839..bfb68ab69ed 100644 --- a/internal/lsp/cache/view.go +++ b/internal/lsp/cache/view.go @@ -717,7 +717,7 @@ func (v *View) maybeReinitialize() { func (v *View) setBuildInformation(ctx context.Context, folder span.URI, options source.Options) error { if err := checkPathCase(folder.Filename()); err != nil { - return fmt.Errorf("invalid workspace configuration: %w", err) + return errors.Errorf("invalid workspace configuration: %w", err) } // Make sure to get the `go env` before continuing with initialization. modFile, err := v.setGoEnv(ctx, options.Env) diff --git a/internal/lsp/cmd/prepare_rename.go b/internal/lsp/cmd/prepare_rename.go index 17c6dd83b0c..2a2fffec254 100644 --- a/internal/lsp/cmd/prepare_rename.go +++ b/internal/lsp/cmd/prepare_rename.go @@ -6,13 +6,13 @@ package cmd import ( "context" - "errors" "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. @@ -68,7 +68,7 @@ func (r *prepareRename) Run(ctx context.Context, args ...string) error { } result, err := conn.PrepareRename(ctx, &p) if err != nil { - return fmt.Errorf("prepare_rename failed: %w", err) + return errors.Errorf("prepare_rename failed: %w", err) } if result == nil { return ErrInvalidRenamePosition diff --git a/internal/lsp/cmd/serve.go b/internal/lsp/cmd/serve.go index 72e2a8cfc73..a3bfd910029 100644 --- a/internal/lsp/cmd/serve.go +++ b/internal/lsp/cmd/serve.go @@ -6,7 +6,6 @@ package cmd import ( "context" - "errors" "flag" "fmt" "io" @@ -22,6 +21,7 @@ import ( "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 diff --git a/internal/lsp/debug/serve.go b/internal/lsp/debug/serve.go index 8d25d8a66cf..ae526ece1ac 100644 --- a/internal/lsp/debug/serve.go +++ b/internal/lsp/debug/serve.go @@ -37,7 +37,7 @@ import ( "golang.org/x/tools/internal/lsp/debug/tag" "golang.org/x/tools/internal/lsp/protocol" "golang.org/x/tools/internal/lsp/source" - "golang.org/x/xerrors" + errors "golang.org/x/xerrors" ) type instanceKeyType int @@ -151,7 +151,7 @@ func (st *State) Clients() []*Client { return clients } -// View returns the View that matches the supplied id. +// Client returns the Client matching the supplied id. func (st *State) Client(id string) *Client { for _, c := range st.Clients() { if c.Session.ID() == id { @@ -338,7 +338,7 @@ func (i *Instance) SetLogFile(logfile string, isDaemon bool) (func(), error) { } f, err := os.Create(logfile) if err != nil { - return nil, fmt.Errorf("unable to create log file: %w", err) + return nil, errors.Errorf("unable to create log file: %w", err) } closeLog = func() { defer f.Close() @@ -480,7 +480,7 @@ func makeGlobalExporter(stderr io.Writer) event.Exporter { if event.IsLog(ev) { // Don't log context cancellation errors. - if err := keys.Err.Get(ev); xerrors.Is(err, context.Canceled) { + if err := keys.Err.Get(ev); errors.Is(err, context.Canceled) { return ctx } // Make sure any log messages without an instance go to stderr. diff --git a/internal/lsp/fake/editor.go b/internal/lsp/fake/editor.go index e97c49b95f7..1a89f9ad83f 100644 --- a/internal/lsp/fake/editor.go +++ b/internal/lsp/fake/editor.go @@ -7,7 +7,6 @@ package fake import ( "bufio" "context" - "errors" "fmt" "path/filepath" "regexp" @@ -18,6 +17,7 @@ import ( "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" ) // Editor is a fake editor client. It keeps track of client state and can be @@ -118,7 +118,7 @@ func (e *Editor) Connect(ctx context.Context, conn jsonrpc2.Conn, hooks ClientHo func (e *Editor) Shutdown(ctx context.Context) error { if e.Server != nil { if err := e.Server.Shutdown(ctx); err != nil { - return fmt.Errorf("Shutdown: %w", err) + return errors.Errorf("Shutdown: %w", err) } } return nil @@ -130,7 +130,7 @@ func (e *Editor) Exit(ctx context.Context) error { // Not all LSP clients issue the exit RPC, but we do so here to ensure that // we gracefully handle it on multi-session servers. if err := e.Server.Exit(ctx); err != nil { - return fmt.Errorf("Exit: %w", err) + return errors.Errorf("Exit: %w", err) } } return nil @@ -150,7 +150,7 @@ func (e *Editor) Close(ctx context.Context) error { // connection closed itself return nil case <-ctx.Done(): - return fmt.Errorf("connection not closed: %w", ctx.Err()) + return errors.Errorf("connection not closed: %w", ctx.Err()) } } @@ -222,14 +222,14 @@ func (e *Editor) initialize(ctx context.Context, withoutWorkspaceFolders bool, e if e.Server != nil { resp, err := e.Server.Initialize(ctx, params) if err != nil { - return fmt.Errorf("initialize: %w", err) + return errors.Errorf("initialize: %w", err) } e.mu.Lock() e.serverCapabilities = resp.Capabilities e.mu.Unlock() if err := e.Server.Initialized(ctx, &protocol.InitializedParams{}); err != nil { - return fmt.Errorf("initialized: %w", err) + return errors.Errorf("initialized: %w", err) } } // TODO: await initial configuration here, or expect gopls to manage that? @@ -271,7 +271,7 @@ func (e *Editor) OpenFileWithContent(ctx context.Context, path, content string) if err := e.Server.DidOpen(ctx, &protocol.DidOpenTextDocumentParams{ TextDocument: item, }); err != nil { - return fmt.Errorf("DidOpen: %w", err) + return errors.Errorf("DidOpen: %w", err) } } return nil @@ -313,7 +313,7 @@ func (e *Editor) CreateBuffer(ctx context.Context, path, content string) error { if err := e.Server.DidOpen(ctx, &protocol.DidOpenTextDocumentParams{ TextDocument: item, }); err != nil { - return fmt.Errorf("DidOpen: %w", err) + return errors.Errorf("DidOpen: %w", err) } } return nil @@ -334,7 +334,7 @@ func (e *Editor) CloseBuffer(ctx context.Context, path string) error { if err := e.Server.DidClose(ctx, &protocol.DidCloseTextDocumentParams{ TextDocument: e.textDocumentIdentifier(path), }); err != nil { - return fmt.Errorf("DidClose: %w", err) + return errors.Errorf("DidClose: %w", err) } } return nil @@ -350,10 +350,10 @@ func (e *Editor) textDocumentIdentifier(path string) protocol.TextDocumentIdenti // the filesystem. func (e *Editor) SaveBuffer(ctx context.Context, path string) error { if err := e.OrganizeImports(ctx, path); err != nil { - return fmt.Errorf("organizing imports before save: %w", err) + return errors.Errorf("organizing imports before save: %w", err) } if err := e.FormatBuffer(ctx, path); err != nil { - return fmt.Errorf("formatting before save: %w", err) + return errors.Errorf("formatting before save: %w", err) } return e.SaveBufferWithoutActions(ctx, path) } @@ -379,11 +379,11 @@ func (e *Editor) SaveBufferWithoutActions(ctx context.Context, path string) erro TextDocument: docID, Reason: protocol.Manual, }); err != nil { - return fmt.Errorf("WillSave: %w", err) + return errors.Errorf("WillSave: %w", err) } } if err := e.sandbox.Workdir.WriteFile(ctx, path, content); err != nil { - return fmt.Errorf("writing %q: %w", path, err) + return errors.Errorf("writing %q: %w", path, err) } if e.Server != nil { params := &protocol.DidSaveTextDocumentParams{ @@ -396,7 +396,7 @@ func (e *Editor) SaveBufferWithoutActions(ctx context.Context, path string) erro params.Text = &content } if err := e.Server.DidSave(ctx, params); err != nil { - return fmt.Errorf("DidSave: %w", err) + return errors.Errorf("DidSave: %w", err) } } return nil @@ -417,7 +417,7 @@ func contentPosition(content string, offset int) (Pos, error) { line++ } if err := scanner.Err(); err != nil { - return Pos{}, fmt.Errorf("scanning content: %w", err) + return Pos{}, errors.Errorf("scanning content: %w", err) } // Scan() will drop the last line if it is empty. Correct for this. if strings.HasSuffix(content, "\n") && offset == start { @@ -565,7 +565,7 @@ func (e *Editor) editBufferLocked(ctx context.Context, path string, edits []Edit } if e.Server != nil { if err := e.Server.DidChange(ctx, params); err != nil { - return fmt.Errorf("DidChange: %w", err) + return errors.Errorf("DidChange: %w", err) } } return nil @@ -583,7 +583,7 @@ func (e *Editor) GoToDefinition(ctx context.Context, path string, pos Pos) (stri resp, err := e.Server.Definition(ctx, params) if err != nil { - return "", Pos{}, fmt.Errorf("definition: %w", err) + return "", Pos{}, errors.Errorf("definition: %w", err) } if len(resp) == 0 { return "", Pos{}, nil @@ -591,7 +591,7 @@ func (e *Editor) GoToDefinition(ctx context.Context, path string, pos Pos) (stri newPath := e.sandbox.Workdir.URIToPath(resp[0].URI) newPos := fromProtocolPosition(resp[0].Range.Start) if err := e.OpenFile(ctx, newPath); err != nil { - return "", Pos{}, fmt.Errorf("OpenFile: %w", err) + return "", Pos{}, errors.Errorf("OpenFile: %w", err) } return newPath, newPos, nil } @@ -603,7 +603,7 @@ func (e *Editor) Symbol(ctx context.Context, query string) ([]SymbolInformation, resp, err := e.Server.Symbol(ctx, params) if err != nil { - return nil, fmt.Errorf("symbol: %w", err) + return nil, errors.Errorf("symbol: %w", err) } var res []SymbolInformation for _, si := range resp { @@ -658,7 +658,7 @@ func (e *Editor) codeAction(ctx context.Context, path string, rng *protocol.Rang } actions, err := e.Server.CodeAction(ctx, params) if err != nil { - return fmt.Errorf("textDocument/codeAction: %w", err) + return errors.Errorf("textDocument/codeAction: %w", err) } for _, action := range actions { var match bool @@ -679,7 +679,7 @@ func (e *Editor) codeAction(ctx context.Context, path string, rng *protocol.Rang } edits := convertEdits(change.Edits) if err := e.EditBuffer(ctx, path, edits); err != nil { - return fmt.Errorf("editing buffer %q: %w", path, err) + return errors.Errorf("editing buffer %q: %w", path, err) } } // Execute any commands. The specification says that commands are @@ -716,7 +716,7 @@ func (e *Editor) FormatBuffer(ctx context.Context, path string) error { params.TextDocument.URI = e.sandbox.Workdir.URI(path) resp, err := e.Server.Formatting(ctx, params) if err != nil { - return fmt.Errorf("textDocument/formatting: %w", err) + return errors.Errorf("textDocument/formatting: %w", err) } e.mu.Lock() defer e.mu.Unlock() @@ -850,7 +850,7 @@ func (e *Editor) Hover(ctx context.Context, path string, pos Pos) (*protocol.Mar resp, err := e.Server.Hover(ctx, params) if err != nil { - return nil, Pos{}, fmt.Errorf("hover: %w", err) + return nil, Pos{}, errors.Errorf("hover: %w", err) } if resp == nil { return nil, Pos{}, nil diff --git a/internal/lsp/fake/sandbox.go b/internal/lsp/fake/sandbox.go index 80fec6b986a..0f6213cead5 100644 --- a/internal/lsp/fake/sandbox.go +++ b/internal/lsp/fake/sandbox.go @@ -15,6 +15,7 @@ import ( "golang.org/x/tools/internal/gocommand" "golang.org/x/tools/internal/testenv" "golang.org/x/tools/txtar" + errors "golang.org/x/xerrors" ) // Sandbox holds a collection of temporary resources to use for working with Go @@ -203,7 +204,7 @@ func (sb *Sandbox) RunGoCommand(ctx context.Context, verb string, args ...string // check if we need to send any any "watched" file events. if sb.Workdir != nil { if err := sb.Workdir.CheckForFileChanges(ctx); err != nil { - return fmt.Errorf("checking for file changes: %w", err) + return errors.Errorf("checking for file changes: %w", err) } } return nil @@ -213,9 +214,7 @@ func (sb *Sandbox) RunGoCommand(ctx context.Context, verb string, args ...string func (sb *Sandbox) Close() error { var goCleanErr error if sb.gopath != "" { - if err := sb.RunGoCommand(context.Background(), "clean", "-modcache"); err != nil { - goCleanErr = fmt.Errorf("cleaning modcache: %v", err) - } + goCleanErr = sb.RunGoCommand(context.Background(), "clean", "-modcache") } err := os.RemoveAll(sb.basedir) if err != nil || goCleanErr != nil { diff --git a/internal/lsp/fake/workdir.go b/internal/lsp/fake/workdir.go index 34307b1a603..fdac27f9536 100644 --- a/internal/lsp/fake/workdir.go +++ b/internal/lsp/fake/workdir.go @@ -6,7 +6,6 @@ package fake import ( "context" - "fmt" "io/ioutil" "os" "path/filepath" @@ -16,6 +15,7 @@ import ( "golang.org/x/tools/internal/lsp/protocol" "golang.org/x/tools/internal/span" + errors "golang.org/x/xerrors" ) // FileEvent wraps the protocol.FileEvent so that it can be associated with a @@ -48,12 +48,12 @@ func (w *Workdir) WriteInitialFiles(txt string) error { files := unpackTxt(txt) for name, data := range files { if err := w.writeFileData(name, string(data)); err != nil { - return fmt.Errorf("writing to workdir: %w", err) + return errors.Errorf("writing to workdir: %w", err) } } // Poll to capture the current file state. if _, err := w.pollFiles(); err != nil { - return fmt.Errorf("polling files: %w", err) + return errors.Errorf("polling files: %w", err) } return nil } @@ -134,7 +134,7 @@ func (w *Workdir) ChangeFilesOnDisk(ctx context.Context, events []FileEvent) err case protocol.Deleted: fp := w.filePath(e.Path) if err := os.Remove(fp); err != nil { - return fmt.Errorf("removing %q: %w", e.Path, err) + return errors.Errorf("removing %q: %w", e.Path, err) } case protocol.Changed, protocol.Created: if _, err := w.writeFile(ctx, e.Path, e.Content); err != nil { @@ -150,7 +150,7 @@ func (w *Workdir) ChangeFilesOnDisk(ctx context.Context, events []FileEvent) err func (w *Workdir) RemoveFile(ctx context.Context, path string) error { fp := w.filePath(path) if err := os.Remove(fp); err != nil { - return fmt.Errorf("removing %q: %w", path, err) + return errors.Errorf("removing %q: %w", path, err) } evts := []FileEvent{{ Path: path, @@ -205,7 +205,7 @@ func (w *Workdir) writeFile(ctx context.Context, path, content string) (FileEven fp := w.filePath(path) _, err := os.Stat(fp) if err != nil && !os.IsNotExist(err) { - return FileEvent{}, fmt.Errorf("checking if %q exists: %w", path, err) + return FileEvent{}, errors.Errorf("checking if %q exists: %w", path, err) } var changeType protocol.FileChangeType if os.IsNotExist(err) { @@ -228,10 +228,10 @@ func (w *Workdir) writeFile(ctx context.Context, path, content string) (FileEven func (w *Workdir) writeFileData(path string, content string) error { fp := w.filePath(path) if err := os.MkdirAll(filepath.Dir(fp), 0755); err != nil { - return fmt.Errorf("creating nested directory: %w", err) + return errors.Errorf("creating nested directory: %w", err) } if err := ioutil.WriteFile(fp, []byte(content), 0644); err != nil { - return fmt.Errorf("writing %q: %w", path, err) + return errors.Errorf("writing %q: %w", path, err) } return nil } diff --git a/internal/lsp/general.go b/internal/lsp/general.go index 1ddc993c8f4..29e274d893d 100644 --- a/internal/lsp/general.go +++ b/internal/lsp/general.go @@ -22,13 +22,14 @@ import ( "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" ) func (s *Server) initialize(ctx context.Context, params *protocol.ParamInitialize) (*protocol.InitializeResult, error) { s.stateMu.Lock() if s.state >= serverInitializing { defer s.stateMu.Unlock() - return nil, fmt.Errorf("%w: initialize called while server in %v state", jsonrpc2.ErrInvalidRequest, s.state) + return nil, errors.Errorf("%w: initialize called while server in %v state", jsonrpc2.ErrInvalidRequest, s.state) } s.state = serverInitializing s.stateMu.Unlock() @@ -142,7 +143,7 @@ func (s *Server) initialized(ctx context.Context, params *protocol.InitializedPa s.stateMu.Lock() if s.state >= serverInitialized { defer s.stateMu.Unlock() - return fmt.Errorf("%w: initalized called while server in %v state", jsonrpc2.ErrInvalidRequest, s.state) + return errors.Errorf("%w: initalized called while server in %v state", jsonrpc2.ErrInvalidRequest, s.state) } s.state = serverInitialized s.stateMu.Unlock() diff --git a/internal/lsp/lsprpc/autostart_default.go b/internal/lsp/lsprpc/autostart_default.go index 9fdd427cca2..2ddc5b6cb52 100644 --- a/internal/lsp/lsprpc/autostart_default.go +++ b/internal/lsp/lsprpc/autostart_default.go @@ -5,8 +5,9 @@ package lsprpc import ( - "fmt" "os/exec" + + errors "golang.org/x/xerrors" ) var ( @@ -18,7 +19,7 @@ var ( func startRemoteDefault(goplsPath string, args ...string) error { cmd := exec.Command(goplsPath, args...) if err := cmd.Start(); err != nil { - return fmt.Errorf("starting remote gopls: %w", err) + return errors.Errorf("starting remote gopls: %w", err) } return nil } diff --git a/internal/lsp/lsprpc/autostart_posix.go b/internal/lsp/lsprpc/autostart_posix.go index 224a5a0d363..5aa0a989e2b 100644 --- a/internal/lsp/lsprpc/autostart_posix.go +++ b/internal/lsp/lsprpc/autostart_posix.go @@ -17,6 +17,8 @@ import ( "path/filepath" "strconv" "syscall" + + "golang.org/x/xerrors" ) func init() { @@ -31,7 +33,7 @@ func startRemotePosix(goplsPath string, args ...string) error { Setsid: true, } if err := cmd.Start(); err != nil { - return fmt.Errorf("starting remote gopls: %w", err) + return xerrors.Errorf("starting remote gopls: %w", err) } return nil } @@ -78,7 +80,7 @@ func verifyRemoteOwnershipPosix(network, address string) (bool, error) { if os.IsNotExist(err) { return true, nil } - return false, fmt.Errorf("checking socket owner: %w", err) + return false, xerrors.Errorf("checking socket owner: %w", err) } stat, ok := fi.Sys().(*syscall.Stat_t) if !ok { @@ -86,11 +88,11 @@ func verifyRemoteOwnershipPosix(network, address string) (bool, error) { } user, err := user.Current() if err != nil { - return false, fmt.Errorf("checking current user: %w", err) + return false, xerrors.Errorf("checking current user: %w", err) } uid, err := strconv.ParseUint(user.Uid, 10, 32) if err != nil { - return false, fmt.Errorf("parsing current UID: %w", err) + return false, xerrors.Errorf("parsing current UID: %w", err) } return stat.Uid == uint32(uid), nil } diff --git a/internal/lsp/lsprpc/lsprpc.go b/internal/lsp/lsprpc/lsprpc.go index 73f496ddcd8..2af6bdc69e5 100644 --- a/internal/lsp/lsprpc/lsprpc.go +++ b/internal/lsp/lsprpc/lsprpc.go @@ -25,6 +25,7 @@ import ( "golang.org/x/tools/internal/lsp/debug" "golang.org/x/tools/internal/lsp/debug/tag" "golang.org/x/tools/internal/lsp/protocol" + errors "golang.org/x/xerrors" ) // AutoNetwork is the pseudo network type used to signal that gopls should use @@ -173,19 +174,19 @@ func QueryServerState(ctx context.Context, network, address string) (*ServerStat if network == AutoNetwork { gp, err := os.Executable() if err != nil { - return nil, fmt.Errorf("getting gopls path: %w", err) + return nil, errors.Errorf("getting gopls path: %w", err) } network, address = autoNetworkAddress(gp, address) } netConn, err := net.DialTimeout(network, address, 5*time.Second) if err != nil { - return nil, fmt.Errorf("dialing remote: %w", err) + return nil, errors.Errorf("dialing remote: %w", err) } serverConn := jsonrpc2.NewConn(jsonrpc2.NewHeaderStream(netConn)) serverConn.Go(ctx, jsonrpc2.MethodNotFound) var state ServerState if err := protocol.Call(ctx, serverConn, sessionsMethod, nil, &state); err != nil { - return nil, fmt.Errorf("querying server state: %w", err) + return nil, errors.Errorf("querying server state: %w", err) } return &state, nil } @@ -197,7 +198,7 @@ func (f *Forwarder) ServeStream(ctx context.Context, clientConn jsonrpc2.Conn) e netConn, err := f.connectToRemote(ctx) if err != nil { - return fmt.Errorf("forwarder: connecting to remote: %w", err) + return errors.Errorf("forwarder: connecting to remote: %w", err) } serverConn := jsonrpc2.NewConn(jsonrpc2.NewHeaderStream(netConn)) server := protocol.ServerDispatcher(serverConn) @@ -320,7 +321,7 @@ func connectToRemote(ctx context.Context, inNetwork, inAddr, goplsPath string, r // instances are simultaneously starting up. if _, err := os.Stat(address); err == nil { if err := os.Remove(address); err != nil { - return nil, fmt.Errorf("removing remote socket file: %w", err) + return nil, errors.Errorf("removing remote socket file: %w", err) } } } @@ -335,7 +336,7 @@ func connectToRemote(ctx context.Context, inNetwork, inAddr, goplsPath string, r args = append(args, "-debug", rcfg.debug) } if err := startRemote(goplsPath, args...); err != nil { - return nil, fmt.Errorf("startRemote(%q, %v): %w", goplsPath, args, err) + return nil, errors.Errorf("startRemote(%q, %v): %w", goplsPath, args, err) } } @@ -355,7 +356,7 @@ func connectToRemote(ctx context.Context, inNetwork, inAddr, goplsPath string, r time.Sleep(dialTimeout - time.Since(startDial)) } } - return nil, fmt.Errorf("dialing remote: %w", err) + return nil, errors.Errorf("dialing remote: %w", err) } // forwarderHandler intercepts 'exit' messages to prevent the shared gopls @@ -555,7 +556,7 @@ func handshaker(session *cache.Session, goplsPath string, logHandshakes bool, ha } func sendError(ctx context.Context, reply jsonrpc2.Replier, err error) { - err = fmt.Errorf("%w: %v", jsonrpc2.ErrParse, err) + err = errors.Errorf("%v: %w", err, jsonrpc2.ErrParse) if err := reply(ctx, nil, err); err != nil { event.Error(ctx, "", err) } diff --git a/internal/lsp/lsprpc/lsprpc_test.go b/internal/lsp/lsprpc/lsprpc_test.go index 339d1d14df5..1b546e72308 100644 --- a/internal/lsp/lsprpc/lsprpc_test.go +++ b/internal/lsp/lsprpc/lsprpc_test.go @@ -18,6 +18,7 @@ import ( "golang.org/x/tools/internal/lsp/debug" "golang.org/x/tools/internal/lsp/fake" "golang.org/x/tools/internal/lsp/protocol" + "golang.org/x/tools/internal/testenv" ) type fakeClient struct { @@ -288,6 +289,7 @@ func (s *initServer) Initialize(ctx context.Context, params *protocol.ParamIniti } func TestEnvForwarding(t *testing.T) { + testenv.NeedsGo1Point(t, 13) server := &initServer{} ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() diff --git a/internal/lsp/mod/code_lens.go b/internal/lsp/mod/code_lens.go index f51c8523fc4..6e7b707ae1d 100644 --- a/internal/lsp/mod/code_lens.go +++ b/internal/lsp/mod/code_lens.go @@ -95,7 +95,7 @@ func CodeLens(ctx context.Context, snapshot source.Snapshot, uri span.URI) ([]pr if err != nil && err != source.ErrTmpModfileUnsupported { return nil, err } - if len(tidied.Errors) > 0 { + if tidied != nil && len(tidied.Errors) > 0 { codelens = append(codelens, protocol.CodeLens{ Range: rng, Command: protocol.Command{ diff --git a/internal/lsp/mod/hover.go b/internal/lsp/mod/hover.go index ad80d14a504..8401c61711b 100644 --- a/internal/lsp/mod/hover.go +++ b/internal/lsp/mod/hover.go @@ -12,6 +12,7 @@ import ( "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" ) func Hover(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, position protocol.Position) (*protocol.Hover, error) { @@ -28,15 +29,15 @@ func Hover(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, // Get the position of the cursor. pm, err := snapshot.ParseMod(ctx, fh) if err != nil { - return nil, fmt.Errorf("getting modfile handle: %w", err) + return nil, errors.Errorf("getting modfile handle: %w", err) } spn, err := pm.Mapper.PointSpan(position) if err != nil { - return nil, fmt.Errorf("computing cursor position: %w", err) + return nil, errors.Errorf("computing cursor position: %w", err) } hoverRng, err := spn.Range(pm.Mapper.Converter) if err != nil { - return nil, fmt.Errorf("computing hover range: %w", err) + return nil, errors.Errorf("computing hover range: %w", err) } // Confirm that the cursor is at the position of a require statement. diff --git a/internal/lsp/protocol/protocol.go b/internal/lsp/protocol/protocol.go index 398e6f4b2af..40bb0831bcd 100644 --- a/internal/lsp/protocol/protocol.go +++ b/internal/lsp/protocol/protocol.go @@ -12,6 +12,7 @@ import ( "golang.org/x/tools/internal/event" "golang.org/x/tools/internal/jsonrpc2" "golang.org/x/tools/internal/xcontext" + errors "golang.org/x/xerrors" ) var ( @@ -133,5 +134,5 @@ func cancelCall(ctx context.Context, conn jsonrpc2.Conn, id jsonrpc2.ID) { } func sendParseError(ctx context.Context, reply jsonrpc2.Replier, err error) error { - return reply(ctx, nil, fmt.Errorf("%w: %s", jsonrpc2.ErrParse, err)) + return reply(ctx, nil, errors.Errorf("%w: %s", jsonrpc2.ErrParse, err)) } diff --git a/internal/lsp/protocol/tsclient.go b/internal/lsp/protocol/tsclient.go index 5ae5328fbbd..251c74a1e5f 100644 --- a/internal/lsp/protocol/tsclient.go +++ b/internal/lsp/protocol/tsclient.go @@ -3,16 +3,16 @@ package protocol // Package protocol contains data types and code for LSP jsonrpcs // generated automatically from vscode-languageserver-node // commit: 399de64448129835b53c7efe8962de91681d6cde -// last fetched Tue Jul 28 2020 09:32:20 GMT-0400 (Eastern Daylight Time) +// last fetched Wed Aug 26 2020 20:34:24 GMT-0400 (Eastern Daylight Time) // Code generated (see typescript/README.md) DO NOT EDIT. import ( "context" "encoding/json" - "fmt" "golang.org/x/tools/internal/jsonrpc2" + errors "golang.org/x/xerrors" ) type Client interface { @@ -69,7 +69,7 @@ func clientDispatch(ctx context.Context, client Client, reply jsonrpc2.Replier, return true, reply(ctx, nil, err) case "workspace/workspaceFolders": // req if len(r.Params()) > 0 { - return true, reply(ctx, nil, fmt.Errorf("%w: expected no params", jsonrpc2.ErrInvalidParams)) + return true, reply(ctx, nil, errors.Errorf("%w: expected no params", jsonrpc2.ErrInvalidParams)) } resp, err := client.WorkspaceFolders(ctx) return true, reply(ctx, resp, err) diff --git a/internal/lsp/protocol/tsprotocol.go b/internal/lsp/protocol/tsprotocol.go index 1da62ed0e78..8d774a64a4b 100644 --- a/internal/lsp/protocol/tsprotocol.go +++ b/internal/lsp/protocol/tsprotocol.go @@ -1,7 +1,7 @@ // Package protocol contains data types and code for LSP jsonrpcs // generated automatically from vscode-languageserver-node // commit: 399de64448129835b53c7efe8962de91681d6cde -// last fetched Tue Jul 28 2020 09:32:20 GMT-0400 (Eastern Daylight Time) +// last fetched Wed Aug 26 2020 20:34:24 GMT-0400 (Eastern Daylight Time) package protocol // Code generated (see typescript/README.md) DO NOT EDIT. diff --git a/internal/lsp/protocol/tsserver.go b/internal/lsp/protocol/tsserver.go index 7c323c0cf41..29285e057d4 100644 --- a/internal/lsp/protocol/tsserver.go +++ b/internal/lsp/protocol/tsserver.go @@ -3,16 +3,16 @@ package protocol // Package protocol contains data types and code for LSP jsonrpcs // generated automatically from vscode-languageserver-node // commit: 399de64448129835b53c7efe8962de91681d6cde -// last fetched Tue Jul 28 2020 09:32:20 GMT-0400 (Eastern Daylight Time) +// last fetched Wed Aug 26 2020 20:34:24 GMT-0400 (Eastern Daylight Time) // Code generated (see typescript/README.md) DO NOT EDIT. import ( "context" "encoding/json" - "fmt" "golang.org/x/tools/internal/jsonrpc2" + errors "golang.org/x/xerrors" ) type Server interface { @@ -236,7 +236,7 @@ func serverDispatch(ctx context.Context, server Server, reply jsonrpc2.Replier, return true, reply(ctx, resp, err) case "shutdown": // req if len(r.Params()) > 0 { - return true, reply(ctx, nil, fmt.Errorf("%w: expected no params", jsonrpc2.ErrInvalidParams)) + return true, reply(ctx, nil, errors.Errorf("%w: expected no params", jsonrpc2.ErrInvalidParams)) } err := server.Shutdown(ctx) return true, reply(ctx, nil, err) diff --git a/internal/lsp/protocol/typescript/code.ts b/internal/lsp/protocol/typescript/code.ts index a68862f9e7a..0bf92650ec0 100644 --- a/internal/lsp/protocol/typescript/code.ts +++ b/internal/lsp/protocol/typescript/code.ts @@ -915,7 +915,7 @@ let server: side = { // commonly used output const notNil = `if len(r.Params()) > 0 { - return true, reply(ctx, nil, fmt.Errorf("%w: expected no params", jsonrpc2.ErrInvalidParams)) + return true, reply(ctx, nil, errors.Errorf("%w: expected no params", jsonrpc2.ErrInvalidParams)) }`; // Go code for notifications. Side is client or server, m is the request @@ -1078,9 +1078,9 @@ function output(side: side) { import ( "context" "encoding/json" - "fmt" "golang.org/x/tools/internal/jsonrpc2" + errors "golang.org/x/xerrors" ) `); const a = side.name[0].toUpperCase() + side.name.substring(1) diff --git a/internal/lsp/regtest/codelens_test.go b/internal/lsp/regtest/codelens_test.go index cb9443aa9e3..c6bfc10ea85 100644 --- a/internal/lsp/regtest/codelens_test.go +++ b/internal/lsp/regtest/codelens_test.go @@ -134,6 +134,7 @@ require golang.org/x/hello v1.3.3 } func TestUnusedDependenciesCodelens(t *testing.T) { + testenv.NeedsGo1Point(t, 14) const proxy = ` -- golang.org/x/hello@v1.0.0/go.mod -- module golang.org/x/hello diff --git a/internal/lsp/regtest/link_test.go b/internal/lsp/regtest/link_test.go index ff1d6cf1337..cfdeeb70b78 100644 --- a/internal/lsp/regtest/link_test.go +++ b/internal/lsp/regtest/link_test.go @@ -7,9 +7,12 @@ package regtest import ( "strings" "testing" + + "golang.org/x/tools/internal/testenv" ) func TestHoverAndDocumentLink(t *testing.T) { + testenv.NeedsGo1Point(t, 13) const program = ` -- go.mod -- module mod.test diff --git a/internal/lsp/regtest/reg_test.go b/internal/lsp/regtest/reg_test.go index 4339215be06..ced277d2404 100644 --- a/internal/lsp/regtest/reg_test.go +++ b/internal/lsp/regtest/reg_test.go @@ -14,6 +14,7 @@ import ( "time" "golang.org/x/tools/internal/lsp/cmd" + "golang.org/x/tools/internal/testenv" "golang.org/x/tools/internal/tool" ) @@ -77,7 +78,13 @@ func TestMain(m *testing.M) { code := m.Run() if err := runner.Close(); err != nil { fmt.Fprintf(os.Stderr, "closing test runner: %v\n", err) - os.Exit(1) + // Regtest cleanup is broken in go1.12 and earlier, but this is OK + // for our CI. + // + // But fail on go1.13+. + if testenv.Go1Point() >= 13 { + os.Exit(1) + } } os.Exit(code) } diff --git a/internal/lsp/regtest/wrappers.go b/internal/lsp/regtest/wrappers.go index 66e19f51fd1..b4271ec418a 100644 --- a/internal/lsp/regtest/wrappers.go +++ b/internal/lsp/regtest/wrappers.go @@ -5,12 +5,12 @@ package regtest import ( - "errors" "io" "testing" "golang.org/x/tools/internal/lsp/fake" "golang.org/x/tools/internal/lsp/protocol" + errors "golang.org/x/xerrors" ) func (e *Env) ChangeFilesOnDisk(events []fake.FileEvent) { @@ -244,7 +244,7 @@ func (e *Env) CodeLens(path string) []protocol.CodeLens { return lens } -// ReferencesAtRegexp calls textDocument/references for the given path at the +// References calls textDocument/references for the given path at the // position of the given regexp. func (e *Env) References(path string, pos fake.Pos) []protocol.Location { e.T.Helper() diff --git a/internal/lsp/server.go b/internal/lsp/server.go index 20568c9d802..52403f5f0f3 100644 --- a/internal/lsp/server.go +++ b/internal/lsp/server.go @@ -14,6 +14,7 @@ import ( "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" ) const concurrentAnalyses = 1 @@ -139,7 +140,7 @@ func (s *Server) nonstandardRequest(ctx context.Context, method string, params i } func notImplemented(method string) error { - return fmt.Errorf("%w: %q not yet implemented", jsonrpc2.ErrMethodNotFound, method) + return errors.Errorf("%w: %q not yet implemented", jsonrpc2.ErrMethodNotFound, method) } //go:generate helper/helper -d protocol/tsserver.go -o server_gen.go -u . diff --git a/internal/lsp/source/command.go b/internal/lsp/source/command.go index 0de8cb57e23..b927aa067a1 100644 --- a/internal/lsp/source/command.go +++ b/internal/lsp/source/command.go @@ -16,6 +16,7 @@ import ( "golang.org/x/tools/internal/lsp/analysis/undeclaredname" "golang.org/x/tools/internal/lsp/protocol" "golang.org/x/tools/internal/span" + errors "golang.org/x/xerrors" ) type Command struct { @@ -209,7 +210,7 @@ func (c *Command) SuggestedFix(ctx context.Context, snapshot Snapshot, fh Versio func getAllSuggestedFixInputs(ctx context.Context, snapshot Snapshot, fh FileHandle, pRng protocol.Range) (*token.FileSet, span.Range, []byte, *ast.File, *protocol.ColumnMapper, *types.Package, *types.Info, error) { pkg, pgf, err := getParsedFile(ctx, snapshot, fh, NarrowestPackage) if err != nil { - return nil, span.Range{}, nil, nil, nil, nil, nil, fmt.Errorf("getting file for Identifier: %w", err) + return nil, span.Range{}, nil, nil, nil, nil, nil, errors.Errorf("getting file for Identifier: %w", err) } spn, err := pgf.Mapper.RangeSpan(pRng) if err != nil { diff --git a/internal/lsp/source/completion.go b/internal/lsp/source/completion.go index 43eb01c0011..e539461d18f 100644 --- a/internal/lsp/source/completion.go +++ b/internal/lsp/source/completion.go @@ -6,7 +6,6 @@ package source import ( "context" - "fmt" "go/ast" "go/constant" "go/scanner" @@ -471,7 +470,7 @@ func Completion(ctx context.Context, snapshot Snapshot, fh FileHandle, protoPos pkg, pgf, err := getParsedFile(ctx, snapshot, fh, NarrowestPackage) if err != nil { - return nil, nil, fmt.Errorf("getting file for Completion: %w", err) + return nil, nil, errors.Errorf("getting file for Completion: %w", err) } spn, err := pgf.Mapper.PointSpan(protoPos) if err != nil { diff --git a/internal/lsp/source/highlight.go b/internal/lsp/source/highlight.go index e4228a29989..f4f7793a404 100644 --- a/internal/lsp/source/highlight.go +++ b/internal/lsp/source/highlight.go @@ -24,7 +24,7 @@ func Highlight(ctx context.Context, snapshot Snapshot, fh FileHandle, pos protoc pkg, pgf, err := getParsedFile(ctx, snapshot, fh, WidestPackage) if err != nil { - return nil, fmt.Errorf("getting file for Highlight: %w", err) + return nil, errors.Errorf("getting file for Highlight: %w", err) } spn, err := pgf.Mapper.PointSpan(pos) if err != nil { diff --git a/internal/lsp/source/implementation.go b/internal/lsp/source/implementation.go index bd5af1f2e10..feaa8487d56 100644 --- a/internal/lsp/source/implementation.go +++ b/internal/lsp/source/implementation.go @@ -15,6 +15,7 @@ import ( "golang.org/x/tools/internal/event" "golang.org/x/tools/internal/lsp/protocol" + "golang.org/x/xerrors" ) func Implementation(ctx context.Context, snapshot Snapshot, f FileHandle, pp protocol.Position) ([]protocol.Location, error) { @@ -239,7 +240,7 @@ func qualifiedObjsAtProtocolPos(ctx context.Context, s Snapshot, fh FileHandle, } else { obj := searchpkg.GetTypesInfo().ObjectOf(leaf) if obj == nil { - return nil, fmt.Errorf("%w for %q", errNoObjectFound, leaf.Name) + return nil, xerrors.Errorf("%w for %q", errNoObjectFound, leaf.Name) } objs = append(objs, obj) } @@ -247,7 +248,7 @@ func qualifiedObjsAtProtocolPos(ctx context.Context, s Snapshot, fh FileHandle, // Look up the implicit *types.PkgName. obj := searchpkg.GetTypesInfo().Implicits[leaf] if obj == nil { - return nil, fmt.Errorf("%w for import %q", errNoObjectFound, importPath(leaf)) + return nil, xerrors.Errorf("%w for import %q", errNoObjectFound, importPath(leaf)) } objs = append(objs, obj) } @@ -265,7 +266,7 @@ func qualifiedObjsAtProtocolPos(ctx context.Context, s Snapshot, fh FileHandle, addPkg(searchpkg) for _, obj := range objs { if obj.Parent() == types.Universe { - return nil, fmt.Errorf("%w %q", errBuiltin, obj.Name()) + return nil, xerrors.Errorf("%q: %w", obj.Name(), errBuiltin) } pkg, ok := pkgs[obj.Pkg()] if !ok { diff --git a/internal/lsp/source/signature_help.go b/internal/lsp/source/signature_help.go index d8a56d48b30..10aee4ffd97 100644 --- a/internal/lsp/source/signature_help.go +++ b/internal/lsp/source/signature_help.go @@ -6,7 +6,6 @@ package source import ( "context" - "fmt" "go/ast" "go/doc" "go/token" @@ -24,7 +23,7 @@ func SignatureHelp(ctx context.Context, snapshot Snapshot, fh FileHandle, pos pr pkg, pgf, err := getParsedFile(ctx, snapshot, fh, NarrowestPackage) if err != nil { - return nil, 0, fmt.Errorf("getting file for SignatureHelp: %w", err) + return nil, 0, errors.Errorf("getting file for SignatureHelp: %w", err) } spn, err := pgf.Mapper.PointSpan(pos) if err != nil { diff --git a/internal/lsp/source/symbols.go b/internal/lsp/source/symbols.go index b46d813b7e7..883ef5d33b5 100644 --- a/internal/lsp/source/symbols.go +++ b/internal/lsp/source/symbols.go @@ -12,6 +12,7 @@ import ( "golang.org/x/tools/internal/event" "golang.org/x/tools/internal/lsp/protocol" + errors "golang.org/x/xerrors" ) func DocumentSymbols(ctx context.Context, snapshot Snapshot, fh FileHandle) ([]protocol.DocumentSymbol, error) { @@ -20,7 +21,7 @@ func DocumentSymbols(ctx context.Context, snapshot Snapshot, fh FileHandle) ([]p pkg, pgf, err := getParsedFile(ctx, snapshot, fh, NarrowestPackage) if err != nil { - return nil, fmt.Errorf("getting file for DocumentSymbols: %w", err) + return nil, errors.Errorf("getting file for DocumentSymbols: %w", err) } info := pkg.GetTypesInfo() diff --git a/internal/lsp/testdata/lsp/primarymod/rename/b/b.go.golden b/internal/lsp/testdata/lsp/primarymod/rename/b/b.go.golden index 5c2c15852ef..9cdc5677fd4 100644 --- a/internal/lsp/testdata/lsp/primarymod/rename/b/b.go.golden +++ b/internal/lsp/testdata/lsp/primarymod/rename/b/b.go.golden @@ -75,4 +75,4 @@ Hello description func Hello() {} //@rename("Hello", "Goodbye") -- uint-rename -- -builtin object "int" +"int": builtin object diff --git a/internal/lsp/text_synchronization.go b/internal/lsp/text_synchronization.go index 29e4ca98f8f..5f8f1aa3b60 100644 --- a/internal/lsp/text_synchronization.go +++ b/internal/lsp/text_synchronization.go @@ -320,7 +320,7 @@ func (s *Server) wasFirstChange(uri span.URI) bool { func (s *Server) changedText(ctx context.Context, uri span.URI, changes []protocol.TextDocumentContentChangeEvent) ([]byte, error) { if len(changes) == 0 { - return nil, fmt.Errorf("%w: no content changes provided", jsonrpc2.ErrInternal) + return nil, errors.Errorf("%w: no content changes provided", jsonrpc2.ErrInternal) } // Check if the client sent the full content of the file. @@ -338,7 +338,7 @@ func (s *Server) applyIncrementalChanges(ctx context.Context, uri span.URI, chan } content, err := fh.Read() if err != nil { - return nil, fmt.Errorf("%w: file not found (%v)", jsonrpc2.ErrInternal, err) + return nil, errors.Errorf("%w: file not found (%v)", jsonrpc2.ErrInternal, err) } for _, change := range changes { // Make sure to update column mapper along with the content. @@ -349,18 +349,18 @@ func (s *Server) applyIncrementalChanges(ctx context.Context, uri span.URI, chan Content: content, } if change.Range == nil { - return nil, fmt.Errorf("%w: unexpected nil range for change", jsonrpc2.ErrInternal) + return nil, errors.Errorf("%w: unexpected nil range for change", jsonrpc2.ErrInternal) } spn, err := m.RangeSpan(*change.Range) if err != nil { return nil, err } if !spn.HasOffset() { - return nil, fmt.Errorf("%w: invalid range for content change", jsonrpc2.ErrInternal) + return nil, errors.Errorf("%w: invalid range for content change", jsonrpc2.ErrInternal) } start, end := spn.Start().Offset(), spn.End().Offset() if end < start { - return nil, fmt.Errorf("%w: invalid range for content change", jsonrpc2.ErrInternal) + return nil, errors.Errorf("%w: invalid range for content change", jsonrpc2.ErrInternal) } var buf bytes.Buffer buf.Write(content[:start])