Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LanguageServerProtocol] Incorrect serialization behaviour on SemanticTokensOptions & SemanticTokensLegend classes #285

Open
Blakintosh opened this issue Jul 16, 2023 · 2 comments

Comments

@Blakintosh
Copy link

Installed products

  • Visual Studio: Community 2022
  • Visual Studio Code

Description

Issue is not specific to the sample given but I could not find any more appropriate place to report this issue with the Microsoft.VisualStudio.LanguageServer.Protocol extension. The SemanticTokensOptions and SemanticTokensLegend classes are lacking [DataContract] attributes on their class definitions, causing the [DataMember] attributes that would camelCase their members getting ignored when serialized, which causes editors like VS Code to ignore the Semantic tokens capability.

Steps to recreate

  1. Setup the SemanticTokensOptions property on ServerCapabilities in the Initialize JSON-RPC result, such as:
SemanticTokensOptions = new SemanticTokensOptions
{
    Full = true,
    Legend = new SemanticTokensLegend
    {
        TokenTypes = SemanticTokensBuilder.SemanticTokenTypes,
        TokenModifiers = SemanticTokensBuilder.SemanticTokenModifiers
    }
},
  1. Run server with a client such as Visual Studio Code.
  2. Observe that the initialize request calls back with PascalCase members on the semanticTokensOptions section.
    image

Current behavior

PascalCase behavior on the semanticTokenProvider causes editors like Visual Studio Code to not issue JSON-RPC textDocument/semanticTokens requests to the server as the object does not conform to the LSP specification.

Expected behavior

semanticTokenProvider members (and legend) should be camelCase (through adding the necessary [DataContract] attributes which will enable semantic token requests in VS Code. I have tested this through a workaround and can confirm that the requests work as expected when the data contract is added.

@upwindtec
Copy link

I struggled for a while with the same issue until I realised as you did that the SemanticToken classes did not have the DataContract attribute. One workaround I found, other than duplicating the SemanticToken classes with the right attribute, is to force the Json serializer to use camelCase formatting. This is done by calling:
((JsonMessageFormatter)this.messageHandler.Formatter).JsonSerializer.ContractResolver = new CamelCasePropertyNamesContractResolver();
in the constructor of the LanguageServer.

One thing still puzzles me though. I thought the "fix" for the DataContract would break Visual Studio semantic handling because it is expecting "Full" instead of "full" or "TokenTypes" instead of "tokenTypes" and so on, except that Visual Studio worked in both cases. It is possible that the VS developers realised there was an issue and implemented code to handle both cases (and forgot to document this...), or there is something completely different going on.

@Blakintosh
Copy link
Author

That sounds like an easier approach to get around the issue, I'll have to use that too! It's entirely possible that Visual Studio's LSP client implementation deserializes the LSP objects case-insensitively. It would explain why they wouldn't have noticed this issue if testing was focused on VS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants