Skip to content

Added support for ILanguageServerConfiguration #207

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

Merged
merged 10 commits into from
Mar 20, 2020
Merged

Conversation

david-driscoll
Copy link
Member

This is a wip that will need some more unit tests.

In essence the goal here is to enable support for both workspace/didChangeConfiguration and workspace/configuration through the MEC IConfiguration interface. such that as configuration changes happen on the client, they are reflected correctly in the configuration of the server. This opens the door to using IOptionsMonitor in places as well.

Another part is to allow support for the scopeUri portion of workspace/configuration returning a disposable interface that is also IConfiguration and managing the state for that object as long it as it hasn't been dispoed. For example keeping the configuration of all the currently opened files is probably something that will be needed.

And finally allowing configuration to just be queried and inspected for different areas of the client. Basically just to make the work of getting that information a little easier to consume.

@david-driscoll
Copy link
Member Author

@NTaylorMullen @mholo65 @tintoy @TylerLeonhardt any feedback you want to give before I push this through? 🌵

@david-driscoll david-driscoll marked this pull request as ready for review February 17, 2020 14:46
@TylerLeonhardt
Copy link
Collaborator

cc @rjmholt

@david-driscoll this is great - we use our own (very basic) ConfigurationService and Configuration Handler today and I'm wondering how we might be able to use these changes.

We keep track of "powershell" scoped settings and also a couple other generic ones ("files" and "search").

Copy link

@NTaylorMullen NTaylorMullen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really cool stuff. @ajaybhargavb you should probably take a glance at the high level portions of this given you had a lot of experience Razor's config handling

ParseClientConfiguration(settings, scope.Section);
}

OnReload();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to wait to trigger a reload until all scopes are updated?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's an interesting observation... they will likely get double updated (once from the OnReload() and once from the update call. It should probably move to the bottom just for consistency.

return Unit.Value;
}

ParseClientConfiguration(request.Settings);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ParseClientConfiguration expects a JSON object but there's no promise that the request.Settings is JSON is there? This is the issue we were having on the Razor front when approaching configuration. We've had to build our LanguageServer to somewhat special case each client because the configurations in each client can have:

  1. Different configuration identifiers
  2. Possibly different configuration formats (XML)

Instead of baking the configuration parser/expectation of JSON into the base class it'd probably be best to split that out into a service that a language server can replace.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have examples of a client that gives back xml as configuration (just my knowledge/testing)? I'll look at adding the service this weekend.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So by default VS stores its configurations in XML format however the LSP client for VS doesn't currently support interacting with those XML based configurations. Therefore, for the time being they brought over JSON configurations to act as a replacement of the XML based configurations but all of the new JSON configs do not translate to XML and do not auto-map to the XML configs either. Therefore VS is trying to figure out how it wants its configuration story to roll out so it can work with new language server.

tl;dr; I don't know of any currently; however, it's definitely possible it'll come down in the future.

@@ -61,6 +61,10 @@ class HandlerDescriptor : ILspHandlerDescriptor, IDisposable, IEquatable<Handler
typeof(DelegatingRequest<>).IsAssignableFrom(@params.GetGenericTypeDefinition()) ||
typeof(DelegatingNotification<>).IsAssignableFrom(@params.GetGenericTypeDefinition())
);
if (handler is IOnStarted started)
{
StartedDelegate = started.OnStarted;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👏

/// </summary>
/// <param name="scopeUri"></param>
/// <returns></returns>
Task<IDisposableConfiguration> GetScopedConfiguration(Uri scopeUri);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, is there value in exposing that this is an IDisposableConfiguration here? Is the LanguageServer author expected to call dispose on it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the high level idea here is that a language server wants to get configuration information for a specific document (at least from the vscode side anyway). This would allow them to see any overrides that might have happened for example vscode lets you do "[csharp]":{} to override settings for a specific language.

Since there is nothing in the protocol today that lets us ask for settings for a generic language or file type, we instead have to go this route. The reason it's disposable is because we don't want to have to double information for files that are no longer in scope, as each refresh will update all the active scopes.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that aspect of it but by exposing the IDisposeableness of the scoped configuration I as the Razor langauge server author could call dispose which wouldn't be expected I'd imagine. I'd think you (as O# lib) would want to reserve the right to dispose

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is on the LSP side I don't know when you're "done" with that configuration, hence the disposable aspect of it.

It could be in context of a file or it could be in context of a file that is currently being acted upon. In essence you wanted the configuration for that file, and you take ownership of when you're done. On the library side we're only going to update the configuration for you automagically.

I could be something that is unnecessary and maybe GetConfiguration is enough.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh I see

@codecov
Copy link

codecov bot commented Mar 19, 2020

Codecov Report

Merging #207 into master will decrease coverage by 4.37%.
The diff coverage is 1.59%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #207      +/-   ##
==========================================
- Coverage   48.29%   43.92%   -4.38%     
==========================================
  Files         350      356       +6     
  Lines        7669     7814     +145     
  Branches      957      975      +18     
==========================================
- Hits         3704     3432     -272     
- Misses       3665     4092     +427     
+ Partials      300      290      -10
Impacted Files Coverage Δ
src/JsonRpc/DapReciever.cs 55.55% <ø> (ø) ⬆️
src/JsonRpc/Reciever.cs 81.35% <ø> (ø) ⬆️
src/Server/LspReciever.cs 0% <ø> (-10.72%) ⬇️
src/JsonRpc/JsonRpcServerOptions.cs 0% <0%> (ø) ⬆️
src/Protocol/ProgressManager.cs 4.21% <0%> (-4.37%) ⬇️
...er/Configuration/DidChangeConfigurationProvider.cs 0% <0%> (ø)
...onfiguration/BaseWorkspaceConfigurationProvider.cs 0% <0%> (ø)
src/JsonRpc/JsonRpcServer.cs 0% <0%> (ø) ⬆️
...rver/Configuration/DidChangeConfigurationSource.cs 0% <0%> (ø)
src/JsonRpc/Connection.cs 0% <0%> (-78.58%) ⬇️
... and 44 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 1b6d19a...f326b94. Read the comment docs.

@david-driscoll david-driscoll merged commit 838be84 into master Mar 20, 2020
@david-driscoll david-driscoll deleted the feature/config branch June 2, 2020 04:47
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

Successfully merging this pull request may close these issues.

3 participants