internal/lsp: handle shadowed variables in lexical completions
Fixes golang/go#31621
Change-Id: I6d5cfde5d5bebc704c9178d40bb93801b255e01c
Reviewed-on: https://go-review.googlesource.com/c/tools/+/173958
Reviewed-by: Ian Cottrell <iancottrell@google.com>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
diff --git a/internal/lsp/source/completion.go b/internal/lsp/source/completion.go
index 1a8fc68..d9879f5 100644
--- a/internal/lsp/source/completion.go
+++ b/internal/lsp/source/completion.go
@@ -239,6 +239,10 @@
}
scopes = append(scopes, pkg.Scope(), types.Universe)
+ // Track seen variables to avoid showing completions for shadowed variables.
+ // This works since we look at scopes from innermost to outermost.
+ seen := make(map[string]struct{})
+
// Process scopes innermost first.
for i, scope := range scopes {
if scope == nil {
@@ -272,7 +276,11 @@
if scope == types.Universe {
score *= 0.1
}
- items = found(obj, score, items)
+ // If we haven't already added a candidate for an object with this name.
+ if _, ok := seen[obj.Name()]; !ok {
+ seen[obj.Name()] = struct{}{}
+ items = found(obj, score, items)
+ }
}
}
return items
diff --git a/internal/lsp/testdata/foo/foo.go b/internal/lsp/testdata/foo/foo.go
index acd6cd1..ab588f1 100644
--- a/internal/lsp/testdata/foo/foo.go
+++ b/internal/lsp/testdata/foo/foo.go
@@ -19,4 +19,12 @@
}
}
+func _() {
+ shadowed := 123
+ {
+ shadowed := "hi" //@item(shadowed, "shadowed", "string", "var")
+ sha //@complete("a", shadowed)
+ }
+}
+
type IntFoo int //@item(IntFoo, "IntFoo", "int", "type"),complete("", Foo, IntFoo, StructFoo)
diff --git a/internal/lsp/tests/tests.go b/internal/lsp/tests/tests.go
index 7948b42..73c30e9 100644
--- a/internal/lsp/tests/tests.go
+++ b/internal/lsp/tests/tests.go
@@ -27,7 +27,7 @@
// We hardcode the expected number of test cases to ensure that all tests
// are being executed. If a test is added, this number must be changed.
const (
- ExpectedCompletionsCount = 84
+ ExpectedCompletionsCount = 85
ExpectedDiagnosticsCount = 17
ExpectedFormatCount = 4
ExpectedDefinitionsCount = 21