Example #1
0
            public TagSource(
                ITextView textViewOpt,
                ITextBuffer subjectBuffer,
                AbstractAsynchronousTaggerProvider <TTag> dataSource,
                IAsynchronousOperationListener asyncListener,
                IForegroundNotificationService notificationService)
            {
                if (dataSource.SpanTrackingMode == SpanTrackingMode.Custom)
                {
                    throw new ArgumentException("SpanTrackingMode.Custom not allowed.", "spanTrackingMode");
                }

                _subjectBuffer       = subjectBuffer;
                _textViewOpt         = textViewOpt;
                _dataSource          = dataSource;
                _asyncListener       = asyncListener;
                _notificationService = notificationService;
                _tagSpanComparer     = new TagSpanComparer(_dataSource.TagComparer);

                DebugRecordInitialStackTrace();

                _workQueue          = new AsynchronousSerialWorkQueue(asyncListener);
                this.CachedTagTrees = ImmutableDictionary.Create <ITextBuffer, TagSpanIntervalTree <TTag> >();

                _eventSource = CreateEventSource();

                Connect();

                // Kick off a task to compute the initial set of tags.
                RecalculateTagsOnChanged(new TaggerEventArgs(TaggerDelay.Short));
            }
Example #2
0
        protected ProducerPopulatedTagSource(
            ITextBuffer subjectBuffer,
            ITagProducer <TTag> tagProducer,
            ITaggerEventSource eventSource,
            IAsynchronousOperationListener asyncListener,
            IForegroundNotificationService notificationService,
            bool removeTagsThatIntersectEdits,
            SpanTrackingMode spanTrackingMode,
            Func <ITextBuffer, ProducerPopulatedTagSource <TTag> > bufferToRelatedTagSource = null) :
            base(subjectBuffer, notificationService, asyncListener)
        {
            if (spanTrackingMode == SpanTrackingMode.Custom)
            {
                throw new ArgumentException("SpanTrackingMode.Custom not allowed.", "spanTrackingMode");
            }

            _tagProducer = tagProducer;
            _removeTagsThatIntersectEdits = removeTagsThatIntersectEdits;
            _spanTrackingMode             = spanTrackingMode;

            _cachedTags = ImmutableDictionary.Create <ITextBuffer, TagSpanIntervalTree <TTag> >();

            _eventSource = eventSource;
            _bufferToRelatedTagSource = bufferToRelatedTagSource;

            _accumulatedTextChanges = null;

            AttachEventHandlersAndStart();
        }
            public TagSource(
                ITextView textViewOpt,
                ITextBuffer subjectBuffer,
                AbstractAsynchronousTaggerProvider <TTag> dataSource,
                IAsynchronousOperationListener asyncListener,
                IForegroundNotificationService notificationService)
            {
                if (dataSource.SpanTrackingMode == SpanTrackingMode.Custom)
                {
                    throw new ArgumentException("SpanTrackingMode.Custom not allowed.", "spanTrackingMode");
                }

                _subjectBuffer       = subjectBuffer;
                _textViewOpt         = textViewOpt;
                _dataSource          = dataSource;
                _asyncListener       = asyncListener;
                _notificationService = notificationService;
                _tagSpanComparer     = new TagSpanComparer(_dataSource.TagComparer);

                DebugRecordInitialStackTrace();

                _workQueue          = new AsynchronousSerialWorkQueue(asyncListener);
                this.CachedTagTrees = ImmutableDictionary.Create <ITextBuffer, TagSpanIntervalTree <TTag> >();

                _eventSource = CreateEventSource();

                Connect();

                // Start computing the initial set of tags immediately.  We want to get the UI
                // to a complete state as soon as possible.
                ComputeInitialTags();
            }
Example #4
0
 public SemanticBufferTagSource(
     ITextBuffer subjectBuffer, ITagProducer <TTag> tagProducer, ITaggerEventSource eventSource,
     IAsynchronousOperationListener asyncListener, IForegroundNotificationService notificationService,
     bool removeTagsThatIntersectEdits, Func <ITextBuffer, ProducerPopulatedTagSource <TTag> > bufferToRelatedTagSource) :
     base(subjectBuffer, tagProducer, eventSource, asyncListener, notificationService, removeTagsThatIntersectEdits, bufferToRelatedTagSource)
 {
     _lastSemanticVersion = VersionStamp.Default;
 }
Example #5
0
 public BufferTagSource(
     ITextBuffer subjectBuffer, ITagProducer <TTag> tagProducer, ITaggerEventSource eventSource,
     IAsynchronousOperationListener asyncListener, IForegroundNotificationService notificationService,
     bool removeTagsThatIntersectEdits,
     SpanTrackingMode spanTrackingMode,
     Func <ITextBuffer, ProducerPopulatedTagSource <TTag> > bufferToRelatedTagSource) :
     base(subjectBuffer, tagProducer, eventSource, asyncListener, notificationService, removeTagsThatIntersectEdits, spanTrackingMode, bufferToRelatedTagSource)
 {
 }
 public ReferenceHighlightingTagSource(
     ITextView textView, ITextBuffer subjectBuffer,
     ITagProducer <AbstractNavigatableReferenceHighlightingTag> tagProducer, ITaggerEventSource eventSource,
     IAsynchronousOperationListener asyncListener, IForegroundNotificationService notificationService,
     bool removeTagsThatIntersectEdits) :
     base(subjectBuffer, tagProducer, eventSource, asyncListener, notificationService, removeTagsThatIntersectEdits, null)
 {
     _textView = textView;
 }
Example #7
0
 public CompilationAvailableTaggerEventSource(
     ITextBuffer subjectBuffer,
     IAsynchronousOperationListener asyncListener,
     params ITaggerEventSource[] eventSources)
 {
     _subjectBuffer          = subjectBuffer;
     _eventSource            = new CompilationAvailableEventSource(asyncListener);
     _underlyingSource       = TaggerEventSources.Compose(eventSources);
     _onCompilationAvailable = () => this.Changed?.Invoke(this, TaggerEventArgs.Empty);
 }
 public HighlightingTagSource(
     ITextView textView,
     ITextBuffer subjectBuffer,
     ITagProducer <HighlightTag> tagProducer,
     ITaggerEventSource eventSource,
     IAsynchronousOperationListener asyncListener,
     IForegroundNotificationService notificationService,
     bool removeTagsThatIntersectEdits,
     SpanTrackingMode spanTrackingMode)
     : base(textView, subjectBuffer, tagProducer, eventSource, asyncListener, notificationService, removeTagsThatIntersectEdits, spanTrackingMode)
 {
 }
 public SemanticBufferTagSource(
     ITextBuffer subjectBuffer,
     ITagProducer <TTag> tagProducer,
     ITaggerEventSource eventSource,
     IAsynchronousOperationListener asyncListener,
     IForegroundNotificationService notificationService,
     bool removeTagsThatIntersectEdits,
     SpanTrackingMode spanTrackingMode)
     : base(subjectBuffer, tagProducer, eventSource, asyncListener, notificationService, removeTagsThatIntersectEdits, spanTrackingMode)
 {
     _lastSemanticVersion = VersionStamp.Default;
 }
Example #10
0
        public CompilationAvailableTaggerEventSource(
            ITextBuffer subjectBuffer,
            IThreadingContext threadingContext,
            IAsynchronousOperationListener asyncListener,
            params ITaggerEventSource[] eventSources)
        {
            _subjectBuffer    = subjectBuffer;
            _asyncListener    = asyncListener;
            _underlyingSource = TaggerEventSources.Compose(eventSources);

            _workQueue = new AsynchronousSerialWorkQueue(threadingContext, asyncListener);
        }
Example #11
0
            public Tagger(SemanticClassificationBufferTaggerProvider owner, ITextBuffer subjectBuffer)
            {
                _owner         = owner;
                _subjectBuffer = subjectBuffer;

                const TaggerDelay Delay = TaggerDelay.Short;

                _eventSource = TaggerEventSources.Compose(
                    TaggerEventSources.OnSemanticChanged(subjectBuffer, Delay, _owner._semanticChangeNotificationService),
                    TaggerEventSources.OnDocumentActiveContextChanged(subjectBuffer, Delay));

                ConnectToEventSource();
            }
Example #12
0
 public TestTaggerProvider(
     Callback callback,
     ITaggerEventSource eventSource,
     Workspace workspace,
     IAsynchronousOperationListener asyncListener,
     IForegroundNotificationService notificationService,
     bool disableCancellation = false)
     : base(asyncListener, notificationService)
 {
     _callback            = callback;
     _eventSource         = eventSource;
     _workspace           = workspace;
     _disableCancellation = disableCancellation;
 }
Example #13
0
            public Tagger(
                SemanticClassificationBufferTaggerProvider owner,
                ITextBuffer subjectBuffer,
                IAsynchronousOperationListener asyncListener)
                : base(owner.ThreadingContext)
            {
                _owner         = owner;
                _subjectBuffer = subjectBuffer;

                const TaggerDelay Delay = TaggerDelay.Short;

                _eventSource = TaggerEventSources.Compose(
                    TaggerEventSources.OnWorkspaceChanged(subjectBuffer, Delay, asyncListener),
                    TaggerEventSources.OnDocumentActiveContextChanged(subjectBuffer, Delay));

                ConnectToEventSource();
            }
            public TagSource(
                ITextView textViewOpt,
                ITextBuffer subjectBuffer,
                AbstractAsynchronousTaggerProvider <TTag> dataSource,
                IAsynchronousOperationListener asyncListener,
                IForegroundNotificationService notificationService)
            {
                if (dataSource.SpanTrackingMode == SpanTrackingMode.Custom)
                {
                    throw new ArgumentException("SpanTrackingMode.Custom not allowed.", "spanTrackingMode");
                }

                _subjectBuffer       = subjectBuffer;
                _textViewOpt         = textViewOpt;
                _dataSource          = dataSource;
                _asyncListener       = asyncListener;
                _notificationService = notificationService;
                _tagSpanComparer     = new TagSpanComparer(_dataSource.TagComparer);

                DebugRecordInitialStackTrace();

                _workQueue          = new AsynchronousSerialWorkQueue(asyncListener);
                this.CachedTagTrees = ImmutableDictionary.Create <ITextBuffer, TagSpanIntervalTree <TTag> >();

                _eventSource = CreateEventSource();

                Connect();

                // Kick off a task to immediately compute the initial set of tags. This work should
                // not be cancellable (except if we get completely released), even if more events come
                // in.  That way we can get the initial set of results for the buffer as quickly as
                // possible, without kicking the work  down the road.
                var initialTagsCancellationToken = _initialComputationCancellationTokenSource.Token;

                // Note: we always kick this off to the new UI pump instead of computing tags right
                // on this thread.  The reason for that is that we may be getting created at a time
                // when the view itself is initializing.  As such the view is not in a state where
                // we want code touching it.
                RegisterNotification(
                    () => RecomputeTagsForeground(cancellationTokenOpt: initialTagsCancellationToken),
                    delay: 0,
                    cancellationToken: initialTagsCancellationToken);
            }
        protected ProducerPopulatedTagSource(
            ITextBuffer subjectBuffer,
            ITagProducer <TTag> tagProducer,
            ITaggerEventSource eventSource,
            IAsynchronousOperationListener asyncListener,
            IForegroundNotificationService notificationService,
            bool removeTagsThatIntersectEdits,
            Func <ITextBuffer, ProducerPopulatedTagSource <TTag> > bufferToRelatedTagSource = null) :
            base(subjectBuffer, notificationService, asyncListener)
        {
            _tagProducer = tagProducer;
            _removeTagsThatIntersectEdits = removeTagsThatIntersectEdits;

            _cachedTags = ImmutableDictionary.Create <ITextBuffer, TagSpanIntervalTree <TTag> >();

            _eventSource = eventSource;
            _bufferToRelatedTagSource = bufferToRelatedTagSource;

            _accumulatedTextChanges = null;

            AttachEventHandlersAndStart();
        }
Example #16
0
 public ViewTagSource(
     ITextView textView, ITextBuffer subjectBuffer, ITagProducer <TTag> tagProducer, ITaggerEventSource eventSource,
     IAsynchronousOperationListener asyncListener, IForegroundNotificationService notificationService,
     bool removeTagsThatIntersectEdits,
     SpanTrackingMode spanTrackingMode) :
     base(subjectBuffer, tagProducer, eventSource, asyncListener, notificationService, removeTagsThatIntersectEdits, spanTrackingMode, bufferToRelatedTagSource: null)
 {
     _textView = textView;
 }
            public CompositionEventSource(ITaggerEventSource[] providers)
            {
                Contract.ThrowIfNull(providers);

                _providers = providers;
            }
Example #18
0
            public TagSource(
                ITextView?textView,
                ITextBuffer subjectBuffer,
                ITextBufferVisibilityTracker?visibilityTracker,
                AbstractAsynchronousTaggerProvider <TTag> dataSource,
                IAsynchronousOperationListener asyncListener)
            {
                dataSource.ThreadingContext.ThrowIfNotOnUIThread();
                if (dataSource.SpanTrackingMode == SpanTrackingMode.Custom)
                {
                    throw new ArgumentException("SpanTrackingMode.Custom not allowed.", "spanTrackingMode");
                }

                _textView          = textView;
                _subjectBuffer     = subjectBuffer;
                _visibilityTracker = visibilityTracker;
                _dataSource        = dataSource;
                _asyncListener     = asyncListener;

                _workspaceRegistration = Workspace.GetWorkspaceRegistration(subjectBuffer.AsTextContainer());

                // Collapse all booleans added to just a max of two ('true' or 'false') representing if we're being
                // asked for initial tags or not
                _eventChangeQueue = new AsyncBatchingWorkQueue <bool>(
                    dataSource.EventChangeDelay.ComputeTimeDelay(),
                    ProcessEventChangeAsync,
                    EqualityComparer <bool> .Default,
                    asyncListener,
                    _disposalTokenSource.Token);

                _highPriTagsChangedQueue = new AsyncBatchingWorkQueue <NormalizedSnapshotSpanCollection>(
                    TaggerDelay.NearImmediate.ComputeTimeDelay(),
                    ProcessTagsChangedAsync,
                    equalityComparer: null,
                    asyncListener,
                    _disposalTokenSource.Token);

                if (_dataSource.AddedTagNotificationDelay == TaggerDelay.NearImmediate)
                {
                    // if the tagger wants "added tags" to be reported "NearImmediate"ly, then just reuse
                    // the "high pri" queue as that already reports things at that cadence.
                    _normalPriTagsChangedQueue = _highPriTagsChangedQueue;
                }
                else
                {
                    _normalPriTagsChangedQueue = new AsyncBatchingWorkQueue <NormalizedSnapshotSpanCollection>(
                        _dataSource.AddedTagNotificationDelay.ComputeTimeDelay(),
                        ProcessTagsChangedAsync,
                        equalityComparer: null,
                        asyncListener,
                        _disposalTokenSource.Token);
                }

                DebugRecordInitialStackTrace();

                // Create the tagger-specific events that will cause the tagger to refresh.
                _eventSource = CreateEventSource();

                // any time visibility changes, resume tagging on all taggers.  Any non-visible taggers will pause
                // themselves immediately afterwards.
                _onVisibilityChanged = () => ResumeIfVisible();

                // Now hook up this tagger to all interesting events.
                Connect();

                // Now that we're all hooked up to the events we care about, start computing the initial set of tags at
                // high priority.  We want to get the UI to a complete state as soon as possible.
                EnqueueWork(highPriority: true);

                return;

                // Represented as a local function just so we can keep this in sync with Dispose.Disconnect below.
                void Connect()
                {
                    _dataSource.ThreadingContext.ThrowIfNotOnUIThread();

                    // Register to hear about visibility changes so we can pause/resume this tagger.
                    _visibilityTracker?.RegisterForVisibilityChanges(subjectBuffer, _onVisibilityChanged);

                    _eventSource.Changed += OnEventSourceChanged;

                    if (_dataSource.TextChangeBehavior.HasFlag(TaggerTextChangeBehavior.TrackTextChanges))
                    {
                        _subjectBuffer.Changed += OnSubjectBufferChanged;
                    }

                    if (_dataSource.CaretChangeBehavior.HasFlag(TaggerCaretChangeBehavior.RemoveAllTagsOnCaretMoveOutsideOfTag))
                    {
                        if (_textView == null)
                        {
                            throw new ArgumentException(
                                      nameof(_dataSource.CaretChangeBehavior) + " can only be specified for an " + nameof(IViewTaggerProvider));
                        }

                        _textView.Caret.PositionChanged += OnCaretPositionChanged;
                    }

                    // Tell the interaction object to start issuing events.
                    _eventSource.Connect();
                }
            }
Example #19
0
            public TagSource(
                ITextView textViewOpt,
                ITextBuffer subjectBuffer,
                AbstractAsynchronousTaggerProvider <TTag> dataSource,
                IAsynchronousOperationListener asyncListener)
                : base(dataSource.ThreadingContext)
            {
                this.AssertIsForeground();
                if (dataSource.SpanTrackingMode == SpanTrackingMode.Custom)
                {
                    throw new ArgumentException("SpanTrackingMode.Custom not allowed.", "spanTrackingMode");
                }

                _subjectBuffer = subjectBuffer;
                _textViewOpt   = textViewOpt;
                _dataSource    = dataSource;
                _asyncListener = asyncListener;

                _highPriTagsChangedQueue = new AsyncBatchingWorkQueue <NormalizedSnapshotSpanCollection>(
                    TaggerDelay.NearImmediate.ComputeTimeDelay(),
                    ProcessTagsChangedAsync,
                    equalityComparer: null,
                    asyncListener,
                    _tagSourceState.Target.DisposalToken);

                if (_dataSource.AddedTagNotificationDelay == TaggerDelay.NearImmediate)
                {
                    // if the tagger wants "added tags" to be reported "NearImmediate"ly, then just reuse
                    // the "high pri" queue as that already reports things at that cadence.
                    _normalPriTagsChangedQueue = _highPriTagsChangedQueue;
                }
                else
                {
                    _normalPriTagsChangedQueue = new AsyncBatchingWorkQueue <NormalizedSnapshotSpanCollection>(
                        _dataSource.AddedTagNotificationDelay.ComputeTimeDelay(),
                        ProcessTagsChangedAsync,
                        equalityComparer: null,
                        asyncListener,
                        _tagSourceState.Target.DisposalToken);
                }

                DebugRecordInitialStackTrace();

                _eventSource = CreateEventSource();
                Connect();

                // Start computing the initial set of tags immediately.  We want to get the UI
                // to a complete state as soon as possible.
                EnqueueWork(initialTags: true);

                return;

                void Connect()
                {
                    this.AssertIsForeground();

                    _eventSource.Changed += OnEventSourceChanged;

                    if (_dataSource.TextChangeBehavior.HasFlag(TaggerTextChangeBehavior.TrackTextChanges))
                    {
                        _subjectBuffer.Changed += OnSubjectBufferChanged;
                    }

                    if (_dataSource.CaretChangeBehavior.HasFlag(TaggerCaretChangeBehavior.RemoveAllTagsOnCaretMoveOutsideOfTag))
                    {
                        if (_textViewOpt == null)
                        {
                            throw new ArgumentException(
                                      nameof(_dataSource.CaretChangeBehavior) + " can only be specified for an " + nameof(IViewTaggerProvider));
                        }

                        _textViewOpt.Caret.PositionChanged += OnCaretPositionChanged;
                    }

                    // Tell the interaction object to start issuing events.
                    _eventSource.Connect();
                }
            }