diff --git a/src/EditorFeatures/Core/Classification/CopyPasteAndPrintingClassificationBufferTaggerProvider.Tagger.cs b/src/EditorFeatures/Core/Classification/CopyPasteAndPrintingClassificationBufferTaggerProvider.Tagger.cs index 0bf78d41ba2be..88b5464cdb662 100644 --- a/src/EditorFeatures/Core/Classification/CopyPasteAndPrintingClassificationBufferTaggerProvider.Tagger.cs +++ b/src/EditorFeatures/Core/Classification/CopyPasteAndPrintingClassificationBufferTaggerProvider.Tagger.cs @@ -48,12 +48,7 @@ public Tagger( _subjectBuffer = subjectBuffer; _globalOptions = globalOptions; - // Note: because we use frozen-partial documents for semantic classification, we may end up with incomplete - // semantics (esp. during solution load). Because of this, we also register to hear when the full - // compilation is available so that reclassify and bring ourselves up to date. - _eventSource = new CompilationAvailableTaggerEventSource( - subjectBuffer, - asyncListener, + _eventSource = TaggerEventSources.Compose( TaggerEventSources.OnWorkspaceChanged(subjectBuffer, asyncListener), TaggerEventSources.OnDocumentActiveContextChanged(subjectBuffer)); diff --git a/src/EditorFeatures/Core/Classification/Semantic/AbstractSemanticOrEmbeddedClassificationViewTaggerProvider.cs b/src/EditorFeatures/Core/Classification/Semantic/AbstractSemanticOrEmbeddedClassificationViewTaggerProvider.cs index 5a912b50f9897..88b1ff86d4d79 100644 --- a/src/EditorFeatures/Core/Classification/Semantic/AbstractSemanticOrEmbeddedClassificationViewTaggerProvider.cs +++ b/src/EditorFeatures/Core/Classification/Semantic/AbstractSemanticOrEmbeddedClassificationViewTaggerProvider.cs @@ -59,13 +59,7 @@ protected sealed override ITaggerEventSource CreateEventSource(ITextView textVie // Note: we don't listen for OnTextChanged. They'll get reported by the ViewSpan changing and also the // SemanticChange notification. - // - // Note: because we use frozen-partial documents for semantic classification, we may end up with incomplete - // semantics (esp. during solution load). Because of this, we also register to hear when the full - // compilation is available so that reclassify and bring ourselves up to date. - return new CompilationAvailableTaggerEventSource( - subjectBuffer, - AsyncListener, + return TaggerEventSources.Compose( TaggerEventSources.OnViewSpanChanged(ThreadingContext, textView), TaggerEventSources.OnWorkspaceChanged(subjectBuffer, AsyncListener), TaggerEventSources.OnDocumentActiveContextChanged(subjectBuffer), diff --git a/src/EditorFeatures/Core/NavigationBar/NavigationBarController.cs b/src/EditorFeatures/Core/NavigationBar/NavigationBarController.cs index 24bd31c9783fe..abce7a9ad1c88 100644 --- a/src/EditorFeatures/Core/NavigationBar/NavigationBarController.cs +++ b/src/EditorFeatures/Core/NavigationBar/NavigationBarController.cs @@ -112,9 +112,7 @@ public NavigationBarController( // Use 'compilation available' as that may produce different results from the initial 'frozen partial' // snapshot we use. - _eventSource = new CompilationAvailableTaggerEventSource( - subjectBuffer, - asyncListener, + _eventSource = TaggerEventSources.Compose( // Any time an edit happens, recompute as the nav bar items may have changed. TaggerEventSources.OnTextChanged(subjectBuffer), // Switching what is the active context may change the nav bar contents. diff --git a/src/EditorFeatures/Core/Tagging/CompilationAvailableTaggerEventSource.cs b/src/EditorFeatures/Core/Tagging/CompilationAvailableTaggerEventSource.cs deleted file mode 100644 index 1f671c903962e..0000000000000 --- a/src/EditorFeatures/Core/Tagging/CompilationAvailableTaggerEventSource.cs +++ /dev/null @@ -1,89 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Editor.Shared.Tagging; -using Microsoft.CodeAnalysis.Host; -using Microsoft.CodeAnalysis.Remote; -using Microsoft.CodeAnalysis.Shared.TestHooks; -using Microsoft.CodeAnalysis.Shared.Utilities; -using Microsoft.CodeAnalysis.Tagging; -using Microsoft.CodeAnalysis.Text; -using Microsoft.VisualStudio.Text; -using Microsoft.VisualStudio.Threading; -using Roslyn.Utilities; - -namespace Microsoft.CodeAnalysis.Editor.Tagging; - -/// -/// Tagger event that fires once the compilation is available in the remote OOP process for a particular project. -/// Used to trigger things such as: -/// -/// reclassification pass as classification may show either cached classifications (from a previous session), -/// or incomplete classifications due to frozen-partial compilations being used. -/// recomputation of navigation bar items due to frozen-partial compilations being used. -/// recomputation of inheritance margin items due to frozen-partial compilations being used. -/// -/// -internal sealed class CompilationAvailableTaggerEventSource : ITaggerEventSource -{ - private readonly ITextBuffer _subjectBuffer; - - /// - /// Other event sources we're composing over. If they fire, we should reclassify. However, after they fire, we - /// should also refire an event once we get the next full compilation ready. - /// - private readonly ITaggerEventSource _underlyingSource; - - private readonly CompilationAvailableEventSource _eventSource; - - private readonly Action _onCompilationAvailable; - - 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 event EventHandler? Changed; - - public void Connect() - { - // When we are connected to, connect to all our underlying sources and have them notify us when they've changed. - _underlyingSource.Connect(); - _underlyingSource.Changed += OnUnderlyingSourceChanged; - } - - public void Disconnect() - { - _underlyingSource.Changed -= OnUnderlyingSourceChanged; - _underlyingSource.Disconnect(); - _eventSource.Dispose(); - } - - public void Pause() - => _underlyingSource.Pause(); - - public void Resume() - => _underlyingSource.Resume(); - - private void OnUnderlyingSourceChanged(object? sender, TaggerEventArgs args) - { - // First, notify anyone listening to us that something definitely changed. - this.Changed?.Invoke(this, args); - - var document = _subjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges(); - if (document == null) - return; - - _eventSource.EnsureCompilationAvailability(document.Project, _onCompilationAvailable); - } -} diff --git a/src/VisualStudio/Core/Def/InheritanceMargin/InheritanceMarginTaggerProvider.cs b/src/VisualStudio/Core/Def/InheritanceMargin/InheritanceMarginTaggerProvider.cs index 62a10c57d380b..f3d1a2a29c881 100644 --- a/src/VisualStudio/Core/Def/InheritanceMargin/InheritanceMarginTaggerProvider.cs +++ b/src/VisualStudio/Core/Def/InheritanceMargin/InheritanceMarginTaggerProvider.cs @@ -65,14 +65,9 @@ protected override bool CanCreateTagger(ITextView textView, ITextBuffer buffer) protected override ITaggerEventSource CreateEventSource(ITextView textView, ITextBuffer subjectBuffer) { - // Because we use frozen-partial documents for semantic classification, we may end up with incomplete - // semantics (esp. during solution load). Because of this, we also register to hear when the full - // compilation is available so that reclassify and bring ourselves up to date. // Note: Also generate tags when InheritanceMarginOptions.InheritanceMarginCombinedWithIndicatorMargin is changed, // because we want to refresh the glyphs in indicator margin. - return new CompilationAvailableTaggerEventSource( - subjectBuffer, - AsyncListener, + return TaggerEventSources.Compose( TaggerEventSources.OnWorkspaceChanged(subjectBuffer, AsyncListener), TaggerEventSources.OnViewSpanChanged(ThreadingContext, textView), TaggerEventSources.OnDocumentActiveContextChanged(subjectBuffer), @@ -103,7 +98,6 @@ protected override async Task ProduceTagsAsync( // Use FrozenSemantics Version of document to get the semantics ready, therefore we could have faster // response. (Since the full load might take a long time) - // We also subscribe to CompilationAvailableTaggerEventSource, so this will finally reach the correct state. document = document.WithFrozenPartialSemantics(cancellationToken); var spanToSearch = spanToTag.SnapshotSpan.Span.ToTextSpan();