using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Editor.Shared.Tagging; using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Tagging; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Editor.Tagging { internal class AsynchronousTaggerContext where TTag : ITag { private readonly ImmutableDictionary> _existingTags; internal IEnumerable _spansTagged; internal ImmutableArray>.Builder tagSpans = ImmutableArray.CreateBuilder>(); public TState State { get; set; } public IEnumerable SpansToTag { get; } public SnapshotPoint? CaretPosition { get; } /// /// The text that has changed between the last successfull tagging and this new request to /// produce tags. In order to be passed this value, /// must be specified in . /// public TextChangeRange? TextChangeRange { get; } public CancellationToken CancellationToken { get; } // For testing only. internal AsynchronousTaggerContext( TState state, IEnumerable spansToTag, SnapshotPoint? caretPosition, TextChangeRange? textChangeRange, CancellationToken cancellationToken) : this(state, spansToTag, caretPosition, textChangeRange, null, cancellationToken) { } internal AsynchronousTaggerContext( TState state, IEnumerable spansToTag, SnapshotPoint? caretPosition, TextChangeRange? textChangeRange, ImmutableDictionary> existingTags, CancellationToken cancellationToken) { this.State = state; this.SpansToTag = spansToTag; this.CaretPosition = caretPosition; this.TextChangeRange = textChangeRange; this.CancellationToken = cancellationToken; _spansTagged = spansToTag; _existingTags = existingTags; } public void AddTag(ITagSpan tag) { tagSpans.Add(tag); } /// /// Used to allow taggers to indicate what spans were actually tagged. This is useful /// when the tagger decides to tag a different span than the entire file. If a sub-span /// of a document is tagged then the tagger infrastructure will keep previously computed /// tags from before and after the sub-span and merge them with the newly produced tags. /// public void SetSpansTagged(IEnumerable spansTagged) { if (spansTagged == null) { throw new ArgumentNullException(nameof(spansTagged)); } this._spansTagged = spansTagged; } public IEnumerable> GetExistingTags(SnapshotSpan span) { TagSpanIntervalTree tree; return _existingTags.TryGetValue(span.Snapshot.TextBuffer, out tree) ? tree.GetIntersectingSpans(span) : SpecializedCollections.EmptyEnumerable>(); } } }