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