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>
This commit is contained in:
Rebecca Stambler 2019-04-25 17:19:24 -04:00
parent 4eab536980
commit ad9eeb8003
3 changed files with 18 additions and 2 deletions

View File

@ -239,6 +239,10 @@ func lexical(path []ast.Node, pos token.Pos, pkg *types.Package, info *types.Inf
} }
scopes = append(scopes, pkg.Scope(), types.Universe) 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. // Process scopes innermost first.
for i, scope := range scopes { for i, scope := range scopes {
if scope == nil { if scope == nil {
@ -272,9 +276,13 @@ func lexical(path []ast.Node, pos token.Pos, pkg *types.Package, info *types.Inf
if scope == types.Universe { if scope == types.Universe {
score *= 0.1 score *= 0.1
} }
// 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) items = found(obj, score, items)
} }
} }
}
return items return items
} }

View File

@ -19,4 +19,12 @@ func _() {
} }
} }
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) type IntFoo int //@item(IntFoo, "IntFoo", "int", "type"),complete("", Foo, IntFoo, StructFoo)

View File

@ -27,7 +27,7 @@ import (
// We hardcode the expected number of test cases to ensure that all tests // 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. // are being executed. If a test is added, this number must be changed.
const ( const (
ExpectedCompletionsCount = 84 ExpectedCompletionsCount = 85
ExpectedDiagnosticsCount = 17 ExpectedDiagnosticsCount = 17
ExpectedFormatCount = 4 ExpectedFormatCount = 4
ExpectedDefinitionsCount = 21 ExpectedDefinitionsCount = 21