diff --git a/src/Analyzers/Core/Analyzers/RemoveUnnecessaryParentheses/AbstractRemoveUnnecessaryParenthesesDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/RemoveUnnecessaryParentheses/AbstractRemoveUnnecessaryParenthesesDiagnosticAnalyzer.cs index 72d31f9ac88c2a2b3a6e6cd80af5550f2a581f98..added76ba8522ff9663a4896098bafd739788e0b 100644 --- a/src/Analyzers/Core/Analyzers/RemoveUnnecessaryParentheses/AbstractRemoveUnnecessaryParenthesesDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/RemoveUnnecessaryParentheses/AbstractRemoveUnnecessaryParenthesesDiagnosticAnalyzer.cs @@ -121,8 +121,10 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context) var severity = preference.Notification.Severity; - var additionalLocations = ImmutableArray.Create(parenthesizedExpression.GetLocation(), - parenthesizedExpression.GetFirstToken().GetLocation(), parenthesizedExpression.GetLastToken().GetLocation()); + var additionalLocations = ImmutableArray.Create( + parenthesizedExpression.GetLocation(), + parenthesizedExpression.GetFirstToken().GetLocation(), + parenthesizedExpression.GetLastToken().GetLocation()); context.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags( s_diagnosticDescriptor, diff --git a/src/EditorFeatures/CSharpTest/Squiggles/ErrorSquiggleProducerTests.cs b/src/EditorFeatures/CSharpTest/Squiggles/ErrorSquiggleProducerTests.cs index 1ba58b988c116d072e595949dec311e364eba0c0..984dc23258260991b0f50678200c86e21541ced7 100644 --- a/src/EditorFeatures/CSharpTest/Squiggles/ErrorSquiggleProducerTests.cs +++ b/src/EditorFeatures/CSharpTest/Squiggles/ErrorSquiggleProducerTests.cs @@ -230,7 +230,7 @@ public async Task SemanticErrorReported() public async Task TestNoErrorsAfterDocumentRemoved() { using var workspace = TestWorkspace.CreateCSharp("class"); - using var wrapper = new DiagnosticTaggerWrapper(workspace); + using var wrapper = new DiagnosticTaggerWrapper(workspace); var tagger = wrapper.TaggerProvider.CreateTagger(workspace.Documents.First().GetTextBuffer()); using var disposable = tagger as IDisposable; await wrapper.WaitForTags(); @@ -256,7 +256,7 @@ public async Task TestNoErrorsAfterDocumentRemoved() public async Task TestNoErrorsAfterProjectRemoved() { using var workspace = TestWorkspace.CreateCSharp("class"); - using var wrapper = new DiagnosticTaggerWrapper(workspace); + using var wrapper = new DiagnosticTaggerWrapper(workspace); var tagger = wrapper.TaggerProvider.CreateTagger(workspace.Documents.First().GetTextBuffer()); using var disposable = tagger as IDisposable; await wrapper.WaitForTags(); diff --git a/src/EditorFeatures/Core/Implementation/Diagnostics/DiagnosticsClassificationTaggerProvider.cs b/src/EditorFeatures/Core/Implementation/Diagnostics/DiagnosticsClassificationTaggerProvider.cs index a6d878d7833b5e69dc296b645da1e58732432af4..f1d7d6b172dc922d4a14c93853a7c7e2da863cef 100644 --- a/src/EditorFeatures/Core/Implementation/Diagnostics/DiagnosticsClassificationTaggerProvider.cs +++ b/src/EditorFeatures/Core/Implementation/Diagnostics/DiagnosticsClassificationTaggerProvider.cs @@ -60,13 +60,14 @@ internal partial class DiagnosticsClassificationTaggerProvider : AbstractDiagnos // If we are under high contrast mode, the editor ignores classification tags that fade things out, // because that reduces contrast. Since the editor will ignore them, there's no reason to produce them. - protected internal override bool IsEnabled => !_editorOptionsFactoryService.GlobalOptions.GetOptionValue(DefaultTextViewHostOptions.IsInContrastModeId); + protected internal override bool IsEnabled + => !_editorOptionsFactoryService.GlobalOptions.GetOptionValue(DefaultTextViewHostOptions.IsInContrastModeId); - protected internal override bool IncludeDiagnostic(DiagnosticData data) => - data.CustomTags.Contains(WellKnownDiagnosticTags.Unnecessary); + protected internal override bool IncludeDiagnostic(DiagnosticData data) + => data.CustomTags.Contains(WellKnownDiagnosticTags.Unnecessary); - protected internal override ITagSpan CreateTagSpan(Workspace workspace, bool isLiveUpdate, SnapshotSpan span, DiagnosticData data) => - new TagSpan(span, _classificationTag); + protected internal override ITagSpan CreateTagSpan(Workspace workspace, bool isLiveUpdate, SnapshotSpan span, DiagnosticData data) + => new TagSpan(span, _classificationTag); protected internal override ImmutableArray GetLocationsToTag(DiagnosticData diagnosticData) { @@ -76,24 +77,26 @@ protected internal override ImmutableArray GetLocationsT && diagnosticData.Properties.TryGetValue(WellKnownDiagnosticTags.Unnecessary, out var unnecessaryIndices) && unnecessaryIndices is object) { - using var locationsToTagDisposer = PooledObjects.ArrayBuilder.GetInstance(out var locationsToTag); + using var _ = PooledObjects.ArrayBuilder.GetInstance(out var locationsToTag); var additionalLocations = diagnosticData.AdditionalLocations.ToImmutableArray(); - var indices = GetLocationIndices(unnecessaryIndices); - locationsToTag.AddRange(indices.Select(i => additionalLocations[i]).ToImmutableArray()); + foreach (var index in GetLocationIndices(unnecessaryIndices)) + locationsToTag.Add(additionalLocations[index]); + + return locationsToTag.ToImmutable(); } // Default to the base implementation for the diagnostic data return base.GetLocationsToTag(diagnosticData); - static IEnumerable? GetLocationIndices(string indicesProperty) + static IEnumerable GetLocationIndices(string indicesProperty) { try { using var stream = new MemoryStream(Encoding.UTF8.GetBytes(indicesProperty)); var serializer = new DataContractJsonSerializer(typeof(IEnumerable)); var result = serializer.ReadObject(stream) as IEnumerable; - return result; + return result ?? Array.Empty(); } catch (Exception e) when (FatalError.ReportWithoutCrash(e)) { diff --git a/src/EditorFeatures/Test/Diagnostics/DiagnosticsClassificationTaggerProviderTests.cs b/src/EditorFeatures/Test/Diagnostics/DiagnosticsClassificationTaggerProviderTests.cs new file mode 100644 index 0000000000000000000000000000000000000000..915917ceac271cde90a5edb1d981b9e91aedd126 --- /dev/null +++ b/src/EditorFeatures/Test/Diagnostics/DiagnosticsClassificationTaggerProviderTests.cs @@ -0,0 +1,91 @@ +// 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. + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics; +using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; +using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Test.Utilities; +using Microsoft.CodeAnalysis.Text; +using Microsoft.CodeAnalysis.Text.Shared.Extensions; +using Microsoft.VisualStudio.Text; +using Microsoft.VisualStudio.Text.Tagging; +using Roslyn.Test.Utilities; +using Roslyn.Utilities; +using Xunit; + +namespace Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics +{ + [UseExportProvider] + public class DiagnosticsClassificationTaggerProviderTests + { + [WpfFact, Trait(Traits.Feature, Traits.Features.Diagnostics)] + public async Task Test_FadingSpans() + { + var analyzer = new Analyzer(); + var analyzerMap = new Dictionary> + { + { LanguageNames.CSharp, ImmutableArray.Create(analyzer) } + }; + + using var workspace = TestWorkspace.CreateCSharp(new string[] { "class A { }", "class E { }" }, CSharpParseOptions.Default); + using var wrapper = new DiagnosticTaggerWrapper(workspace, analyzerMap); + var tagger = wrapper.TaggerProvider.CreateTagger(workspace.Documents.First().GetTextBuffer()); + using var disposable = tagger as IDisposable; + // test first update + await wrapper.WaitForTags(); + + // We should get two spans, the 1-index and 2-index locations in the original diagnostic. + var snapshot = workspace.Documents.First().GetTextBuffer().CurrentSnapshot; + var spans = tagger.GetTags(snapshot.GetSnapshotSpanCollection()).ToList(); + Assert.Equal(2, spans.Count); + + Assert.Equal(new Span(0, 1), spans[0].Span.Span); + Assert.Equal(new Span(9, 1), spans[1].Span.Span); + + Assert.Equal(ClassificationTypeDefinitions.UnnecessaryCode, spans[0].Tag.ClassificationType.Classification); + Assert.Equal(ClassificationTypeDefinitions.UnnecessaryCode, spans[1].Tag.ClassificationType.Classification); + } + + private class Analyzer : DiagnosticAnalyzer + { + // Mark elements 1, and 2 in the locations as the fading locations. + private static readonly ImmutableDictionary> s_fadeLocations = new Dictionary> + { + { nameof(WellKnownDiagnosticTags.Unnecessary), new int[] { 1, 2 } }, + }.ToImmutableDictionary(); + + private readonly DiagnosticDescriptor _rule = new DiagnosticDescriptor( + "test", "test", "test", "test", DiagnosticSeverity.Error, true, + customTags: DiagnosticCustomTags.Create(isUnnecessary: true, isConfigurable: false)); + + public override ImmutableArray SupportedDiagnostics + => ImmutableArray.Create(_rule); + + public override void Initialize(AnalysisContext context) + { + context.RegisterSyntaxTreeAction(c => + { + c.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags( + _rule, Location.Create(c.Tree, new TextSpan(0, 10)), + ReportDiagnostic.Error, + new Location[] { + Location.Create(c.Tree, new TextSpan(0, 10)), + Location.Create(c.Tree, new TextSpan(0, 1)), + Location.Create(c.Tree, new TextSpan(9, 1)), + }, + s_fadeLocations)); + }); + } + } + } +} diff --git a/src/EditorFeatures/Test/Diagnostics/DiagnosticsSquiggleTaggerProviderTests.cs b/src/EditorFeatures/Test/Diagnostics/DiagnosticsSquiggleTaggerProviderTests.cs index 458b316c49a19d37779f0ec1a8df6090afd445d2..1c6431bf7e6c9cbb4121ac44e667c03756b6d6b0 100644 --- a/src/EditorFeatures/Test/Diagnostics/DiagnosticsSquiggleTaggerProviderTests.cs +++ b/src/EditorFeatures/Test/Diagnostics/DiagnosticsSquiggleTaggerProviderTests.cs @@ -10,7 +10,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Common; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics; @@ -42,7 +41,7 @@ public async Task Test_TagSourceDiffer() }; using var workspace = TestWorkspace.CreateCSharp(new string[] { "class A { }", "class E { }" }, CSharpParseOptions.Default); - using var wrapper = new DiagnosticTaggerWrapper(workspace, analyzerMap); + using var wrapper = new DiagnosticTaggerWrapper(workspace, analyzerMap); var tagger = wrapper.TaggerProvider.CreateTagger(workspace.Documents.First().GetTextBuffer()); using var disposable = tagger as IDisposable; // test first update @@ -70,7 +69,7 @@ public async Task Test_TagSourceDiffer() public async Task MultipleTaggersAndDispose() { using var workspace = TestWorkspace.CreateCSharp(new string[] { "class A {" }, CSharpParseOptions.Default); - using var wrapper = new DiagnosticTaggerWrapper(workspace); + using var wrapper = new DiagnosticTaggerWrapper(workspace); // Make two taggers. var tagger1 = wrapper.TaggerProvider.CreateTagger(workspace.Documents.First().GetTextBuffer()); var tagger2 = wrapper.TaggerProvider.CreateTagger(workspace.Documents.First().GetTextBuffer()); @@ -90,7 +89,7 @@ public async Task MultipleTaggersAndDispose() public async Task TaggerProviderCreatedAfterInitialDiagnosticsReported() { using var workspace = TestWorkspace.CreateCSharp(new string[] { "class C {" }, CSharpParseOptions.Default); - using var wrapper = new DiagnosticTaggerWrapper(workspace, analyzerMap: null, createTaggerProvider: false); + using var wrapper = new DiagnosticTaggerWrapper(workspace, analyzerMap: null, createTaggerProvider: false); // First, make sure all diagnostics have been reported. await wrapper.WaitForTags(); @@ -118,7 +117,7 @@ public async Task TestWithMockDiagnosticService_TaggerProviderCreatedBeforeIniti // diagnostics engine not actually reporting all diagnostics properly. using var workspace = TestWorkspace.CreateCSharp(new string[] { "class A { }" }, CSharpParseOptions.Default); - using var wrapper = new DiagnosticTaggerWrapper(workspace); + using var wrapper = new DiagnosticTaggerWrapper(workspace); var listenerProvider = workspace.ExportProvider.GetExportedValue(); var diagnosticService = new MockDiagnosticService(workspace); @@ -156,7 +155,7 @@ public async Task TestWithMockDiagnosticService_TaggerProviderCreatedAfterInitia // diagnostics engine not actually reporting all diagnostics properly. using var workspace = TestWorkspace.CreateCSharp(new string[] { "class A { }" }, CSharpParseOptions.Default); - using var wrapper = new DiagnosticTaggerWrapper(workspace); + using var wrapper = new DiagnosticTaggerWrapper(workspace); var listenerProvider = workspace.ExportProvider.GetExportedValue(); var diagnosticService = new MockDiagnosticService(workspace); @@ -182,70 +181,6 @@ public async Task TestWithMockDiagnosticService_TaggerProviderCreatedAfterInitia Assert.Equal(span.ToSpan(), spans[0].Span.Span); } - private class MockDiagnosticService : IDiagnosticService - { - public const string DiagnosticId = "MockId"; - - private readonly Workspace _workspace; - private DiagnosticData? _diagnostic; - - public event EventHandler? DiagnosticsUpdated; - - public MockDiagnosticService(Workspace workspace) - => _workspace = workspace; - - public IEnumerable 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()); - - if (_diagnostic == null) - { - yield break; - } - else - { - yield return _diagnostic; - } - } - - public IEnumerable GetDiagnosticsUpdatedEventArgs(Workspace workspace, ProjectId projectId, DocumentId documentId, CancellationToken cancellationToken) - { - Assert.Equal(workspace, _workspace); - Assert.Equal(projectId, GetProjectId()); - Assert.Equal(documentId, GetDocumentId()); - - if (_diagnostic == null) - { - yield break; - } - else - { - yield return new UpdatedEventArgs(this, workspace, GetProjectId(), GetDocumentId()); - } - } - - internal void CreateDiagnosticAndFireEvents(Location location) - { - 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(), - ImmutableArray.Create(_diagnostic))); - } - - private DocumentId GetDocumentId() - => _workspace.CurrentSolution.Projects.Single().Documents.Single().Id; - - private ProjectId GetProjectId() - => _workspace.CurrentSolution.Projects.Single().Id; - } - private class Analyzer : DiagnosticAnalyzer { private DiagnosticDescriptor _rule = new DiagnosticDescriptor("test", "test", "test", "test", DiagnosticSeverity.Error, true); diff --git a/src/EditorFeatures/Test/Diagnostics/MockDiagnosticService.cs b/src/EditorFeatures/Test/Diagnostics/MockDiagnosticService.cs new file mode 100644 index 0000000000000000000000000000000000000000..c05b430642019f48ea5c5c4b647dc2b8c31a50fc --- /dev/null +++ b/src/EditorFeatures/Test/Diagnostics/MockDiagnosticService.cs @@ -0,0 +1,82 @@ +// 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. + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading; +using Microsoft.CodeAnalysis.Common; +using Microsoft.CodeAnalysis.Diagnostics; +using Roslyn.Utilities; +using Xunit; + +namespace Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics +{ + internal class MockDiagnosticService : IDiagnosticService + { + public const string DiagnosticId = "MockId"; + + private readonly Workspace _workspace; + private DiagnosticData? _diagnostic; + + public event EventHandler? DiagnosticsUpdated; + + public MockDiagnosticService(Workspace workspace) + => _workspace = workspace; + + public IEnumerable 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()); + + if (_diagnostic == null) + { + yield break; + } + else + { + yield return _diagnostic; + } + } + + public IEnumerable GetDiagnosticsUpdatedEventArgs(Workspace workspace, ProjectId projectId, DocumentId documentId, CancellationToken cancellationToken) + { + Assert.Equal(workspace, _workspace); + Assert.Equal(projectId, GetProjectId()); + Assert.Equal(documentId, GetDocumentId()); + + if (_diagnostic == null) + { + yield break; + } + else + { + yield return new UpdatedEventArgs(this, workspace, GetProjectId(), GetDocumentId()); + } + } + + internal void CreateDiagnosticAndFireEvents(Location location) + { + 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(), + ImmutableArray.Create(_diagnostic))); + } + + private DocumentId GetDocumentId() + => _workspace.CurrentSolution.Projects.Single().Documents.Single().Id; + + private ProjectId GetProjectId() + => _workspace.CurrentSolution.Projects.Single().Id; + } +} diff --git a/src/EditorFeatures/TestUtilities/Diagnostics/DiagnosticTaggerWrapper.cs b/src/EditorFeatures/TestUtilities/Diagnostics/DiagnosticTaggerWrapper.cs index 769b9a1af9815e0de3d4db5a3b1838edc623cf35..4ffa164b3cc1fc9b86611b1110e83ae11e007e1d 100644 --- a/src/EditorFeatures/TestUtilities/Diagnostics/DiagnosticTaggerWrapper.cs +++ b/src/EditorFeatures/TestUtilities/Diagnostics/DiagnosticTaggerWrapper.cs @@ -7,12 +7,12 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Linq; using System.Threading.Tasks; 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.Host; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.CodeAnalysis.SolutionCrawler; using Microsoft.VisualStudio.Text.Tagging; @@ -20,8 +20,9 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics { - internal class DiagnosticTaggerWrapper : IDisposable - where TProvider : AbstractDiagnosticsAdornmentTaggerProvider + internal class DiagnosticTaggerWrapper : IDisposable + where TProvider : AbstractDiagnosticsTaggerProvider + where TTag : ITag { private readonly TestWorkspace _workspace; public readonly DiagnosticAnalyzerService? AnalyzerService; @@ -56,7 +57,7 @@ internal class DiagnosticTaggerWrapper : IDisposable _registrationService = workspace.Services.GetRequiredService(); _registrationService.Register(workspace); - DiagnosticService = new DiagnosticService(_listenerProvider, Array.Empty>()); + DiagnosticService = (DiagnosticService)workspace.ExportProvider.GetExportedValue(); DiagnosticService.Register(updateSource); if (createTaggerProvider) @@ -77,7 +78,7 @@ public ITaggerProvider TaggerProvider { if (_taggerProvider == null) { - WpfTestRunner.RequireWpfFact($"{nameof(DiagnosticTaggerWrapper)}.{nameof(TaggerProvider)} creates asynchronous taggers"); + WpfTestRunner.RequireWpfFact($"{nameof(DiagnosticTaggerWrapper)}.{nameof(TaggerProvider)} creates asynchronous taggers"); if (typeof(TProvider) == typeof(DiagnosticsSquiggleTaggerProvider)) { @@ -95,6 +96,12 @@ public ITaggerProvider TaggerProvider _workspace.GetService(), _listenerProvider); } + else if (typeof(TProvider) == typeof(DiagnosticsClassificationTaggerProvider)) + { + _taggerProvider = _workspace.ExportProvider.GetExportedValues() + .OfType() + .Single(); + } else { throw new InvalidOperationException(); @@ -117,6 +124,7 @@ public async Task WaitForTags() await _listenerProvider.GetWaiter(FeatureAttribute.DiagnosticService).ExpeditedWaitAsync(); await _listenerProvider.GetWaiter(FeatureAttribute.ErrorSquiggles).ExpeditedWaitAsync(); + await _listenerProvider.GetWaiter(FeatureAttribute.Classification).ExpeditedWaitAsync(); } private class MyDiagnosticAnalyzerService : DiagnosticAnalyzerService diff --git a/src/EditorFeatures/TestUtilities/Squiggles/AbstractSquiggleProducerTests.cs b/src/EditorFeatures/TestUtilities/Squiggles/AbstractSquiggleProducerTests.cs index 1bea6af495e88db24b64d1005ce86e929d8c4e3b..feb97f4a97f91c4cefcb28cc69d706c962a3d5de 100644 --- a/src/EditorFeatures/TestUtilities/Squiggles/AbstractSquiggleProducerTests.cs +++ b/src/EditorFeatures/TestUtilities/Squiggles/AbstractSquiggleProducerTests.cs @@ -26,21 +26,18 @@ public static class SquiggleUtilities IReadOnlyDictionary> analyzerMap = null) where TProvider : AbstractDiagnosticsAdornmentTaggerProvider { - using (var wrapper = new DiagnosticTaggerWrapper(workspace, analyzerMap)) - { - var tagger = wrapper.TaggerProvider.CreateTagger(workspace.Documents.First().GetTextBuffer()); - using (var disposable = tagger as IDisposable) - { - await wrapper.WaitForTags(); + using var wrapper = new DiagnosticTaggerWrapper(workspace, analyzerMap); + var tagger = wrapper.TaggerProvider.CreateTagger(workspace.Documents.First().GetTextBuffer()); - var analyzerDiagnostics = await wrapper.AnalyzerService.GetDiagnosticsAsync(workspace.CurrentSolution); + using var disposable = tagger as IDisposable; + await wrapper.WaitForTags(); - var snapshot = workspace.Documents.First().GetTextBuffer().CurrentSnapshot; - var spans = tagger.GetTags(snapshot.GetSnapshotSpanCollection()).ToImmutableArray(); + var analyzerDiagnostics = await wrapper.AnalyzerService.GetDiagnosticsAsync(workspace.CurrentSolution); - return (analyzerDiagnostics, spans); - } - } + var snapshot = workspace.Documents.First().GetTextBuffer().CurrentSnapshot; + var spans = tagger.GetTags(snapshot.GetSnapshotSpanCollection()).ToImmutableArray(); + + return (analyzerDiagnostics, spans); } } @@ -57,7 +54,7 @@ internal sealed class DiagnosticTagProducer internal async Task>> GetErrorsFromUpdateSource(TestWorkspace workspace, DiagnosticsUpdatedArgs updateArgs) { var source = new TestDiagnosticUpdateSource(); - using (var wrapper = new DiagnosticTaggerWrapper(workspace, updateSource: source)) + using (var wrapper = new DiagnosticTaggerWrapper(workspace, updateSource: source)) { var tagger = wrapper.TaggerProvider.CreateTagger(workspace.Documents.First().GetTextBuffer()); using (var disposable = tagger as IDisposable)