Description
gopls version
Build info
golang.org/x/tools/gopls v0.0.0-20240816163142-66adacf20fc4
golang.org/x/tools/gopls@v0.0.0-20240816163142-66adacf20fc4 h1:iSreTB1mHFYjQkoNmGjFjKRGkrhedt4wmfg
47nKSo28=
github.com/BurntSushi/toml@v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
github.com/google/go-cmp@v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
golang.org/x/exp/typeparams@v0.0.0-20221212164502-fae10dda9338 h1:2O2DON6y3XMJiQRAS1UWU+54aec2uopH
3x7MAiqGW6Y=
golang.org/x/mod@v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/sync@v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/telemetry@v0.0.0-20240712210958-268b4a8ec2d7 h1:nU8/tAV/21mkPrCjACUeSibjhynTovgRMXc32
+Y1Aec=
golang.org/x/text@v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/tools@v0.24.1-0.20240816163142-66adacf20fc4 h1:PoPnfVMls3TamN2+Zq6FsI1uSjUOqW1mt6AXfY
w3kdw=
golang.org/x/vuln@v1.0.4 h1:SP0mPeg2PmGCu03V+61EcQiOjmpri2XijexKdzv8Z1I=
honnef.co/go/tools@v0.4.7 h1:9MDAWxMoSnB6QoSqiVr7P5mtkT9pOc1kSxchzPCnqJs=
mvdan.cc/gofumpt@v0.6.0 h1:G3QvahNDmpD+Aek/bNOLrFR2XC6ZAdo62dZu65gmwGo=
mvdan.cc/xurls/v2@v2.5.0 h1:lyBNOm8Wo71UknhUs4QTFUNNMyxy2JEIaKKo0RWOh+8=
go: go1.22.4
go env
GO111MODULE='auto'
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/xzb/Library/Caches/go-build'
GOENV='/Users/xzb/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/xzb/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/xzb/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.22.4'
GCCGO='gccgo'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD=''
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -f
file-prefix-map=/var/folders/gv/r110hgbx1gbgzp95kf_q71x40000gn/T/go-build3574151232=/tmp/go-build -gno
-record-gcc-switches -fno-common'
What did you do?
in semtok.go This does not have any actual implementation, and lack of interface color make it very hard to decide wether a param/return variable is a interface or a struct
What did you see happen?
The output of :inspect shows A and B both have
Semantic Tokens
- @lsp.type.type.go links to Type priority: 125
- @lsp.mod.definition.go links to @lsp priority: 126
- @lsp.typemod.type.definition.go links to @lsp priority: 127
What did you expect to see?
I want to see different colors of struct and interface in definition and param position. I'd like to implement this if it is not that hard, thanks to any guidance in advance!
Editor and settings
neovim
Logs
No response
Activity
gabyhelp commentedon Aug 20, 2024
Related Issues and Documentation
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
adonovan commentedon Aug 22, 2024
Semantic tokens are mostly concerned with properties of identifiers, which refer to symbols (named entities). The interesting properties of symbols in Go are things like whether they are var/func/const/type/label, and so on; the actual underlying type (map or channel, say), is not something that semantic tokens cares about. In Go, interface is more like map and channel than like var/func/const/type. So I argue that it's not an appropriate token type for us to report. (By contrast, in Java, "class" and "interface" are properties of the declared symbol, so it does make sense to report them.)
xzbdmw commentedon Aug 22, 2024
But they can be easily identified by regex and treesitter, while recognizing whether a typename is an interface requires true understanding of code as the term semantic highlights implies.
Hmm at leat interface looks like the same abstract level as an concrete type despite it is itself a type, given interface are so widespread in codebase and semantically different from a concrete struct type, the ability to distinguish them brings real values, especially in an unfamaliar codebase.
adonovan commentedon Aug 23, 2024
I'm not sure I follow. Why is knowing that a symbol's type is an interface more important than knowing that it's a struct, map, channel, or number? There's no technical reason that we couldn't extend semantic tokens to report distinct modifiers for each top-level type constructor of a symbol's type, but I don't understand why would we do this just for interface types.
xzbdmw commentedon Aug 23, 2024
Sorry to be unclear here, what I mean "interface" is the typename of an identifier instead of the identifier itself, for example

The
ResponseWriter
is an interface type andRequest
is a concrete type, and it would be better to paintResponseWriter
a different color by semantic tokens so we can know in a glance that this param needs to pass a struct implements this interface.adonovan commentedon Aug 23, 2024
Understood, but my question is: what's special about interface types, as opposed to pointer, struct, number types, etc? Why does only one particular type constructor warrant this special treatment?
xzbdmw commentedon Aug 23, 2024
Because we know a pointer has a prefix *, number types are some finite set such as int32 or float32, and map or slice both has special typedef syntax, but interfaces and structs are hard to distinguish just by their content like the image above.
adonovan commentedon Aug 23, 2024
But that's not true in general. Go has three kinds of named types (alias types, defined types, and type parameters), all of which can obscure the underlying type so that you can't tell (without digging) whether type T is a pointer, a struct, or a number.
adonovan commentedon Aug 23, 2024
I will reopen this issue as a more general feature request for semantic tokens to include the top-level type constructor of each identifier.
[-]x/tools/gopls: semantic tokens lackes interface[/-][+]x/tools/gopls: semantic tokens should report the top-level type constructor of each symbol (e.g. struct, number, pointer, interface, etc)[/+]15 remaining items