diff --git a/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_ProduceTags.cs b/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_ProduceTags.cs index 1797f9d137912f3a28389b4c08b9b36541774ab1..0e841e1586f7ba7a9e76301f2d35e01a2e8da8bc 100644 --- a/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_ProduceTags.cs +++ b/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_ProduceTags.cs @@ -374,6 +374,7 @@ private void CheckSnapshot(ITextSnapshot snapshot) private ImmutableDictionary> ConvertToTagTrees( ImmutableDictionary> oldTagTrees, + ISet buffersToTag, ILookup> newTagsByBuffer, IEnumerable spansTagged) { @@ -400,6 +401,14 @@ private void CheckSnapshot(ITextSnapshot snapshot) var newTagTrees = ImmutableDictionary>.Empty; foreach (var buffer in buffers) { + if (!buffersToTag.Contains(buffer)) + { + // Avoid computing a new tag tree for a buffer not requested for tagging. This handles cases + // where oldTagTrees contains tags for a buffer that was removed from the buffers of interest, + // and also cases where one or more taggers produced tags outside the requested context. + continue; + } + var newTagTree = ComputeNewTagTree(oldTagTrees, buffer, newTagsByBuffer[buffer], spansToInvalidateByBuffer[buffer]); if (newTagTree != null) { @@ -627,7 +636,7 @@ private void ProduceTagsSynchronously(TaggerContext context) var newTagsByBuffer = context.tagSpans.Where(ts => buffersToTag.Contains(ts.Span.Snapshot.TextBuffer)) .ToLookup(t => t.Span.Snapshot.TextBuffer); - var newTagTrees = ConvertToTagTrees(oldTagTrees, newTagsByBuffer, context._spansTagged); + var newTagTrees = ConvertToTagTrees(oldTagTrees, buffersToTag, newTagsByBuffer, context._spansTagged); ProcessNewTagTrees( context.SpansToTag, oldTagTrees, newTagTrees, context.State, initialTags, context.CancellationToken);