internal/lsp: fix completion insertion with non-identifier suffix
Completions like "foo.Bar(baz.<>)" were replacing one too many
characters resulting in "foo.Bar(baz.Qux()". This is because the go
parser adds a phantom "_" identifier when parsing "foo.". We thought
the "_" was really there, so we were issuing text edits to replace
it. Fix by ignoring "_" selectors when the cursor is positioned to
their left.
Fixes microsoft/vscode-go#2525
Change-Id: I1233a9d6275e2a79b666ca0230862238160b4aab
GitHub-Last-Rev: de9a3f00187b1b9bfcc4e497461f4602ae6f8923
GitHub-Pull-Request: golang/tools#104
Reviewed-on: https://go-review.googlesource.com/c/tools/+/178217
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/internal/lsp/source/completion.go b/internal/lsp/source/completion.go
index de010b7..e1d03dc 100644
--- a/internal/lsp/source/completion.go
+++ b/internal/lsp/source/completion.go
@@ -312,7 +312,14 @@
}
case *ast.SelectorExpr:
- c.setSurrounding(n.Sel)
+ // The go parser inserts a phantom "_" Sel node when the selector is
+ // not followed by an identifier or a "(". The "_" isn't actually in
+ // the text, so don't think it is our surrounding.
+ // TODO: Find a way to differentiate between phantom "_" and real "_",
+ // perhaps by checking if "_" is present in file contents.
+ if n.Sel.Name != "_" || c.pos != n.Sel.Pos() {
+ c.setSurrounding(n.Sel)
+ }
if err := c.selector(n); err != nil {
return nil, nil, err