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>
This commit is contained in:
pjw 2021-05-11 07:33:51 -04:00 committed by Peter Weinberger
parent 9cddb0ea22
commit 2db0265cb2
4 changed files with 27 additions and 2 deletions

View File

@ -511,9 +511,14 @@ func (e *encoded) definitionFor(x *ast.Ident) (tokenType, []string) {
// (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

View File

@ -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.

View File

@ -23,3 +23,12 @@ func weirⰀd() { /*😀*/ // comment
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

View File

@ -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