internal/lsp/cache: initialize view before LookupBuiltin
This will crash otherwise.
Change-Id: I4fbce813283291792ed21fa5d83186ec59543ff1
Reviewed-on: https://go-review.googlesource.com/c/tools/+/214948
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
diff --git a/internal/lsp/cache/view.go b/internal/lsp/cache/view.go
index b6a529c..8e7ddf8 100644
--- a/internal/lsp/cache/view.go
+++ b/internal/lsp/cache/view.go
@@ -181,8 +181,11 @@
return newView, err
}
-func (v *view) LookupBuiltin(name string) (*ast.Object, error) {
- data := v.builtin.handle.Get(context.Background())
+func (v *view) LookupBuiltin(ctx context.Context, name string) (*ast.Object, error) {
+ if err := v.awaitInitialized(ctx); err != nil {
+ return nil, err
+ }
+ data := v.builtin.handle.Get(ctx)
if data == nil {
return nil, errors.Errorf("unexpected nil builtin package")
}
diff --git a/internal/lsp/source/completion_builtin.go b/internal/lsp/source/completion_builtin.go
index ddead70..64da769 100644
--- a/internal/lsp/source/completion_builtin.go
+++ b/internal/lsp/source/completion_builtin.go
@@ -13,7 +13,7 @@
// argument. It attempts to use the AST hints from builtin.go where
// possible.
func (c *completer) builtinArgKind(obj types.Object, call *ast.CallExpr) objKind {
- astObj, err := c.snapshot.View().LookupBuiltin(obj.Name())
+ astObj, err := c.snapshot.View().LookupBuiltin(c.ctx, obj.Name())
if err != nil {
return 0
}
diff --git a/internal/lsp/source/completion_format.go b/internal/lsp/source/completion_format.go
index f9a5aa4..950e06b 100644
--- a/internal/lsp/source/completion_format.go
+++ b/internal/lsp/source/completion_format.go
@@ -47,7 +47,7 @@
// expandFuncCall mutates the completion label, detail, and snippet
// to that of an invocation of sig.
expandFuncCall := func(sig *types.Signature) {
- params := formatParams(c.snapshot, c.pkg, sig, c.qf)
+ params := formatParams(c.ctx, c.snapshot, c.pkg, sig, c.qf)
snip = c.functionCallSnippet(label, params)
results, writeParens := formatResults(sig.Results(), c.qf)
detail = "func" + formatFunction(params, results, writeParens)
@@ -68,7 +68,7 @@
detail = "struct{...}" // for anonymous structs
} else if obj.IsField() {
var err error
- detail, err = formatFieldType(c.snapshot, c.pkg, obj, c.qf)
+ detail, err = formatFieldType(c.ctx, c.snapshot, c.pkg, obj, c.qf)
if err != nil {
detail = types.TypeString(obj.Type(), c.qf)
}
@@ -190,7 +190,7 @@
if err != nil {
return item, nil
}
- ident, err := findIdentifier(c.snapshot, pkg, file, obj.Pos())
+ ident, err := findIdentifier(c.ctx, c.snapshot, pkg, file, obj.Pos())
if err != nil {
return item, nil
}
@@ -245,7 +245,7 @@
item.Kind = protocol.ConstantCompletion
case *types.Builtin:
item.Kind = protocol.FunctionCompletion
- astObj, err := c.snapshot.View().LookupBuiltin(obj.Name())
+ astObj, err := c.snapshot.View().LookupBuiltin(c.ctx, obj.Name())
if err != nil {
log.Error(c.ctx, "no builtin package", err)
break
diff --git a/internal/lsp/source/identifier.go b/internal/lsp/source/identifier.go
index d4c7c95..987bae2 100644
--- a/internal/lsp/source/identifier.go
+++ b/internal/lsp/source/identifier.go
@@ -79,19 +79,19 @@
if err != nil {
return nil, err
}
- return findIdentifier(snapshot, pkg, file, rng.Start)
+ return findIdentifier(ctx, snapshot, pkg, file, rng.Start)
}
var ErrNoIdentFound = errors.New("no identifier found")
-func findIdentifier(snapshot Snapshot, pkg Package, file *ast.File, pos token.Pos) (*IdentifierInfo, error) {
- if result, err := identifier(snapshot, pkg, file, pos); err != nil || result != nil {
+func findIdentifier(ctx context.Context, snapshot Snapshot, pkg Package, file *ast.File, pos token.Pos) (*IdentifierInfo, error) {
+ if result, err := identifier(ctx, snapshot, pkg, file, pos); err != nil || result != nil {
return result, err
}
// If the position is not an identifier but immediately follows
// an identifier or selector period (as is common when
// requesting a completion), use the path to the preceding node.
- ident, err := identifier(snapshot, pkg, file, pos-1)
+ ident, err := identifier(ctx, snapshot, pkg, file, pos-1)
if ident == nil && err == nil {
err = ErrNoIdentFound
}
@@ -99,7 +99,7 @@
}
// identifier checks a single position for a potential identifier.
-func identifier(s Snapshot, pkg Package, file *ast.File, pos token.Pos) (*IdentifierInfo, error) {
+func identifier(ctx context.Context, s Snapshot, pkg Package, file *ast.File, pos token.Pos) (*IdentifierInfo, error) {
var err error
// Handle import specs separately, as there is no formal position for a package declaration.
@@ -153,7 +153,7 @@
// Handle builtins separately.
if result.Declaration.obj.Parent() == types.Universe {
- astObj, err := view.LookupBuiltin(result.Name)
+ astObj, err := view.LookupBuiltin(ctx, result.Name)
if err != nil {
return nil, err
}
diff --git a/internal/lsp/source/signature_help.go b/internal/lsp/source/signature_help.go
index ac7141b..bb6a83f 100644
--- a/internal/lsp/source/signature_help.go
+++ b/internal/lsp/source/signature_help.go
@@ -101,7 +101,7 @@
}
qf := qualifier(file, pkg.GetTypes(), pkg.GetTypesInfo())
- params := formatParams(snapshot, pkg, sig, qf)
+ params := formatParams(ctx, snapshot, pkg, sig, qf)
results, writeResultParens := formatResults(sig.Results(), qf)
activeParam := activeParameter(callExpr, sig.Params().Len(), sig.Variadic(), rng.Start)
@@ -136,7 +136,7 @@
}
func builtinSignature(ctx context.Context, v View, callExpr *ast.CallExpr, name string, pos token.Pos) (*SignatureInformation, error) {
- astObj, err := v.LookupBuiltin(name)
+ astObj, err := v.LookupBuiltin(ctx, name)
if err != nil {
return nil, err
}
diff --git a/internal/lsp/source/util.go b/internal/lsp/source/util.go
index 9d729ec..7039fb8 100644
--- a/internal/lsp/source/util.go
+++ b/internal/lsp/source/util.go
@@ -488,11 +488,11 @@
return false
}
-func formatParams(s Snapshot, pkg Package, sig *types.Signature, qf types.Qualifier) []string {
+func formatParams(ctx context.Context, s Snapshot, pkg Package, sig *types.Signature, qf types.Qualifier) []string {
params := make([]string, 0, sig.Params().Len())
for i := 0; i < sig.Params().Len(); i++ {
el := sig.Params().At(i)
- typ, err := formatFieldType(s, pkg, el, qf)
+ typ, err := formatFieldType(ctx, s, pkg, el, qf)
if err != nil {
typ = types.TypeString(el.Type(), qf)
}
@@ -511,12 +511,12 @@
return params
}
-func formatFieldType(s Snapshot, srcpkg Package, obj types.Object, qf types.Qualifier) (string, error) {
+func formatFieldType(ctx context.Context, s Snapshot, srcpkg Package, obj types.Object, qf types.Qualifier) (string, error) {
file, pkg, err := findPosInPackage(s.View(), srcpkg, obj.Pos())
if err != nil {
return "", err
}
- ident, err := findIdentifier(s, pkg, file, obj.Pos())
+ ident, err := findIdentifier(ctx, s, pkg, file, obj.Pos())
if err != nil {
return "", err
}
diff --git a/internal/lsp/source/view.go b/internal/lsp/source/view.go
index e8da7bc..729ed5e 100644
--- a/internal/lsp/source/view.go
+++ b/internal/lsp/source/view.go
@@ -93,7 +93,7 @@
Folder() span.URI
// LookupBuiltin returns the go/ast.Object for the given name in the builtin package.
- LookupBuiltin(name string) (*ast.Object, error)
+ LookupBuiltin(ctx context.Context, name string) (*ast.Object, error)
// BackgroundContext returns a context used for all background processing
// on behalf of this view.