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();