From 40b0cbae313cb0d0faf191295b330fbf8aa8d5f6 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 14 Feb 2025 01:13:44 -0800 Subject: [PATCH] Cache based on project state not project. (#77141) --- .../DiagnosticAnalyzerDriverTests.cs | 2 + .../Test/CodeFixes/CodeFixServiceTests.cs | 6 ++- .../DiagnosticAnalyzerServiceTests.cs | 2 + .../Diagnostics/DiagnosticServiceTests.vb | 35 ++++++++++++++++ ...cIncrementalAnalyzer.CompilationManager.cs | 41 ++++++++----------- ...ticIncrementalAnalyzer.HostAnalyzerInfo.cs | 11 +++-- ...ntalAnalyzer.StateManager.ProjectStates.cs | 5 ++- ...gnosticIncrementalAnalyzer.StateManager.cs | 6 ++- ...IncrementalAnalyzer_IncrementalAnalyzer.cs | 3 +- .../InProcOrRemoteHostAnalyzerRunner.cs | 2 +- .../Diagnostics/HostDiagnosticAnalyzers.cs | 2 +- .../SerializerService_Reference.cs | 39 ++++++++++++------ .../Portable/Workspace/Solution/Project.cs | 3 -- .../TestAnalyzerReferenceByLanguage.cs | 6 ++- .../Workspaces/TestWorkspace`1.cs | 8 +--- .../DiagnosticAnalyzer/DiagnosticComputer.cs | 3 +- 16 files changed, 114 insertions(+), 60 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs index 898774278f37c..199cf2081e86b 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs @@ -13,6 +13,7 @@ using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor.UnitTests; using Microsoft.CodeAnalysis.PooledObjects; +using Microsoft.CodeAnalysis.Serialization; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Simplification; using Microsoft.CodeAnalysis.Test.Utilities; @@ -775,6 +776,7 @@ private static async Task TestNuGetAndVsixAnalyzerCoreAsync( if (nugetAnalyzerReferences.Count > 0) { project = project.WithAnalyzerReferences([new AnalyzerImageReference([.. nugetAnalyzerReferences])]); + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences); } var document = project.Documents.Single(); diff --git a/src/EditorFeatures/Test/CodeFixes/CodeFixServiceTests.cs b/src/EditorFeatures/Test/CodeFixes/CodeFixServiceTests.cs index f449f7978a0af..149dd06940b05 100644 --- a/src/EditorFeatures/Test/CodeFixes/CodeFixServiceTests.cs +++ b/src/EditorFeatures/Test/CodeFixes/CodeFixServiceTests.cs @@ -18,6 +18,7 @@ using Microsoft.CodeAnalysis.Extensions; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.PooledObjects; +using Microsoft.CodeAnalysis.Serialization; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.SolutionCrawler; using Microsoft.CodeAnalysis.Test.Utilities; @@ -429,7 +430,8 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) } } - private class MockAnalyzerReference : AnalyzerReference, ICodeFixProviderFactory + private class MockAnalyzerReference + : AnalyzerReference, ICodeFixProviderFactory, SerializerService.TestAccessor.IAnalyzerReferenceWithGuid { public readonly ImmutableArray Fixers; public readonly ImmutableArray Analyzers; @@ -490,6 +492,8 @@ public override object Id } } + public Guid Guid { get; } = Guid.NewGuid(); + public override ImmutableArray GetAnalyzers(string language) => Analyzers; diff --git a/src/EditorFeatures/Test/Diagnostics/DiagnosticAnalyzerServiceTests.cs b/src/EditorFeatures/Test/Diagnostics/DiagnosticAnalyzerServiceTests.cs index 6b141120ee330..db5836abe05f2 100644 --- a/src/EditorFeatures/Test/Diagnostics/DiagnosticAnalyzerServiceTests.cs +++ b/src/EditorFeatures/Test/Diagnostics/DiagnosticAnalyzerServiceTests.cs @@ -17,6 +17,7 @@ using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Remote.Diagnostics; using Microsoft.CodeAnalysis.Remote.Testing; +using Microsoft.CodeAnalysis.Serialization; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Simplification; using Microsoft.CodeAnalysis.SolutionCrawler; @@ -435,6 +436,7 @@ internal async Task TestAdditionalFileAnalyzer(bool registerFromInitialize, bool project = project.AddAdditionalDocument(name: "dummy2.txt", text: "Additional File2 Text", filePath: "dummy2.txt").Project; } + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences); var applied = workspace.TryApplyChanges(project.Solution); Assert.True(applied); diff --git a/src/EditorFeatures/Test2/Diagnostics/DiagnosticServiceTests.vb b/src/EditorFeatures/Test2/Diagnostics/DiagnosticServiceTests.vb index c52637d2bcb8e..9913c17cfea6b 100644 --- a/src/EditorFeatures/Test2/Diagnostics/DiagnosticServiceTests.vb +++ b/src/EditorFeatures/Test2/Diagnostics/DiagnosticServiceTests.vb @@ -13,6 +13,7 @@ Imports Microsoft.CodeAnalysis.Diagnostics Imports Microsoft.CodeAnalysis.Diagnostics.CSharp Imports Microsoft.CodeAnalysis.Editor.UnitTests Imports Microsoft.CodeAnalysis.Host.Mef +Imports Microsoft.CodeAnalysis.Serialization Imports Microsoft.CodeAnalysis.SolutionCrawler Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.UnitTests.Diagnostics @@ -104,6 +105,7 @@ Namespace Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics.UnitTests Dim projectAnalyzerReference1 = New AnalyzerImageReference(projectAnalyzers1, display:=NameOf(projectAnalyzers1)) Dim projectAnalyzerReferences1 = ImmutableArray.Create(Of AnalyzerReference)(projectAnalyzerReference1) project = project.WithAnalyzerReferences(projectAnalyzerReferences1) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) ' Verify available diagnostic descriptors/analyzers descriptorsMap = hostAnalyzers.GetDiagnosticDescriptorsPerReference(diagnosticService.AnalyzerInfoCache, project) @@ -119,6 +121,7 @@ Namespace Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics.UnitTests Dim projectAnalyzers2 = ImmutableArray.Create(Of DiagnosticAnalyzer)(projectDiagnosticAnalyzer2) Dim projectAnalyzerReference2 = New AnalyzerImageReference(projectAnalyzers2, display:=NameOf(projectAnalyzers2)) project = project.AddAnalyzerReference(projectAnalyzerReference2) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) ' Verify available diagnostic descriptors/analyzers descriptorsMap = hostAnalyzers.GetDiagnosticDescriptorsPerReference(diagnosticService.AnalyzerInfoCache, project) @@ -332,10 +335,12 @@ Namespace Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics.UnitTests Dim p1 = solution.Projects.Single(Function(p) p.Language = LanguageNames.CSharp) p1 = p1.WithAnalyzerReferences(SpecializedCollections.SingletonCollection(New AnalyzerImageReference(ImmutableArray.Create(analyzer1)))) solution = p1.Solution + SerializerService.TestAccessor.AddAnalyzerImageReferences(p1.AnalyzerReferences) Dim p2 = solution.Projects.Single(Function(p) p.Language = LanguageNames.VisualBasic) p2 = p2.WithAnalyzerReferences(SpecializedCollections.SingletonCollection(New AnalyzerImageReference(ImmutableArray.Create(analyzer2)))) solution = p2.Solution + SerializerService.TestAccessor.AddAnalyzerImageReferences(p2.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -478,6 +483,7 @@ Namespace Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics.UnitTests Dim analyzer = New ThrowsExceptionAnalyzer Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -512,6 +518,7 @@ Namespace Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics.UnitTests Dim analyzer = New CodeBlockStartedAnalyzer(Of Microsoft.CodeAnalysis.CSharp.SyntaxKind) Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -589,6 +596,7 @@ Namespace Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics.UnitTests Dim analyzer = New OperationAnalyzer(actionKind) Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim descriptorsMap = solution.SolutionState.Analyzers.GetDiagnosticDescriptorsPerReference(diagnosticService.AnalyzerInfoCache, project) Assert.Equal(1, descriptorsMap.Count) @@ -622,6 +630,7 @@ Namespace Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics.UnitTests Dim analyzer = New CodeBlockEndedAnalyzer() Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -655,6 +664,7 @@ Namespace Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics.UnitTests Dim analyzer = New CodeBlockStartedAndEndedAnalyzer(Of Microsoft.CodeAnalysis.CSharp.SyntaxKind) Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -730,6 +740,7 @@ class AnonymousFunctions Dim analyzer = New CodeBlockStartedAndEndedAnalyzer(Of Microsoft.CodeAnalysis.CSharp.SyntaxKind) Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -765,6 +776,7 @@ class AnonymousFunctions Dim analyzer = New CompilationEndedAnalyzer Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -825,6 +837,7 @@ class AnonymousFunctions Dim analyzer = New StatefulCompilationAnalyzer Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim projectDiagnostics = Await DiagnosticProviderTestUtilities.GetProjectDiagnosticsAsync(workspace, project) Assert.Equal(1, projectDiagnostics.Count()) @@ -850,6 +863,7 @@ class AnonymousFunctions Dim analyzer = New StatefulCompilationAnalyzer Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) ' Make couple of dummy invocations to GetDocumentDiagnostics. Dim document = project.Documents.Single() @@ -889,6 +903,7 @@ class AnonymousFunctions Dim analyzer = New StatefulCompilationAnalyzer Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim projectDiagnostics = Await DiagnosticProviderTestUtilities.GetProjectDiagnosticsAsync(workspace, project) @@ -924,6 +939,8 @@ class AnonymousFunctions Dim analyzer = New NamedTypeAnalyzer Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) + Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -962,6 +979,7 @@ class AnonymousFunctions Dim analyzer = New PartialTypeDiagnosticAnalyzer(indexOfDeclToReportDiagnostic:=1) Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -1017,6 +1035,7 @@ class AnonymousFunctions ' Test partial type diagnostic reported on all source files. Dim analyzerReference = New AnalyzerImageReference(analyzers) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -1068,6 +1087,7 @@ public class B Dim analyzer As DiagnosticAnalyzer = New CodeBlockOrSyntaxNodeAnalyzer(isCodeBlockAnalyzer:=True) Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -1110,6 +1130,7 @@ public class B Dim analyzer As DiagnosticAnalyzer = New CodeBlockOrSyntaxNodeAnalyzer(isCodeBlockAnalyzer:=False) Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -1152,6 +1173,7 @@ public class B Dim analyzer As DiagnosticAnalyzer = New MethodSymbolAnalyzer Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -1202,6 +1224,7 @@ End Class Dim analyzer = New MustOverrideMethodAnalyzer() Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -1264,6 +1287,7 @@ public class B Dim analyzer = New FieldDeclarationAnalyzer() Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -1310,6 +1334,7 @@ public class B Dim analyzer = New FieldDeclarationAnalyzer() Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -1375,6 +1400,7 @@ public class B Dim analyzer = New CompilationAnalyzerWithAnalyzerOptions() Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) ' Add additional document Dim additionalDocText = "First" @@ -1932,6 +1958,7 @@ End Class Dim analyzer = New CodeBlockActionAnalyzer(onlyStatelessAction) Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -1991,6 +2018,7 @@ namespace ConsoleApplication1 ' Add analyzer Dim analyzerReference = New AnalyzerImageReference(analyzers.ToImmutableArray()) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -2057,6 +2085,7 @@ class MyClass Dim analyzer = New AnalyzerWithNoSupportedDiagnostics() Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -2095,6 +2124,7 @@ class MyClass Dim analyzer = New CompilationAnalyzerWithSeverity(DiagnosticSeverity.Hidden, configurable:=False) Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -2148,6 +2178,7 @@ class C Dim analyzer = DiagnosticExtensions.GetCompilerDiagnosticAnalyzer(LanguageNames.CSharp) Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) ' Get span to analyze Dim document = project.Documents.Single() @@ -2194,6 +2225,7 @@ class C Dim analyzer = New EnsureNoMergedNamespaceSymbolAnalyzer() Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -2238,6 +2270,7 @@ class MyClass Dim compilerAnalyzer = New CSharpCompilerDiagnosticAnalyzer() Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(compilerAnalyzer, syntaxAnalyzer, semanticAnalyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -2307,6 +2340,7 @@ class MyClass Dim compilerAnalyzer = New CSharpCompilerDiagnosticAnalyzer() Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(compilerAnalyzer, syntaxAnalyzer, semanticAnalyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() @@ -2396,6 +2430,7 @@ public class C Dim analyzer = New AllActionsAnalyzer() Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) project = project.AddAnalyzerReference(analyzerReference) + SerializerService.TestAccessor.AddAnalyzerImageReferences(project.AnalyzerReferences) Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) Dim diagnosticService = workspace.GetService(Of IDiagnosticAnalyzerService)() diff --git a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.CompilationManager.cs b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.CompilationManager.cs index 09efb8642d42b..52dde0ab537aa 100644 --- a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.CompilationManager.cs +++ b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.CompilationManager.cs @@ -18,13 +18,13 @@ namespace Microsoft.CodeAnalysis.Diagnostics; internal partial class DiagnosticAnalyzerService { /// - /// Cached data from a to the last instance created - /// for it. Note: the CompilationWithAnalyzersPair instance is dependent on the set of to the last instance + /// created for it. Note: the CompilationWithAnalyzersPair instance is dependent on the set of s passed along with the project. As such, we might not be able to use a prior cached /// value if the set of analyzers changes. In that case, a new instance will be created and will be cached for the /// next caller. /// - private static readonly ConditionalWeakTable analyzers, CompilationWithAnalyzersPair? compilationWithAnalyzersPair)>> s_projectToCompilationWithAnalyzers = new(); + private static readonly ConditionalWeakTable analyzers, CompilationWithAnalyzersPair? compilationWithAnalyzersPair)>> s_projectToCompilationWithAnalyzers = new(); private static async Task GetOrCreateCompilationWithAnalyzersAsync( Project project, @@ -36,25 +36,30 @@ internal partial class DiagnosticAnalyzerService if (!project.SupportsCompilation) return null; + var projectState = project.State; + var checksum = await project.GetDependentChecksumAsync(cancellationToken).ConfigureAwait(false); + // Make sure the cached pair was computed with at least the same state sets we're asking about. if not, // recompute and cache with the new state sets. - if (!s_projectToCompilationWithAnalyzers.TryGetValue(project, out var tupleBox) || + if (!s_projectToCompilationWithAnalyzers.TryGetValue(projectState, out var tupleBox) || + tupleBox.Value.checksum != checksum || !analyzers.IsSubsetOf(tupleBox.Value.analyzers)) { - var compilationWithAnalyzersPair = await CreateCompilationWithAnalyzersAsync().ConfigureAwait(false); - tupleBox = new((analyzers, compilationWithAnalyzersPair)); + var compilation = await project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); + var compilationWithAnalyzersPair = CreateCompilationWithAnalyzers(projectState, compilation); + tupleBox = new((checksum, analyzers, compilationWithAnalyzersPair)); #if NET - s_projectToCompilationWithAnalyzers.AddOrUpdate(project, tupleBox); + s_projectToCompilationWithAnalyzers.AddOrUpdate(projectState, tupleBox); #else // Make a best effort attempt to store the latest computed value against these state sets. If this // fails (because another thread interleaves with this), that's ok. We still return the pair we // computed, so our caller will still see the right data - s_projectToCompilationWithAnalyzers.Remove(project); + s_projectToCompilationWithAnalyzers.Remove(projectState); // Intentionally ignore the result of this. We still want to use the value we computed above, even if // another thread interleaves and sets a different value. - s_projectToCompilationWithAnalyzers.GetValue(project, _ => tupleBox); + s_projectToCompilationWithAnalyzers.GetValue(projectState, _ => tupleBox); #endif } @@ -63,13 +68,12 @@ internal partial class DiagnosticAnalyzerService // // Should only be called on a that . // - async Task CreateCompilationWithAnalyzersAsync() + CompilationWithAnalyzersPair? CreateCompilationWithAnalyzers( + ProjectState project, Compilation compilation) { var projectAnalyzers = analyzers.WhereAsArray(static (s, info) => !info.IsHostAnalyzer(s), hostAnalyzerInfo); var hostAnalyzers = analyzers.WhereAsArray(static (s, info) => info.IsHostAnalyzer(s), hostAnalyzerInfo); - var compilation = await project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); - // Create driver that holds onto compilation and associated analyzers var filteredProjectAnalyzers = projectAnalyzers.WhereAsArray(static a => !a.IsWorkspaceDiagnosticAnalyzer()); var filteredHostAnalyzers = hostAnalyzers.WhereAsArray(static a => !a.IsWorkspaceDiagnosticAnalyzer()); @@ -83,9 +87,6 @@ internal partial class DiagnosticAnalyzerService return null; } - Contract.ThrowIfFalse(project.SupportsCompilation); - AssertCompilation(project, compilation); - var exceptionFilter = (Exception ex) => { if (ex is not OperationCanceledException && crashOnAnalyzerException) @@ -105,7 +106,7 @@ internal partial class DiagnosticAnalyzerService var projectCompilation = !filteredProjectAnalyzers.Any() ? null : compilation.WithAnalyzers(filteredProjectAnalyzers, new CompilationWithAnalyzersOptions( - options: project.AnalyzerOptions, + options: project.ProjectAnalyzerOptions, onAnalyzerException: null, analyzerExceptionFilter: exceptionFilter, concurrentAnalysis: false, @@ -126,12 +127,4 @@ internal partial class DiagnosticAnalyzerService return new CompilationWithAnalyzersPair(projectCompilation, hostCompilation); } } - - [Conditional("DEBUG")] - private static void AssertCompilation(Project project, Compilation compilation1) - { - // given compilation must be from given project. - Contract.ThrowIfFalse(project.TryGetCompilation(out var compilation2)); - Contract.ThrowIfFalse(compilation1 == compilation2); - } } diff --git a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.HostAnalyzerInfo.cs b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.HostAnalyzerInfo.cs index 292ac0a5d21d9..e9a565a45c145 100644 --- a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.HostAnalyzerInfo.cs +++ b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.HostAnalyzerInfo.cs @@ -17,13 +17,15 @@ private partial class DiagnosticIncrementalAnalyzer { private partial class StateManager { - private HostAnalyzerInfo GetOrCreateHostAnalyzerInfo(Project project, ProjectAnalyzerInfo projectAnalyzerInfo) + private HostAnalyzerInfo GetOrCreateHostAnalyzerInfo( + Project project, ProjectAnalyzerInfo projectAnalyzerInfo) { - var key = new HostAnalyzerInfoKey(project.Language, project.State.HasSdkCodeStyleAnalyzers, project.Solution.SolutionState.Analyzers.HostAnalyzerReferences); + var analyzers = project.Solution.SolutionState.Analyzers; + var key = new HostAnalyzerInfoKey(project.Language, project.State.HasSdkCodeStyleAnalyzers, analyzers.HostAnalyzerReferences); // Some Host Analyzers may need to be treated as Project Analyzers so that they do not have access to the // Host fallback options. These ids will be used when building up the Host and Project analyzer collections. var referenceIdsToRedirect = GetReferenceIdsToRedirectAsProjectAnalyzers(project); - var hostAnalyzerInfo = ImmutableInterlocked.GetOrAdd(ref _hostAnalyzerStateMap, key, CreateLanguageSpecificAnalyzerMap, (project.Solution.SolutionState.Analyzers, referenceIdsToRedirect)); + var hostAnalyzerInfo = ImmutableInterlocked.GetOrAdd(ref _hostAnalyzerStateMap, key, CreateLanguageSpecificAnalyzerMap, (Analyzers: analyzers, referenceIdsToRedirect)); return hostAnalyzerInfo.WithExcludedAnalyzers(projectAnalyzerInfo.SkippedAnalyzersInfo.SkippedAnalyzers); static HostAnalyzerInfo CreateLanguageSpecificAnalyzerMap(HostAnalyzerInfoKey arg, (HostDiagnosticAnalyzers HostAnalyzers, ImmutableHashSet ReferenceIdsToRedirect) state) @@ -65,7 +67,8 @@ static HostAnalyzerInfo CreateLanguageSpecificAnalyzerMap(HostAnalyzerInfoKey ar } } - private static ImmutableHashSet GetReferenceIdsToRedirectAsProjectAnalyzers(Project project) + private static ImmutableHashSet GetReferenceIdsToRedirectAsProjectAnalyzers( + Project project) { if (project.State.HasSdkCodeStyleAnalyzers) { diff --git a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateManager.ProjectStates.cs b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateManager.ProjectStates.cs index c3eca357edf17..cb8fb9be7fb50 100644 --- a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateManager.ProjectStates.cs +++ b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateManager.ProjectStates.cs @@ -78,14 +78,15 @@ private ProjectAnalyzerInfo CreateProjectAnalyzerInfo(Project project) // workspace placeholder analyzers. So we should never get host analyzers back here. Contract.ThrowIfTrue(newHostAnalyzers.Count > 0); - var skippedAnalyzersInfo = project.GetSkippedAnalyzersInfo(_analyzerInfoCache); + var skippedAnalyzersInfo = hostAnalyzers.GetSkippedAnalyzersInfo(project.State, _analyzerInfoCache); return new ProjectAnalyzerInfo(project.AnalyzerReferences, newAllAnalyzers, skippedAnalyzersInfo); } /// /// Updates the map to the given project snapshot. /// - private async Task UpdateProjectAnalyzerInfoAsync(Project project, CancellationToken cancellationToken) + private async Task UpdateProjectAnalyzerInfoAsync( + Project project, CancellationToken cancellationToken) { // This code is called concurrently for a project, so the guard prevents duplicated effort calculating StateSets. using (await _projectAnalyzerStateMapGuard.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) diff --git a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateManager.cs b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateManager.cs index cd07e28f14daf..d55167d8f3fb5 100644 --- a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateManager.cs +++ b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateManager.cs @@ -47,14 +47,16 @@ private partial class StateManager(DiagnosticAnalyzerInfoCache analyzerInfoCache /// /// Return s for the given . /// - public async Task> GetOrCreateAnalyzersAsync(Project project, CancellationToken cancellationToken) + public async Task> GetOrCreateAnalyzersAsync( + Project project, CancellationToken cancellationToken) { var hostAnalyzerInfo = await GetOrCreateHostAnalyzerInfoAsync(project, cancellationToken).ConfigureAwait(false); var projectAnalyzerInfo = await GetOrCreateProjectAnalyzerInfoAsync(project, cancellationToken).ConfigureAwait(false); return hostAnalyzerInfo.OrderedAllAnalyzers.AddRange(projectAnalyzerInfo.Analyzers); } - public async Task GetOrCreateHostAnalyzerInfoAsync(Project project, CancellationToken cancellationToken) + public async Task GetOrCreateHostAnalyzerInfoAsync( + Project project, CancellationToken cancellationToken) { var projectAnalyzerInfo = await GetOrCreateProjectAnalyzerInfoAsync(project, cancellationToken).ConfigureAwait(false); return GetOrCreateHostAnalyzerInfo(project, projectAnalyzerInfo); diff --git a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_IncrementalAnalyzer.cs b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_IncrementalAnalyzer.cs index 4cd34cada2180..0e1dd1817a38a 100644 --- a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_IncrementalAnalyzer.cs +++ b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_IncrementalAnalyzer.cs @@ -11,7 +11,6 @@ using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Workspaces.Diagnostics; -using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Diagnostics; @@ -29,6 +28,8 @@ private partial class DiagnosticIncrementalAnalyzer public async Task> ForceAnalyzeProjectAsync(Project project, CancellationToken cancellationToken) { + var projectState = project.State; + try { if (!_projectToForceAnalysisData.TryGetValue(project, out var box)) diff --git a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/InProcOrRemoteHostAnalyzerRunner.cs b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/InProcOrRemoteHostAnalyzerRunner.cs index 1203bb1dabee7..d43c3016d6487 100644 --- a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/InProcOrRemoteHostAnalyzerRunner.cs +++ b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/InProcOrRemoteHostAnalyzerRunner.cs @@ -131,7 +131,7 @@ private async Task.Empty; diff --git a/src/Workspaces/Core/Portable/Diagnostics/HostDiagnosticAnalyzers.cs b/src/Workspaces/Core/Portable/Diagnostics/HostDiagnosticAnalyzers.cs index e63221b427381..09c0145948cb0 100644 --- a/src/Workspaces/Core/Portable/Diagnostics/HostDiagnosticAnalyzers.cs +++ b/src/Workspaces/Core/Portable/Diagnostics/HostDiagnosticAnalyzers.cs @@ -296,7 +296,7 @@ private static ImmutableDictionary> M return current; } - public SkippedHostAnalyzersInfo GetSkippedAnalyzersInfo(Project project, DiagnosticAnalyzerInfoCache infoCache) + public SkippedHostAnalyzersInfo GetSkippedAnalyzersInfo(ProjectState project, DiagnosticAnalyzerInfoCache infoCache) { var box = _skippedHostAnalyzers.GetOrCreateValue(project.AnalyzerReferences); diff --git a/src/Workspaces/Core/Portable/Serialization/SerializerService_Reference.cs b/src/Workspaces/Core/Portable/Serialization/SerializerService_Reference.cs index 7bb2618b19b0a..9c1adb44c8940 100644 --- a/src/Workspaces/Core/Portable/Serialization/SerializerService_Reference.cs +++ b/src/Workspaces/Core/Portable/Serialization/SerializerService_Reference.cs @@ -15,6 +15,7 @@ namespace Microsoft.CodeAnalysis.Serialization; +using static Microsoft.CodeAnalysis.Serialization.SerializerService.TestAccessor; using static TemporaryStorageService; internal partial class SerializerService @@ -29,18 +30,18 @@ internal partial class SerializerService /// pretend that a is a during tests. /// private static readonly object s_analyzerImageReferenceMapGate = new(); - private static IBidirectionalMap s_analyzerImageReferenceMap = BidirectionalMap.Empty; + private static IBidirectionalMap s_analyzerReferenceMap = BidirectionalMap.Empty; private static bool TryGetAnalyzerImageReferenceGuid(AnalyzerImageReference imageReference, out Guid guid) { lock (s_analyzerImageReferenceMapGate) - return s_analyzerImageReferenceMap.TryGetValue(imageReference, out guid); + return s_analyzerReferenceMap.TryGetValue(imageReference, out guid); } - private static bool TryGetAnalyzerImageReferenceFromGuid(Guid guid, [NotNullWhen(true)] out AnalyzerImageReference? imageReference) + private static bool TryGetAnalyzerImageReferenceFromGuid(Guid guid, [NotNullWhen(true)] out AnalyzerReference? analyzerReference) { lock (s_analyzerImageReferenceMapGate) - return s_analyzerImageReferenceMap.TryGetKey(guid, out imageReference); + return s_analyzerReferenceMap.TryGetKey(guid, out analyzerReference); } private static Checksum CreateChecksum(MetadataReference reference) @@ -78,6 +79,12 @@ protected virtual Checksum CreateChecksum(AnalyzerReference reference) writer.WriteGuid(guid); break; + case IAnalyzerReferenceWithGuid analyzerReferenceWithGuid: + lock (s_analyzerImageReferenceMapGate) + s_analyzerReferenceMap = s_analyzerReferenceMap.Add(reference, analyzerReferenceWithGuid.Guid); + writer.WriteGuid(analyzerReferenceWithGuid.Guid); + break; + default: throw ExceptionUtilities.UnexpectedValue(reference); } @@ -482,12 +489,6 @@ private static unsafe void WriteTo(MetadataReader reader, ObjectWriter writer) writer.WriteSpan(new ReadOnlySpan(reader.MetadataPointer, reader.MetadataLength)); } - private static void WriteUnresolvedAnalyzerReferenceTo(AnalyzerReference reference, ObjectWriter writer) - { - writer.WriteString(nameof(UnresolvedAnalyzerReference)); - writer.WriteString(reference.FullPath); - } - private static Metadata? TryGetMetadata(PortableExecutableReference reference) { try @@ -541,9 +542,23 @@ public static void AddAnalyzerImageReference(AnalyzerImageReference analyzerImag { lock (s_analyzerImageReferenceMapGate) { - if (!s_analyzerImageReferenceMap.ContainsKey(analyzerImageReference)) - s_analyzerImageReferenceMap = s_analyzerImageReferenceMap.Add(analyzerImageReference, Guid.NewGuid()); + if (!s_analyzerReferenceMap.ContainsKey(analyzerImageReference)) + s_analyzerReferenceMap = s_analyzerReferenceMap.Add(analyzerImageReference, Guid.NewGuid()); } } + + public static void AddAnalyzerImageReferences(IReadOnlyList analyzerReferences) + { + foreach (var analyzer in analyzerReferences) + { + if (analyzer is AnalyzerImageReference analyzerImageReference) + AddAnalyzerImageReference(analyzerImageReference); + } + } + + public interface IAnalyzerReferenceWithGuid + { + Guid Guid { get; } + } } } diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/Project.cs b/src/Workspaces/Core/Portable/Workspace/Solution/Project.cs index c76d53fcca168..260c146144562 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/Project.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/Project.cs @@ -830,9 +830,6 @@ internal StructuredAnalyzerConfigOptions GetFallbackAnalyzerOptions() private string GetDebuggerDisplay() => this.Name; - internal SkippedHostAnalyzersInfo GetSkippedAnalyzersInfo(DiagnosticAnalyzerInfoCache infoCache) - => Solution.SolutionState.Analyzers.GetSkippedAnalyzersInfo(this, infoCache); - internal async ValueTask GetDocumentAsync(ImmutableArray contentHash, CancellationToken cancellationToken) { var documentId = await State.GetDocumentIdAsync(contentHash, cancellationToken).ConfigureAwait(false); diff --git a/src/Workspaces/CoreTestUtilities/TestAnalyzerReferenceByLanguage.cs b/src/Workspaces/CoreTestUtilities/TestAnalyzerReferenceByLanguage.cs index c8a762042ae32..5371d55acc443 100644 --- a/src/Workspaces/CoreTestUtilities/TestAnalyzerReferenceByLanguage.cs +++ b/src/Workspaces/CoreTestUtilities/TestAnalyzerReferenceByLanguage.cs @@ -6,11 +6,14 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; +using Microsoft.CodeAnalysis.Serialization; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Diagnostics { - internal class TestAnalyzerReferenceByLanguage : AnalyzerReference + internal class TestAnalyzerReferenceByLanguage : + AnalyzerReference, + SerializerService.TestAccessor.IAnalyzerReferenceWithGuid { private readonly IReadOnlyDictionary> _analyzersMap; @@ -28,6 +31,7 @@ public TestAnalyzerReferenceByLanguage(IReadOnlyDictionary nameof(TestAnalyzerReferenceByLanguage); public override object Id => Display; + public Guid Guid { get; } = Guid.NewGuid(); public Checksum Checksum; diff --git a/src/Workspaces/CoreTestUtilities/Workspaces/TestWorkspace`1.cs b/src/Workspaces/CoreTestUtilities/Workspaces/TestWorkspace`1.cs index bac4fc5437153..40533be8db84b 100644 --- a/src/Workspaces/CoreTestUtilities/Workspaces/TestWorkspace`1.cs +++ b/src/Workspaces/CoreTestUtilities/Workspaces/TestWorkspace`1.cs @@ -774,15 +774,9 @@ public override bool TryApplyChanges(Solution newSolution) // Ensure that any in-memory analyzer references in this test workspace are known by the serializer service // so that we can validate OOP scenarios involving analyzers. - foreach (var analyzer in this.CurrentSolution.AnalyzerReferences) - { - if (analyzer is AnalyzerImageReference analyzerImageReference) - { #pragma warning disable CA1416 // Validate platform compatibility - SerializerService.TestAccessor.AddAnalyzerImageReference(analyzerImageReference); + SerializerService.TestAccessor.AddAnalyzerImageReferences(this.CurrentSolution.AnalyzerReferences); #pragma warning restore CA1416 // Validate platform compatibility - } - } return result; } diff --git a/src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/DiagnosticComputer.cs b/src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/DiagnosticComputer.cs index 3a767508ac893..6ff32cf4ac6e1 100644 --- a/src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/DiagnosticComputer.cs +++ b/src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/DiagnosticComputer.cs @@ -356,7 +356,8 @@ private async Task GetDiagnosticsAsync( } } - var skippedAnalyzersInfo = _project.GetSkippedAnalyzersInfo(_analyzerInfoCache); + var skippedAnalyzersInfo = _project.Solution.SolutionState.Analyzers.GetSkippedAnalyzersInfo( + _project.State, _analyzerInfoCache); return await AnalyzeAsync(compilationWithAnalyzers, analyzerToIdMap, projectAnalyzers, hostAnalyzers, skippedAnalyzersInfo, logPerformanceInfo, getTelemetryInfo, cancellationToken).ConfigureAwait(false);