internal/lsp: add nil checks for ASTs and token
Fixes golang/go#32120 Updates golang/go#32132 Change-Id: Ib4bb8a4818be7dec468c46b72afc3dd57b35f155 Reviewed-on: https://go-review.googlesource.com/c/tools/+/178158 Run-TryBot: Rebecca Stambler <rstambler@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Cottrell <iancottrell@google.com>
This commit is contained in:
parent
faf83c64e9
commit
7e7c6e5214
|
@ -20,14 +20,13 @@ func (s *Server) documentLink(ctx context.Context, params *protocol.DocumentLink
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// find the import block
|
file := f.GetAST(ctx)
|
||||||
ast := f.GetAST(ctx)
|
if file == nil {
|
||||||
if ast == nil {
|
|
||||||
return nil, fmt.Errorf("no AST for %v", uri)
|
return nil, fmt.Errorf("no AST for %v", uri)
|
||||||
}
|
}
|
||||||
|
// Add a Godoc link for each imported package.
|
||||||
var result []protocol.DocumentLink
|
var result []protocol.DocumentLink
|
||||||
for _, imp := range ast.Imports {
|
for _, imp := range file.Imports {
|
||||||
spn, err := span.NewRange(f.GetFileSet(ctx), imp.Pos(), imp.End()).Span()
|
spn, err := span.NewRange(f.GetFileSet(ctx), imp.Pos(), imp.End()).Span()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -222,6 +222,9 @@ func (c *completer) found(obj types.Object, weight float64) {
|
||||||
// may tolerate imperfect matches as valid completion results, since users may make typos.
|
// may tolerate imperfect matches as valid completion results, since users may make typos.
|
||||||
func Completion(ctx context.Context, f GoFile, pos token.Pos) ([]CompletionItem, *Selection, error) {
|
func Completion(ctx context.Context, f GoFile, pos token.Pos) ([]CompletionItem, *Selection, error) {
|
||||||
file := f.GetAST(ctx)
|
file := f.GetAST(ctx)
|
||||||
|
if file == nil {
|
||||||
|
return nil, nil, fmt.Errorf("no AST for %s", f.URI())
|
||||||
|
}
|
||||||
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, fmt.Errorf("package for %s is ill typed", f.URI())
|
||||||
|
|
|
@ -20,12 +20,15 @@ import (
|
||||||
|
|
||||||
// Format formats a file with a given range.
|
// Format formats a file with a given range.
|
||||||
func Format(ctx context.Context, f GoFile, rng span.Range) ([]TextEdit, error) {
|
func Format(ctx context.Context, f GoFile, rng span.Range) ([]TextEdit, error) {
|
||||||
|
file := f.GetAST(ctx)
|
||||||
|
if file == nil {
|
||||||
|
return nil, fmt.Errorf("no AST for %s", f.URI())
|
||||||
|
}
|
||||||
pkg := f.GetPackage(ctx)
|
pkg := f.GetPackage(ctx)
|
||||||
if hasParseErrors(pkg.GetErrors()) {
|
if hasParseErrors(pkg.GetErrors()) {
|
||||||
return nil, fmt.Errorf("%s has parse errors, not formatting", f.URI())
|
return nil, fmt.Errorf("%s has parse errors, not formatting", f.URI())
|
||||||
}
|
}
|
||||||
fAST := f.GetAST(ctx)
|
path, exact := astutil.PathEnclosingInterval(file, rng.Start, rng.End)
|
||||||
path, exact := astutil.PathEnclosingInterval(fAST, 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, fmt.Errorf("no exact AST node matching the specified range")
|
||||||
}
|
}
|
||||||
|
@ -53,7 +56,11 @@ func hasParseErrors(errors []packages.Error) bool {
|
||||||
|
|
||||||
// Imports formats a file using the goimports tool.
|
// Imports formats a file using the goimports tool.
|
||||||
func Imports(ctx context.Context, f GoFile, rng span.Range) ([]TextEdit, error) {
|
func Imports(ctx context.Context, f GoFile, rng span.Range) ([]TextEdit, error) {
|
||||||
formatted, err := imports.Process(f.GetToken(ctx).Name(), f.GetContent(ctx), nil)
|
tok := f.GetToken(ctx)
|
||||||
|
if tok == nil {
|
||||||
|
return nil, fmt.Errorf("no token file for %s", f.URI())
|
||||||
|
}
|
||||||
|
formatted, err := imports.Process(tok.Name(), f.GetContent(ctx), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func Highlight(ctx context.Context, f GoFile, pos token.Pos) []span.Span {
|
func Highlight(ctx context.Context, f GoFile, pos token.Pos) []span.Span {
|
||||||
fAST := f.GetAST(ctx)
|
file := f.GetAST(ctx)
|
||||||
|
if file == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
fset := f.GetFileSet(ctx)
|
fset := f.GetFileSet(ctx)
|
||||||
path, _ := astutil.PathEnclosingInterval(fAST, pos, pos)
|
path, _ := astutil.PathEnclosingInterval(file, pos, pos)
|
||||||
if len(path) == 0 {
|
if len(path) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,19 +53,22 @@ func Identifier(ctx context.Context, v View, f GoFile, pos token.Pos) (*Identifi
|
||||||
|
|
||||||
// identifier checks a single position for a potential identifier.
|
// identifier checks a single position for a potential identifier.
|
||||||
func identifier(ctx context.Context, v View, f GoFile, pos token.Pos) (*IdentifierInfo, error) {
|
func identifier(ctx context.Context, v View, f GoFile, pos token.Pos) (*IdentifierInfo, error) {
|
||||||
fAST := f.GetAST(ctx)
|
file := f.GetAST(ctx)
|
||||||
|
if file == nil {
|
||||||
|
return nil, fmt.Errorf("no AST for %s", f.URI())
|
||||||
|
}
|
||||||
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, fmt.Errorf("package for %s is ill typed", f.URI())
|
||||||
}
|
}
|
||||||
|
|
||||||
path, _ := astutil.PathEnclosingInterval(fAST, 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, fmt.Errorf("can't find node enclosing position")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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(f, fAST, pkg, pos); result != nil || err != nil {
|
if result, err := importSpec(f, file, pkg, pos); result != nil || err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,10 @@ type ParameterInformation struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func SignatureHelp(ctx context.Context, f GoFile, pos token.Pos) (*SignatureInformation, error) {
|
func SignatureHelp(ctx context.Context, f GoFile, pos token.Pos) (*SignatureInformation, error) {
|
||||||
fAST := f.GetAST(ctx)
|
file := f.GetAST(ctx)
|
||||||
|
if file == nil {
|
||||||
|
return nil, fmt.Errorf("no AST for %s", f.URI())
|
||||||
|
}
|
||||||
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, fmt.Errorf("package for %s is ill typed", f.URI())
|
||||||
|
@ -33,7 +36,7 @@ func SignatureHelp(ctx context.Context, f GoFile, pos token.Pos) (*SignatureInfo
|
||||||
|
|
||||||
// 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(fAST, 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, fmt.Errorf("cannot find node enclosing position")
|
||||||
}
|
}
|
||||||
|
@ -74,7 +77,7 @@ func SignatureHelp(ctx context.Context, f GoFile, pos token.Pos) (*SignatureInfo
|
||||||
return nil, fmt.Errorf("cannot find signature for Fun %[1]T (%[1]v)", callExpr.Fun)
|
return nil, fmt.Errorf("cannot find signature for Fun %[1]T (%[1]v)", callExpr.Fun)
|
||||||
}
|
}
|
||||||
|
|
||||||
qf := qualifier(fAST, pkg.GetTypes(), pkg.GetTypesInfo())
|
qf := qualifier(file, pkg.GetTypes(), pkg.GetTypesInfo())
|
||||||
params := formatParams(sig.Params(), sig.Variadic(), qf)
|
params := formatParams(sig.Params(), sig.Variadic(), qf)
|
||||||
results, writeResultParens := formatResults(sig.Results(), qf)
|
results, writeResultParens := formatResults(sig.Results(), qf)
|
||||||
activeParam := activeParameter(callExpr, sig.Params().Len(), sig.Variadic(), pos)
|
activeParam := activeParameter(callExpr, sig.Params().Len(), sig.Variadic(), pos)
|
||||||
|
|
|
@ -43,7 +43,13 @@ type Symbol struct {
|
||||||
func DocumentSymbols(ctx context.Context, f GoFile) []Symbol {
|
func DocumentSymbols(ctx context.Context, f GoFile) []Symbol {
|
||||||
fset := f.GetFileSet(ctx)
|
fset := f.GetFileSet(ctx)
|
||||||
file := f.GetAST(ctx)
|
file := f.GetAST(ctx)
|
||||||
|
if file == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
pkg := f.GetPackage(ctx)
|
pkg := f.GetPackage(ctx)
|
||||||
|
if pkg == nil || pkg.IsIllTyped() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
info := pkg.GetTypesInfo()
|
info := pkg.GetTypesInfo()
|
||||||
q := qualifier(file, pkg.GetTypes(), info)
|
q := qualifier(file, pkg.GetTypes(), info)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue