-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Design issues for speeding up .editorconfig processing #44936
Comments
Note: 3 is probably a dead end. It's a big layering violation and would probably have too many other impacts, including potential perf problems. |
I don't actually understand any of the issues/surprises section. Would be happy to chat tomorrow about it.
Seems totally reasonable. A change to a .editorconfig ends up as a change to the CompilationOptions for affected projects.
Seems fine. If we want to support Workspace.TryApplyChanges applying .editorconfig changes, then we support that. If we don't, then we don't support it.
Honestly, is it hard to just support changing all compilation options in Workspace.TryApplyChanges? I think we did the minimal amount before, which started with:
I don't honestly see why we wouldn't want to support roundtripping effectively everything we could here. |
@agocke: how is it a layering violation? I can imagine many impacts but I wouldn't have imagined that one. 😄
@CyrusNajmabadi: It's just the standard time/value tradeoff; it's also host specific in that it requires specific project system APIs to change things.
Anybody trying to modify the .editorconfig by modifying the file will still work fine, and we support that today. It's just there's extra wrinkles to support it now. |
@jasonmalinowski AnalyzerConfig splits into two sets of options: analyzer options and diagnostic configs. In order to make this work we would have to push the analyzer configs into the compilation, then have the compilation pass the analyzer options back up in some opaque fashion to the analyzer driver. I'm not sure how we would deal with AdditionalFiles, which aren't present in the Compilation, but could have analyzer options provided. |
@agocke I don't see any reason we can't just pass the object again to the analyzer driver if that's the problem there. |
So if it's just providing DiangosticOptions, why wouldn't it go in the CompilationOptions, which is where we store all the other diagnostic options settings? |
We decided to continue with the approach in Possible Solution 2, and deal with the workspace changes that fell out from it. |
Background
When we implemented .editorconfig support in the compiler, a SyntaxTree was given a collection of DiagnosticOptions. Before we parsed syntax trees, we would parse and process all .editorconfig files to collect the dotnet_diagnostic severity settings. Then, when parsing a tree we'd compute the .editorconfig rules that applied to that tree and parse the tree. Those trees all got added to the Compilation like anything else, and the compiler would consume that information when computing effective diagnostic severities.
The Problem
First there was just a performance issue in the original implementation: if a change happens to an .editorconfig that didn't actually impact the dotnet_diagnostic rules, we'd still reparse trees regardless. We can fix that, but it doesn't address some of the original concerns. If you are editing inside of the diagnostic code, say the CS4242 below:
any single keystroke in there was still going to reparse the entire project. If this is happening in an .editorconfig that shared across all your projects, a single keystroke invalidates all syntax trees, and in turn all compilations.
Possible Solution 1: Don't Reparse
The reparsing was done because of a bit of a misunderstanding: the belief was the compiler was going to potentially apply changes to compiler warnings during parsing at that time, but the parsing wasn't actually dependent on it at all. So we can avoid reparsing trees, but a change to the .editorconfig would still require us to go to each syntax tree and create new compilations replacing all the trees; since those would expose new syntax roots the decltree caches in the compilations would have to be tossed out regardless. This would be an improvement over the current situation, but still means a single keystroke is forcing us to recreate a lot of information in each Compilation.
We didn't find a good way to save this option, but it's possible we missed something.
Possible Solution 2: Move this all to CompilationOptions
This is the approach that Andy explored in #44331 and we want to discuss further. This design:
The upside of this approach is syntax trees don't need to change at all; the addition or changing of an .editorconfig only changes the compilation options, and the compiler could see that only the SyntaxTreeOptionsProvider is changing and not have to drop decltrees or other related caches, and we can be much more efficient here.
This however creates strangess in the workspaces layer. Today the Workspace doesn't have to provide any of the values in a CompilationOptions from other state elsewhere: the workspace host just creates the CompilationOptions and that's passed through to the Compilation. Now, there is bit of a cycle we have to deal with. Generally it seems we have to either:
We went with option 1 for Andy's experiment, and then ran into the following issues/surprises:
roslyn/src/VisualStudio/CSharp/Impl/Utilities/CSharpCompilationOptionsChangingService.cs
Lines 29 to 30 in 2a58f73
Which was an easy way to say "is the only thing that changed between these two options the supported values". It seems we now need call this method with newOptions now being newOptions.WithSyntaxTreeOptionsProvider(oldOptions.SyntaxTreeOptionProvider) so that way the existing code and hooks would continue to work, but that seems surprising and odd in it's own right.
Possible Solution 3: Don't put it in CompilationOptions, but put it somewhere else
We quickly discussed a third option to avoid all of this by making the SyntaxTreeOptionsProvider not be in CompilationOptions, but is directly held by the Compilation. As it stands the Compilation's only inputs are trees, references, and options, so we'd either be making the AnalyzerConfig a top-level input, or have to make another "options" type which seemed odd.
The text was updated successfully, but these errors were encountered: