private void ProduceTagsSynchronously(TaggerContext <TTag> context)
            {
                if (ShouldSkipTagProduction())
                {
                    return;
                }

                _dataSource.ProduceTagsSynchronously(context);
            }
Beispiel #2
0
 /// <summary>
 /// Produce tags for the given context.
 /// Keep in sync with <see cref="ProduceTagsAsync(TaggerContext{TTag})"/>
 /// </summary>
 protected void ProduceTagsSynchronously(TaggerContext <TTag> context)
 {
     foreach (var spanToTag in context.SpansToTag)
     {
         context.CancellationToken.ThrowIfCancellationRequested();
         ProduceTagsSynchronously(
             context, spanToTag,
             GetCaretPosition(context.CaretPosition, spanToTag.SnapshotSpan));
     }
 }
Beispiel #3
0
 /// <summary>
 /// Produce tags for the given context.
 /// Keep in sync with <see cref="ProduceTagsSynchronously(TaggerContext{TTag})"/>
 /// </summary>
 protected virtual async Task ProduceTagsAsync(TaggerContext <TTag> context)
 {
     foreach (var spanToTag in context.SpansToTag)
     {
         context.CancellationToken.ThrowIfCancellationRequested();
         await ProduceTagsAsync(
             context, spanToTag,
             GetCaretPosition(context.CaretPosition, spanToTag.SnapshotSpan)).ConfigureAwait(false);
     }
 }
            private Task ProduceTagsAsync(TaggerContext <TTag> context)
            {
                if (ShouldSkipTagProduction())
                {
                    // If the feature is disabled, then just produce no tags.
                    return(SpecializedTasks.EmptyTask);
                }

                return(_dataSource.ProduceTagsAsync(context));
            }
Beispiel #5
0
 protected virtual void ProduceTagsSynchronously(TaggerContext <TTag> context, DocumentSnapshotSpan spanToTag, int?caretPosition)
 {
     // By default we implement the sync version of this by blocking on the async version.
     //
     // The benefit of this is that all taggers can implicitly be used as IAccurateTaggers
     // without any code changes.
     //
     // However, the drawback is that it means the UI thread might be blocked waiting for
     // tasks to be scheduled and run on the threadpool.
     //
     // Taggers that need to be called accurately should override this method to produce
     // results quickly if possible.
     ProduceTagsAsync(context, spanToTag, caretPosition).Wait(context.CancellationToken);
 }
            private void ProcessContext(
                List <DocumentSnapshotSpan> spansToTag,
                ImmutableDictionary <ITextBuffer, TagSpanIntervalTree <TTag> > oldTagTrees,
                TaggerContext <TTag> context)
            {
                var buffersToTag = spansToTag.Select(dss => dss.SnapshotSpan.Snapshot.TextBuffer).ToSet();

                // Ignore any tag spans reported for any buffers we weren't interested in.
                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);

                ProcessNewTagTrees(spansToTag, oldTagTrees, newTagTrees, context.State, context.CancellationToken);
            }
            private async Task RecomputeTagsAsync(
                object oldState,
                SnapshotPoint?caretPosition,
                TextChangeRange?textChangeRange,
                List <DocumentSnapshotSpan> spansToTag,
                ImmutableDictionary <ITextBuffer, TagSpanIntervalTree <TTag> > oldTagTrees,
                CancellationToken cancellationToken)
            {
                cancellationToken.ThrowIfCancellationRequested();

                var context = new TaggerContext <TTag>(
                    oldState, spansToTag, caretPosition, textChangeRange, oldTagTrees, cancellationToken);

                await ProduceTagsAsync(context).ConfigureAwait(false);

                ProcessContext(spansToTag, oldTagTrees, context);
            }
            public TagSpanIntervalTree <TTag> GetAccurateTagIntervalTreeForBuffer(ITextBuffer buffer, CancellationToken cancellationToken)
            {
                _workQueue.AssertIsForeground();

                if (!this.UpToDate)
                {
                    // We're not up to date.  That means we have an outstanding update that we're
                    // currently processing.  Unfortunately we have no way to track the progress of
                    // that update (i.e. a Task).  Also, even if we did, we'd have the problem that
                    // we have delays coded into the normal tagging process.  So waiting on that Task
                    // could take a long time.
                    //
                    // So, instead, we just cancel whatever work we're currently doing, and we just
                    // compute the results synchronously in this call.

                    // We can cancel any background computations currently happening
                    _workQueue.CancelCurrentWork();

                    var spansToTag = GetSpansAndDocumentsToTag();

                    // Safe to access _cachedTagTrees here.  We're on the UI thread.
                    var oldTagTrees = this.CachedTagTrees;
                    var caretPoint  = _dataSource.GetCaretPoint(_textViewOpt, _subjectBuffer);

                    var context = new TaggerContext <TTag>(
                        this.State, spansToTag, caretPoint, this.AccumulatedTextChanges, oldTagTrees, cancellationToken);

                    ProduceTagsSynchronously(context);

                    ProcessContext(spansToTag, oldTagTrees, context);
                }

                Debug.Assert(this.UpToDate);
                this.CachedTagTrees.TryGetValue(buffer, out var tags);
                return(tags);
            }
Beispiel #9
0
 protected virtual Task ProduceTagsAsync(TaggerContext <TTag> context, DocumentSnapshotSpan spanToTag, int?caretPosition)
 {
     return(SpecializedTasks.EmptyTask);
 }
Beispiel #10
0
 internal Task ProduceTagsAsync_ForTestingPurposesOnly(TaggerContext <TTag> context)
 {
     return(ProduceTagsAsync(context));
 }