diff --git a/src/EditorFeatures/Core/ReferenceHighlighting/ReferenceHighlightingViewTaggerProvider.cs b/src/EditorFeatures/Core/ReferenceHighlighting/ReferenceHighlightingViewTaggerProvider.cs index 9360d63894685fd77f0f89136c0f442e8f5a53b2..e6bdedad10855f62332f2fb4ef585911938f1b5f 100644 --- a/src/EditorFeatures/Core/ReferenceHighlighting/ReferenceHighlightingViewTaggerProvider.cs +++ b/src/EditorFeatures/Core/ReferenceHighlighting/ReferenceHighlightingViewTaggerProvider.cs @@ -69,6 +69,8 @@ protected override ITaggerEventSource CreateEventSource(ITextView textView, ITex protected override IEnumerable GetSpansToTag(ITextView textViewOpt, ITextBuffer subjectBuffer) { + // Note: this may return no snapshot spans. We have to be resilient to that + // when processing the TaggerContext<>.SpansToTag below. return textViewOpt.BufferGraph.GetTextBuffers(b => IsSupportedContentType(b.ContentType)) .Select(b => b.CurrentSnapshot.GetFullSpan()) .ToList(); @@ -91,7 +93,8 @@ protected override Task ProduceTagsAsync(TaggerContext co return SpecializedTasks.EmptyTask; } - var document = context.SpansToTag.First(vt => vt.SnapshotSpan.Snapshot == caretPosition.Snapshot).Document; + // GetSpansToTag may have produced no actual spans to tag. Be resilient to that. + var document = context.SpansToTag.FirstOrDefault(vt => vt.SnapshotSpan.Snapshot == caretPosition.Snapshot).Document; if (document == null) { return SpecializedTasks.EmptyTask; diff --git a/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_ProduceTags.cs b/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_ProduceTags.cs index df3e44fda2a4720ac142b652a8cb76bc44c182ca..99f45d5a94fb242a824e697b360afafa39910b17 100644 --- a/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_ProduceTags.cs +++ b/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_ProduceTags.cs @@ -335,7 +335,7 @@ private CancellationToken GetCancellationToken(bool initialTags) ? _initialComputationCancellationTokenSource.Token : _workQueue.CancellationToken; - private List GetSpansAndDocumentsToTag() + private ImmutableArray GetSpansAndDocumentsToTag() { _workQueue.AssertIsForeground(); @@ -356,9 +356,8 @@ private List GetSpansAndDocumentsToTag() // document can be null if the buffer the given span is part of is not part of our workspace. return new DocumentSnapshotSpan(document, span); - }).ToList(); + }).ToImmutableArray(); - Debug.Assert(spansAndDocumentsToTag.Count > 0); return spansAndDocumentsToTag; } @@ -573,7 +572,7 @@ private IEnumerable> GetNonIntersectingTagSpans(IEnumerable spansToTag, + ImmutableArray spansToTag, ImmutableDictionary> oldTagTrees, bool initialTags, CancellationToken cancellationToken) @@ -618,7 +617,7 @@ private void ProduceTagsSynchronously(TaggerContext context) } private void ProcessContext( - List spansToTag, + ImmutableArray spansToTag, ImmutableDictionary> oldTagTrees, TaggerContext context, bool initialTags) @@ -636,7 +635,7 @@ private void ProduceTagsSynchronously(TaggerContext context) } private void ProcessNewTagTrees( - List spansToTag, + ImmutableArray spansToTag, ImmutableDictionary> oldTagTrees, ImmutableDictionary> newTagTrees, object newState, diff --git a/src/EditorFeatures/Core/Tagging/TaggerContext.cs b/src/EditorFeatures/Core/Tagging/TaggerContext.cs index 4ce5c8cc5a9d6c49aac7fd74d3a51799c3d247bf..a8d34dc488ab2197fe7225cc29a5180c360abd79 100644 --- a/src/EditorFeatures/Core/Tagging/TaggerContext.cs +++ b/src/EditorFeatures/Core/Tagging/TaggerContext.cs @@ -20,7 +20,7 @@ internal class TaggerContext where TTag : ITag internal IEnumerable _spansTagged; internal ImmutableArray>.Builder tagSpans = ImmutableArray.CreateBuilder>(); - public IEnumerable SpansToTag { get; } + public ImmutableArray SpansToTag { get; } public SnapshotPoint? CaretPosition { get; } /// @@ -47,14 +47,14 @@ internal class TaggerContext where TTag : ITag SnapshotPoint? caretPosition = null, TextChangeRange? textChangeRange = null, CancellationToken cancellationToken = default) - : this(null, new[] { new DocumentSnapshotSpan(document, snapshot.GetFullSpan()) }, + : this(null, ImmutableArray.Create(new DocumentSnapshotSpan(document, snapshot.GetFullSpan())), caretPosition, textChangeRange, null, cancellationToken) { } internal TaggerContext( object state, - IEnumerable spansToTag, + ImmutableArray spansToTag, SnapshotPoint? caretPosition, TextChangeRange? textChangeRange, ImmutableDictionary> existingTags,