-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Avoid rooting documents for languages that support syntax trees #67960
Conversation
...rFeatures/Core/Classification/Syntactic/SyntacticClassificationTaggerProvider.TagComputer.cs
Show resolved
Hide resolved
...rFeatures/Core/Classification/Syntactic/SyntacticClassificationTaggerProvider.TagComputer.cs
Outdated
Show resolved
Hide resolved
I need to look at this in front of a computer. However, my recollection is that this type exists only for c#/vb. But I def could be wrong on that. If this is only for those two, we can likely simplify this. |
I definitely agree, but it seems like that could be a follow-up item. |
...rFeatures/Core/Classification/Syntactic/SyntacticClassificationTaggerProvider.TagComputer.cs
Outdated
Show resolved
Hide resolved
...rFeatures/Core/Classification/Syntactic/SyntacticClassificationTaggerProvider.TagComputer.cs
Outdated
Show resolved
Hide resolved
i'm ok with the general approach here (storing the root instead of the doc). But i feel you did the PR a disservice both with the nullability change and the static change. it just makes it a slog of passing data around :) |
@@ -272,15 +282,18 @@ private async ValueTask ProcessChangesAsync(ImmutableSegmentedList<ITextSnapshot | |||
Contract.ThrowIfTrue(snapshots.IsDefault || snapshots.IsEmpty); | |||
var currentSnapshot = GetLatest(snapshots); | |||
|
|||
var classificationService = TryGetClassificationService(currentSnapshot); | |||
if (classificationService == null) | |||
if (TryGetClassificationService(currentSnapshot) is not (var solutionServices, var classificationService)) | |||
return; | |||
|
|||
var currentDocument = currentSnapshot.GetOpenDocumentInCurrentContextWithChanges(); | |||
if (currentDocument == null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aside, this whole pattern is wonky. we get the document or not... so we dont need the helper for getting the classificationservice/solution-service. We could always just get that from currentDocument. Would simplify a lot it seems.
@@ -69,7 +71,7 @@ internal partial class TagComputer | |||
// get called. | |||
|
|||
private readonly object _gate = new(); | |||
private (ITextSnapshot? lastSnapshot, Document? lastDocument, SyntaxNode? lastRoot) _lastProcessedData; | |||
private (ITextSnapshot lastSnapshot, SumType<SyntaxNode, Document> lastDocumentOrRoot)? _lastProcessedData; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i would intentionally doc that we want to drop teh Doc in the case where we have the root to ensure we're not holding onto old solutions. Then maybe a note that this could potentially be bad for other languages, but we can revisit as needed.
{ | ||
// We don't have a syntax tree yet. Just do a lexical classification of the document. | ||
AddLexicalClassifications(classificationService, span, classifiedSpans); | ||
return; | ||
} | ||
|
||
// If we have a document, we must have a snapshot as well. | ||
Contract.ThrowIfNull(lastProcessedSnapshot); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok. i see why you made the invariant change. i'm ok with it :)
else | ||
classificationService.AddSyntacticClassifications(document.Project.Solution.Services, root, span.Span.ToTextSpan(), tempList, cancellationToken); | ||
classificationService.AddSyntacticClassifications(solutionServices, root, span.Span.ToTextSpan(), tempList, cancellationToken); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, either consider flipping the if/else, or just do TryGetSecond in the above. but i don't feel strongly, something just minorly confused me here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm. very clear. thanks!
all the feedback is nits, except the part about documenting things. i would ask that that be done :) |
@dotnet/roslyn-compiler I'm getting hit hard by this problem locally, but I'm not able to get the fix merged because bootstrap build is failing with this assertion. Can I get some help resolving it?
|
@@ -291,7 +301,7 @@ private async ValueTask ProcessChangesAsync(ImmutableSegmentedList<ITextSnapshot | |||
|
|||
lock (_gate) | |||
{ | |||
_lastProcessedData = (currentSnapshot, currentDocument, currentRoot); | |||
_lastProcessedData = (currentSnapshot, currentRoot is not null ? currentRoot : currentDocument); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm getting hit hard by this problem locally, but I'm not able to get the fix merged because bootstrap build is failing with this assertion. Can I get some help resolving it?
Looking. The assertion is hit when nullable walker visits this conditional operator. If you want a workaround, I guess you could try changing the code, e.g.:
_lastProcessedData = (currentSnapshot, currentRoot is not null ? currentRoot : currentDocument); | |
_lastProcessedData = (currentSnapshot, currentRoot ?? currentDocument); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, this expression is special. I'll see if adding explicit casts helps.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I filed #67975 and added the explicit casts, but then I realized I can use a modified version with ??
and switched to that.
Addresses 17GB memory overhead observed in a local heap dump where 50+ documents were open.