gopls/semantic: elide zero-length tokens

vscode complains in the Window channel about zero-length semantic
tokens. It may not matter but it seems cleaner to avoid the error
and not send zero-length semantic tokens.

Fixes: golang/go#65254

Change-Id: I470f8052a6288f5bf4b592794cf6cd54d55b5539
Reviewed-on: https://go-review.googlesource.com/c/tools/+/561155
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Peter Weinberger <pjw@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Peter Weinberger 2024-02-04 07:52:56 -05:00
Родитель 7f80389ada
Коммит c11269ccb0
3 изменённых файлов: 50 добавлений и 0 удалений

Просмотреть файл

@ -132,6 +132,9 @@ func (tv *tokenVisitor) visit() {
}
func (tv *tokenVisitor) token(start token.Pos, leng int, typ semtok.TokenType, mods []string) {
if leng <= 0 {
return // vscode doesn't like 0-length Tokens
}
if !start.IsValid() {
// This is not worth reporting. TODO(pjw): does it still happen?
return

Просмотреть файл

@ -169,6 +169,9 @@ func SemanticTokens(ctx context.Context, snapshot *cache.Snapshot, spn protocol.
var items []semtok.Token
add := func(line, start, len uint32) {
if len == 0 {
return // vscode doesn't like 0-length Tokens
}
// TODO(adonovan): don't ignore the rng restriction, if any.
items = append(items, semtok.Token{
Line: line,

Просмотреть файл

@ -193,3 +193,47 @@ func bar() {}
}
})
}
// Make sure no zero-length tokens occur
func TestSemantic_65254(t *testing.T) {
src := `
-- go.mod --
module example.com
go 1.21
-- main.go --
package main
/* a comment with an
empty line
*/
const bad = `
src += "`foo" + `
` + "bar`"
want := []fake.SemanticToken{
{Token: "package", TokenType: "keyword"},
{Token: "main", TokenType: "namespace"},
{Token: "/* a comment with an", TokenType: "comment"},
// --- Note that the zero length line does not show up
{Token: "empty line", TokenType: "comment"},
{Token: "*/", TokenType: "comment"},
{Token: "const", TokenType: "keyword"},
{Token: "bad", TokenType: "variable", Mod: "definition readonly"},
{Token: "`foo", TokenType: "string"},
// --- Note the zero length line does not show up
{Token: "\tbar`", TokenType: "string"},
}
WithOptions(
Modes(Default),
Settings{"semanticTokens": true},
).Run(t, src, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
seen := env.SemanticTokensFull("main.go")
if x := cmp.Diff(want, seen); x != "" {
t.Errorf("Semantic tokens do not match (-want +got):\n%s", x)
}
})
}