mirror of
https://github.com/golang/go.git
synced 2025-05-05 07:33:00 +00:00
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:
parent
249e2b9b6d
commit
be5259f298
1
go.mod
1
go.mod
@ -5,4 +5,5 @@ go 1.11
|
|||||||
require (
|
require (
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58
|
||||||
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7
|
||||||
)
|
)
|
||||||
|
2
go.sum
2
go.sum
@ -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/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/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/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=
|
||||||
|
28
internal/lsp/cache/check.go
vendored
28
internal/lsp/cache/check.go
vendored
@ -6,7 +6,6 @@ package cache
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/scanner"
|
"go/scanner"
|
||||||
"go/token"
|
"go/token"
|
||||||
@ -20,6 +19,7 @@ import (
|
|||||||
"golang.org/x/tools/internal/lsp/telemetry/log"
|
"golang.org/x/tools/internal/lsp/telemetry/log"
|
||||||
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type importer struct {
|
type importer struct {
|
||||||
@ -40,7 +40,7 @@ func (imp *importer) Import(pkgPath string) (*types.Package, error) {
|
|||||||
ctx := imp.ctx
|
ctx := imp.ctx
|
||||||
id, ok := imp.view.mcache.ids[packagePath(pkgPath)]
|
id, ok := imp.view.mcache.ids[packagePath(pkgPath)]
|
||||||
if !ok {
|
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)
|
pkg, err := imp.getPkg(ctx, id)
|
||||||
if err != nil {
|
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) {
|
func (imp *importer) getPkg(ctx context.Context, id packageID) (*pkg, error) {
|
||||||
if _, ok := imp.seen[id]; ok {
|
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()
|
imp.view.pcache.mu.Lock()
|
||||||
e, ok := imp.view.pcache.packages[id]
|
e, ok := imp.view.pcache.packages[id]
|
||||||
@ -99,7 +99,7 @@ func (imp *importer) typeCheck(ctx context.Context, id packageID) (*pkg, error)
|
|||||||
defer done()
|
defer done()
|
||||||
meta, ok := imp.view.mcache.packages[id]
|
meta, ok := imp.view.mcache.packages[id]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("no metadata for %v", id)
|
return nil, errors.Errorf("no metadata for %v", id)
|
||||||
}
|
}
|
||||||
pkg := &pkg{
|
pkg := &pkg{
|
||||||
id: meta.id,
|
id: meta.id,
|
||||||
@ -123,9 +123,9 @@ func (imp *importer) typeCheck(ctx context.Context, id packageID) (*pkg, error)
|
|||||||
mode = source.ParseExported
|
mode = source.ParseExported
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
files = make([]*ast.File, len(meta.files))
|
files = make([]*ast.File, len(meta.files))
|
||||||
errors = make([]error, len(meta.files))
|
parseErrors = make([]error, len(meta.files))
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
)
|
)
|
||||||
for _, filename := range meta.files {
|
for _, filename := range meta.files {
|
||||||
uri := span.FileURI(filename)
|
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) {
|
go func(i int, ph source.ParseGoHandle) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
files[i], errors[i] = ph.Parse(ctx)
|
files[i], parseErrors[i] = ph.Parse(ctx)
|
||||||
}(i, ph)
|
}(i, ph)
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
@ -153,7 +153,7 @@ func (imp *importer) typeCheck(ctx context.Context, id packageID) (*pkg, error)
|
|||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, err := range errors {
|
for _, err := range parseErrors {
|
||||||
if err == context.Canceled {
|
if err == context.Canceled {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -166,7 +166,7 @@ func (imp *importer) typeCheck(ctx context.Context, id packageID) (*pkg, error)
|
|||||||
if meta.pkgPath == "unsafe" {
|
if meta.pkgPath == "unsafe" {
|
||||||
pkg.types = types.Unsafe
|
pkg.types = types.Unsafe
|
||||||
} else if len(files) == 0 { // not the unsafe package, no parsed files
|
} 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 {
|
} else {
|
||||||
pkg.types = types.NewPackage(string(meta.pkgPath), meta.name)
|
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
|
uri := ph.File().Identity().URI
|
||||||
f, err := imp.view.getFile(ctx, uri)
|
f, err := imp.view.getFile(ctx, uri)
|
||||||
if err != nil {
|
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)
|
gof, ok := f.(*goFile)
|
||||||
if !ok {
|
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 {
|
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)
|
file, err := ph.Parse(imp.ctx)
|
||||||
if file == nil {
|
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
|
gof.imports = file.Imports
|
||||||
return nil
|
return nil
|
||||||
|
6
internal/lsp/cache/gofile.go
vendored
6
internal/lsp/cache/gofile.go
vendored
@ -6,7 +6,6 @@ package cache
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/token"
|
"go/token"
|
||||||
"sync"
|
"sync"
|
||||||
@ -15,6 +14,7 @@ import (
|
|||||||
"golang.org/x/tools/internal/lsp/telemetry"
|
"golang.org/x/tools/internal/lsp/telemetry"
|
||||||
"golang.org/x/tools/internal/lsp/telemetry/log"
|
"golang.org/x/tools/internal/lsp/telemetry/log"
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// goFile holds all of the information we know about a Go file.
|
// 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())
|
tok := f.view.session.cache.fset.File(file.Pos())
|
||||||
if tok == nil {
|
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
|
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 f.isDirty(ctx) || f.wrongParseMode(ctx, mode) {
|
||||||
if _, err := f.view.loadParseTypecheck(ctx, f); err != nil {
|
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)
|
fh := f.Handle(ctx)
|
||||||
|
13
internal/lsp/cache/load.go
vendored
13
internal/lsp/cache/load.go
vendored
@ -15,6 +15,7 @@ import (
|
|||||||
"golang.org/x/tools/internal/lsp/telemetry/tag"
|
"golang.org/x/tools/internal/lsp/telemetry/tag"
|
||||||
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (v *view) loadParseTypecheck(ctx context.Context, f *goFile) ([]packages.Error, error) {
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
if pkg == nil || pkg.IsIllTyped() {
|
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 {
|
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
|
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()))
|
pkgs, err := packages.Load(v.Config(ctx), fmt.Sprintf("file=%s", f.filename()))
|
||||||
if len(pkgs) == 0 {
|
if len(pkgs) == 0 {
|
||||||
if err == nil {
|
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 this error as a diagnostic to the user.
|
||||||
return nil, []packages.Error{
|
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`,
|
// If the package comes back with errors from `go list`,
|
||||||
// don't bother type-checking it.
|
// don't bother type-checking it.
|
||||||
if len(pkg.Errors) > 0 {
|
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.
|
// Build the import graph for this package.
|
||||||
if err := v.link(ctx, packagePath(pkg.PkgPath), pkg, nil, missingImports); err != nil {
|
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 `go list` failed to get data for the file in question (this should never happen).
|
||||||
if len(f.meta) == 0 {
|
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,
|
// 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 {
|
for importPath, importPkg := range pkg.Imports {
|
||||||
importPkgPath := packagePath(importPath)
|
importPkgPath := packagePath(importPath)
|
||||||
if importPkgPath == pkgPath {
|
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.
|
// Don't remember any imports with significant errors.
|
||||||
if importPkgPath != "unsafe" && len(pkg.CompiledGoFiles) == 0 {
|
if importPkgPath != "unsafe" && len(pkg.CompiledGoFiles) == 0 {
|
||||||
|
5
internal/lsp/cache/modfile.go
vendored
5
internal/lsp/cache/modfile.go
vendored
@ -6,8 +6,9 @@ package cache
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"go/token"
|
"go/token"
|
||||||
|
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// modFile holds all of the information we know about a mod file.
|
// 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) {
|
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) {}
|
func (*modFile) setContent(content []byte) {}
|
||||||
|
14
internal/lsp/cache/parse.go
vendored
14
internal/lsp/cache/parse.go
vendored
@ -6,7 +6,6 @@ package cache
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/parser"
|
"go/parser"
|
||||||
"go/scanner"
|
"go/scanner"
|
||||||
@ -16,6 +15,7 @@ import (
|
|||||||
"golang.org/x/tools/internal/lsp/telemetry"
|
"golang.org/x/tools/internal/lsp/telemetry"
|
||||||
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
||||||
"golang.org/x/tools/internal/memoize"
|
"golang.org/x/tools/internal/memoize"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Limits the number of parallel parser calls per process.
|
// 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:
|
case *ast.BadStmt:
|
||||||
err = parseDeferOrGoStmt(n, parent, tok, src) // don't shadow err
|
err = parseDeferOrGoStmt(n, parent, tok, src) // don't shadow err
|
||||||
if err != nil {
|
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
|
return false
|
||||||
default:
|
default:
|
||||||
@ -182,7 +182,7 @@ func parseDeferOrGoStmt(bad *ast.BadStmt, parent ast.Node, tok *token.File, src
|
|||||||
var lit string
|
var lit string
|
||||||
for {
|
for {
|
||||||
if tkn == token.EOF {
|
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 {
|
if pos >= bad.From {
|
||||||
break
|
break
|
||||||
@ -200,7 +200,7 @@ func parseDeferOrGoStmt(bad *ast.BadStmt, parent ast.Node, tok *token.File, src
|
|||||||
Go: pos,
|
Go: pos,
|
||||||
}
|
}
|
||||||
default:
|
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.
|
// The expression after the "defer" or "go" starts at this position.
|
||||||
@ -225,15 +225,15 @@ FindTo:
|
|||||||
to = curr
|
to = curr
|
||||||
}
|
}
|
||||||
if !from.IsValid() || tok.Offset(from) >= len(src) {
|
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) {
|
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])
|
exprstr := string(src[tok.Offset(from) : tok.Offset(to)+1])
|
||||||
expr, err := parser.ParseExpr(exprstr)
|
expr, err := parser.ParseExpr(exprstr)
|
||||||
if expr == nil {
|
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.
|
// parser.ParseExpr returns undefined positions.
|
||||||
// Adjust them for the current file.
|
// Adjust them for the current file.
|
||||||
|
4
internal/lsp/cache/session.go
vendored
4
internal/lsp/cache/session.go
vendored
@ -6,7 +6,6 @@ package cache
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -21,6 +20,7 @@ import (
|
|||||||
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
"golang.org/x/tools/internal/xcontext"
|
"golang.org/x/tools/internal/xcontext"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type session struct {
|
type session struct {
|
||||||
@ -178,7 +178,7 @@ func (s *session) removeView(ctx context.Context, view *view) error {
|
|||||||
return nil
|
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.
|
// TODO: Propagate the language ID through to the view.
|
||||||
|
5
internal/lsp/cache/sumfile.go
vendored
5
internal/lsp/cache/sumfile.go
vendored
@ -6,8 +6,9 @@ package cache
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"go/token"
|
"go/token"
|
||||||
|
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// sumFile holds all of the information we know about a sum file.
|
// 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) {
|
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) {}
|
func (*sumFile) setContent(content []byte) {}
|
||||||
|
4
internal/lsp/cache/token.go
vendored
4
internal/lsp/cache/token.go
vendored
@ -6,11 +6,11 @@ package cache
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"go/token"
|
"go/token"
|
||||||
|
|
||||||
"golang.org/x/tools/internal/lsp/source"
|
"golang.org/x/tools/internal/lsp/source"
|
||||||
"golang.org/x/tools/internal/memoize"
|
"golang.org/x/tools/internal/memoize"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type tokenKey struct {
|
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))
|
tok := c.FileSet().AddFile(fh.Identity().URI.Filename(), -1, len(buf))
|
||||||
if tok == nil {
|
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)
|
tok.SetLinesForContent(buf)
|
||||||
return tok, nil
|
return tok, nil
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// check implements the check verb for gopls.
|
// check implements the check verb for gopls.
|
||||||
@ -60,14 +61,14 @@ func (c *check) Run(ctx context.Context, args ...string) error {
|
|||||||
select {
|
select {
|
||||||
case <-file.hasDiagnostics:
|
case <-file.hasDiagnostics:
|
||||||
case <-time.After(30 * time.Second):
|
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()
|
file.diagnosticsMu.Lock()
|
||||||
defer file.diagnosticsMu.Unlock()
|
defer file.diagnosticsMu.Unlock()
|
||||||
for _, d := range file.diagnostics {
|
for _, d := range file.diagnostics {
|
||||||
spn, err := file.mapper.RangeSpan(d.Range)
|
spn, err := file.mapper.RangeSpan(d.Range)
|
||||||
if err != nil {
|
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)
|
fmt.Printf("%v: %v\n", spn, d.Message)
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ import (
|
|||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
"golang.org/x/tools/internal/tool"
|
"golang.org/x/tools/internal/tool"
|
||||||
"golang.org/x/tools/internal/xcontext"
|
"golang.org/x/tools/internal/xcontext"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Application is the main application as passed to tool.Main
|
// 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()
|
fname := uri.Filename()
|
||||||
content, err := ioutil.ReadFile(fname)
|
content, err := ioutil.ReadFile(fname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
file.err = fmt.Errorf("getFile %v: %v", uri, err)
|
file.err = errors.Errorf("getFile: %v: %v", uri, err)
|
||||||
return file
|
return file
|
||||||
}
|
}
|
||||||
f := c.fset.AddFile(fname, -1, len(content))
|
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.Text = string(file.mapper.Content)
|
||||||
p.TextDocument.LanguageID = source.DetectLanguage("", file.uri.Filename()).String()
|
p.TextDocument.LanguageID = source.DetectLanguage("", file.uri.Filename()).String()
|
||||||
if err := c.Server.DidOpen(ctx, p); err != nil {
|
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
|
return file
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import (
|
|||||||
"golang.org/x/tools/internal/lsp/protocol"
|
"golang.org/x/tools/internal/lsp/protocol"
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
"golang.org/x/tools/internal/tool"
|
"golang.org/x/tools/internal/tool"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Definition is the result of a 'definition' query.
|
// 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)
|
locs, err := conn.Definition(ctx, &p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%v: %v", from, err)
|
return errors.Errorf("%v: %v", from, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(locs) == 0 {
|
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)
|
hover, err := conn.Hover(ctx, &p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%v: %v", from, err)
|
return errors.Errorf("%v: %v", from, err)
|
||||||
}
|
}
|
||||||
if hover == nil {
|
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))
|
file = conn.AddFile(ctx, span.NewURI(locs[0].URI))
|
||||||
if file.err != nil {
|
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])
|
definition, err := file.mapper.Span(locs[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%v: %v", from, err)
|
return errors.Errorf("%v: %v", from, err)
|
||||||
}
|
}
|
||||||
description := strings.TrimSpace(hover.Contents.Value)
|
description := strings.TrimSpace(hover.Contents.Value)
|
||||||
var result interface{}
|
var result interface{}
|
||||||
@ -115,7 +116,7 @@ func (d *definition) Run(ctx context.Context, args ...string) error {
|
|||||||
Desc: description,
|
Desc: description,
|
||||||
}
|
}
|
||||||
default:
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -131,7 +132,7 @@ func (d *definition) Run(ctx context.Context, args ...string) error {
|
|||||||
case *guru.Definition:
|
case *guru.Definition:
|
||||||
fmt.Printf("%s: defined here as %s", d.ObjPos, d.Desc)
|
fmt.Printf("%s: defined here as %s", d.ObjPos, d.Desc)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("no printer for type %T", result)
|
return errors.Errorf("no printer for type %T", result)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import (
|
|||||||
"golang.org/x/tools/internal/lsp/protocol"
|
"golang.org/x/tools/internal/lsp/protocol"
|
||||||
"golang.org/x/tools/internal/lsp/source"
|
"golang.org/x/tools/internal/lsp/source"
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// format implements the format verb for gopls.
|
// format implements the format verb for gopls.
|
||||||
@ -68,18 +69,18 @@ func (f *format) Run(ctx context.Context, args ...string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if loc.Range.Start != loc.Range.End {
|
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{
|
p := protocol.DocumentFormattingParams{
|
||||||
TextDocument: protocol.TextDocumentIdentifier{URI: loc.URI},
|
TextDocument: protocol.TextDocumentIdentifier{URI: loc.URI},
|
||||||
}
|
}
|
||||||
edits, err := conn.Formatting(ctx, &p)
|
edits, err := conn.Formatting(ctx, &p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%v: %v", spn, err)
|
return errors.Errorf("%v: %v", spn, err)
|
||||||
}
|
}
|
||||||
sedits, err := lsp.FromProtocolEdits(file.mapper, edits)
|
sedits, err := lsp.FromProtocolEdits(file.mapper, edits)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%v: %v", spn, err)
|
return errors.Errorf("%v: %v", spn, err)
|
||||||
}
|
}
|
||||||
ops := source.EditsToDiff(sedits)
|
ops := source.EditsToDiff(sedits)
|
||||||
lines := diff.SplitLines(string(file.mapper.Content))
|
lines := diff.SplitLines(string(file.mapper.Content))
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
"golang.org/x/tools/internal/lsp/telemetry/tag"
|
"golang.org/x/tools/internal/lsp/telemetry/tag"
|
||||||
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
||||||
"golang.org/x/tools/internal/tool"
|
"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
|
// 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)
|
f, err := os.Create(filename)
|
||||||
if err != nil {
|
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()
|
defer f.Close()
|
||||||
log.SetOutput(io.MultiWriter(os.Stderr, f))
|
log.SetOutput(io.MultiWriter(os.Stderr, f))
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
"golang.org/x/tools/internal/lsp/telemetry"
|
"golang.org/x/tools/internal/lsp/telemetry"
|
||||||
"golang.org/x/tools/internal/lsp/telemetry/log"
|
"golang.org/x/tools/internal/lsp/telemetry/log"
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) codeAction(ctx context.Context, params *protocol.CodeActionParams) ([]protocol.CodeAction, error) {
|
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 {
|
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)
|
spn, err := m.RangeSpan(params.Range)
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
"golang.org/x/tools/internal/lsp/telemetry/log"
|
"golang.org/x/tools/internal/lsp/telemetry/log"
|
||||||
"golang.org/x/tools/internal/lsp/telemetry/tag"
|
"golang.org/x/tools/internal/lsp/telemetry/tag"
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) initialize(ctx context.Context, params *protocol.InitializeParams) (*protocol.InitializeResult, error) {
|
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
|
// no folders and no root, single file mode
|
||||||
//TODO(iancottrell): not sure how to do single file mode yet
|
//TODO(iancottrell): not sure how to do single file mode yet
|
||||||
//issue: golang.org/issue/31168
|
//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{})
|
c, ok := config.(map[string]interface{})
|
||||||
if !ok {
|
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.
|
// Get the environment for the go/packages config.
|
||||||
if env := c["env"]; env != nil {
|
if env := c["env"]; env != nil {
|
||||||
menv, ok := env.(map[string]interface{})
|
menv, ok := env.(map[string]interface{})
|
||||||
if !ok {
|
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()
|
env := view.Env()
|
||||||
for k, v := range menv {
|
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 {
|
if buildFlags := c["buildFlags"]; buildFlags != nil {
|
||||||
iflags, ok := buildFlags.([]interface{})
|
iflags, ok := buildFlags.([]interface{})
|
||||||
if !ok {
|
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))
|
flags := make([]string, 0, len(iflags))
|
||||||
for _, flag := range iflags {
|
for _, flag := range iflags {
|
||||||
|
@ -6,7 +6,6 @@ package lsp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/token"
|
"go/token"
|
||||||
"regexp"
|
"regexp"
|
||||||
@ -18,6 +17,7 @@ import (
|
|||||||
"golang.org/x/tools/internal/lsp/telemetry/log"
|
"golang.org/x/tools/internal/lsp/telemetry/log"
|
||||||
"golang.org/x/tools/internal/lsp/telemetry/tag"
|
"golang.org/x/tools/internal/lsp/telemetry/tag"
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) documentLink(ctx context.Context, params *protocol.DocumentLinkParams) ([]protocol.DocumentLink, error) {
|
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
|
var links []protocol.DocumentLink
|
||||||
re, err := getURLRegexp()
|
re, err := getURLRegexp()
|
||||||
if err != nil {
|
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) {
|
for _, urlIndex := range re.FindAllIndex([]byte(src), -1) {
|
||||||
start := urlIndex[0]
|
start := urlIndex[0]
|
||||||
|
@ -7,10 +7,10 @@
|
|||||||
package protocol
|
package protocol
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"go/token"
|
"go/token"
|
||||||
|
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ColumnMapper struct {
|
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) {
|
func (m *ColumnMapper) Range(s span.Span) (Range, error) {
|
||||||
if span.CompareURI(m.URI, s.URI()) != 0 {
|
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)
|
s, err := s.WithAll(m.Converter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
"golang.org/x/tools/go/analysis"
|
"golang.org/x/tools/go/analysis"
|
||||||
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
"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) {
|
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 {
|
if failed != nil {
|
||||||
sort.Strings(failed)
|
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
|
return act.err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,12 +164,12 @@ func (act *Action) execOnce(ctx context.Context, fset *token.FileSet) error {
|
|||||||
act.pass = pass
|
act.pass = pass
|
||||||
|
|
||||||
if act.Pkg.IsIllTyped() && !pass.Analyzer.RunDespiteErrors {
|
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 {
|
} else {
|
||||||
act.result, act.err = pass.Analyzer.Run(pass)
|
act.result, act.err = pass.Analyzer.Run(pass)
|
||||||
if act.err == nil {
|
if act.err == nil {
|
||||||
if got, want := reflect.TypeOf(act.result), pass.Analyzer.ResultType; got != want {
|
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",
|
"internal error: on package %s, analyzer %s returned a result of type %v, but declared ResultType %v",
|
||||||
pass.Pkg.Path(), pass.Analyzer, got, want)
|
pass.Pkg.Path(), pass.Analyzer, got, want)
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ package source
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/token"
|
"go/token"
|
||||||
"go/types"
|
"go/types"
|
||||||
@ -16,6 +15,7 @@ import (
|
|||||||
"golang.org/x/tools/internal/lsp/snippet"
|
"golang.org/x/tools/internal/lsp/snippet"
|
||||||
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CompletionItem struct {
|
type CompletionItem struct {
|
||||||
@ -212,7 +212,7 @@ func (c *completer) setSurrounding(ident *ast.Ident) {
|
|||||||
// members for more candidates.
|
// members for more candidates.
|
||||||
func (c *completer) found(obj types.Object, score float64) error {
|
func (c *completer) found(obj types.Object, score float64) error {
|
||||||
if obj.Pkg() != nil && obj.Pkg() != c.types && !obj.Exported() {
|
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() {
|
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)
|
pkg := f.GetPackage(ctx)
|
||||||
if pkg == nil || pkg.IsIllTyped() {
|
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.
|
// Completion is based on what precedes the cursor.
|
||||||
// Find the path to the position before pos.
|
// Find the path to the position before pos.
|
||||||
path, _ := astutil.PathEnclosingInterval(file, pos-1, pos-1)
|
path, _ := astutil.PathEnclosingInterval(file, pos-1, pos-1)
|
||||||
if path == nil {
|
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.
|
// Skip completion inside comments.
|
||||||
for _, g := range file.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())
|
qual := types.RelativeTo(pkg.GetTypes())
|
||||||
of += ", of " + types.ObjectString(obj, qual)
|
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 {
|
if err := c.lexical(); err != nil {
|
||||||
@ -423,7 +423,7 @@ func (c *completer) selector(sel *ast.SelectorExpr) error {
|
|||||||
// Invariant: sel is a true selector.
|
// Invariant: sel is a true selector.
|
||||||
tv, ok := c.info.Types[sel.X]
|
tv, ok := c.info.Types[sel.X]
|
||||||
if !ok {
|
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())
|
return c.methodsAndFields(tv.Type, tv.Addressable())
|
||||||
|
@ -8,7 +8,6 @@ package source
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"go/format"
|
"go/format"
|
||||||
|
|
||||||
"golang.org/x/tools/go/ast/astutil"
|
"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/log"
|
||||||
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Format formats a file with a given range.
|
// 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)
|
path, exact := astutil.PathEnclosingInterval(file, rng.Start, rng.End)
|
||||||
if !exact || len(path) == 0 {
|
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]
|
node := path[0]
|
||||||
|
|
||||||
@ -80,10 +80,10 @@ func Imports(ctx context.Context, view View, f GoFile, rng span.Range) ([]TextEd
|
|||||||
}
|
}
|
||||||
pkg := f.GetPackage(ctx)
|
pkg := f.GetPackage(ctx)
|
||||||
if pkg == nil || pkg.IsIllTyped() {
|
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()) {
|
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{
|
options := &imports.Options{
|
||||||
@ -125,10 +125,10 @@ func AllImportsFixes(ctx context.Context, view View, f GoFile, rng span.Range) (
|
|||||||
}
|
}
|
||||||
pkg := f.GetPackage(ctx)
|
pkg := f.GetPackage(ctx)
|
||||||
if pkg == nil || pkg.IsIllTyped() {
|
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()) {
|
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{
|
options := &imports.Options{
|
||||||
|
@ -6,13 +6,13 @@ package source
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/token"
|
"go/token"
|
||||||
|
|
||||||
"golang.org/x/tools/go/ast/astutil"
|
"golang.org/x/tools/go/ast/astutil"
|
||||||
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Highlight(ctx context.Context, f GoFile, pos token.Pos) ([]span.Span, error) {
|
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()
|
fset := f.FileSet()
|
||||||
path, _ := astutil.PathEnclosingInterval(file, pos, pos)
|
path, _ := astutil.PathEnclosingInterval(file, pos, pos)
|
||||||
if len(path) == 0 {
|
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)
|
id, ok := path[0].(*ast.Ident)
|
||||||
if !ok {
|
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
|
var result []span.Span
|
||||||
if id.Obj != nil {
|
if id.Obj != nil {
|
||||||
|
@ -6,7 +6,6 @@ package source
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/doc"
|
"go/doc"
|
||||||
"go/format"
|
"go/format"
|
||||||
@ -14,6 +13,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type documentation struct {
|
type documentation struct {
|
||||||
@ -129,7 +129,7 @@ func formatGenDecl(node *ast.GenDecl, obj types.Object, typ types.Type) (*docume
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if spec == nil {
|
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.
|
// If we have a field or method.
|
||||||
switch obj.(type) {
|
switch obj.(type) {
|
||||||
@ -150,7 +150,7 @@ func formatGenDecl(node *ast.GenDecl, obj types.Object, typ types.Type) (*docume
|
|||||||
case *ast.ImportSpec:
|
case *ast.ImportSpec:
|
||||||
return &documentation{spec, spec.Doc}, nil
|
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) {
|
func formatVar(node ast.Spec, obj types.Object) (*documentation, error) {
|
||||||
|
@ -6,7 +6,6 @@ package source
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/token"
|
"go/token"
|
||||||
"go/types"
|
"go/types"
|
||||||
@ -15,6 +14,7 @@ import (
|
|||||||
"golang.org/x/tools/go/ast/astutil"
|
"golang.org/x/tools/go/ast/astutil"
|
||||||
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IdentifierInfo holds information about an identifier in Go source.
|
// 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.
|
// requesting a completion), use the path to the preceding node.
|
||||||
result, err := identifier(ctx, view, f, pos-1)
|
result, err := identifier(ctx, view, f, pos-1)
|
||||||
if result == nil && err == nil {
|
if result == nil && err == nil {
|
||||||
err = fmt.Errorf("no identifier found")
|
err = errors.Errorf("no identifier found")
|
||||||
}
|
}
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
@ -72,7 +72,7 @@ func identifier(ctx context.Context, view View, f GoFile, pos token.Pos) (*Ident
|
|||||||
}
|
}
|
||||||
pkg := f.GetPackage(ctx)
|
pkg := f.GetPackage(ctx)
|
||||||
if pkg == nil || pkg.IsIllTyped() {
|
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.
|
// 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 {
|
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)
|
path, _ := astutil.PathEnclosingInterval(file, pos, pos)
|
||||||
if path == nil {
|
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{
|
result := &IdentifierInfo{
|
||||||
File: f,
|
File: f,
|
||||||
@ -118,7 +118,7 @@ func identifier(ctx context.Context, view View, f GoFile, pos token.Pos) (*Ident
|
|||||||
result.decl.wasImplicit = true
|
result.decl.wasImplicit = true
|
||||||
} else {
|
} else {
|
||||||
// Probably a type error.
|
// 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 {
|
if result.decl.obj.Parent() == types.Universe {
|
||||||
decl, ok := lookupBuiltinDecl(f.View(), result.Name).(ast.Node)
|
decl, ok := lookupBuiltinDecl(f.View(), result.Name).(ast.Node)
|
||||||
if !ok {
|
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
|
result.decl.node = decl
|
||||||
if result.decl.rng, err = posToRange(ctx, f.FileSet(), result.Name, decl.Pos()); err != nil {
|
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) {
|
func posToRange(ctx context.Context, fset *token.FileSet, name string, pos token.Pos) (span.Range, error) {
|
||||||
if !pos.IsValid() {
|
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
|
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)
|
declFile, ok := f.(GoFile)
|
||||||
if !ok {
|
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,
|
// If the object is exported from a different package,
|
||||||
// we don't need its full AST to find the definition.
|
// 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)
|
path, _ := astutil.PathEnclosingInterval(declAST, rng.Start, rng.End)
|
||||||
if path == nil {
|
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 {
|
for _, node := range path {
|
||||||
switch node := node.(type) {
|
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)
|
importPath, err := strconv.Unquote(imp.Path.Value)
|
||||||
if err != nil {
|
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{
|
result := &IdentifierInfo{
|
||||||
File: f,
|
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.
|
// Consider the "declaration" of an import spec to be the imported package.
|
||||||
importedPkg := pkg.GetImport(importPath)
|
importedPkg := pkg.GetImport(importPath)
|
||||||
if importedPkg == nil {
|
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 {
|
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.
|
// Heuristic: Jump to the longest (most "interesting") file of the package.
|
||||||
var dest *ast.File
|
var dest *ast.File
|
||||||
@ -301,7 +301,7 @@ func importSpec(ctx context.Context, f GoFile, fAST *ast.File, pkg Package, pos
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if dest == nil {
|
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.rng = span.NewRange(f.FileSet(), dest.Name.Pos(), dest.Name.End())
|
||||||
result.decl.node = imp
|
result.decl.node = imp
|
||||||
|
@ -6,12 +6,12 @@ package source
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/types"
|
"go/types"
|
||||||
|
|
||||||
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ReferenceInfo holds information about reference to an identifier in Go source.
|
// 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 the object declaration is nil, assume it is an import spec and do not look for references.
|
||||||
if i.decl.obj == nil {
|
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)
|
pkgs := i.File.GetPackages(ctx)
|
||||||
for _, pkg := range pkgs {
|
for _, pkg := range pkgs {
|
||||||
if pkg == nil || pkg.IsIllTyped() {
|
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()
|
info := pkg.GetTypesInfo()
|
||||||
if info == nil {
|
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 {
|
if i.decl.wasImplicit {
|
||||||
|
@ -7,7 +7,6 @@ package source
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/format"
|
"go/format"
|
||||||
"go/token"
|
"go/token"
|
||||||
@ -18,6 +17,7 @@ import (
|
|||||||
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
"golang.org/x/tools/refactor/satisfy"
|
"golang.org/x/tools/refactor/satisfy"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type renamer struct {
|
type renamer struct {
|
||||||
@ -41,22 +41,22 @@ func (i *IdentifierInfo) Rename(ctx context.Context, newName string) (map[span.U
|
|||||||
defer done()
|
defer done()
|
||||||
|
|
||||||
if i.Name == newName {
|
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) {
|
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() {
|
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.
|
// Do not rename builtin identifiers.
|
||||||
if i.decl.obj.Parent() == types.Universe {
|
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.
|
// Do not rename identifiers declared in another package.
|
||||||
if i.pkg.GetTypes() != i.decl.obj.Pkg() {
|
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)
|
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)
|
r.check(from.obj)
|
||||||
}
|
}
|
||||||
if r.hadConflicts {
|
if r.hadConflicts {
|
||||||
return nil, fmt.Errorf(r.errors)
|
return nil, errors.Errorf(r.errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
changes, err := r.update()
|
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())
|
_, path, _ := pathEnclosingInterval(r.ctx, r.fset, pkg, pkgName.Pos(), pkgName.Pos())
|
||||||
|
|
||||||
if len(path) < 2 {
|
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)
|
spec, ok := path[1].(*ast.ImportSpec)
|
||||||
if !ok {
|
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
|
var astIdent *ast.Ident // will be nil if ident is removed
|
||||||
|
@ -6,13 +6,13 @@ package source
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/token"
|
"go/token"
|
||||||
"go/types"
|
"go/types"
|
||||||
|
|
||||||
"golang.org/x/tools/go/ast/astutil"
|
"golang.org/x/tools/go/ast/astutil"
|
||||||
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SignatureInformation struct {
|
type SignatureInformation struct {
|
||||||
@ -35,14 +35,14 @@ func SignatureHelp(ctx context.Context, f GoFile, pos token.Pos) (*SignatureInfo
|
|||||||
}
|
}
|
||||||
pkg := f.GetPackage(ctx)
|
pkg := f.GetPackage(ctx)
|
||||||
if pkg == nil || pkg.IsIllTyped() {
|
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.
|
// Find a call expression surrounding the query position.
|
||||||
var callExpr *ast.CallExpr
|
var callExpr *ast.CallExpr
|
||||||
path, _ := astutil.PathEnclosingInterval(file, pos, pos)
|
path, _ := astutil.PathEnclosingInterval(file, pos, pos)
|
||||||
if path == nil {
|
if path == nil {
|
||||||
return nil, fmt.Errorf("cannot find node enclosing position")
|
return nil, errors.Errorf("cannot find node enclosing position")
|
||||||
}
|
}
|
||||||
FindCall:
|
FindCall:
|
||||||
for _, node := range path {
|
for _, node := range path {
|
||||||
@ -56,11 +56,11 @@ FindCall:
|
|||||||
// The user is within an anonymous function,
|
// The user is within an anonymous function,
|
||||||
// which may be the parameter to the *ast.CallExpr.
|
// which may be the parameter to the *ast.CallExpr.
|
||||||
// Don't show signature help in this case.
|
// 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 {
|
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.
|
// Get the object representing the function, if available.
|
||||||
@ -82,12 +82,12 @@ FindCall:
|
|||||||
// Get the type information for the function being called.
|
// Get the type information for the function being called.
|
||||||
sigType := pkg.GetTypesInfo().TypeOf(callExpr.Fun)
|
sigType := pkg.GetTypesInfo().TypeOf(callExpr.Fun)
|
||||||
if sigType == nil {
|
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)
|
sig, _ := sigType.Underlying().(*types.Signature)
|
||||||
if sig == nil {
|
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())
|
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) {
|
func builtinSignature(ctx context.Context, v View, callExpr *ast.CallExpr, name string, pos token.Pos) (*SignatureInformation, error) {
|
||||||
decl, ok := lookupBuiltinDecl(v, name).(*ast.FuncDecl)
|
decl, ok := lookupBuiltinDecl(v, name).(*ast.FuncDecl)
|
||||||
if !ok {
|
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)
|
params, _ := formatFieldList(ctx, v, decl.Type.Params)
|
||||||
results, writeResultParens := formatFieldList(ctx, v, decl.Type.Results)
|
results, writeResultParens := formatFieldList(ctx, v, decl.Type.Results)
|
||||||
|
@ -6,7 +6,6 @@ package source
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/token"
|
"go/token"
|
||||||
@ -14,6 +13,7 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SymbolKind int
|
type SymbolKind int
|
||||||
@ -52,7 +52,7 @@ func DocumentSymbols(ctx context.Context, f GoFile) ([]Symbol, error) {
|
|||||||
}
|
}
|
||||||
pkg := f.GetPackage(ctx)
|
pkg := f.GetPackage(ctx)
|
||||||
if pkg == nil || pkg.IsIllTyped() {
|
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()
|
info := pkg.GetTypesInfo()
|
||||||
q := qualifier(file, pkg.GetTypes(), info)
|
q := qualifier(file, pkg.GetTypes(), info)
|
||||||
|
@ -7,7 +7,6 @@ package lsp
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"golang.org/x/tools/internal/jsonrpc2"
|
"golang.org/x/tools/internal/jsonrpc2"
|
||||||
"golang.org/x/tools/internal/lsp/protocol"
|
"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/log"
|
||||||
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) didOpen(ctx context.Context, params *protocol.DidOpenTextDocumentParams) error {
|
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 {
|
if !isFullChange {
|
||||||
switch s.textDocumentSyncKind {
|
switch s.textDocumentSyncKind {
|
||||||
case protocol.Full:
|
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:
|
case protocol.Incremental:
|
||||||
// Determine the new file content.
|
// Determine the new file content.
|
||||||
var err error
|
var err error
|
||||||
|
@ -6,11 +6,11 @@ package lsp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"golang.org/x/tools/internal/lsp/protocol"
|
"golang.org/x/tools/internal/lsp/protocol"
|
||||||
"golang.org/x/tools/internal/lsp/source"
|
"golang.org/x/tools/internal/lsp/source"
|
||||||
"golang.org/x/tools/internal/span"
|
"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) {
|
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)
|
gof, ok := f.(source.GoFile)
|
||||||
if !ok {
|
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
|
return gof, m, nil
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,10 @@ package lsp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"golang.org/x/tools/internal/lsp/protocol"
|
"golang.org/x/tools/internal/lsp/protocol"
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) changeFolders(ctx context.Context, event protocol.WorkspaceFoldersChangeEvent) error {
|
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 {
|
if view != nil {
|
||||||
view.Shutdown(ctx)
|
view.Shutdown(ctx)
|
||||||
} else {
|
} 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user