[LSP] Implement support for workspace/semanticTokens/refresh notifications#60824
[LSP] Implement support for workspace/semanticTokens/refresh notifications#60824allisonchou merged 16 commits intodotnet:mainfrom
workspace/semanticTokens/refresh notifications#60824Conversation
| /// <summary> | ||
| /// Gets a value indicating whether a notification bubble show be shown when the language server fails to initialize. | ||
| /// </summary> | ||
| public abstract bool ShowNotificationOnInitializeFailed { get; } |
There was a problem hiding this comment.
Just moved this property up to fit in with the rest of the properties
| // differentiate between the different C# LSP servers that have the same client name. | ||
| // We also don't use the language client's name property as it is a localized user facing string | ||
| // which is difficult to write telemetry queries for. | ||
| _requestTelemetryLogger = new RequestTelemetryLogger(_serverKind.ToTelemetryString()); |
There was a problem hiding this comment.
Moved these two values up to LanguageServerTarget since they're needed by the semantic tokens refresh listener
| _workQueue = new AsyncBatchingWorkQueue( | ||
| delay: TimeSpan.FromMilliseconds(2000), | ||
| processBatchAsync: SendSemanticTokensRefreshNotificationAsync, | ||
| asyncListener: listener, |
There was a problem hiding this comment.
I wasn't sure what the correct value of asyncListener should be here - currently it's FeatureAttribute.LanguageServer, but not sure if we want that or FeatureAttribute.Workspace instead
| Contract.ThrowIfTrue(_clientCapabilities != null, $"{nameof(InitializeAsync)} called multiple times"); | ||
| _clientCapabilities = initializeParams.Capabilities; | ||
|
|
||
| // TO-DO: Add client capability check below once LSP side is merged |
There was a problem hiding this comment.
Before merging this PR, will add a client capability check for refresh once LSP side is merged - https://devdiv.visualstudio.com/DevDiv/_git/VSLanguageServerClient/pullrequest/388715
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <!-- No warn on NU1701 until the LSP client targets netstandard2.0 https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1369985/ --> |
There was a problem hiding this comment.
This was adapted from EditorFeatures.csproj in order to include the VS LSP client package reference, which is needed for access to the ILanguageClientMiddleLayer type.
@dibarbet it looks like the underlying issue here was marked as "completed" but I'm still seeing the same errors mentioned in the internal issue. Would you have any context here?
There was a problem hiding this comment.
@allisonchou depending on when the bug was completed, we may need to depend on an updated version of the VS language client
https://github.com/dotnet/roslyn/blob/main/eng/Versions.props#L155
There was a problem hiding this comment.
It looks like the bug was completed in mid-January, however I attempted updating to a client version from February and the problem persists. I'll comment on the original bug to ask
src/Tools/ExternalAccess/Razor/RazorLanguageServerFactoryWrapper.cs
Outdated
Show resolved
Hide resolved
| /// <remarks> | ||
| /// Currently utilized by Razor to intercept Roslyn's workspace/semanticTokens/refresh requests. | ||
| /// </remarks> | ||
| public object? MiddleLayer => _middleLayer; |
There was a problem hiding this comment.
Interesting - why do we need to support a middle layer here? Shouldn't that be possible entirely on the client side?
There was a problem hiding this comment.
We can specify the middle layer as part of the ILanguageClientCustomMessage2 interface, which the client then uses to send messages through the interceptors. I'm thinking it's meant to be specified on the server side so we can specify the middle layer we want, otherwise the client could send requests to all the potential middle layers.
There was a problem hiding this comment.
Interesting. It seems like it could be done via content type or lsp server name. But I dont generally have a problem with this, was just wondering
src/Features/LanguageServer/Protocol/Handler/SemanticTokens/SemanticTokensRefreshListener.cs
Outdated
Show resolved
Hide resolved
src/Features/LanguageServer/Protocol/Workspaces/LspWorkspaceManager.cs
Outdated
Show resolved
Hide resolved
| } | ||
|
|
||
| // Send a workspace changed notification to anyone subscribed. For example, this is important for semantic tokens refresh. | ||
| LspWorkspaceChanged?.Invoke(sender, e); |
There was a problem hiding this comment.
We may want to document that the event handler implementation for this should not do basically any synchronous work, as that will block here.
Right now the only implementation basically does nothing (good), but I'm wondering if there is a way to ensure this cannot block even if the implementation of the event does something bad. Async callback function is an obvious option, but doesn't allow for easy registration of listeners (@CyrusNajmabadi for ideas)
There was a problem hiding this comment.
I added a huge bolded XML warning above the event handler. Would be curious if Cyrus has any ideas on how to improve this too though
src/Tools/ExternalAccess/Razor/RazorCSharpInterceptionMiddleLayer.cs
Outdated
Show resolved
Hide resolved
src/Features/LanguageServer/Protocol/Workspaces/LspWorkspaceManager.cs
Outdated
Show resolved
Hide resolved
src/Features/LanguageServer/Protocol/Handler/SemanticTokens/SemanticTokensRefreshListener.cs
Show resolved
Hide resolved
|
|
||
| namespace Microsoft.CodeAnalysis.LanguageServer | ||
| { | ||
| internal interface IRefreshListener : IDisposable |
There was a problem hiding this comment.
I think this was probably my mistake for not being clear - what I meant was a wrapper interface around the jsonrpc object that has a SendNotification method that takes in the params and method name.
Then you import that wrapper interface into the semantic tokens notification thing
There was a problem hiding this comment.
Done! Hopefully the abstraction makes things easier in the future. I wasn't sure about naming, if you have any suggestions feel free to lmk
workspace/semanticTokens/refreshsupport, which should improve perf by making polling obsolete.cc @gundermanc