Fix 'new project' not properly reading current user options when formatting initial files#81523
Conversation
…atting initial files
| // has the right fallback analyzer options. This normally happens in Workspace.SetCurrentSolutionAsync as | ||
| // it mutates. But that has never happened so far, so we have to simulate that manually here. This ensures | ||
| // we pick up the right host/vs options which is needed in order to run the code cleanup pass below. | ||
| solution = solution.WithFallbackAnalyzerOptions(Workspace.ComputeFinalFallbackAnalyzerOptions(solution, projectToAddTo.Solution)); |
There was a problem hiding this comment.
i don't love this. alternatively, above this, we call solution.AddProject. if we're comfortable with the idea, i could make it so that this logic automatically happens in .Add/.RemoveProject so that our in-memory forks reread this host data.
It feels OOGy to me though. because that means you might have a solution snapshot with one set of options, and you fork it,a nd now the options are different due to the underlying host. it feels like we don't want that, and options in forked snapshots should not change unless explicit. instead, only when the host updates .CurrentSolution should it change.
So this, while oogy, feels the cleanest to me.
There was a problem hiding this comment.
Why not fork the solution with the project projectToAddTo.Solution further to add the options?
Then you could just call InitializeAnalyzerFallbackOptions and we wouldn't need ComputeFinalFallbackAnalyzerOptions
There was a problem hiding this comment.
oops. that's just a mistake. though, wehen you say "to add the options", how do you envision computing which options are needed?
There was a problem hiding this comment.
i suppose i could just do:
var provider = oldSolution.Services.GetRequiredService<IFallbackAnalyzerConfigOptionsProvider>();
newFallbackOptions = newFallbackOptions.Add(language, provider.GetOptions(language));
though the benefit of having and calling into the helper is that it works regardless of the state the workspace is in when FormatDocumentCreatedFromTemplateAsync is called.
There was a problem hiding this comment.
This does the same thing now, no?
private static Solution InitializeAnalyzerFallbackOptions(Solution oldSolution, Solution newSolution)
=> newSolution.WithFallbackAnalyzerOptions(ComputeFinalFallbackAnalyzerOptions(oldSolution, newSolution));
| continue; | ||
| } | ||
|
|
||
| var provider = Services.GetRequiredService<IFallbackAnalyzerConfigOptionsProvider>(); |
There was a problem hiding this comment.
Services is 'HostWorkspaceServices', which is the exact same backing store for Solution.Services. So we dno't need to access this.Services and can instead make this a static method that only depends on OldSolution/NewSolution. To make it clearer what this is doing, i had this just return the final desired 'fallback analyzer options', and it's up to the caller to decide what to do with it.
Note: as a static method on Workspace, this could just move to an instance/static method on Solution instead, which seems to be the more appropriate location. I'm open to thoughts here.
|
@tmat @jasonmalinowski ptal. Core issue, as described in internal teams chat is that we're being asked to format a file on disk prior to our workspace having had anything happen to it. As such, ti's just an empty-solution initially (with no projects) and as such doesn't know what languages we have, and hasn't done anything to prepopulate itself with information about the current host options. This means that when we cleanup the file, we get all the defaults (or editorconfig values) instead of picking up what the user has set in the host. This fix is incredibly simple and works, but pushes the logic to the AbstractEditorFactory.FormatDocumentCreatedFromTemplateAsync helper to have to know about this. I don't personally hate this, as that function also knows that hte solution is empty,a nd is simulating a project/doc by forking in memory. But i'm open to thoughts on alternative strategies here if we find this unpleasant/inappropriate. I've given thoughts in the PR to an alternate routee, but why i did not like doing things that way. |
src/VisualStudio/Core/Def/Implementation/AbstractEditorFactory.cs
Outdated
Show resolved
Hide resolved
b1cdbfa to
38cfa3e
Compare
38cfa3e to
e1bcda0
Compare
|
@tmat @jasonmalinowski @JoeRobich ptal. |
Fixes #79231