未验证 提交 9b22e9c8 编写于 作者: S Sam Harwell 提交者: GitHub

Merge pull request #44892 from sharwell/use-mef

Use MEF instead of direct construction
......@@ -9,12 +9,12 @@
using System.Collections.Immutable;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.Implementation.EditAndContinue;
using Microsoft.CodeAnalysis.Editor.Shared.Options;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.Options;
using Microsoft.CodeAnalysis.Shared.TestHooks;
......@@ -37,7 +37,7 @@ internal partial class DiagnosticsSquiggleTaggerProvider : AbstractDiagnosticsAd
protected override IEnumerable<Option2<bool>> Options => s_tagSourceOptions;
[ImportingConstructor]
[SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public DiagnosticsSquiggleTaggerProvider(
IThreadingContext threadingContext,
IDiagnosticService diagnosticService,
......
......@@ -4,13 +4,14 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel.Composition;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.Shared.Options;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.Options;
using Microsoft.CodeAnalysis.Shared.TestHooks;
......@@ -34,7 +35,7 @@ internal partial class DiagnosticsSuggestionTaggerProvider :
protected override IEnumerable<Option2<bool>> Options => s_tagSourceOptions;
[ImportingConstructor]
[SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public DiagnosticsSuggestionTaggerProvider(
IThreadingContext threadingContext,
IDiagnosticService diagnosticService,
......
......@@ -8,9 +8,7 @@
using System.Threading;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Host;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics
......@@ -18,6 +16,18 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics
[UseExportProvider]
public class DiagnosticServiceTests
{
private static DiagnosticService GetDiagnosticService(TestWorkspace workspace)
{
var diagnosticService = Assert.IsType<DiagnosticService>(workspace.ExportProvider.GetExportedValue<IDiagnosticService>());
// These tests were originally written under the assumption that the diagnostic service will not be
// initialized with listeners. If this check ever fails, the tests that use this method should be reviewed
// for impact.
Assert.Empty(diagnosticService.GetTestAccessor().EventListenerTracker.GetTestAccessor().EventListeners);
return diagnosticService;
}
[Fact, Trait(Traits.Feature, Traits.Features.Diagnostics)]
public void TestGetDiagnostics1()
{
......@@ -26,8 +36,7 @@ public void TestGetDiagnostics1()
var document = workspace.CurrentSolution.AddProject("TestProject", "TestProject", LanguageNames.CSharp).AddDocument("TestDocument", string.Empty);
var source = new TestDiagnosticUpdateSource(false, null);
var diagnosticService = new DiagnosticService(
AsynchronousOperationListenerProvider.NullProvider, Array.Empty<Lazy<IEventListener, EventListenerMetadata>>());
var diagnosticService = GetDiagnosticService(workspace);
diagnosticService.Register(source);
diagnosticService.DiagnosticsUpdated += (s, o) => { mutex.Set(); };
......@@ -57,8 +66,7 @@ public void TestGetDiagnostics2()
var document2 = document.Project.AddDocument("TestDocument2", string.Empty);
var source = new TestDiagnosticUpdateSource(false, null);
var diagnosticService = new DiagnosticService(
AsynchronousOperationListenerProvider.NullProvider, Array.Empty<Lazy<IEventListener, EventListenerMetadata>>());
var diagnosticService = GetDiagnosticService(workspace);
diagnosticService.Register(source);
diagnosticService.DiagnosticsUpdated += (s, o) => { mutex.Set(); };
......@@ -99,8 +107,7 @@ public void TestCleared()
var document = workspace.CurrentSolution.AddProject("TestProject", "TestProject", LanguageNames.CSharp).AddDocument("TestDocument", string.Empty);
var document2 = document.Project.AddDocument("TestDocument2", string.Empty);
var diagnosticService = new DiagnosticService(
AsynchronousOperationListenerProvider.NullProvider, Array.Empty<Lazy<IEventListener, EventListenerMetadata>>());
var diagnosticService = GetDiagnosticService(workspace);
var source1 = new TestDiagnosticUpdateSource(support: false, diagnosticData: null);
diagnosticService.Register(source1);
......
......@@ -13,13 +13,13 @@
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.Text.Shared.Extensions;
using Microsoft.VisualStudio.Composition;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Tagging;
using Roslyn.Test.Utilities;
......@@ -31,6 +31,12 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics
[UseExportProvider]
public class DiagnosticsSquiggleTaggerProviderTests
{
private static readonly IExportProviderFactory s_exportProviderWithMockDiagnosticService =
ExportProviderCache.GetOrCreateExportProviderFactory(
TestExportProvider.EntireAssemblyCatalogWithCSharpAndVisualBasic
.WithoutPartsOfType(typeof(IDiagnosticService))
.WithPart(typeof(MockDiagnosticService)));
[WpfFact, Trait(Traits.Feature, Traits.Features.Diagnostics)]
public async Task Test_TagSourceDiffer()
{
......@@ -116,16 +122,15 @@ public async Task TestWithMockDiagnosticService_TaggerProviderCreatedBeforeIniti
// succeed, but other squiggle tests fail, then it is likely an issue with the
// diagnostics engine not actually reporting all diagnostics properly.
using var workspace = TestWorkspace.CreateCSharp(new string[] { "class A { }" }, CSharpParseOptions.Default);
using var wrapper = new DiagnosticTaggerWrapper<DiagnosticsSquiggleTaggerProvider, IErrorTag>(workspace);
using var workspace = TestWorkspace.CreateCSharp(
new string[] { "class A { }" },
CSharpParseOptions.Default,
exportProvider: s_exportProviderWithMockDiagnosticService.CreateExportProvider());
var listenerProvider = workspace.ExportProvider.GetExportedValue<IAsynchronousOperationListenerProvider>();
var diagnosticService = new MockDiagnosticService(workspace);
var provider = new DiagnosticsSquiggleTaggerProvider(
workspace.ExportProvider.GetExportedValue<IThreadingContext>(),
diagnosticService,
workspace.GetService<IForegroundNotificationService>(),
listenerProvider);
var diagnosticService = Assert.IsType<MockDiagnosticService>(workspace.ExportProvider.GetExportedValue<IDiagnosticService>());
var provider = workspace.ExportProvider.GetExportedValues<ITaggerProvider>().OfType<DiagnosticsSquiggleTaggerProvider>().Single();
// Create the tagger before the first diagnostic event has been fired.
var tagger = provider.CreateTagger<IErrorTag>(workspace.Documents.First().GetTextBuffer());
......@@ -133,7 +138,7 @@ public async Task TestWithMockDiagnosticService_TaggerProviderCreatedBeforeIniti
// Now product the first diagnostic and fire the events.
var tree = await workspace.CurrentSolution.Projects.Single().Documents.Single().GetRequiredSyntaxTreeAsync(CancellationToken.None);
var span = TextSpan.FromBounds(0, 5);
diagnosticService.CreateDiagnosticAndFireEvents(Location.Create(tree, span));
diagnosticService.CreateDiagnosticAndFireEvents(workspace, Location.Create(tree, span));
using var disposable = tagger as IDisposable;
await listenerProvider.GetWaiter(FeatureAttribute.DiagnosticService).ExpeditedWaitAsync();
......@@ -154,21 +159,20 @@ public async Task TestWithMockDiagnosticService_TaggerProviderCreatedAfterInitia
// succeed, but other squiggle tests fail, then it is likely an issue with the
// diagnostics engine not actually reporting all diagnostics properly.
using var workspace = TestWorkspace.CreateCSharp(new string[] { "class A { }" }, CSharpParseOptions.Default);
using var wrapper = new DiagnosticTaggerWrapper<DiagnosticsSquiggleTaggerProvider, IErrorTag>(workspace);
using var workspace = TestWorkspace.CreateCSharp(
new string[] { "class A { }" },
CSharpParseOptions.Default,
exportProvider: s_exportProviderWithMockDiagnosticService.CreateExportProvider());
var listenerProvider = workspace.ExportProvider.GetExportedValue<IAsynchronousOperationListenerProvider>();
var diagnosticService = new MockDiagnosticService(workspace);
var provider = new DiagnosticsSquiggleTaggerProvider(
workspace.ExportProvider.GetExportedValue<IThreadingContext>(),
diagnosticService,
workspace.GetService<IForegroundNotificationService>(),
listenerProvider);
var diagnosticService = Assert.IsType<MockDiagnosticService>(workspace.ExportProvider.GetExportedValue<IDiagnosticService>());
var provider = workspace.ExportProvider.GetExportedValues<ITaggerProvider>().OfType<DiagnosticsSquiggleTaggerProvider>().Single();
// Create and fire the diagnostic events before the tagger is even made.
var tree = await workspace.CurrentSolution.Projects.Single().Documents.Single().GetRequiredSyntaxTreeAsync(CancellationToken.None);
var span = TextSpan.FromBounds(0, 5);
diagnosticService.CreateDiagnosticAndFireEvents(Location.Create(tree, span));
diagnosticService.CreateDiagnosticAndFireEvents(workspace, Location.Create(tree, span));
var tagger = provider.CreateTagger<IErrorTag>(workspace.Documents.First().GetTextBuffer());
using var disposable = tagger as IDisposable;
......
......@@ -7,32 +7,37 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.Common;
using Microsoft.CodeAnalysis.Diagnostics;
using Roslyn.Utilities;
using Microsoft.CodeAnalysis.Host.Mef;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics
{
[Export(typeof(IDiagnosticService))]
[Shared]
[PartNotDiscoverable]
internal class MockDiagnosticService : IDiagnosticService
{
public const string DiagnosticId = "MockId";
private readonly Workspace _workspace;
private DiagnosticData? _diagnostic;
public event EventHandler<DiagnosticsUpdatedArgs>? DiagnosticsUpdated;
public MockDiagnosticService(Workspace workspace)
=> _workspace = workspace;
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public MockDiagnosticService()
{
}
public IEnumerable<DiagnosticData> GetDiagnostics(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics, CancellationToken cancellationToken)
{
Assert.Equal(workspace, _workspace);
Assert.Equal(projectId, GetProjectId());
Assert.Equal(documentId, GetDocumentId());
Assert.Equal(projectId, GetProjectId(workspace));
Assert.Equal(documentId, GetDocumentId(workspace));
if (_diagnostic == null)
{
......@@ -46,9 +51,8 @@ public IEnumerable<DiagnosticData> GetDiagnostics(Workspace workspace, ProjectId
public IEnumerable<UpdatedEventArgs> GetDiagnosticsUpdatedEventArgs(Workspace workspace, ProjectId projectId, DocumentId documentId, CancellationToken cancellationToken)
{
Assert.Equal(workspace, _workspace);
Assert.Equal(projectId, GetProjectId());
Assert.Equal(documentId, GetDocumentId());
Assert.Equal(projectId, GetProjectId(workspace));
Assert.Equal(documentId, GetDocumentId(workspace));
if (_diagnostic == null)
{
......@@ -56,27 +60,27 @@ public IEnumerable<UpdatedEventArgs> GetDiagnosticsUpdatedEventArgs(Workspace wo
}
else
{
yield return new UpdatedEventArgs(this, workspace, GetProjectId(), GetDocumentId());
yield return new UpdatedEventArgs(this, workspace, GetProjectId(workspace), GetDocumentId(workspace));
}
}
internal void CreateDiagnosticAndFireEvents(Location location)
internal void CreateDiagnosticAndFireEvents(Workspace workspace, Location location)
{
var document = _workspace.CurrentSolution.Projects.Single().Documents.Single();
var document = workspace.CurrentSolution.Projects.Single().Documents.Single();
_diagnostic = DiagnosticData.Create(Diagnostic.Create(DiagnosticId, "MockCategory", "MockMessage", DiagnosticSeverity.Error, DiagnosticSeverity.Error, isEnabledByDefault: true, warningLevel: 0,
location: location),
document);
DiagnosticsUpdated?.Invoke(this, DiagnosticsUpdatedArgs.DiagnosticsCreated(
this, _workspace, _workspace.CurrentSolution,
GetProjectId(), GetDocumentId(),
this, workspace, workspace.CurrentSolution,
GetProjectId(workspace), GetDocumentId(workspace),
ImmutableArray.Create(_diagnostic)));
}
private DocumentId GetDocumentId()
=> _workspace.CurrentSolution.Projects.Single().Documents.Single().Id;
private DocumentId GetDocumentId(Workspace workspace)
=> workspace.CurrentSolution.Projects.Single().Documents.Single().Id;
private ProjectId GetProjectId()
=> _workspace.CurrentSolution.Projects.Single().Id;
private ProjectId GetProjectId(Workspace workspace)
=> workspace.CurrentSolution.Projects.Single().Id;
}
}
......@@ -13,7 +13,6 @@
using Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics;
using Microsoft.CodeAnalysis.Editor.Implementation.Preview;
using Microsoft.CodeAnalysis.Editor.Shared.Preview;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Editor.UnitTests.Squiggles;
using Microsoft.CodeAnalysis.Editor.UnitTests.Utilities;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
......@@ -196,7 +195,7 @@ public async Task TestPreviewDiagnosticTaggerInPreviewPane()
workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences(new[] { DiagnosticExtensions.GetCompilerDiagnosticAnalyzerReference(LanguageNames.CSharp) }));
// set up listener to wait until diagnostic finish running
var diagnosticService = workspace.ExportProvider.GetExportedValue<IDiagnosticService>();
_ = workspace.ExportProvider.GetExportedValue<IDiagnosticService>();
var hostDocument = workspace.Projects.First().Documents.First();
......@@ -211,18 +210,16 @@ public async Task TestPreviewDiagnosticTaggerInPreviewPane()
var previewFactoryService = (PreviewFactoryService)workspace.ExportProvider.GetExportedValue<IPreviewFactoryService>();
using var diffView = await previewFactoryService.CreateChangedDocumentPreviewViewAsync(oldDocument, newDocument, CancellationToken.None);
var foregroundService = workspace.GetService<IForegroundNotificationService>();
var listenerProvider = workspace.ExportProvider.GetExportedValue<AsynchronousOperationListenerProvider>();
// set up tagger for both buffers
var leftBuffer = diffView.Viewer.LeftView.BufferGraph.GetTextBuffers(t => t.ContentType.IsOfType(ContentTypeNames.CSharpContentType)).First();
var leftProvider = new DiagnosticsSquiggleTaggerProvider(workspace.ExportProvider.GetExportedValue<IThreadingContext>(), diagnosticService, foregroundService, listenerProvider);
var leftTagger = leftProvider.CreateTagger<IErrorTag>(leftBuffer);
var provider = workspace.ExportProvider.GetExportedValues<ITaggerProvider>().OfType<DiagnosticsSquiggleTaggerProvider>().Single();
var leftTagger = provider.CreateTagger<IErrorTag>(leftBuffer);
using var leftDisposable = leftTagger as IDisposable;
var rightBuffer = diffView.Viewer.RightView.BufferGraph.GetTextBuffers(t => t.ContentType.IsOfType(ContentTypeNames.CSharpContentType)).First();
var rightProvider = new DiagnosticsSquiggleTaggerProvider(workspace.ExportProvider.GetExportedValue<IThreadingContext>(), diagnosticService, foregroundService, listenerProvider);
var rightTagger = rightProvider.CreateTagger<IErrorTag>(rightBuffer);
var rightTagger = provider.CreateTagger<IErrorTag>(rightBuffer);
using var rightDisposable = rightTagger as IDisposable;
// wait for diagnostics and taggers
await listenerProvider.WaitAllDispatcherOperationAndTasksAsync(FeatureAttribute.DiagnosticService, FeatureAttribute.ErrorSquiggles);
......
......@@ -80,26 +80,12 @@ public ITaggerProvider TaggerProvider
{
WpfTestRunner.RequireWpfFact($"{nameof(DiagnosticTaggerWrapper<TProvider, TTag>)}.{nameof(TaggerProvider)} creates asynchronous taggers");
if (typeof(TProvider) == typeof(DiagnosticsSquiggleTaggerProvider))
{
_taggerProvider = new DiagnosticsSquiggleTaggerProvider(
_threadingContext,
DiagnosticService,
_workspace.GetService<IForegroundNotificationService>(),
_listenerProvider);
}
else if (typeof(TProvider) == typeof(DiagnosticsSuggestionTaggerProvider))
{
_taggerProvider = new DiagnosticsSuggestionTaggerProvider(
_threadingContext,
DiagnosticService,
_workspace.GetService<IForegroundNotificationService>(),
_listenerProvider);
}
else if (typeof(TProvider) == typeof(DiagnosticsClassificationTaggerProvider))
if (typeof(TProvider) == typeof(DiagnosticsSquiggleTaggerProvider)
|| typeof(TProvider) == typeof(DiagnosticsSuggestionTaggerProvider)
|| typeof(TProvider) == typeof(DiagnosticsClassificationTaggerProvider))
{
_taggerProvider = _workspace.ExportProvider.GetExportedValues<ITaggerProvider>()
.OfType<DiagnosticsClassificationTaggerProvider>()
.OfType<TProvider>()
.Single();
}
else
......
......@@ -7,10 +7,10 @@
using System.Collections.Immutable;
using System.Composition;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using Microsoft.CodeAnalysis.Common;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Roslyn.Utilities;
......@@ -32,7 +32,7 @@ internal partial class DiagnosticService : IDiagnosticService
private readonly EventListenerTracker<IDiagnosticService> _eventListenerTracker;
[ImportingConstructor]
[SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public DiagnosticService(
IAsynchronousOperationListenerProvider listenerProvider,
[ImportMany] IEnumerable<Lazy<IEventListener, EventListenerMetadata>> eventListeners) : this()
......@@ -406,5 +406,19 @@ public Data(UpdatedEventArgs args, ImmutableArray<DiagnosticData> diagnostics)
Diagnostics = diagnostics;
}
}
internal TestAccessor GetTestAccessor()
=> new TestAccessor(this);
internal readonly struct TestAccessor
{
private readonly DiagnosticService _diagnosticService;
internal TestAccessor(DiagnosticService diagnosticService)
=> _diagnosticService = diagnosticService;
internal ref readonly EventListenerTracker<IDiagnosticService> EventListenerTracker
=> ref _diagnosticService._eventListenerTracker;
}
}
}
......@@ -8,7 +8,6 @@ Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Editor
Imports Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics
Imports Microsoft.CodeAnalysis.Editor.Shared.Utilities
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
Imports Microsoft.CodeAnalysis.Shared.TestHooks
......@@ -43,10 +42,9 @@ class 123 { }
Dim buffer = workspace.Documents.First().GetTextBuffer()
WpfTestRunner.RequireWpfFact($"This test uses {NameOf(IForegroundNotificationService)}")
Dim foregroundService = workspace.GetService(Of IForegroundNotificationService)()
Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider)
Dim provider = New DiagnosticsSquiggleTaggerProvider(workspace.ExportProvider.GetExportedValue(Of IThreadingContext), diagnosticService, foregroundService, listenerProvider)
Dim provider = workspace.ExportProvider.GetExportedValues(Of ITaggerProvider)().OfType(Of DiagnosticsSquiggleTaggerProvider)().Single()
Dim tagger = provider.CreateTagger(Of IErrorTag)(buffer)
Using disposable = TryCast(tagger, IDisposable)
......
......@@ -10,7 +10,6 @@ Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Common
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
Imports Microsoft.CodeAnalysis.Host
Imports Microsoft.CodeAnalysis.Options
Imports Microsoft.CodeAnalysis.Shared.TestHooks
Imports Microsoft.CodeAnalysis.SolutionCrawler
......@@ -623,7 +622,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics
workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences({analyzerReference}))
Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider)
Dim service = New DiagnosticService(listenerProvider, Array.Empty(Of Lazy(Of IEventListener, EventListenerMetadata))())
Dim service = Assert.IsType(Of DiagnosticService)(workspace.ExportProvider.GetExportedValue(Of IDiagnosticService)())
Dim tableManagerProvider = New TestTableManagerProvider()
Dim table = New VisualStudioDiagnosticListTableWorkspaceEventListener.VisualStudioDiagnosticListTable(workspace, service, tableManagerProvider)
......@@ -673,7 +672,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics
Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider)
Dim listener = listenerProvider.GetListener(FeatureAttribute.DiagnosticService)
Dim service = New DiagnosticService(listenerProvider, Array.Empty(Of Lazy(Of IEventListener, EventListenerMetadata))())
Dim service = Assert.IsType(Of DiagnosticService)(workspace.ExportProvider.GetExportedValue(Of IDiagnosticService)())
Dim analyzerService = New MyDiagnosticAnalyzerService(service, listener)
Dim updateSource = New ExternalErrorDiagnosticUpdateSource(workspace, analyzerService, listener)
......
......@@ -54,5 +54,21 @@ public void EnsureEventListener(Workspace workspace, TService serviceOpt)
.Select(l => l.Value)
.OfType<IEventListener<TService>>();
}
internal TestAccessor GetTestAccessor()
{
return new TestAccessor(this);
}
internal readonly struct TestAccessor
{
private readonly EventListenerTracker<TService> _eventListenerTracker;
internal TestAccessor(EventListenerTracker<TService> eventListenerTracker)
=> _eventListenerTracker = eventListenerTracker;
internal ref readonly ImmutableArray<Lazy<IEventListener, EventListenerMetadata>> EventListeners
=> ref _eventListenerTracker._eventListeners;
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册