diff --git a/src/EditorFeatures/CSharpTest/InlineDiagnostics/InlineDiagnosticsTaggerProviderTests.cs b/src/EditorFeatures/CSharpTest/InlineDiagnostics/InlineDiagnosticsTaggerProviderTests.cs index 27dec7d534912..cffcb7f9b2344 100644 --- a/src/EditorFeatures/CSharpTest/InlineDiagnostics/InlineDiagnosticsTaggerProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/InlineDiagnostics/InlineDiagnosticsTaggerProviderTests.cs @@ -34,13 +34,13 @@ public async Task ErrorTagGeneratedForErrorInSourceGeneratedDocument() Assert.Equal(PredefinedErrorTypeNames.SyntaxError, firstSpan.Tag.ErrorType); } - private static async Task>> GetTagSpansAsync(string content) + private static async Task>> GetTagSpansAsync(string content) { using var workspace = EditorTestWorkspace.CreateCSharp(content, composition: SquiggleUtilities.WpfCompositionWithSolutionCrawler); return await GetTagSpansAsync(workspace); } - private static async Task>> GetTagSpansInSourceGeneratedDocumentAsync(string content) + private static async Task>> GetTagSpansInSourceGeneratedDocumentAsync(string content) { using var workspace = EditorTestWorkspace.CreateCSharp( files: [], @@ -50,7 +50,7 @@ private static async Task>> GetTag return await GetTagSpansAsync(workspace); } - private static async Task>> GetTagSpansAsync(EditorTestWorkspace workspace) + private static async Task>> GetTagSpansAsync(EditorTestWorkspace workspace) { workspace.GlobalOptions.SetGlobalOption(InlineDiagnosticsOptionsStorage.EnableInlineDiagnostics, LanguageNames.CSharp, true); return await TestDiagnosticTagProducer.GetTagSpansAsync(workspace); diff --git a/src/EditorFeatures/CSharpTest/Interactive/BraceMatching/InteractiveBraceHighlightingTests.cs b/src/EditorFeatures/CSharpTest/Interactive/BraceMatching/InteractiveBraceHighlightingTests.cs index 7d45b5a022061..5addeed9e1d4d 100644 --- a/src/EditorFeatures/CSharpTest/Interactive/BraceMatching/InteractiveBraceHighlightingTests.cs +++ b/src/EditorFeatures/CSharpTest/Interactive/BraceMatching/InteractiveBraceHighlightingTests.cs @@ -30,7 +30,7 @@ public class InteractiveBraceHighlightingTests private static IEnumerable Enumerable(params T[] array) => array; - private static async Task>> ProduceTagsAsync( + private static async Task>> ProduceTagsAsync( EditorTestWorkspace workspace, ITextBuffer buffer, int position) diff --git a/src/EditorFeatures/Core.Wpf/InlineDiagnostics/AbstractDiagnosticsTaggerProvider.cs b/src/EditorFeatures/Core.Wpf/InlineDiagnostics/AbstractDiagnosticsTaggerProvider.cs index 497d22eebb946..4491a2a3a16b0 100644 --- a/src/EditorFeatures/Core.Wpf/InlineDiagnostics/AbstractDiagnosticsTaggerProvider.cs +++ b/src/EditorFeatures/Core.Wpf/InlineDiagnostics/AbstractDiagnosticsTaggerProvider.cs @@ -77,17 +77,10 @@ SingleDiagnosticKindPullTaggerProvider CreateDiagnosticsTaggerProvider(Diagnosti protected virtual ImmutableArray GetLocationsToTag(DiagnosticData diagnosticData) => diagnosticData.DataLocation is not null ? [diagnosticData.DataLocation] : []; - public ITagger? CreateTagger(ITextBuffer buffer) where T : ITag + ITagger? ITaggerProvider.CreateTagger(ITextBuffer buffer) { - using var taggers = TemporaryArray>.Empty; - foreach (var taggerProvider in _diagnosticsTaggerProviders) - { - var innerTagger = taggerProvider.CreateTagger(buffer); - if (innerTagger != null) - taggers.Add(innerTagger); - } + var tagger = CreateTagger(buffer); - var tagger = new SimpleAggregateTagger(taggers.ToImmutableAndClear()); if (tagger is not ITagger genericTagger) { tagger.Dispose(); @@ -97,7 +90,20 @@ protected virtual ImmutableArray GetLocationsToTag(Diagn return genericTagger; } - protected ITagSpan? CreateTagSpan(Workspace workspace, SnapshotSpan span, DiagnosticData data) + public SimpleAggregateTagger CreateTagger(ITextBuffer buffer) where T : ITag + { + using var taggers = TemporaryArray>.Empty; + foreach (var taggerProvider in _diagnosticsTaggerProviders) + { + var innerTagger = taggerProvider.CreateTagger(buffer); + if (innerTagger != null) + taggers.Add(innerTagger); + } + + return new SimpleAggregateTagger(taggers.ToImmutableAndClear()); + } + + protected TagSpan? CreateTagSpan(Workspace workspace, SnapshotSpan span, DiagnosticData data) { var errorTag = CreateTag(workspace, data); if (errorTag == null) diff --git a/src/EditorFeatures/Core.Wpf/InlineHints/InlineHintsTagger.cs b/src/EditorFeatures/Core.Wpf/InlineHints/InlineHintsTagger.cs index ef932da5377e4..ed2bb08bd6060 100644 --- a/src/EditorFeatures/Core.Wpf/InlineHints/InlineHintsTagger.cs +++ b/src/EditorFeatures/Core.Wpf/InlineHints/InlineHintsTagger.cs @@ -28,7 +28,7 @@ internal sealed class InlineHintsTagger : ITagger, IDispo /// /// stores the parameter hint tags in a global location /// - private readonly List<(IMappingTagSpan mappingTagSpan, ITagSpan? tagSpan)> _cache = []; + private readonly List<(IMappingTagSpan mappingTagSpan, TagSpan? tagSpan)> _cache = []; /// /// Stores the snapshot associated with the cached tags in @@ -133,14 +133,15 @@ private void InvalidateCache() _cache.Clear(); } - public IEnumerable> GetTags(NormalizedSnapshotSpanCollection spans) + IEnumerable> ITagger.GetTags(NormalizedSnapshotSpanCollection spans) + => GetTags(spans); + + public IReadOnlyList> GetTags(NormalizedSnapshotSpanCollection spans) { try { if (spans.Count == 0) - { - return Array.Empty>(); - } + return []; var snapshot = spans[0].Snapshot; if (snapshot != _cacheSnapshot) @@ -169,7 +170,7 @@ public IEnumerable> GetTags(NormalizedSnapshotSp var document = snapshot.GetOpenDocumentInCurrentContextWithChanges(); var classify = document != null && _taggerProvider.EditorOptionsService.GlobalOptions.GetOption(InlineHintsViewOptionsStorage.ColorHints, document.Project.Language); - var selectedSpans = new List>(); + var selectedSpans = new List>(); for (var i = 0; i < _cache.Count; i++) { var tagSpans = _cache[i].mappingTagSpan.Span.GetSpans(snapshot); diff --git a/src/EditorFeatures/Core.Wpf/Preview/AbstractPreviewTaggerProvider.cs b/src/EditorFeatures/Core.Wpf/Preview/AbstractPreviewTaggerProvider.cs index 5a61207d23f78..0f4c218878488 100644 --- a/src/EditorFeatures/Core.Wpf/Preview/AbstractPreviewTaggerProvider.cs +++ b/src/EditorFeatures/Core.Wpf/Preview/AbstractPreviewTaggerProvider.cs @@ -40,7 +40,10 @@ public Tagger(ITextBuffer buffer, object key, TTag tagInstance) _tagInstance = tagInstance; } - public IEnumerable> GetTags(NormalizedSnapshotSpanCollection spans) + IEnumerable> ITagger.GetTags(NormalizedSnapshotSpanCollection spans) + => GetTags(spans); + + public IEnumerable> GetTags(NormalizedSnapshotSpanCollection spans) { if (_buffer.Properties.TryGetProperty(_key, out NormalizedSnapshotSpanCollection matchingSpans)) { diff --git a/src/EditorFeatures/Core.Wpf/Preview/PreviewStaticClassificationTaggerProvider.cs b/src/EditorFeatures/Core.Wpf/Preview/PreviewStaticClassificationTaggerProvider.cs index f825c2cbe827c..62e6669b4c7cf 100644 --- a/src/EditorFeatures/Core.Wpf/Preview/PreviewStaticClassificationTaggerProvider.cs +++ b/src/EditorFeatures/Core.Wpf/Preview/PreviewStaticClassificationTaggerProvider.cs @@ -61,7 +61,10 @@ public Tagger(ClassificationTypeMap typeMap, ITextBuffer buffer) /// event EventHandler ITagger.TagsChanged { add { } remove { } } - public IEnumerable> GetTags(NormalizedSnapshotSpanCollection spans) + IEnumerable> ITagger.GetTags(NormalizedSnapshotSpanCollection spans) + => GetTags(spans); + + public IEnumerable> GetTags(NormalizedSnapshotSpanCollection spans) { if (!_buffer.Properties.TryGetProperty(PredefinedPreviewTaggerKeys.StaticClassificationSpansKey, out ImmutableArray classifiedSpans)) { diff --git a/src/EditorFeatures/Core/Classification/CopyPasteAndPrintingClassificationBufferTaggerProvider.Tagger.cs b/src/EditorFeatures/Core/Classification/CopyPasteAndPrintingClassificationBufferTaggerProvider.Tagger.cs index d508117fcfcda..8dafcaae62f0a 100644 --- a/src/EditorFeatures/Core/Classification/CopyPasteAndPrintingClassificationBufferTaggerProvider.Tagger.cs +++ b/src/EditorFeatures/Core/Classification/CopyPasteAndPrintingClassificationBufferTaggerProvider.Tagger.cs @@ -89,12 +89,15 @@ public IEnumerable> GetTags(NormalizedSnapshotSpanC return []; } - private static IEnumerable> GetIntersectingTags(NormalizedSnapshotSpanCollection spans, TagSpanIntervalTree cachedTags) + private static IReadOnlyList> GetIntersectingTags(NormalizedSnapshotSpanCollection spans, TagSpanIntervalTree cachedTags) => SegmentedListPool>.ComputeList( static (args, tags) => args.cachedTags.AddIntersectingTagSpans(args.spans, tags), (cachedTags, spans)); - public IEnumerable> GetAllTags(NormalizedSnapshotSpanCollection spans, CancellationToken cancellationToken) + IEnumerable> IAccurateTagger.GetAllTags(NormalizedSnapshotSpanCollection spans, CancellationToken cancellationToken) + => GetAllTags(spans, cancellationToken); + + public IEnumerable> GetAllTags(NormalizedSnapshotSpanCollection spans, CancellationToken cancellationToken) { if (spans.Count == 0) return []; @@ -125,7 +128,7 @@ public IEnumerable> GetAllTags(NormalizedSnapshotSp } } - private IEnumerable> ComputeAndCacheAllTags( + private IEnumerable> ComputeAndCacheAllTags( NormalizedSnapshotSpanCollection spans, ITextSnapshot snapshot, Document document, diff --git a/src/EditorFeatures/Core/InlineRename/Taggers/AbstractRenameTagger.cs b/src/EditorFeatures/Core/InlineRename/Taggers/AbstractRenameTagger.cs index 29a85fb2a8f65..c111df73c478e 100644 --- a/src/EditorFeatures/Core/InlineRename/Taggers/AbstractRenameTagger.cs +++ b/src/EditorFeatures/Core/InlineRename/Taggers/AbstractRenameTagger.cs @@ -90,7 +90,10 @@ public void Dispose() public event EventHandler TagsChanged; - public IEnumerable> GetTags(NormalizedSnapshotSpanCollection spans) + IEnumerable> ITagger.GetTags(NormalizedSnapshotSpanCollection spans) + => GetTags(spans); + + public IEnumerable> GetTags(NormalizedSnapshotSpanCollection spans) { if (_renameService.ActiveSession == null) { diff --git a/src/EditorFeatures/Core/RenameTracking/RenameTrackingTaggerProvider.Tagger.cs b/src/EditorFeatures/Core/RenameTracking/RenameTrackingTaggerProvider.Tagger.cs index 3d25bc9efd715..deaef04b1024e 100644 --- a/src/EditorFeatures/Core/RenameTracking/RenameTrackingTaggerProvider.Tagger.cs +++ b/src/EditorFeatures/Core/RenameTracking/RenameTrackingTaggerProvider.Tagger.cs @@ -45,7 +45,7 @@ public IEnumerable> GetTags(NormalizedSnapshotSpanCo IEnumerable> ITagger.GetTags(NormalizedSnapshotSpanCollection spans) => GetTags(spans, new ErrorTag(PredefinedErrorTypeNames.Suggestion)); - private IEnumerable> GetTags(NormalizedSnapshotSpanCollection spans, T tag) where T : ITag + private IEnumerable> GetTags(NormalizedSnapshotSpanCollection spans, T tag) where T : ITag { if (!_stateMachine.GlobalOptions.GetOption(RenameTrackingOptionsStorage.RenameTracking)) { diff --git a/src/EditorFeatures/Core/Shared/Tagging/Utilities/TagSpanIntervalTree.IntervalIntrospector.cs b/src/EditorFeatures/Core/Shared/Tagging/Utilities/TagSpanIntervalTree.IntervalIntrospector.cs index 85db301aa397b..a2e12c47d692b 100644 --- a/src/EditorFeatures/Core/Shared/Tagging/Utilities/TagSpanIntervalTree.IntervalIntrospector.cs +++ b/src/EditorFeatures/Core/Shared/Tagging/Utilities/TagSpanIntervalTree.IntervalIntrospector.cs @@ -15,9 +15,9 @@ internal partial class TagSpanIntervalTree private readonly struct IntervalIntrospector( ITextSnapshot snapshot, SpanTrackingMode trackingMode) - : IIntervalIntrospector> + : IIntervalIntrospector> { - public TextSpan GetSpan(ITagSpan value) + public TextSpan GetSpan(TagSpan value) => GetTranslatedSpan(value, snapshot, trackingMode).Span.ToTextSpan(); } } diff --git a/src/EditorFeatures/Core/Shared/Tagging/Utilities/TagSpanIntervalTree.cs b/src/EditorFeatures/Core/Shared/Tagging/Utilities/TagSpanIntervalTree.cs index a5cb9b4847f04..793642e205702 100644 --- a/src/EditorFeatures/Core/Shared/Tagging/Utilities/TagSpanIntervalTree.cs +++ b/src/EditorFeatures/Core/Shared/Tagging/Utilities/TagSpanIntervalTree.cs @@ -24,17 +24,17 @@ namespace Microsoft.CodeAnalysis.Editor.Shared.Tagging; internal sealed partial class TagSpanIntervalTree( ITextBuffer textBuffer, SpanTrackingMode trackingMode, - IEnumerable>? values1 = null, - IEnumerable>? values2 = null) where TTag : ITag + IEnumerable>? values1 = null, + IEnumerable>? values2 = null) where TTag : ITag { private readonly ITextBuffer _textBuffer = textBuffer; private readonly SpanTrackingMode _spanTrackingMode = trackingMode; - private readonly IntervalTree> _tree = IntervalTree.Create( + private readonly IntervalTree> _tree = IntervalTree.Create( new IntervalIntrospector(textBuffer.CurrentSnapshot, trackingMode), values1, values2); private static SnapshotSpan GetTranslatedSpan( - ITagSpan originalTagSpan, ITextSnapshot textSnapshot, SpanTrackingMode trackingMode) + TagSpan originalTagSpan, ITextSnapshot textSnapshot, SpanTrackingMode trackingMode) { var localSpan = originalTagSpan.Span; @@ -43,13 +43,13 @@ private static SnapshotSpan GetTranslatedSpan( : localSpan.TranslateTo(textSnapshot, trackingMode); } - private ITagSpan GetTranslatedITagSpan(ITagSpan originalTagSpan, ITextSnapshot textSnapshot) + private TagSpan GetTranslatedITagSpan(TagSpan originalTagSpan, ITextSnapshot textSnapshot) // Avoid reallocating in the case where we're on the same snapshot. => originalTagSpan.Span.Snapshot == textSnapshot ? originalTagSpan : GetTranslatedTagSpan(originalTagSpan, textSnapshot, _spanTrackingMode); - private static TagSpan GetTranslatedTagSpan(ITagSpan originalTagSpan, ITextSnapshot textSnapshot, SpanTrackingMode trackingMode) + private static TagSpan GetTranslatedTagSpan(TagSpan originalTagSpan, ITextSnapshot textSnapshot, SpanTrackingMode trackingMode) // Avoid reallocating in the case where we're on the same snapshot. => originalTagSpan is TagSpan tagSpan && tagSpan.Span.Snapshot == textSnapshot ? tagSpan @@ -67,7 +67,7 @@ public bool HasSpanThatContains(SnapshotPoint point) return _tree.HasIntervalThatContains(point.Position, length: 0, new IntervalIntrospector(snapshot, _spanTrackingMode)); } - public IList> GetIntersectingSpans(SnapshotSpan snapshotSpan) + public IReadOnlyList> GetIntersectingSpans(SnapshotSpan snapshotSpan) => SegmentedListPool>.ComputeList( static (args, tags) => args.@this.AppendIntersectingSpansInSortedOrder(args.snapshotSpan, tags), (@this: this, snapshotSpan)); @@ -82,7 +82,7 @@ private void AppendIntersectingSpansInSortedOrder(SnapshotSpan snapshotSpan, Seg var snapshot = snapshotSpan.Snapshot; Debug.Assert(snapshot.TextBuffer == _textBuffer); - using var intersectingIntervals = TemporaryArray>.Empty; + using var intersectingIntervals = TemporaryArray>.Empty; _tree.FillWithIntervalsThatIntersectWith( snapshotSpan.Start, snapshotSpan.Length, ref intersectingIntervals.AsRef(), @@ -92,14 +92,14 @@ ref intersectingIntervals.AsRef(), result.Add(GetTranslatedTagSpan(tagSpan, snapshot, _spanTrackingMode)); } - public IEnumerable> GetSpans(ITextSnapshot snapshot) + public IEnumerable> GetSpans(ITextSnapshot snapshot) => _tree.Select(tn => GetTranslatedITagSpan(tn, snapshot)); /// /// Adds all the tag spans in to , translating them to the given /// location based on . /// - public void AddAllSpans(ITextSnapshot textSnapshot, HashSet> tagSpans) + public void AddAllSpans(ITextSnapshot textSnapshot, HashSet> tagSpans) { foreach (var tagSpan in _tree) tagSpans.Add(GetTranslatedITagSpan(tagSpan, textSnapshot)); @@ -110,9 +110,9 @@ public void AddAllSpans(ITextSnapshot textSnapshot, HashSet> tagS /// the spans in . /// public void RemoveIntersectingTagSpans( - ArrayBuilder snapshotSpansToRemove, HashSet> tagSpans) + ArrayBuilder snapshotSpansToRemove, HashSet> tagSpans) { - using var buffer = TemporaryArray>.Empty; + using var buffer = TemporaryArray>.Empty; foreach (var snapshotSpan in snapshotSpansToRemove) { @@ -202,7 +202,7 @@ private void AddTagsForLargeNumberOfSpans(NormalizedSnapshotSpanCollection reque if (!enumerator.MoveNext()) return; - using var _2 = PooledHashSet>.GetInstance(out var hashSet); + using var _2 = PooledHashSet>.GetInstance(out var hashSet); var requestIndex = 0; while (true) diff --git a/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource.cs b/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource.cs index 9b982d3d6e45e..da3fd9653023f 100644 --- a/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource.cs +++ b/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource.cs @@ -172,7 +172,7 @@ public TagSource( _dataSource = dataSource; _asyncListener = asyncListener; _nonFrozenComputationCancellationSeries = new(_disposalTokenSource.Token); - _tagSpanSetPool = new ObjectPool>>(() => new HashSet>(this), trimOnFree: false); + _tagSpanSetPool = new ObjectPool>>(() => new HashSet>(this), trimOnFree: false); _workspaceRegistration = Workspace.GetWorkspaceRegistration(subjectBuffer.AsTextContainer()); diff --git a/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_IEqualityComparer.cs b/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_IEqualityComparer.cs index 9c3c2cdfff77d..531badc090be8 100644 --- a/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_IEqualityComparer.cs +++ b/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_IEqualityComparer.cs @@ -10,11 +10,11 @@ namespace Microsoft.CodeAnalysis.Editor.Tagging; internal abstract partial class AbstractAsynchronousTaggerProvider { - private partial class TagSource : IEqualityComparer> + private partial class TagSource : IEqualityComparer> { - private readonly ObjectPool>> _tagSpanSetPool; + private readonly ObjectPool>> _tagSpanSetPool; - public bool Equals(ITagSpan? x, ITagSpan? y) + public bool Equals(TagSpan? x, TagSpan? y) { if (x == y) return true; @@ -28,10 +28,10 @@ public bool Equals(ITagSpan? x, ITagSpan? y) /// /// For the purposes of hashing, just hash spans. This will prevent most collisions. And the rare /// collision of two tag spans with the same span will be handled by checking if their tags are the same - /// through . This prevents us from having to + /// through . This prevents us from having to /// define a suitable hashing strategy for all our tags. /// - public int GetHashCode(ITagSpan obj) + public int GetHashCode(TagSpan obj) => obj.Span.Span.GetHashCode(); } } diff --git a/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_ProduceTags.cs b/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_ProduceTags.cs index e4373e0457923..e9e4fdfa3b487 100644 --- a/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_ProduceTags.cs +++ b/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_ProduceTags.cs @@ -393,7 +393,7 @@ private ImmutableDictionary> ComputeNewTa foreach (var spanToTag in context.SpansToTag) buffersToTag.Add(spanToTag.SnapshotSpan.Snapshot.TextBuffer); - using var _2 = ArrayBuilder>.GetInstance(out var newTagsInBuffer); + using var _2 = ArrayBuilder>.GetInstance(out var newTagsInBuffer); using var _3 = ArrayBuilder.GetInstance(out var spansToInvalidateInBuffer); var newTagTrees = ImmutableDictionary.CreateBuilder>(); @@ -427,7 +427,7 @@ private ImmutableDictionary> ComputeNewTa private TagSpanIntervalTree? ComputeNewTagTree( ImmutableDictionary> oldTagTrees, ITextBuffer textBuffer, - ArrayBuilder> newTags, + ArrayBuilder> newTags, ArrayBuilder spansToInvalidate) { var noNewTags = newTags.IsEmpty; @@ -469,7 +469,7 @@ private ImmutableDictionary> ComputeNewTa private static void AddNonIntersectingTagSpans( ArrayBuilder spansToInvalidate, TagSpanIntervalTree oldTagTree, - HashSet> nonIntersectingTagSpans) + HashSet> nonIntersectingTagSpans) { var firstSpanToInvalidate = spansToInvalidate.First(); var snapshot = firstSpanToInvalidate.Snapshot; @@ -611,7 +611,7 @@ private DiffResult ComputeDifference( return new DiffResult(new(added), new(removed)); - static ITagSpan? NextOrNull(IEnumerator> enumerator) + static TagSpan? NextOrNull(IEnumerator> enumerator) => enumerator.MoveNext() ? enumerator.Current : null; } diff --git a/src/EditorFeatures/Core/Tagging/EfficientTagger.cs b/src/EditorFeatures/Core/Tagging/EfficientTagger.cs index 09277d30982cd..8349cb739bfa7 100644 --- a/src/EditorFeatures/Core/Tagging/EfficientTagger.cs +++ b/src/EditorFeatures/Core/Tagging/EfficientTagger.cs @@ -26,10 +26,13 @@ internal abstract class EfficientTagger : ITagger, IDisposable where public abstract void Dispose(); + IEnumerable> ITagger.GetTags(NormalizedSnapshotSpanCollection spans) + => GetTags(spans); + /// /// Default impl of the core interface. Forces an allocation. /// - public IEnumerable> GetTags(NormalizedSnapshotSpanCollection spans) + public IReadOnlyList> GetTags(NormalizedSnapshotSpanCollection spans) => SegmentedListPool>.ComputeList( static (args, tags) => args.@this.AddTags(args.spans, tags), (@this: this, spans)); diff --git a/src/EditorFeatures/Core/Tagging/TaggerContext.cs b/src/EditorFeatures/Core/Tagging/TaggerContext.cs index ba972866c5417..bba0730503ceb 100644 --- a/src/EditorFeatures/Core/Tagging/TaggerContext.cs +++ b/src/EditorFeatures/Core/Tagging/TaggerContext.cs @@ -19,7 +19,7 @@ internal sealed class TaggerContext where TTag : ITag private readonly ImmutableDictionary> _existingTags; internal ImmutableArray _spansTagged; - public readonly SegmentedList> TagSpans = []; + public readonly SegmentedList> TagSpans = []; /// /// If the client should compute tags using frozen partial semantics. This generally should have no effect if tags @@ -73,7 +73,7 @@ internal TaggerContext( _existingTags = existingTags; } - public void AddTag(ITagSpan tag) + public void AddTag(TagSpan tag) => TagSpans.Add(tag); public void ClearTags() diff --git a/src/EditorFeatures/Test/Tagging/AsynchronousTaggerTests.cs b/src/EditorFeatures/Test/Tagging/AsynchronousTaggerTests.cs index 6833e685ded8c..d1caf71f9075f 100644 --- a/src/EditorFeatures/Test/Tagging/AsynchronousTaggerTests.cs +++ b/src/EditorFeatures/Test/Tagging/AsynchronousTaggerTests.cs @@ -247,7 +247,7 @@ class Program private sealed class TestTaggerProvider( IThreadingContext threadingContext, - Func, DocumentSnapshotSpan, IEnumerable>> callback, + Func, DocumentSnapshotSpan, IEnumerable>> callback, ITaggerEventSource eventSource, IGlobalOptionService globalOptions, bool supportsFrozenPartialSemantics, diff --git a/src/EditorFeatures/TestUtilities/Diagnostics/DiagnosticTaggerWrapper.cs b/src/EditorFeatures/TestUtilities/Diagnostics/DiagnosticTaggerWrapper.cs index d999fb74614ff..17acbf67cd762 100644 --- a/src/EditorFeatures/TestUtilities/Diagnostics/DiagnosticTaggerWrapper.cs +++ b/src/EditorFeatures/TestUtilities/Diagnostics/DiagnosticTaggerWrapper.cs @@ -10,6 +10,7 @@ using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor.InlineDiagnostics; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.Editor.Tagging; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.CodeAnalysis.SolutionCrawler; using Microsoft.CodeAnalysis.Test.Utilities; @@ -26,7 +27,7 @@ internal class DiagnosticTaggerWrapper private readonly IThreadingContext _threadingContext; private readonly IAsynchronousOperationListenerProvider _listenerProvider; - private ITaggerProvider? _taggerProvider; + private AbstractDiagnosticsTaggerProvider? _taggerProvider; public DiagnosticTaggerWrapper( EditorTestWorkspace workspace, @@ -52,7 +53,7 @@ public DiagnosticTaggerWrapper( } } - public ITaggerProvider TaggerProvider + public AbstractDiagnosticsTaggerProvider TaggerProvider { get { @@ -62,7 +63,7 @@ public ITaggerProvider TaggerProvider if (typeof(TProvider) == typeof(InlineDiagnosticsTaggerProvider)) { - _taggerProvider = _workspace.ExportProvider.GetExportedValues() + _taggerProvider = (AbstractDiagnosticsTaggerProvider)(object)_workspace.ExportProvider.GetExportedValues() .OfType() .Single(); } diff --git a/src/EditorFeatures/TestUtilities/Squiggles/SquiggleUtilities.cs b/src/EditorFeatures/TestUtilities/Squiggles/SquiggleUtilities.cs index 20b54b9a7e42e..b76d73bede467 100644 --- a/src/EditorFeatures/TestUtilities/Squiggles/SquiggleUtilities.cs +++ b/src/EditorFeatures/TestUtilities/Squiggles/SquiggleUtilities.cs @@ -27,7 +27,7 @@ public static class SquiggleUtilities internal static TestComposition WpfCompositionWithSolutionCrawler = EditorTestCompositions.EditorFeaturesWpf .RemoveParts(typeof(MockWorkspaceEventListenerProvider)); - internal static async Task>> GetTagSpansAsync( + internal static async Task>> GetTagSpansAsync( EditorTestWorkspace workspace, IReadOnlyDictionary> analyzerMap = null) where TProvider : AbstractDiagnosticsTaggerProvider @@ -37,9 +37,8 @@ internal static async Task>> GetTagSpansAsync(textBuffer); + using var tagger = wrapper.TaggerProvider.CreateTagger(textBuffer); - using var disposable = tagger as IDisposable; await wrapper.WaitForTags(); var snapshot = textBuffer.CurrentSnapshot; diff --git a/src/EditorFeatures/TestUtilities/Squiggles/TestDiagnosticTagProducer.cs b/src/EditorFeatures/TestUtilities/Squiggles/TestDiagnosticTagProducer.cs index 03826c1a9fe0c..6e3ef4081cb3f 100644 --- a/src/EditorFeatures/TestUtilities/Squiggles/TestDiagnosticTagProducer.cs +++ b/src/EditorFeatures/TestUtilities/Squiggles/TestDiagnosticTagProducer.cs @@ -17,7 +17,7 @@ internal sealed class TestDiagnosticTagProducer where TProvider : AbstractDiagnosticsTaggerProvider where TTag : class, ITag { - internal static Task>> GetTagSpansAsync( + internal static Task>> GetTagSpansAsync( EditorTestWorkspace workspace, IReadOnlyDictionary>? analyzerMap = null) { diff --git a/src/EditorFeatures/Text/Shared/Extensions/ITextSnapshotExtensions.cs b/src/EditorFeatures/Text/Shared/Extensions/ITextSnapshotExtensions.cs index 124db4ddacaab..27f3a280aa6cd 100644 --- a/src/EditorFeatures/Text/Shared/Extensions/ITextSnapshotExtensions.cs +++ b/src/EditorFeatures/Text/Shared/Extensions/ITextSnapshotExtensions.cs @@ -85,11 +85,8 @@ public static SnapshotSpan GetSpanFromBounds(this ITextSnapshot snapshot, int st public static SnapshotSpan GetSpan(this ITextSnapshot snapshot, Span span) => new SnapshotSpan(snapshot, span); - public static ITagSpan GetTagSpan(this ITextSnapshot snapshot, Span span, TTag tag) - where TTag : ITag - { - return new TagSpan(new SnapshotSpan(snapshot, span), tag); - } + public static TagSpan GetTagSpan(this ITextSnapshot snapshot, Span span, TTag tag) where TTag : ITag + => new(new SnapshotSpan(snapshot, span), tag); public static SnapshotSpan GetSpan(this ITextSnapshot snapshot, int startLine, int startIndex, int endLine, int endIndex) => TryGetSpan(snapshot, startLine, startIndex, endLine, endIndex) ?? throw new InvalidOperationException(TextEditorResources.The_snapshot_does_not_contain_the_specified_span); diff --git a/src/VisualStudio/Core/Def/Preview/PreviewUpdater.Tagger.cs b/src/VisualStudio/Core/Def/Preview/PreviewUpdater.Tagger.cs index 06bfd62e62d15..cc6de9e908d15 100644 --- a/src/VisualStudio/Core/Def/Preview/PreviewUpdater.Tagger.cs +++ b/src/VisualStudio/Core/Def/Preview/PreviewUpdater.Tagger.cs @@ -40,7 +40,10 @@ public Span Span public event EventHandler? TagsChanged; - public IEnumerable> GetTags(NormalizedSnapshotSpanCollection spans) + IEnumerable> ITagger.GetTags(NormalizedSnapshotSpanCollection spans) + => GetTags(); + + public IEnumerable> GetTags() { var lines = _textBuffer.CurrentSnapshot.Lines.Where(line => line.Extent.OverlapsWith(_span)); diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VenusMargin/ProjectionSpanTagger.cs b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VenusMargin/ProjectionSpanTagger.cs index a3cae96d938a4..87e958ebd86a6 100644 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VenusMargin/ProjectionSpanTagger.cs +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VenusMargin/ProjectionSpanTagger.cs @@ -58,12 +58,13 @@ private void RaiseTagsChanged(SnapshotSpanEventArgs args) this.TagsChanged?.Invoke(this, args); } - public IEnumerable> GetTags(NormalizedSnapshotSpanCollection spans) + IEnumerable> ITagger.GetTags(NormalizedSnapshotSpanCollection spans) + => GetTags(spans); + + public IEnumerable> GetTags(NormalizedSnapshotSpanCollection spans) { if (!_textView.Properties.TryGetProperty(PropertyName, out List allSpans)) - { - return null; - } + return []; return allSpans .Where(s => spans.Any(ss => ss.IntersectsWith(s))) diff --git a/src/Workspaces/Core/Portable/Utilities/SegmentedListPool.cs b/src/Workspaces/Core/Portable/Utilities/SegmentedListPool.cs index b78767a598ce6..08225e1b37496 100644 --- a/src/Workspaces/Core/Portable/Utilities/SegmentedListPool.cs +++ b/src/Workspaces/Core/Portable/Utilities/SegmentedListPool.cs @@ -39,7 +39,7 @@ internal static PooledObject> GetPooledList(out SegmentedLis /// are added to the list, then the singleton will be returned. Otherwise the /// instance will be returned. /// - public static IList ComputeList( + public static IReadOnlyList ComputeList( Action> addItems, TArgs args, // Only used to allow type inference to work at callsite @@ -63,10 +63,6 @@ public static IList ComputeList( internal static class SegmentedListPool { - public static IList ComputeList( - Action> addItems, - TArgs args) - { - return SegmentedListPool.ComputeList(addItems, args, _: default); - } + public static IReadOnlyList ComputeList(Action> addItems, TArgs args) + => SegmentedListPool.ComputeList(addItems, args, _: default); }