internal/lsp: in semantic tokens, better distinguish between types and variables

If A is a type, then in
type B {
  A
} it is a type, but in
type C {
  A int
 }
it is a variable (and similarly in function types). The old code got this wrong.

Fixes: golang/go#46068

Change-Id: Ib7320914de81d2b7377214f53f99f4fea25e00fb
Reviewed-on: https://go-review.googlesource.com/c/tools/+/318749
Run-TryBot: Peter Weinberger <pjw@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Peter Weinberger <pjw@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
diff --git a/internal/lsp/semantic.go b/internal/lsp/semantic.go
index b7746bf..8ef30ff 100644
--- a/internal/lsp/semantic.go
+++ b/internal/lsp/semantic.go
@@ -511,9 +511,14 @@
 			// (type A func(b uint64)) (err error)
 			// b and err should not be tokType, but tokVaraible
 			// and in GenDecl/TpeSpec/StructType/FieldList/Field/Ident
-			// (type A struct{b uint64})
+			// (type A struct{b uint64}
+			// but on type B struct{C}), C is a type, but is not being defined.
 			fldm := e.stack[len(e.stack)-2]
-			if _, ok := fldm.(*ast.Field); ok {
+			if fld, ok := fldm.(*ast.Field); ok {
+				// if len(fld.names) == 0 this is a tokType, being used
+				if len(fld.Names) == 0 {
+					return tokType, nil
+				}
 				return tokVariable, mods
 			}
 			return tokType, mods
diff --git a/internal/lsp/testdata/semantic/README.md b/internal/lsp/testdata/semantic/README.md
new file mode 100644
index 0000000..00ec19a
--- /dev/null
+++ b/internal/lsp/testdata/semantic/README.md
@@ -0,0 +1,2 @@
+The golden files are the output of `gopls semtok <src-file>`, with `-- semantic --`
+inserted as the first line (the spaces are mandatory) and an extra newline at the end.
diff --git a/internal/lsp/testdata/semantic/b.go b/internal/lsp/testdata/semantic/b.go
index e633f4e..a536f97 100644
--- a/internal/lsp/testdata/semantic/b.go
+++ b/internal/lsp/testdata/semantic/b.go
@@ -23,3 +23,12 @@
 multiline */ /*
 multiline
 */
+type AA int
+type BB struct {
+	AA
+}
+type CC struct {
+	AA int
+}
+type D func(aa AA) (BB error)
+type E func(AA) BB
diff --git a/internal/lsp/testdata/semantic/b.go.golden b/internal/lsp/testdata/semantic/b.go.golden
index 48be5ea..863a68c 100644
--- a/internal/lsp/testdata/semantic/b.go.golden
+++ b/internal/lsp/testdata/semantic/b.go.golden
@@ -24,4 +24,13 @@
 /*⇒12,comment,[]*/multiline */ /*⇒2,comment,[]*//*
 /*⇒9,comment,[]*/multiline
 /*⇒2,comment,[]*/*/
+/*⇒4,keyword,[]*/type /*⇒2,type,[definition]*/AA /*⇒3,type,[defaultLibrary]*/int
+/*⇒4,keyword,[]*/type /*⇒2,type,[definition]*/BB /*⇒6,keyword,[]*/struct {
+	/*⇒2,type,[]*/AA
+}
+/*⇒4,keyword,[]*/type /*⇒2,type,[definition]*/CC /*⇒6,keyword,[]*/struct {
+	/*⇒2,variable,[definition]*/AA /*⇒3,type,[defaultLibrary]*/int
+}
+/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/D /*⇒4,keyword,[]*/func(/*⇒2,variable,[definition]*/aa /*⇒2,type,[]*/AA) (/*⇒2,variable,[definition]*/BB /*⇒5,type,[]*/error)
+/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/E /*⇒4,keyword,[]*/func(/*⇒2,type,[]*/AA) /*⇒2,type,[]*/BB