internal/lsp: do not complete inside comments

Fixes golang/go#29370

Change-Id: I160b00f95fe44b2d87f66dc5842bb3a124e0292c
GitHub-Last-Rev: 924c13bc86f947ca01b291e7cc0d171164c2c856
GitHub-Pull-Request: golang/tools#69
Reviewed-on: https://go-review.googlesource.com/c/157678
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
diff --git a/internal/lsp/source/completion.go b/internal/lsp/source/completion.go
index 4bb2d3e..6df0f57 100644
--- a/internal/lsp/source/completion.go
+++ b/internal/lsp/source/completion.go
@@ -59,6 +59,7 @@
 	if path == nil {
 		return nil, "", fmt.Errorf("cannot find node enclosing position")
 	}
+
 	// If the position is not an identifier but immediately follows
 	// an identifier or selector period (as is common when
 	// requesting a completion), use the path to the preceding node.
@@ -71,6 +72,11 @@
 		}
 	}
 
+	// Skip completion inside comment blocks.
+	if p, ok := path[0].(*ast.File); ok && isCommentNode(p, pos) {
+		return items, prefix, nil
+	}
+
 	// Save certain facts about the query position, including the expected type
 	// of the completion result, the signature of the function enclosing the
 	// position.
@@ -246,6 +252,24 @@
 	return items
 }
 
+// isCommentNode checks if given token position is inside ast.Comment node.
+func isCommentNode(root ast.Node, pos token.Pos) bool {
+	var found bool
+	ast.Inspect(root, func(n ast.Node) bool {
+		if n == nil {
+			return false
+		}
+		if n.Pos() <= pos && pos <= n.End() {
+			if _, ok := n.(*ast.Comment); ok {
+				found = true
+				return false
+			}
+		}
+		return true
+	})
+	return found
+}
+
 // complit finds completions for field names inside a composite literal.
 // It reports whether the node was handled as part of a composite literal.
 func complit(path []ast.Node, pos token.Pos, pkg *types.Package, info *types.Info, found finder) (items []CompletionItem, prefix string, ok bool) {
diff --git a/internal/lsp/testdata/foo/foo.go b/internal/lsp/testdata/foo/foo.go
index cc515c2..eb06d32 100644
--- a/internal/lsp/testdata/foo/foo.go
+++ b/internal/lsp/testdata/foo/foo.go
@@ -20,4 +20,5 @@
 }
 
 //@complete("", Foo, IntFoo, StructFoo)
+
 type IntFoo int //@item(IntFoo, "IntFoo", "int", "type")