Keep collapsed regions while a project has no options - #20451
Open
xperiandri wants to merge 3 commits into
Open
Conversation
Contributor
❗ Release notes requiredYou can open this PR in browser to add release notes: open in github.dev
|
xperiandri
force-pushed
the
outlining-quick-parsing-options
branch
from
September 4, 2026 17:30
16b46f2 to
1d1ee34
Compare
Every entry point in WorkspaceExtensions signalled "the project has no options yet" by raising an OperationCanceledException, which the callers then had to tell apart from a real cancellation. They cannot, so they treat both as "cancelled" and return an empty result. For a service Roslyn asks repeatedly while a solution loads, that is a wrong answer, not a missing one. Add `Try` siblings that return ValueNone instead, and keep the raising members as thin wrappers so the call sites that have not moved over still get the same exception with the same message. The four-tuple those members hand out becomes a named record, which is also what ProjectCache stores, so a cache hit hands back the instance it holds rather than rebuilding a tuple. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Splitting the semantic classification cache in two (dotnet#15954) left the open-document branch reading the opened-documents cache and writing the unopened one, so the opened cache was never populated and every request for an open file re-ran the checker. What it wrote was also only the requested span, keyed by document and text version, so a second request for another span of the same version (scrolling, a split view, Roslyn asking around the viewport) would have hit that entry and sliced nothing out of it. Cache the classification of the whole file instead, and slice it per request, the way the unopened-documents branch already does. A check that cannot complete - the project is loading or reloading, or the check was superseded - must not answer with no classifications either: Roslyn replaces the tags of a span with whatever comes back, so an empty answer strips the colours the user is looking at, while a cancellation carrying Roslyn's own token leaves them alone. Keep the last classification per document and re-emit it for those requests, but only while the text it was computed from is still the current one, as its spans would otherwise land on the wrong characters. `ifCanceledThen` replaces `ifCanceledReturn ()` for the same reason: the checker relabels its internal cancellations with the caller's token, and those must produce the last known colours rather than none. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Outlining needs a parse, nothing more, but it asked for the parse of a fully configured project and answered with no regions whenever that was unavailable - while the project loads or reloads, and for any cancellation the checker relabelled with the caller's token. Roslyn takes that literally and expands every region the user had folded. Parse with the quick parsing options in that case, the ones syntactic classification and brace matching already use, and keep the regions. Those options carried no source files, so `ParseFile` threw looking for the last compiland; give them the file being parsed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
xperiandri
force-pushed
the
outlining-quick-parsing-options
branch
from
September 4, 2026 22:10
1d1ee34 to
f41f3e4
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Outlining needs a parse and nothing else, but
FSharpBlockStructureServiceasked for the parse of a fully configured project and answered with no regions whenever that was unavailable — while a project loads or reloads, and for any cancellation the checker relabels with the caller's token. Roslyn takes "no regions" literally and expands every region the user had folded.It now parses with the quick parsing options in that case, the same ones syntactic classification and brace matching already use, so the folds survive a project reload. Those options carried no source files, which made
ParseFilethrow looking for the last compiland, so they now carry the file being parsed.Depends on #20450 — it is the head of this branch and supplies
Document.TryGetFSharpParseResultsAsync. Only the last commit, "Outline with the quick parsing options when a project has none", belongs to this pull request; please review it after #20450 merges.Checklist