From a835c872fcea276c439f23036693a44975ace28c Mon Sep 17 00:00:00 2001 From: Muir Manders Date: Sat, 5 Dec 2020 12:43:06 -0800 Subject: [PATCH] internal/lsp/source: omit assign stmt LHS in RHS completion In the below example: fooBar := fooB<> We will no longer suggest "fooBar" at <>. Fixes golang/go#39203. Change-Id: Ie1450397ce3de4f21fb0862c1a4f0fe2812325fd Reviewed-on: https://go-review.googlesource.com/c/tools/+/275693 Run-TryBot: Muir Manders gopls-CI: kokoro TryBot-Result: Go Bot Reviewed-by: Rebecca Stambler Trust: Rebecca Stambler Trust: Robert Findley --- internal/lsp/source/completion/completion.go | 10 ++++------ internal/lsp/source/completion/util.go | 17 ++++++++++++++--- internal/lsp/testdata/assign/assign.go.in | 8 ++++++++ internal/lsp/testdata/summary.txt.golden | 2 +- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/internal/lsp/source/completion/completion.go b/internal/lsp/source/completion/completion.go index e720e78cc0..14afb8f58e 100644 --- a/internal/lsp/source/completion/completion.go +++ b/internal/lsp/source/completion/completion.go @@ -1284,12 +1284,10 @@ func (c *completer) lexical(ctx context.Context) error { } } - // Don't use LHS of value spec in RHS. - if vs := enclosingValueSpec(c.path); vs != nil { - for _, ident := range vs.Names { - if obj.Pos() == ident.Pos() { - continue Names - } + // Don't use LHS of decl in RHS. + for _, ident := range enclosingDeclLHS(c.path) { + if obj.Pos() == ident.Pos() { + continue Names } } diff --git a/internal/lsp/source/completion/util.go b/internal/lsp/source/completion/util.go index 6d0883e0ff..673390625d 100644 --- a/internal/lsp/source/completion/util.go +++ b/internal/lsp/source/completion/util.go @@ -195,10 +195,21 @@ func enclosingSelector(path []ast.Node, pos token.Pos) *ast.SelectorExpr { return nil } -func enclosingValueSpec(path []ast.Node) *ast.ValueSpec { +// enclosingDeclLHS returns LHS idents from containing value spec or +// assign statement. +func enclosingDeclLHS(path []ast.Node) []*ast.Ident { for _, n := range path { - if vs, ok := n.(*ast.ValueSpec); ok { - return vs + switch n := n.(type) { + case *ast.ValueSpec: + return n.Names + case *ast.AssignStmt: + ids := make([]*ast.Ident, 0, len(n.Lhs)) + for _, e := range n.Lhs { + if id, ok := e.(*ast.Ident); ok { + ids = append(ids, id) + } + } + return ids } } diff --git a/internal/lsp/testdata/assign/assign.go.in b/internal/lsp/testdata/assign/assign.go.in index 3fe256e66b..8c00ae9e0e 100644 --- a/internal/lsp/testdata/assign/assign.go.in +++ b/internal/lsp/testdata/assign/assign.go.in @@ -16,3 +16,11 @@ func _() { func _() { var a string = a //@complete(" //") } + +func _() { + fooBar := fooBa //@complete(" //"),item(assignFooBar, "fooBar", "", "var") + abc, fooBar := 123, fooBa //@complete(" //", assignFooBar) + { + fooBar := fooBa //@complete(" //", assignFooBar) + } +} diff --git a/internal/lsp/testdata/summary.txt.golden b/internal/lsp/testdata/summary.txt.golden index 8d095cbb51..a2bb47340b 100644 --- a/internal/lsp/testdata/summary.txt.golden +++ b/internal/lsp/testdata/summary.txt.golden @@ -1,7 +1,7 @@ -- summary -- CallHierarchyCount = 1 CodeLensCount = 5 -CompletionsCount = 255 +CompletionsCount = 258 CompletionSnippetCount = 88 UnimportedCompletionsCount = 5 DeepCompletionsCount = 5