internal/lsp: don't show blank identifiers in outline

Fixes golang/go#41654

Change-Id: Ie8ac59051e19d2d312ba48b6649660f53b573731
Reviewed-on: https://go-review.googlesource.com/c/tools/+/259142
Trust: Rebecca Stambler <rstambler@golang.org>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Peter Weinberger <pjw@google.com>
diff --git a/internal/lsp/cmd/test/workspace_symbol.go b/internal/lsp/cmd/test/workspace_symbol.go
index 796dfb8..96d9504 100644
--- a/internal/lsp/cmd/test/workspace_symbol.go
+++ b/internal/lsp/cmd/test/workspace_symbol.go
@@ -11,6 +11,7 @@
 	"testing"
 
 	"golang.org/x/tools/internal/lsp/protocol"
+	"golang.org/x/tools/internal/lsp/tests"
 )
 
 func (r *runner) WorkspaceSymbols(t *testing.T, query string, expectedSymbols []protocol.SymbolInformation, dirs map[string]struct{}) {
@@ -46,7 +47,7 @@
 	}))
 
 	if expect != got {
-		t.Errorf("workspace_symbol failed for %s expected:\n%s\ngot:\n%s", query, expect, got)
+		t.Errorf("workspace_symbol failed for %s:\n%s", query, tests.Diff(expect, got))
 	}
 }
 
diff --git a/internal/lsp/source/symbols.go b/internal/lsp/source/symbols.go
index 0565062..16fb222 100644
--- a/internal/lsp/source/symbols.go
+++ b/internal/lsp/source/symbols.go
@@ -32,6 +32,9 @@
 	for _, decl := range pgf.File.Decls {
 		switch decl := decl.(type) {
 		case *ast.FuncDecl:
+			if decl.Name.Name == "_" {
+				continue
+			}
 			if obj := info.ObjectOf(decl.Name); obj != nil {
 				fs, err := funcSymbol(snapshot, pkg, decl, obj, q)
 				if err != nil {
@@ -48,6 +51,9 @@
 			for _, spec := range decl.Specs {
 				switch spec := spec.(type) {
 				case *ast.TypeSpec:
+					if spec.Name.Name == "_" {
+						continue
+					}
 					if obj := info.ObjectOf(spec.Name); obj != nil {
 						ts, err := typeSymbol(snapshot, pkg, info, spec, obj, q)
 						if err != nil {
@@ -58,6 +64,9 @@
 					}
 				case *ast.ValueSpec:
 					for _, name := range spec.Names {
+						if name.Name == "_" {
+							continue
+						}
 						if obj := info.ObjectOf(name); obj != nil {
 							vs, err := varSymbol(snapshot, pkg, decl, name, obj, q)
 							if err != nil {
diff --git a/internal/lsp/testdata/symbols/main.go b/internal/lsp/testdata/symbols/main.go
index 3da7139..8111250 100644
--- a/internal/lsp/testdata/symbols/main.go
+++ b/internal/lsp/testdata/symbols/main.go
@@ -4,6 +4,8 @@
 	"io"
 )
 
+var _ = 1
+
 var x = 42 //@mark(symbolsx, "x"), symbol("x", "x", "Variable", "", "main.x")
 
 const y = 43 //@symbol("y", "y", "Constant", "", "main.y")
@@ -34,6 +36,8 @@
 	return f.baz
 }
 
+func _() {}
+
 func (q *Quux) Do() {} //@mark(qDo, "Do"), symbol("(*Quux).Do", "Do", "Method", "", "main.Quux.Do")
 
 func main() { //@symbol("main", "main", "Function", "", "main.main")
diff --git a/internal/lsp/testdata/symbols/main.go.golden b/internal/lsp/testdata/symbols/main.go.golden
index 08d1da7..ebb6a8a 100644
--- a/internal/lsp/testdata/symbols/main.go.golden
+++ b/internal/lsp/testdata/symbols/main.go.golden
@@ -1,31 +1,31 @@
 -- symbols --
-x Variable 7:5-7:6
-y Constant 9:7-9:8
-Number Number 11:6-11:12
-Alias String 13:6-13:11
-NumberAlias Number 15:6-15:17
-Boolean Boolean 18:2-18:9
-BoolAlias Boolean 19:2-19:11
-Foo Struct 22:6-22:9
-	Bar Field 25:2-25:5
-	Quux Field 23:2-23:6
-	W Field 24:2-24:3
-	baz Field 26:2-26:5
-Quux Struct 29:6-29:10
-	X Field 30:2-30:3
-	Y Field 30:5-30:6
-(Foo).Baz Method 33:14-33:17
-(*Quux).Do Method 37:16-37:18
-main Function 39:6-39:10
-Stringer Interface 43:6-43:14
-	String Method 44:2-44:8
-ABer Interface 47:6-47:10
-	A Method 49:2-49:3
-	B Method 48:2-48:3
-WithEmbeddeds Interface 52:6-52:19
-	ABer Interface 54:2-54:6
-	Do Method 53:2-53:4
-	io.Writer Interface 55:2-55:11
-Dunk Function 58:6-58:10
-dunk Function 60:6-60:10
+x Variable 9:5-9:6
+y Constant 11:7-11:8
+Number Number 13:6-13:12
+Alias String 15:6-15:11
+NumberAlias Number 17:6-17:17
+Boolean Boolean 20:2-20:9
+BoolAlias Boolean 21:2-21:11
+Foo Struct 24:6-24:9
+	Bar Field 27:2-27:5
+	Quux Field 25:2-25:6
+	W Field 26:2-26:3
+	baz Field 28:2-28:5
+Quux Struct 31:6-31:10
+	X Field 32:2-32:3
+	Y Field 32:5-32:6
+(Foo).Baz Method 35:14-35:17
+(*Quux).Do Method 41:16-41:18
+main Function 43:6-43:10
+Stringer Interface 47:6-47:14
+	String Method 48:2-48:8
+ABer Interface 51:6-51:10
+	A Method 53:2-53:3
+	B Method 52:2-52:3
+WithEmbeddeds Interface 56:6-56:19
+	ABer Interface 58:2-58:6
+	Do Method 57:2-57:4
+	io.Writer Interface 59:2-59:11
+Dunk Function 62:6-62:10
+dunk Function 64:6-64:10
 
diff --git "a/internal/lsp/testdata/workspacesymbol/casesensitive/\041dunk.golden" "b/internal/lsp/testdata/workspacesymbol/casesensitive/\041dunk.golden"
index e990607..9b7b8b7 100644
--- "a/internal/lsp/testdata/workspacesymbol/casesensitive/\041dunk.golden"
+++ "b/internal/lsp/testdata/workspacesymbol/casesensitive/\041dunk.golden"
@@ -1,2 +1,2 @@
 -- workspace_symbol --
-symbols/main.go:58:6-10 main.Dunk Function
+symbols/main.go:62:6-10 main.Dunk Function
diff --git a/internal/lsp/testdata/workspacesymbol/casesensitive/dunk.golden b/internal/lsp/testdata/workspacesymbol/casesensitive/dunk.golden
index b8a91ea..018e3a8 100644
--- a/internal/lsp/testdata/workspacesymbol/casesensitive/dunk.golden
+++ b/internal/lsp/testdata/workspacesymbol/casesensitive/dunk.golden
@@ -1,2 +1,2 @@
 -- workspace_symbol --
-symbols/main.go:60:6-10 main.dunk Function
+symbols/main.go:64:6-10 main.dunk Function