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