internal/lsp: use x/xerrors to create new errors

This relates to https://github.com/golang/go/issues/31374 and should switch all instances within `gopls` to use `x/errors` instead of `fmt` to create new errors.

Change-Id: I18339b75d12418d852e0dcc2ba0ed6c2970783b3
GitHub-Last-Rev: f4a55d9b79e7458ef1f1e06cb5eabbabd884f321
GitHub-Pull-Request: golang/tools#108
Reviewed-on: https://go-review.googlesource.com/c/tools/+/179880
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
Jan Steinke 2019-08-06 19:13:11 +00:00 committed by Rebecca Stambler
parent 249e2b9b6d
commit be5259f298
32 changed files with 140 additions and 126 deletions

1
go.mod
View File

@ -5,4 +5,5 @@ go 1.11
require (
golang.org/x/net v0.0.0-20190620200207-3b0461eec859
golang.org/x/sync v0.0.0-20190423024810-112230192c58
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7
)

2
go.sum
View File

@ -5,3 +5,5 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEha
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@ -6,7 +6,6 @@ package cache
import (
"context"
"fmt"
"go/ast"
"go/scanner"
"go/token"
@ -20,6 +19,7 @@ import (
"golang.org/x/tools/internal/lsp/telemetry/log"
"golang.org/x/tools/internal/lsp/telemetry/trace"
"golang.org/x/tools/internal/span"
errors "golang.org/x/xerrors"
)
type importer struct {
@ -40,7 +40,7 @@ func (imp *importer) Import(pkgPath string) (*types.Package, error) {
ctx := imp.ctx
id, ok := imp.view.mcache.ids[packagePath(pkgPath)]
if !ok {
return nil, fmt.Errorf("no known ID for %s", pkgPath)
return nil, errors.Errorf("no known ID for %s", pkgPath)
}
pkg, err := imp.getPkg(ctx, id)
if err != nil {
@ -51,7 +51,7 @@ func (imp *importer) Import(pkgPath string) (*types.Package, error) {
func (imp *importer) getPkg(ctx context.Context, id packageID) (*pkg, error) {
if _, ok := imp.seen[id]; ok {
return nil, fmt.Errorf("circular import detected")
return nil, errors.Errorf("circular import detected")
}
imp.view.pcache.mu.Lock()
e, ok := imp.view.pcache.packages[id]
@ -99,7 +99,7 @@ func (imp *importer) typeCheck(ctx context.Context, id packageID) (*pkg, error)
defer done()
meta, ok := imp.view.mcache.packages[id]
if !ok {
return nil, fmt.Errorf("no metadata for %v", id)
return nil, errors.Errorf("no metadata for %v", id)
}
pkg := &pkg{
id: meta.id,
@ -123,9 +123,9 @@ func (imp *importer) typeCheck(ctx context.Context, id packageID) (*pkg, error)
mode = source.ParseExported
}
var (
files = make([]*ast.File, len(meta.files))
errors = make([]error, len(meta.files))
wg sync.WaitGroup
files = make([]*ast.File, len(meta.files))
parseErrors = make([]error, len(meta.files))
wg sync.WaitGroup
)
for _, filename := range meta.files {
uri := span.FileURI(filename)
@ -141,7 +141,7 @@ func (imp *importer) typeCheck(ctx context.Context, id packageID) (*pkg, error)
go func(i int, ph source.ParseGoHandle) {
defer wg.Done()
files[i], errors[i] = ph.Parse(ctx)
files[i], parseErrors[i] = ph.Parse(ctx)
}(i, ph)
}
wg.Wait()
@ -153,7 +153,7 @@ func (imp *importer) typeCheck(ctx context.Context, id packageID) (*pkg, error)
i++
}
}
for _, err := range errors {
for _, err := range parseErrors {
if err == context.Canceled {
return nil, err
}
@ -166,7 +166,7 @@ func (imp *importer) typeCheck(ctx context.Context, id packageID) (*pkg, error)
if meta.pkgPath == "unsafe" {
pkg.types = types.Unsafe
} else if len(files) == 0 { // not the unsafe package, no parsed files
return nil, fmt.Errorf("no parsed files for package %s", pkg.pkgPath)
return nil, errors.Errorf("no parsed files for package %s", pkg.pkgPath)
} else {
pkg.types = types.NewPackage(string(meta.pkgPath), meta.name)
}
@ -209,14 +209,14 @@ func (imp *importer) cachePackage(ctx context.Context, pkg *pkg, meta *metadata,
uri := ph.File().Identity().URI
f, err := imp.view.getFile(ctx, uri)
if err != nil {
return fmt.Errorf("no such file %s: %v", uri, err)
return errors.Errorf("no such file %s: %v", uri, err)
}
gof, ok := f.(*goFile)
if !ok {
return fmt.Errorf("non Go file %s", uri)
return errors.Errorf("non Go file %s", uri)
}
if err := imp.cachePerFile(gof, ph, pkg); err != nil {
return fmt.Errorf("failed to cache file %s: %v", gof.URI(), err)
return errors.Errorf("failed to cache file %s: %v", gof.URI(), err)
}
}
@ -246,7 +246,7 @@ func (imp *importer) cachePerFile(gof *goFile, ph source.ParseGoHandle, p *pkg)
file, err := ph.Parse(imp.ctx)
if file == nil {
return fmt.Errorf("no AST for %s: %v", ph.File().Identity().URI, err)
return errors.Errorf("no AST for %s: %v", ph.File().Identity().URI, err)
}
gof.imports = file.Imports
return nil

View File

@ -6,7 +6,6 @@ package cache
import (
"context"
"fmt"
"go/ast"
"go/token"
"sync"
@ -15,6 +14,7 @@ import (
"golang.org/x/tools/internal/lsp/telemetry"
"golang.org/x/tools/internal/lsp/telemetry/log"
"golang.org/x/tools/internal/span"
errors "golang.org/x/xerrors"
)
// goFile holds all of the information we know about a Go file.
@ -55,7 +55,7 @@ func (f *goFile) GetToken(ctx context.Context) (*token.File, error) {
}
tok := f.view.session.cache.fset.File(file.Pos())
if tok == nil {
return nil, fmt.Errorf("no token.File for %s", f.URI())
return nil, errors.Errorf("no token.File for %s", f.URI())
}
return tok, nil
}
@ -67,7 +67,7 @@ func (f *goFile) GetAST(ctx context.Context, mode source.ParseMode) (*ast.File,
if f.isDirty(ctx) || f.wrongParseMode(ctx, mode) {
if _, err := f.view.loadParseTypecheck(ctx, f); err != nil {
return nil, fmt.Errorf("GetAST: unable to check package for %s: %v", f.URI(), err)
return nil, errors.Errorf("GetAST: unable to check package for %s: %v", f.URI(), err)
}
}
fh := f.Handle(ctx)

View File

@ -15,6 +15,7 @@ import (
"golang.org/x/tools/internal/lsp/telemetry/tag"
"golang.org/x/tools/internal/lsp/telemetry/trace"
"golang.org/x/tools/internal/span"
errors "golang.org/x/xerrors"
)
func (v *view) loadParseTypecheck(ctx context.Context, f *goFile) ([]packages.Error, error) {
@ -55,11 +56,11 @@ func (v *view) loadParseTypecheck(ctx context.Context, f *goFile) ([]packages.Er
return nil, err
}
if pkg == nil || pkg.IsIllTyped() {
return nil, fmt.Errorf("loadParseTypecheck: %s is ill typed", m.pkgPath)
return nil, errors.Errorf("loadParseTypecheck: %s is ill typed", m.pkgPath)
}
}
if len(f.pkgs) == 0 {
return nil, fmt.Errorf("no packages found for %s", f.URI())
return nil, errors.Errorf("no packages found for %s", f.URI())
}
return nil, nil
}
@ -93,7 +94,7 @@ func (v *view) checkMetadata(ctx context.Context, f *goFile) (map[packageID]*met
pkgs, err := packages.Load(v.Config(ctx), fmt.Sprintf("file=%s", f.filename()))
if len(pkgs) == 0 {
if err == nil {
err = fmt.Errorf("go/packages.Load: no packages found for %s", f.filename())
err = errors.Errorf("go/packages.Load: no packages found for %s", f.filename())
}
// Return this error as a diagnostic to the user.
return nil, []packages.Error{
@ -112,7 +113,7 @@ func (v *view) checkMetadata(ctx context.Context, f *goFile) (map[packageID]*met
// If the package comes back with errors from `go list`,
// don't bother type-checking it.
if len(pkg.Errors) > 0 {
return nil, pkg.Errors, fmt.Errorf("package %s has errors, skipping type-checking", pkg.PkgPath)
return nil, pkg.Errors, errors.Errorf("package %s has errors, skipping type-checking", pkg.PkgPath)
}
// Build the import graph for this package.
if err := v.link(ctx, packagePath(pkg.PkgPath), pkg, nil, missingImports); err != nil {
@ -132,7 +133,7 @@ func validateMetadata(ctx context.Context, missingImports map[packagePath]struct
// If `go list` failed to get data for the file in question (this should never happen).
if len(f.meta) == 0 {
return nil, fmt.Errorf("loadParseTypecheck: no metadata found for %v", f.filename())
return nil, errors.Errorf("loadParseTypecheck: no metadata found for %v", f.filename())
}
// If we have already seen these missing imports before, and we have type information,
@ -254,7 +255,7 @@ func (v *view) link(ctx context.Context, pkgPath packagePath, pkg *packages.Pack
for importPath, importPkg := range pkg.Imports {
importPkgPath := packagePath(importPath)
if importPkgPath == pkgPath {
return fmt.Errorf("cycle detected in %s", importPath)
return errors.Errorf("cycle detected in %s", importPath)
}
// Don't remember any imports with significant errors.
if importPkgPath != "unsafe" && len(pkg.CompiledGoFiles) == 0 {

View File

@ -6,8 +6,9 @@ package cache
import (
"context"
"fmt"
"go/token"
errors "golang.org/x/xerrors"
)
// modFile holds all of the information we know about a mod file.
@ -16,7 +17,7 @@ type modFile struct {
}
func (*modFile) GetToken(context.Context) (*token.File, error) {
return nil, fmt.Errorf("GetToken: not implemented")
return nil, errors.Errorf("GetToken: not implemented")
}
func (*modFile) setContent(content []byte) {}

View File

@ -6,7 +6,6 @@ package cache
import (
"context"
"fmt"
"go/ast"
"go/parser"
"go/scanner"
@ -16,6 +15,7 @@ import (
"golang.org/x/tools/internal/lsp/telemetry"
"golang.org/x/tools/internal/lsp/telemetry/trace"
"golang.org/x/tools/internal/memoize"
errors "golang.org/x/xerrors"
)
// Limits the number of parallel parser calls per process.
@ -154,7 +154,7 @@ func fix(ctx context.Context, file *ast.File, tok *token.File, src []byte) error
case *ast.BadStmt:
err = parseDeferOrGoStmt(n, parent, tok, src) // don't shadow err
if err != nil {
err = fmt.Errorf("unable to parse defer or go from *ast.BadStmt: %v", err)
err = errors.Errorf("unable to parse defer or go from *ast.BadStmt: %v", err)
}
return false
default:
@ -182,7 +182,7 @@ func parseDeferOrGoStmt(bad *ast.BadStmt, parent ast.Node, tok *token.File, src
var lit string
for {
if tkn == token.EOF {
return fmt.Errorf("reached the end of the file")
return errors.Errorf("reached the end of the file")
}
if pos >= bad.From {
break
@ -200,7 +200,7 @@ func parseDeferOrGoStmt(bad *ast.BadStmt, parent ast.Node, tok *token.File, src
Go: pos,
}
default:
return fmt.Errorf("no defer or go statement found")
return errors.Errorf("no defer or go statement found")
}
// The expression after the "defer" or "go" starts at this position.
@ -225,15 +225,15 @@ FindTo:
to = curr
}
if !from.IsValid() || tok.Offset(from) >= len(src) {
return fmt.Errorf("invalid from position")
return errors.Errorf("invalid from position")
}
if !to.IsValid() || tok.Offset(to)+1 >= len(src) {
return fmt.Errorf("invalid to position")
return errors.Errorf("invalid to position")
}
exprstr := string(src[tok.Offset(from) : tok.Offset(to)+1])
expr, err := parser.ParseExpr(exprstr)
if expr == nil {
return fmt.Errorf("no expr in %s: %v", exprstr, err)
return errors.Errorf("no expr in %s: %v", exprstr, err)
}
// parser.ParseExpr returns undefined positions.
// Adjust them for the current file.

View File

@ -6,7 +6,6 @@ package cache
import (
"context"
"fmt"
"os"
"sort"
"strconv"
@ -21,6 +20,7 @@ import (
"golang.org/x/tools/internal/lsp/telemetry/trace"
"golang.org/x/tools/internal/span"
"golang.org/x/tools/internal/xcontext"
errors "golang.org/x/xerrors"
)
type session struct {
@ -178,7 +178,7 @@ func (s *session) removeView(ctx context.Context, view *view) error {
return nil
}
}
return fmt.Errorf("view %s for %v not found", view.Name(), view.Folder())
return errors.Errorf("view %s for %v not found", view.Name(), view.Folder())
}
// TODO: Propagate the language ID through to the view.

View File

@ -6,8 +6,9 @@ package cache
import (
"context"
"fmt"
"go/token"
errors "golang.org/x/xerrors"
)
// sumFile holds all of the information we know about a sum file.
@ -16,7 +17,7 @@ type sumFile struct {
}
func (*sumFile) GetToken(context.Context) (*token.File, error) {
return nil, fmt.Errorf("GetToken: not implemented")
return nil, errors.Errorf("GetToken: not implemented")
}
func (*sumFile) setContent(content []byte) {}

View File

@ -6,11 +6,11 @@ package cache
import (
"context"
"fmt"
"go/token"
"golang.org/x/tools/internal/lsp/source"
"golang.org/x/tools/internal/memoize"
errors "golang.org/x/xerrors"
)
type tokenKey struct {
@ -87,7 +87,7 @@ func tokenFile(ctx context.Context, c *cache, fh source.FileHandle) (*token.File
}
tok := c.FileSet().AddFile(fh.Identity().URI.Filename(), -1, len(buf))
if tok == nil {
return nil, fmt.Errorf("no token.File for %s", fh.Identity().URI)
return nil, errors.Errorf("no token.File for %s", fh.Identity().URI)
}
tok.SetLinesForContent(buf)
return tok, nil

View File

@ -11,6 +11,7 @@ import (
"time"
"golang.org/x/tools/internal/span"
errors "golang.org/x/xerrors"
)
// check implements the check verb for gopls.
@ -60,14 +61,14 @@ func (c *check) Run(ctx context.Context, args ...string) error {
select {
case <-file.hasDiagnostics:
case <-time.After(30 * time.Second):
return fmt.Errorf("timed out waiting for results from %v", file.uri)
return errors.Errorf("timed out waiting for results from %v", file.uri)
}
file.diagnosticsMu.Lock()
defer file.diagnosticsMu.Unlock()
for _, d := range file.diagnostics {
spn, err := file.mapper.RangeSpan(d.Range)
if err != nil {
return fmt.Errorf("Could not convert position %v for %q", d.Range, d.Message)
return errors.Errorf("Could not convert position %v for %q", d.Range, d.Message)
}
fmt.Printf("%v: %v\n", spn, d.Message)
}

View File

@ -28,6 +28,7 @@ import (
"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
@ -335,7 +336,7 @@ func (c *cmdClient) getFile(ctx context.Context, uri span.URI) *cmdFile {
fname := uri.Filename()
content, err := ioutil.ReadFile(fname)
if err != nil {
file.err = fmt.Errorf("getFile %v: %v", uri, err)
file.err = errors.Errorf("getFile: %v: %v", uri, err)
return file
}
f := c.fset.AddFile(fname, -1, len(content))
@ -366,7 +367,7 @@ func (c *connection) AddFile(ctx context.Context, uri span.URI) *cmdFile {
p.TextDocument.Text = string(file.mapper.Content)
p.TextDocument.LanguageID = source.DetectLanguage("", file.uri.Filename()).String()
if err := c.Server.DidOpen(ctx, p); err != nil {
file.err = fmt.Errorf("%v: %v", uri, err)
file.err = errors.Errorf("%v: %v", uri, err)
}
return file
}

View File

@ -16,6 +16,7 @@ import (
"golang.org/x/tools/internal/lsp/protocol"
"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.
@ -79,26 +80,26 @@ func (d *definition) Run(ctx context.Context, args ...string) error {
}
locs, err := conn.Definition(ctx, &p)
if err != nil {
return fmt.Errorf("%v: %v", from, err)
return errors.Errorf("%v: %v", from, err)
}
if len(locs) == 0 {
return fmt.Errorf("%v: not an identifier", from)
return errors.Errorf("%v: not an identifier", from)
}
hover, err := conn.Hover(ctx, &p)
if err != nil {
return fmt.Errorf("%v: %v", from, err)
return errors.Errorf("%v: %v", from, err)
}
if hover == nil {
return fmt.Errorf("%v: not an identifier", from)
return errors.Errorf("%v: not an identifier", from)
}
file = conn.AddFile(ctx, span.NewURI(locs[0].URI))
if file.err != nil {
return fmt.Errorf("%v: %v", from, file.err)
return errors.Errorf("%v: %v", from, file.err)
}
definition, err := file.mapper.Span(locs[0])
if err != nil {
return fmt.Errorf("%v: %v", from, err)
return errors.Errorf("%v: %v", from, err)
}
description := strings.TrimSpace(hover.Contents.Value)
var result interface{}
@ -115,7 +116,7 @@ func (d *definition) Run(ctx context.Context, args ...string) error {
Desc: description,
}
default:
return fmt.Errorf("unknown emulation for definition: %s", d.query.Emulate)
return errors.Errorf("unknown emulation for definition: %s", d.query.Emulate)
}
if err != nil {
return err
@ -131,7 +132,7 @@ func (d *definition) Run(ctx context.Context, args ...string) error {
case *guru.Definition:
fmt.Printf("%s: defined here as %s", d.ObjPos, d.Desc)
default:
return fmt.Errorf("no printer for type %T", result)
return errors.Errorf("no printer for type %T", result)
}
return nil
}

View File

@ -16,6 +16,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"
)
// format implements the format verb for gopls.
@ -68,18 +69,18 @@ func (f *format) Run(ctx context.Context, args ...string) error {
return err
}
if loc.Range.Start != loc.Range.End {
return fmt.Errorf("only full file formatting supported")
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 fmt.Errorf("%v: %v", spn, err)
return errors.Errorf("%v: %v", spn, err)
}
sedits, err := lsp.FromProtocolEdits(file.mapper, edits)
if err != nil {
return fmt.Errorf("%v: %v", spn, err)
return errors.Errorf("%v: %v", spn, err)
}
ops := source.EditsToDiff(sedits)
lines := diff.SplitLines(string(file.mapper.Content))

View File

@ -24,6 +24,7 @@ import (
"golang.org/x/tools/internal/lsp/telemetry/tag"
"golang.org/x/tools/internal/lsp/telemetry/trace"
"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
@ -68,7 +69,7 @@ func (s *Serve) Run(ctx context.Context, args ...string) error {
}
f, err := os.Create(filename)
if err != nil {
return fmt.Errorf("Unable to create log file: %v", err)
return errors.Errorf("Unable to create log file: %v", err)
}
defer f.Close()
log.SetOutput(io.MultiWriter(os.Stderr, f))

View File

@ -15,6 +15,7 @@ import (
"golang.org/x/tools/internal/lsp/telemetry"
"golang.org/x/tools/internal/lsp/telemetry/log"
"golang.org/x/tools/internal/span"
errors "golang.org/x/xerrors"
)
func (s *Server) codeAction(ctx context.Context, params *protocol.CodeActionParams) ([]protocol.CodeAction, error) {
@ -44,7 +45,7 @@ func (s *Server) codeAction(ctx context.Context, params *protocol.CodeActionPara
}
}
if len(wanted) == 0 {
return nil, fmt.Errorf("no supported code action to execute for %s, wanted %v", uri, params.Context.Only)
return nil, errors.Errorf("no supported code action to execute for %s, wanted %v", uri, params.Context.Only)
}
spn, err := m.RangeSpan(params.Range)

View File

@ -18,6 +18,7 @@ import (
"golang.org/x/tools/internal/lsp/telemetry/log"
"golang.org/x/tools/internal/lsp/telemetry/tag"
"golang.org/x/tools/internal/span"
errors "golang.org/x/xerrors"
)
func (s *Server) initialize(ctx context.Context, params *protocol.InitializeParams) (*protocol.InitializeResult, error) {
@ -64,7 +65,7 @@ func (s *Server) initialize(ctx context.Context, params *protocol.InitializePara
// no folders and no root, single file mode
//TODO(iancottrell): not sure how to do single file mode yet
//issue: golang.org/issue/31168
return nil, fmt.Errorf("single file mode not supported yet")
return nil, errors.Errorf("single file mode not supported yet")
}
}
@ -191,13 +192,13 @@ func (s *Server) processConfig(ctx context.Context, view source.View, config int
}
c, ok := config.(map[string]interface{})
if !ok {
return fmt.Errorf("invalid config gopls type %T", config)
return errors.Errorf("invalid config gopls type %T", config)
}
// Get the environment for the go/packages config.
if env := c["env"]; env != nil {
menv, ok := env.(map[string]interface{})
if !ok {
return fmt.Errorf("invalid config gopls.env type %T", env)
return errors.Errorf("invalid config gopls.env type %T", env)
}
env := view.Env()
for k, v := range menv {
@ -209,7 +210,7 @@ func (s *Server) processConfig(ctx context.Context, view source.View, config int
if buildFlags := c["buildFlags"]; buildFlags != nil {
iflags, ok := buildFlags.([]interface{})
if !ok {
return fmt.Errorf("invalid config gopls.buildFlags type %T", buildFlags)
return errors.Errorf("invalid config gopls.buildFlags type %T", buildFlags)
}
flags := make([]string, 0, len(iflags))
for _, flag := range iflags {

View File

@ -6,7 +6,6 @@ package lsp
import (
"context"
"fmt"
"go/ast"
"go/token"
"regexp"
@ -18,6 +17,7 @@ import (
"golang.org/x/tools/internal/lsp/telemetry/log"
"golang.org/x/tools/internal/lsp/telemetry/tag"
"golang.org/x/tools/internal/span"
errors "golang.org/x/xerrors"
)
func (s *Server) documentLink(ctx context.Context, params *protocol.DocumentLinkParams) ([]protocol.DocumentLink, error) {
@ -82,7 +82,7 @@ func findLinksInString(src string, pos token.Pos, view source.View, mapper *prot
var links []protocol.DocumentLink
re, err := getURLRegexp()
if err != nil {
return nil, fmt.Errorf("cannot create regexp for links: %s", err.Error())
return nil, errors.Errorf("cannot create regexp for links: %s", err.Error())
}
for _, urlIndex := range re.FindAllIndex([]byte(src), -1) {
start := urlIndex[0]

View File

@ -7,10 +7,10 @@
package protocol
import (
"fmt"
"go/token"
"golang.org/x/tools/internal/span"
errors "golang.org/x/xerrors"
)
type ColumnMapper struct {
@ -47,7 +47,7 @@ func (m *ColumnMapper) Location(s span.Span) (Location, error) {
func (m *ColumnMapper) Range(s span.Span) (Range, error) {
if span.CompareURI(m.URI, s.URI()) != 0 {
return Range{}, fmt.Errorf("column mapper is for file %q instead of %q", m.URI, s.URI())
return Range{}, errors.Errorf("column mapper is for file %q instead of %q", m.URI, s.URI())
}
s, err := s.WithAll(m.Converter)
if err != nil {

View File

@ -20,6 +20,7 @@ import (
"golang.org/x/sync/errgroup"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/internal/lsp/telemetry/trace"
errors "golang.org/x/xerrors"
)
func analyze(ctx context.Context, v View, pkgs []Package, analyzers []*analysis.Analyzer) ([]*Action, error) {
@ -119,7 +120,7 @@ func (act *Action) execOnce(ctx context.Context, fset *token.FileSet) error {
}
if failed != nil {
sort.Strings(failed)
act.err = fmt.Errorf("failed prerequisites: %s", strings.Join(failed, ", "))
act.err = errors.Errorf("failed prerequisites: %s", strings.Join(failed, ", "))
return act.err
}
@ -163,12 +164,12 @@ func (act *Action) execOnce(ctx context.Context, fset *token.FileSet) error {
act.pass = pass
if act.Pkg.IsIllTyped() && !pass.Analyzer.RunDespiteErrors {
act.err = fmt.Errorf("analysis skipped due to errors in package: %v", act.Pkg.GetErrors())
act.err = errors.Errorf("analysis skipped due to errors in package: %v", act.Pkg.GetErrors())
} else {
act.result, act.err = pass.Analyzer.Run(pass)
if act.err == nil {
if got, want := reflect.TypeOf(act.result), pass.Analyzer.ResultType; got != want {
act.err = fmt.Errorf(
act.err = errors.Errorf(
"internal error: on package %s, analyzer %s returned a result of type %v, but declared ResultType %v",
pass.Pkg.Path(), pass.Analyzer, got, want)
}

View File

@ -6,7 +6,6 @@ package source
import (
"context"
"fmt"
"go/ast"
"go/token"
"go/types"
@ -16,6 +15,7 @@ import (
"golang.org/x/tools/internal/lsp/snippet"
"golang.org/x/tools/internal/lsp/telemetry/trace"
"golang.org/x/tools/internal/span"
errors "golang.org/x/xerrors"
)
type CompletionItem struct {
@ -212,7 +212,7 @@ func (c *completer) setSurrounding(ident *ast.Ident) {
// members for more candidates.
func (c *completer) found(obj types.Object, score float64) error {
if obj.Pkg() != nil && obj.Pkg() != c.types && !obj.Exported() {
return fmt.Errorf("%s is inaccessible from %s", obj.Name(), c.types.Path())
return errors.Errorf("%s is inaccessible from %s", obj.Name(), c.types.Path())
}
if c.inDeepCompletion() {
@ -287,14 +287,14 @@ func Completion(ctx context.Context, view View, f GoFile, pos token.Pos, opts Co
}
pkg := f.GetPackage(ctx)
if pkg == nil || pkg.IsIllTyped() {
return nil, nil, fmt.Errorf("package for %s is ill typed", f.URI())
return nil, nil, errors.Errorf("package for %s is ill typed", f.URI())
}
// Completion is based on what precedes the cursor.
// Find the path to the position before pos.
path, _ := astutil.PathEnclosingInterval(file, pos-1, pos-1)
if path == nil {
return nil, nil, fmt.Errorf("cannot find node enclosing position")
return nil, nil, errors.Errorf("cannot find node enclosing position")
}
// Skip completion inside comments.
for _, g := range file.Comments {
@ -358,7 +358,7 @@ func Completion(ctx context.Context, view View, f GoFile, pos token.Pos, opts Co
qual := types.RelativeTo(pkg.GetTypes())
of += ", of " + types.ObjectString(obj, qual)
}
return nil, nil, fmt.Errorf("this is a definition%s", of)
return nil, nil, errors.Errorf("this is a definition%s", of)
}
}
if err := c.lexical(); err != nil {
@ -423,7 +423,7 @@ func (c *completer) selector(sel *ast.SelectorExpr) error {
// Invariant: sel is a true selector.
tv, ok := c.info.Types[sel.X]
if !ok {
return fmt.Errorf("cannot resolve %s", sel.X)
return errors.Errorf("cannot resolve %s", sel.X)
}
return c.methodsAndFields(tv.Type, tv.Addressable())

View File

@ -8,7 +8,6 @@ package source
import (
"bytes"
"context"
"fmt"
"go/format"
"golang.org/x/tools/go/ast/astutil"
@ -18,6 +17,7 @@ import (
"golang.org/x/tools/internal/lsp/telemetry/log"
"golang.org/x/tools/internal/lsp/telemetry/trace"
"golang.org/x/tools/internal/span"
errors "golang.org/x/xerrors"
)
// Format formats a file with a given range.
@ -43,7 +43,7 @@ func Format(ctx context.Context, f GoFile, rng span.Range) ([]TextEdit, error) {
}
path, exact := astutil.PathEnclosingInterval(file, rng.Start, rng.End)
if !exact || len(path) == 0 {
return nil, fmt.Errorf("no exact AST node matching the specified range")
return nil, errors.Errorf("no exact AST node matching the specified range")
}
node := path[0]
@ -80,10 +80,10 @@ func Imports(ctx context.Context, view View, f GoFile, rng span.Range) ([]TextEd
}
pkg := f.GetPackage(ctx)
if pkg == nil || pkg.IsIllTyped() {
return nil, fmt.Errorf("no package for file %s", f.URI())
return nil, errors.Errorf("no package for file %s", f.URI())
}
if hasListErrors(pkg.GetErrors()) {
return nil, fmt.Errorf("%s has list errors, not running goimports", f.URI())
return nil, errors.Errorf("%s has list errors, not running goimports", f.URI())
}
options := &imports.Options{
@ -125,10 +125,10 @@ func AllImportsFixes(ctx context.Context, view View, f GoFile, rng span.Range) (
}
pkg := f.GetPackage(ctx)
if pkg == nil || pkg.IsIllTyped() {
return nil, nil, fmt.Errorf("no package for file %s", f.URI())
return nil, nil, errors.Errorf("no package for file %s", f.URI())
}
if hasListErrors(pkg.GetErrors()) {
return nil, nil, fmt.Errorf("%s has list errors, not running goimports", f.URI())
return nil, nil, errors.Errorf("%s has list errors, not running goimports", f.URI())
}
options := &imports.Options{

View File

@ -6,13 +6,13 @@ package source
import (
"context"
"fmt"
"go/ast"
"go/token"
"golang.org/x/tools/go/ast/astutil"
"golang.org/x/tools/internal/lsp/telemetry/trace"
"golang.org/x/tools/internal/span"
errors "golang.org/x/xerrors"
)
func Highlight(ctx context.Context, f GoFile, pos token.Pos) ([]span.Span, error) {
@ -26,11 +26,11 @@ func Highlight(ctx context.Context, f GoFile, pos token.Pos) ([]span.Span, error
fset := f.FileSet()
path, _ := astutil.PathEnclosingInterval(file, pos, pos)
if len(path) == 0 {
return nil, fmt.Errorf("no enclosing position found for %s", fset.Position(pos))
return nil, errors.Errorf("no enclosing position found for %s", fset.Position(pos))
}
id, ok := path[0].(*ast.Ident)
if !ok {
return nil, fmt.Errorf("%s is not an identifier", fset.Position(pos))
return nil, errors.Errorf("%s is not an identifier", fset.Position(pos))
}
var result []span.Span
if id.Obj != nil {

View File

@ -6,7 +6,6 @@ package source
import (
"context"
"fmt"
"go/ast"
"go/doc"
"go/format"
@ -14,6 +13,7 @@ import (
"strings"
"golang.org/x/tools/internal/lsp/telemetry/trace"
errors "golang.org/x/xerrors"
)
type documentation struct {
@ -129,7 +129,7 @@ func formatGenDecl(node *ast.GenDecl, obj types.Object, typ types.Type) (*docume
}
}
if spec == nil {
return nil, fmt.Errorf("no spec for node %v at position %v", node, obj.Pos())
return nil, errors.Errorf("no spec for node %v at position %v", node, obj.Pos())
}
// If we have a field or method.
switch obj.(type) {
@ -150,7 +150,7 @@ func formatGenDecl(node *ast.GenDecl, obj types.Object, typ types.Type) (*docume
case *ast.ImportSpec:
return &documentation{spec, spec.Doc}, nil
}
return nil, fmt.Errorf("unable to format spec %v (%T)", spec, spec)
return nil, errors.Errorf("unable to format spec %v (%T)", spec, spec)
}
func formatVar(node ast.Spec, obj types.Object) (*documentation, error) {

View File

@ -6,7 +6,6 @@ package source
import (
"context"
"fmt"
"go/ast"
"go/token"
"go/types"
@ -15,6 +14,7 @@ import (
"golang.org/x/tools/go/ast/astutil"
"golang.org/x/tools/internal/lsp/telemetry/trace"
"golang.org/x/tools/internal/span"
errors "golang.org/x/xerrors"
)
// IdentifierInfo holds information about an identifier in Go source.
@ -56,7 +56,7 @@ func Identifier(ctx context.Context, view View, f GoFile, pos token.Pos) (*Ident
// requesting a completion), use the path to the preceding node.
result, err := identifier(ctx, view, f, pos-1)
if result == nil && err == nil {
err = fmt.Errorf("no identifier found")
err = errors.Errorf("no identifier found")
}
return result, err
}
@ -72,7 +72,7 @@ func identifier(ctx context.Context, view View, f GoFile, pos token.Pos) (*Ident
}
pkg := f.GetPackage(ctx)
if pkg == nil || pkg.IsIllTyped() {
return nil, fmt.Errorf("pkg for %s is ill-typed", f.URI())
return nil, errors.Errorf("pkg for %s is ill-typed", f.URI())
}
// Handle import specs separately, as there is no formal position for a package declaration.
if result, err := importSpec(ctx, f, file, pkg, pos); result != nil || err != nil {
@ -80,7 +80,7 @@ func identifier(ctx context.Context, view View, f GoFile, pos token.Pos) (*Ident
}
path, _ := astutil.PathEnclosingInterval(file, pos, pos)
if path == nil {
return nil, fmt.Errorf("can't find node enclosing position")
return nil, errors.Errorf("can't find node enclosing position")
}
result := &IdentifierInfo{
File: f,
@ -118,7 +118,7 @@ func identifier(ctx context.Context, view View, f GoFile, pos token.Pos) (*Ident
result.decl.wasImplicit = true
} else {
// Probably a type error.
return nil, fmt.Errorf("no object for ident %v", result.Name)
return nil, errors.Errorf("no object for ident %v", result.Name)
}
}
@ -126,7 +126,7 @@ func identifier(ctx context.Context, view View, f GoFile, pos token.Pos) (*Ident
if result.decl.obj.Parent() == types.Universe {
decl, ok := lookupBuiltinDecl(f.View(), result.Name).(ast.Node)
if !ok {
return nil, fmt.Errorf("no declaration for %s", result.Name)
return nil, errors.Errorf("no declaration for %s", result.Name)
}
result.decl.node = decl
if result.decl.rng, err = posToRange(ctx, f.FileSet(), result.Name, decl.Pos()); err != nil {
@ -214,7 +214,7 @@ func objToRange(ctx context.Context, fset *token.FileSet, obj types.Object) (spa
func posToRange(ctx context.Context, fset *token.FileSet, name string, pos token.Pos) (span.Range, error) {
if !pos.IsValid() {
return span.Range{}, fmt.Errorf("invalid position for %v", name)
return span.Range{}, errors.Errorf("invalid position for %v", name)
}
return span.NewRange(fset, pos, pos+token.Pos(len(name))), nil
}
@ -230,7 +230,7 @@ func objToNode(ctx context.Context, view View, originPkg *types.Package, obj typ
}
declFile, ok := f.(GoFile)
if !ok {
return nil, fmt.Errorf("%s is not a Go file", s.URI())
return nil, errors.Errorf("%s is not a Go file", s.URI())
}
// If the object is exported from a different package,
// we don't need its full AST to find the definition.
@ -244,7 +244,7 @@ func objToNode(ctx context.Context, view View, originPkg *types.Package, obj typ
}
path, _ := astutil.PathEnclosingInterval(declAST, rng.Start, rng.End)
if path == nil {
return nil, fmt.Errorf("no path for range %v", rng)
return nil, errors.Errorf("no path for range %v", rng)
}
for _, node := range path {
switch node := node.(type) {
@ -277,7 +277,7 @@ func importSpec(ctx context.Context, f GoFile, fAST *ast.File, pkg Package, pos
}
importPath, err := strconv.Unquote(imp.Path.Value)
if err != nil {
return nil, fmt.Errorf("import path not quoted: %s (%v)", imp.Path.Value, err)
return nil, errors.Errorf("import path not quoted: %s (%v)", imp.Path.Value, err)
}
result := &IdentifierInfo{
File: f,
@ -288,10 +288,10 @@ func importSpec(ctx context.Context, f GoFile, fAST *ast.File, pkg Package, pos
// Consider the "declaration" of an import spec to be the imported package.
importedPkg := pkg.GetImport(importPath)
if importedPkg == nil {
return nil, fmt.Errorf("no import for %q", importPath)
return nil, errors.Errorf("no import for %q", importPath)
}
if importedPkg.GetSyntax(ctx) == nil {
return nil, fmt.Errorf("no syntax for for %q", importPath)
return nil, errors.Errorf("no syntax for for %q", importPath)
}
// Heuristic: Jump to the longest (most "interesting") file of the package.
var dest *ast.File
@ -301,7 +301,7 @@ func importSpec(ctx context.Context, f GoFile, fAST *ast.File, pkg Package, pos
}
}
if dest == nil {
return nil, fmt.Errorf("package %q has no files", importPath)
return nil, errors.Errorf("package %q has no files", importPath)
}
result.decl.rng = span.NewRange(f.FileSet(), dest.Name.Pos(), dest.Name.End())
result.decl.node = imp

View File

@ -6,12 +6,12 @@ package source
import (
"context"
"fmt"
"go/ast"
"go/types"
"golang.org/x/tools/internal/lsp/telemetry/trace"
"golang.org/x/tools/internal/span"
errors "golang.org/x/xerrors"
)
// ReferenceInfo holds information about reference to an identifier in Go source.
@ -33,17 +33,17 @@ func (i *IdentifierInfo) References(ctx context.Context) ([]*ReferenceInfo, erro
// If the object declaration is nil, assume it is an import spec and do not look for references.
if i.decl.obj == nil {
return nil, fmt.Errorf("no references for an import spec")
return nil, errors.Errorf("no references for an import spec")
}
pkgs := i.File.GetPackages(ctx)
for _, pkg := range pkgs {
if pkg == nil || pkg.IsIllTyped() {
return nil, fmt.Errorf("package for %s is ill typed", i.File.URI())
return nil, errors.Errorf("package for %s is ill typed", i.File.URI())
}
info := pkg.GetTypesInfo()
if info == nil {
return nil, fmt.Errorf("package %s has no types info", pkg.PkgPath())
return nil, errors.Errorf("package %s has no types info", pkg.PkgPath())
}
if i.decl.wasImplicit {

View File

@ -7,7 +7,6 @@ package source
import (
"bytes"
"context"
"fmt"
"go/ast"
"go/format"
"go/token"
@ -18,6 +17,7 @@ import (
"golang.org/x/tools/internal/lsp/telemetry/trace"
"golang.org/x/tools/internal/span"
"golang.org/x/tools/refactor/satisfy"
errors "golang.org/x/xerrors"
)
type renamer struct {
@ -41,22 +41,22 @@ func (i *IdentifierInfo) Rename(ctx context.Context, newName string) (map[span.U
defer done()
if i.Name == newName {
return nil, fmt.Errorf("old and new names are the same: %s", newName)
return nil, errors.Errorf("old and new names are the same: %s", newName)
}
if !isValidIdentifier(i.Name) {
return nil, fmt.Errorf("invalid identifier to rename: %q", i.Name)
return nil, errors.Errorf("invalid identifier to rename: %q", i.Name)
}
if i.pkg == nil || i.pkg.IsIllTyped() {
return nil, fmt.Errorf("package for %s is ill typed", i.File.URI())
return nil, errors.Errorf("package for %s is ill typed", i.File.URI())
}
// Do not rename builtin identifiers.
if i.decl.obj.Parent() == types.Universe {
return nil, fmt.Errorf("cannot rename builtin %q", i.Name)
return nil, errors.Errorf("cannot rename builtin %q", i.Name)
}
// Do not rename identifiers declared in another package.
if i.pkg.GetTypes() != i.decl.obj.Pkg() {
return nil, fmt.Errorf("failed to rename because %q is declared in package %q", i.Name, i.decl.obj.Pkg().Name())
return nil, errors.Errorf("failed to rename because %q is declared in package %q", i.Name, i.decl.obj.Pkg().Name())
}
refs, err := i.References(ctx)
@ -83,7 +83,7 @@ func (i *IdentifierInfo) Rename(ctx context.Context, newName string) (map[span.U
r.check(from.obj)
}
if r.hadConflicts {
return nil, fmt.Errorf(r.errors)
return nil, errors.Errorf(r.errors)
}
changes, err := r.update()
@ -200,11 +200,11 @@ func (r *renamer) updatePkgName(pkgName *types.PkgName) (*TextEdit, error) {
_, path, _ := pathEnclosingInterval(r.ctx, r.fset, pkg, pkgName.Pos(), pkgName.Pos())
if len(path) < 2 {
return nil, fmt.Errorf("failed to update PkgName for %s", pkgName.Name())
return nil, errors.Errorf("failed to update PkgName for %s", pkgName.Name())
}
spec, ok := path[1].(*ast.ImportSpec)
if !ok {
return nil, fmt.Errorf("failed to update PkgName for %s", pkgName.Name())
return nil, errors.Errorf("failed to update PkgName for %s", pkgName.Name())
}
var astIdent *ast.Ident // will be nil if ident is removed

View File

@ -6,13 +6,13 @@ package source
import (
"context"
"fmt"
"go/ast"
"go/token"
"go/types"
"golang.org/x/tools/go/ast/astutil"
"golang.org/x/tools/internal/lsp/telemetry/trace"
errors "golang.org/x/xerrors"
)
type SignatureInformation struct {
@ -35,14 +35,14 @@ func SignatureHelp(ctx context.Context, f GoFile, pos token.Pos) (*SignatureInfo
}
pkg := f.GetPackage(ctx)
if pkg == nil || pkg.IsIllTyped() {
return nil, fmt.Errorf("package for %s is ill typed", f.URI())
return nil, errors.Errorf("package for %s is ill typed", f.URI())
}
// Find a call expression surrounding the query position.
var callExpr *ast.CallExpr
path, _ := astutil.PathEnclosingInterval(file, pos, pos)
if path == nil {
return nil, fmt.Errorf("cannot find node enclosing position")
return nil, errors.Errorf("cannot find node enclosing position")
}
FindCall:
for _, node := range path {
@ -56,11 +56,11 @@ FindCall:
// The user is within an anonymous function,
// which may be the parameter to the *ast.CallExpr.
// Don't show signature help in this case.
return nil, fmt.Errorf("no signature help within a function declaration")
return nil, errors.Errorf("no signature help within a function declaration")
}
}
if callExpr == nil || callExpr.Fun == nil {
return nil, fmt.Errorf("cannot find an enclosing function")
return nil, errors.Errorf("cannot find an enclosing function")
}
// Get the object representing the function, if available.
@ -82,12 +82,12 @@ FindCall:
// Get the type information for the function being called.
sigType := pkg.GetTypesInfo().TypeOf(callExpr.Fun)
if sigType == nil {
return nil, fmt.Errorf("cannot get type for Fun %[1]T (%[1]v)", callExpr.Fun)
return nil, errors.Errorf("cannot get type for Fun %[1]T (%[1]v)", callExpr.Fun)
}
sig, _ := sigType.Underlying().(*types.Signature)
if sig == nil {
return nil, fmt.Errorf("cannot find signature for Fun %[1]T (%[1]v)", callExpr.Fun)
return nil, errors.Errorf("cannot find signature for Fun %[1]T (%[1]v)", callExpr.Fun)
}
qf := qualifier(file, pkg.GetTypes(), pkg.GetTypesInfo())
@ -128,7 +128,7 @@ FindCall:
func builtinSignature(ctx context.Context, v View, callExpr *ast.CallExpr, name string, pos token.Pos) (*SignatureInformation, error) {
decl, ok := lookupBuiltinDecl(v, name).(*ast.FuncDecl)
if !ok {
return nil, fmt.Errorf("no function declaration for builtin: %s", name)
return nil, errors.Errorf("no function declaration for builtin: %s", name)
}
params, _ := formatFieldList(ctx, v, decl.Type.Params)
results, writeResultParens := formatFieldList(ctx, v, decl.Type.Results)

View File

@ -6,7 +6,6 @@ package source
import (
"context"
"errors"
"fmt"
"go/ast"
"go/token"
@ -14,6 +13,7 @@ import (
"golang.org/x/tools/internal/lsp/telemetry/trace"
"golang.org/x/tools/internal/span"
errors "golang.org/x/xerrors"
)
type SymbolKind int
@ -52,7 +52,7 @@ func DocumentSymbols(ctx context.Context, f GoFile) ([]Symbol, error) {
}
pkg := f.GetPackage(ctx)
if pkg == nil || pkg.IsIllTyped() {
return nil, fmt.Errorf("no package for %s", f.URI())
return nil, errors.Errorf("no package for %s", f.URI())
}
info := pkg.GetTypesInfo()
q := qualifier(file, pkg.GetTypes(), info)

View File

@ -7,7 +7,6 @@ package lsp
import (
"bytes"
"context"
"fmt"
"golang.org/x/tools/internal/jsonrpc2"
"golang.org/x/tools/internal/lsp/protocol"
@ -16,6 +15,7 @@ import (
"golang.org/x/tools/internal/lsp/telemetry/log"
"golang.org/x/tools/internal/lsp/telemetry/trace"
"golang.org/x/tools/internal/span"
errors "golang.org/x/xerrors"
)
func (s *Server) didOpen(ctx context.Context, params *protocol.DidOpenTextDocumentParams) error {
@ -54,7 +54,7 @@ func (s *Server) didChange(ctx context.Context, params *protocol.DidChangeTextDo
if !isFullChange {
switch s.textDocumentSyncKind {
case protocol.Full:
return fmt.Errorf("expected a full content change, received incremental changes for %s", uri)
return errors.Errorf("expected a full content change, received incremental changes for %s", uri)
case protocol.Incremental:
// Determine the new file content.
var err error

View File

@ -6,11 +6,11 @@ package lsp
import (
"context"
"fmt"
"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 getSourceFile(ctx context.Context, v source.View, uri span.URI) (source.File, *protocol.ColumnMapper, error) {
@ -38,7 +38,7 @@ func getGoFile(ctx context.Context, v source.View, uri span.URI) (source.GoFile,
}
gof, ok := f.(source.GoFile)
if !ok {
return nil, nil, fmt.Errorf("not a Go file %v", f.URI())
return nil, nil, errors.Errorf("not a Go file %v", f.URI())
}
return gof, m, nil
}

View File

@ -6,10 +6,10 @@ package lsp
import (
"context"
"fmt"
"golang.org/x/tools/internal/lsp/protocol"
"golang.org/x/tools/internal/span"
errors "golang.org/x/xerrors"
)
func (s *Server) changeFolders(ctx context.Context, event protocol.WorkspaceFoldersChangeEvent) error {
@ -18,7 +18,7 @@ func (s *Server) changeFolders(ctx context.Context, event protocol.WorkspaceFold
if view != nil {
view.Shutdown(ctx)
} else {
return fmt.Errorf("view %s for %v not found", folder.Name, folder.URI)
return errors.Errorf("view %s for %v not found", folder.Name, folder.URI)
}
}