gopls/internal/server: return a non-nil slice for empty token result
Some clients encounter errors in the presence of a nil semantic tokens
data slice. Since the field is not marked optional, it seems most
appropriate to return a non-nil empty slice when semantic tokens are
disabled.
Fixes golang/go#67885
Change-Id: I85b1e856e0829d73508edae06b373e135340d9ac
Reviewed-on: https://go-review.googlesource.com/c/tools/+/591415
Reviewed-by: Alan Donovan <adonovan@google.com>
Auto-Submit: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/gopls/internal/server/semantic.go b/gopls/internal/server/semantic.go
index ca3df78..f746593 100644
--- a/gopls/internal/server/semantic.go
+++ b/gopls/internal/server/semantic.go
@@ -32,24 +32,25 @@
return nil, err
}
defer release()
- if !snapshot.Options().SemanticTokens {
- // Note: returning new(protocol.SemanticTokens) is necessary here to
- // invalidate semantic tokens in VS Code (and perhaps other editors).
- // Previously, an error was returned here to achieve the same effect, but
- // that had the side effect of very noisy "semantictokens are disabled"
- // logs on every keystroke.
- return new(protocol.SemanticTokens), nil
+
+ if snapshot.Options().SemanticTokens {
+ switch snapshot.FileKind(fh) {
+ case file.Tmpl:
+ return template.SemanticTokens(ctx, snapshot, fh.URI())
+ case file.Go:
+ return golang.SemanticTokens(ctx, snapshot, fh, rng)
+ }
}
- switch snapshot.FileKind(fh) {
- case file.Tmpl:
- return template.SemanticTokens(ctx, snapshot, fh.URI())
-
- case file.Go:
- return golang.SemanticTokens(ctx, snapshot, fh, rng)
-
- default:
- // TODO(adonovan): should return an error!
- return nil, nil // empty result
- }
+ // Not enabled, or unsupported file type: return empty result.
+ //
+ // Returning an empty response is necessary to invalidate
+ // semantic tokens in VS Code (and perhaps other editors).
+ // Previously, we returned an error, but that had the side effect
+ // of noisy "semantictokens are disabled" logs on every keystroke.
+ //
+ // We must return a non-nil Data slice for JSON serialization.
+ // We do not return an empty field with "omitempty" set,
+ // as it is not marked optional in the protocol (golang/go#67885).
+ return &protocol.SemanticTokens{Data: []uint32{}}, nil
}