diff --git a/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs b/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs index 2ec0635e27b7f5859acdd64c7beb6b23a36e4544..0a3a8787e63ab32ac34676dd6e11538302042aee 100644 --- a/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs +++ b/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs @@ -310,6 +310,7 @@ private static void AssertCompilation(Project project, Compilation compilation1) Document document, AnalysisKind kind, CompilationWithAnalyzers? compilationWithAnalyzers, + Func? getSkippedAnalyzersInfo, TextSpan? span, CancellationToken cancellationToken) { @@ -362,7 +363,7 @@ private static void AssertCompilation(Project project, Compilation compilation1) // REVIEW: more unnecessary allocations just to get diagnostics per analyzer var singleAnalyzer = ImmutableArray.Create(analyzer); - var skippedAnalyzerInfo = analyzerInfoCache.GetOrCreateSkippedAnalyzersInfo(document.Project); + var skippedAnalyzerInfo = getSkippedAnalyzersInfo?.Invoke(document.Project) ?? SkippedHostAnalyzersInfo.Default; ImmutableArray filteredIds; switch (kind) diff --git a/src/Features/Core/Portable/Diagnostics/DefaultDiagnosticAnalyzerService.cs b/src/Features/Core/Portable/Diagnostics/DefaultDiagnosticAnalyzerService.cs index d113b9edfa0290a864a36f272eee1c7fffeb77cb..bb0377207fe16917befca6536d560fa014cba7eb 100644 --- a/src/Features/Core/Portable/Diagnostics/DefaultDiagnosticAnalyzerService.cs +++ b/src/Features/Core/Portable/Diagnostics/DefaultDiagnosticAnalyzerService.cs @@ -164,7 +164,7 @@ private async Task AnalyzeForKindAsync(Document document, AnalysisKind kind, Can foreach (var analyzer in analyzers) { builder.AddRange(await AnalyzerHelper.ComputeDiagnosticsAsync(analyzer, - document, kind, compilationWithAnalyzers, span: null, cancellationToken).ConfigureAwait(false)); + document, kind, compilationWithAnalyzers, getSkippedAnalyzersInfo: null, span: null, cancellationToken).ConfigureAwait(false)); } return builder.ToImmutableAndFree(); diff --git a/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerInfoCache.cs b/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerInfoCache.cs index c8c13c862dc3dc4d76d29a7f9a5e8cd19a7a342d..f385c9b9bc4c020167d4dd1eea7c04615e075d38 100644 --- a/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerInfoCache.cs +++ b/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerInfoCache.cs @@ -4,6 +4,7 @@ #nullable enable +using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Runtime.CompilerServices; @@ -44,14 +45,14 @@ public DiagnosticDescriptorsInfo(ImmutableArray supportedD } /// - /// Information about host analyzers that can be skipped for the given project ID. + /// Information about host analyzers that can be skipped for the given project analyzers. /// - private readonly ConditionalWeakTable _skippedAnalyzersInfo; + private readonly ConditionalWeakTable, ISkippedAnalyzersInfo> _skippedAnalyzersInfo; internal DiagnosticAnalyzerInfoCache() { _descriptorsInfo = new ConditionalWeakTable(); - _skippedAnalyzersInfo = new ConditionalWeakTable(); + _skippedAnalyzersInfo = new ConditionalWeakTable, ISkippedAnalyzersInfo>(); } /// @@ -121,19 +122,28 @@ public bool IsAnalyzerSuppressed(DiagnosticAnalyzer analyzer, Project project) return false; } - public ISkippedAnalyzersInfo GetOrCreateSkippedAnalyzersInfo(Project project) + public ISkippedAnalyzersInfo GetOrCreateSkippedAnalyzersInfo(Project project, HostDiagnosticAnalyzers hostAnalyzers) { - if (_skippedAnalyzersInfo.TryGetValue(project.Id, out var skippedAnalyzersInfo)) + if (_skippedAnalyzersInfo.TryGetValue(project.AnalyzerReferences, out var skippedAnalyzersInfo)) { return skippedAnalyzersInfo; } - var createValueCallback = new ConditionalWeakTable.CreateValueCallback( - _ => SkippedHostAnalyzersInfo.Create(project, this)); - return _skippedAnalyzersInfo.GetValue(project.Id, createValueCallback); + var createValueCallback = new ConditionalWeakTable, ISkippedAnalyzersInfo>.CreateValueCallback( + _ => SkippedHostAnalyzersInfo.Create(project, hostAnalyzers, this)); + return _skippedAnalyzersInfo.GetValue(project.AnalyzerReferences, createValueCallback); } - public void ClearProjectCache(ProjectId projectId) - => _skippedAnalyzersInfo.Remove(projectId); + public ISkippedAnalyzersInfo GetOrCreateSkippedAnalyzersInfo(Project project, IEnumerable hostAnalyzers) + { + if (_skippedAnalyzersInfo.TryGetValue(project.AnalyzerReferences, out var skippedAnalyzersInfo)) + { + return skippedAnalyzersInfo; + } + + var createValueCallback = new ConditionalWeakTable, ISkippedAnalyzersInfo>.CreateValueCallback( + _ => SkippedHostAnalyzersInfo.Create(project, hostAnalyzers, this)); + return _skippedAnalyzersInfo.GetValue(project.AnalyzerReferences, createValueCallback); + } } } diff --git a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.Executor.cs b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.Executor.cs index 6ea4b07e8f7b89aed663d579f8499e5d37ed5d89..87deb6d2fa6cdc72c7199adc95731b8c9143cde1 100644 --- a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.Executor.cs +++ b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.Executor.cs @@ -54,7 +54,7 @@ internal partial class DiagnosticIncrementalAnalyzer return new DocumentAnalysisData(version, existingData.Items, ImmutableArray.Empty); } - var diagnostics = await AnalyzerHelper.ComputeDiagnosticsAsync(stateSet.Analyzer, document, kind, compilation, span: null, cancellationToken).ConfigureAwait(false); + var diagnostics = await AnalyzerHelper.ComputeDiagnosticsAsync(stateSet.Analyzer, document, kind, compilation, GetOrCreateSkippedAnalyzersInfo, span: null, cancellationToken).ConfigureAwait(false); // this is no-op in product. only run in test environment Logger.Log(functionId, (t, d, a, ds) => $"{GetDocumentLogMessage(t, d, a)}, {string.Join(Environment.NewLine, ds)}", @@ -180,7 +180,7 @@ private static bool CompilationHasOpenFileOnlyAnalyzers(CompilationWithAnalyzers if (compilation != null && compilation.Analyzers.Length != 0) { // calculate regular diagnostic analyzers diagnostics - var resultMap = await _diagnosticAnalyzerRunner.AnalyzeAsync(compilation, project, forcedAnalysis, cancellationToken).ConfigureAwait(false); + var resultMap = await _diagnosticAnalyzerRunner.AnalyzeAsync(compilation, project, GetOrCreateSkippedAnalyzersInfo, forcedAnalysis, cancellationToken).ConfigureAwait(false); result = resultMap.AnalysisResult; @@ -197,6 +197,9 @@ private static bool CompilationHasOpenFileOnlyAnalyzers(CompilationWithAnalyzers } } + private ISkippedAnalyzersInfo GetOrCreateSkippedAnalyzersInfo(Project project) + => DiagnosticAnalyzerInfoCache.GetOrCreateSkippedAnalyzersInfo(project, HostAnalyzers); + private async Task> ComputeDiagnosticsAsync( CompilationWithAnalyzers? compilation, Project project, IEnumerable stateSets, bool forcedAnalysis, ImmutableDictionary existing, CancellationToken cancellationToken) diff --git a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.InProcOrRemoteHostAnalyzerRunner.cs b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.InProcOrRemoteHostAnalyzerRunner.cs index cfa09b0cd16595704cad59de7300f3017d873887..f6d42e8fb7cbe1040201cadf95c7c891da3e57eb 100644 --- a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.InProcOrRemoteHostAnalyzerRunner.cs +++ b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.InProcOrRemoteHostAnalyzerRunner.cs @@ -48,7 +48,7 @@ public InProcOrRemoteHostAnalyzerRunner(IAsynchronousOperationListener operation _lastOptionSetPerLanguage = new ConcurrentDictionary>(); } - public async Task> AnalyzeAsync(CompilationWithAnalyzers compilation, Project project, bool forcedAnalysis, CancellationToken cancellationToken) + public async Task> AnalyzeAsync(CompilationWithAnalyzers compilation, Project project, Func? getSkippedAnalyzersInfo, bool forcedAnalysis, CancellationToken cancellationToken) { Contract.ThrowIfFalse(compilation.Analyzers.Length != 0); @@ -57,14 +57,14 @@ public InProcOrRemoteHostAnalyzerRunner(IAsynchronousOperationListener operation if (service == null) { // host doesn't support RemoteHostService such as under unit test - return await AnalyzeInProcAsync(compilation, project, client: null, cancellationToken).ConfigureAwait(false); + return await AnalyzeInProcAsync(compilation, project, client: null, getSkippedAnalyzersInfo, cancellationToken).ConfigureAwait(false); } var remoteHostClient = await service.TryGetRemoteHostClientAsync(cancellationToken).ConfigureAwait(false); if (remoteHostClient == null) { // remote host is not running. this can happen if remote host is disabled. - return await AnalyzeInProcAsync(compilation, project, client: null, cancellationToken).ConfigureAwait(false); + return await AnalyzeInProcAsync(compilation, project, client: null, getSkippedAnalyzersInfo, cancellationToken).ConfigureAwait(false); } // out of proc analysis will use 2 source of analyzers. one is AnalyzerReference from project (nuget). and the other is host analyzers (vsix) @@ -73,7 +73,7 @@ public InProcOrRemoteHostAnalyzerRunner(IAsynchronousOperationListener operation } private async Task> AnalyzeInProcAsync( - CompilationWithAnalyzers compilation, Project project, RemoteHostClient? client, CancellationToken cancellationToken) + CompilationWithAnalyzers compilation, Project project, RemoteHostClient? client, Func? getSkippedAnalyzersInfo, CancellationToken cancellationToken) { Debug.Assert(compilation.Analyzers.Length != 0); @@ -87,7 +87,7 @@ public InProcOrRemoteHostAnalyzerRunner(IAsynchronousOperationListener operation var _ = FireAndForgetReportAnalyzerPerformanceAsync(project, client, analysisResult, cancellationToken).CompletesAsyncOperation(asyncToken); // get skipped analyzers info - var skippedAnalyzersInfo = _analyzerInfoCache.GetOrCreateSkippedAnalyzersInfo(project); + var skippedAnalyzersInfo = getSkippedAnalyzersInfo?.Invoke(project) ?? SkippedHostAnalyzersInfo.Default; // get compiler result builder map var builderMap = analysisResult.ToResultBuilderMap(project, version, compilation.Compilation, compilation.Analyzers, skippedAnalyzersInfo, cancellationToken); diff --git a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateManager.ProjectStates.cs b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateManager.ProjectStates.cs index cbf1741a4d713065c15826172dfe08cdabb3c129..c9e9f10c5b78a754337842d4de3e254efa6b334a 100644 --- a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateManager.ProjectStates.cs +++ b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateManager.ProjectStates.cs @@ -49,11 +49,12 @@ private partial class StateManager Project project, ImmutableDictionary> mapPerReferences, ImmutableDictionary analyzerMap, - DiagnosticAnalyzerInfoCache analyzerInfoCache) + DiagnosticAnalyzerInfoCache analyzerInfoCache, + HostDiagnosticAnalyzers hostAnalyzers) : this(project.AnalyzerReferences, mapPerReferences, analyzerMap, - analyzerInfoCache.GetOrCreateSkippedAnalyzersInfo(project)) + analyzerInfoCache.GetOrCreateSkippedAnalyzersInfo(project, hostAnalyzers)) { Contract.ThrowIfNull(project); Contract.ThrowIfNull(mapPerReferences); @@ -110,7 +111,7 @@ private ProjectAnalyzerStateSets CreateProjectStateSets(Project project) } var newMap = CreateStateSetMap(project.Language, analyzersPerReference.Values, includeFileContentLoadAnalyzer: false); - return new ProjectAnalyzerStateSets(project, analyzersPerReference, newMap, _analyzerInfoCache); + return new ProjectAnalyzerStateSets(project, analyzersPerReference, newMap, _analyzerInfoCache, _hostAnalyzers); } /// @@ -118,7 +119,6 @@ private ProjectAnalyzerStateSets CreateProjectStateSets(Project project) /// private ProjectAnalyzerStateSets UpdateProjectStateSets(Project project) { - _analyzerInfoCache.ClearProjectCache(project.Id); var projectStateSets = CreateProjectStateSets(project); RaiseProjectAnalyzerReferenceChangedIfNeeded(project, projectStateSets.MapPerReferences, projectStateSets.StateSetMap); diff --git a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateManager.cs b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateManager.cs index af72c8109da0356c558fcf8397923d9024bfa67e..ad7d2e6a5c49adc540d0ecc6fdd802864038bd18 100644 --- a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateManager.cs +++ b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateManager.cs @@ -253,7 +253,6 @@ public bool OnProjectRemoved(IEnumerable stateSets, ProjectId projectI } _projectAnalyzerStateMap.TryRemove(projectId, out _); - _analyzerInfoCache.ClearProjectCache(projectId); return removed; } diff --git a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs index bfc3e0fbcbfd2ed07a0bc58d1f0e390517ef8061..d8c74ad501229b09976feff04d1a95d4654377d6 100644 --- a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs +++ b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs @@ -215,7 +215,7 @@ private async Task> GetCompilerSemanticDiagnosticsAs private Task> GetSyntaxDiagnosticsAsync(DiagnosticAnalyzer analyzer, CancellationToken cancellationToken) { - return AnalyzerHelper.ComputeDiagnosticsAsync(analyzer, _document, AnalysisKind.Syntax, _compilation, _range, cancellationToken); + return AnalyzerHelper.ComputeDiagnosticsAsync(analyzer, _document, AnalysisKind.Syntax, _compilation, _owner.GetOrCreateSkippedAnalyzersInfo, _range, cancellationToken); } private Task> GetSemanticDiagnosticsAsync(DiagnosticAnalyzer analyzer, CancellationToken cancellationToken) @@ -223,7 +223,7 @@ private Task> GetSemanticDiagnosticsAsync(Diagnostic var supportsSemanticInSpan = analyzer.SupportsSpanBasedSemanticDiagnosticAnalysis(); var analysisSpan = supportsSemanticInSpan ? (TextSpan?)_range : null; - return AnalyzerHelper.ComputeDiagnosticsAsync(analyzer, _document, AnalysisKind.Semantic, _compilation, analysisSpan, cancellationToken); + return AnalyzerHelper.ComputeDiagnosticsAsync(analyzer, _document, AnalysisKind.Semantic, _compilation, _owner.GetOrCreateSkippedAnalyzersInfo, analysisSpan, cancellationToken); } private async Task> GetProjectDiagnosticsAsync(DiagnosticAnalyzer analyzer, CancellationToken cancellationToken) diff --git a/src/Features/Core/Portable/Diagnostics/SkippedHostAnalyzersInfo.cs b/src/Features/Core/Portable/Diagnostics/SkippedHostAnalyzersInfo.cs index 33e0da92d3bd40005741871f2c9f5e9540d252fb..42e8c936c0bada82d441cf2bbf139a2973f630fd 100644 --- a/src/Features/Core/Portable/Diagnostics/SkippedHostAnalyzersInfo.cs +++ b/src/Features/Core/Portable/Diagnostics/SkippedHostAnalyzersInfo.cs @@ -46,15 +46,40 @@ internal sealed class SkippedHostAnalyzersInfo : ISkippedAnalyzersInfo public static SkippedHostAnalyzersInfo Create( Project project, + HostDiagnosticAnalyzers hostAnalyzers, DiagnosticAnalyzerInfoCache analyzerInfoCache) { - var projectAnalyzers = analyzerInfoCache.CreateProjectDiagnosticAnalyzersPerReference(project).SelectMany(v => v.Value); + var projectAnalyzers = hostAnalyzers.CreateProjectDiagnosticAnalyzersPerReference(project).SelectMany(v => v.Value); if (projectAnalyzers.IsEmpty()) { return Default; } - ComputeSkippedHostAnalyzers(project, projectAnalyzers, analyzerInfoCache, + var hostAnalyzersPerReference = hostAnalyzers.GetOrCreateHostDiagnosticAnalyzersPerReference(project.Language).SelectMany(v => v.Value); + return Create(projectAnalyzers, hostAnalyzersPerReference, analyzerInfoCache); + } + + public static SkippedHostAnalyzersInfo Create( + Project project, + IEnumerable hostAnalyzerReferences, + DiagnosticAnalyzerInfoCache analyzerInfoCache) + { + var projectAnalyzers = project.AnalyzerReferences.SelectMany(p => p.GetAnalyzers(project.Language)); + if (projectAnalyzers.IsEmpty()) + { + return Default; + } + + var hostAnalyzers = hostAnalyzerReferences.SelectMany(p => p.GetAnalyzers(project.Language)); + return Create(projectAnalyzers, hostAnalyzers, analyzerInfoCache); + } + + private static SkippedHostAnalyzersInfo Create( + IEnumerable projectAnalyzers, + IEnumerable hostAnalyzers, + DiagnosticAnalyzerInfoCache analyzerInfoCache) + { + ComputeSkippedHostAnalyzers(projectAnalyzers, hostAnalyzers, analyzerInfoCache, out var fullySkippedHostAnalyzers, out var filteredDiagnosticIdsForAnalyzers); if (fullySkippedHostAnalyzers.IsEmpty && filteredDiagnosticIdsForAnalyzers.IsEmpty) { @@ -64,13 +89,12 @@ internal sealed class SkippedHostAnalyzersInfo : ISkippedAnalyzersInfo return new SkippedHostAnalyzersInfo(fullySkippedHostAnalyzers, filteredDiagnosticIdsForAnalyzers); static void ComputeSkippedHostAnalyzers( - Project project, IEnumerable projectAnalyzers, + IEnumerable hostAnalyzers, DiagnosticAnalyzerInfoCache analyzerInfoCache, out ImmutableHashSet fullySkippedHostAnalyzers, out ImmutableDictionary> filteredDiagnosticIdsForAnalyzers) { - var hostAnalyzers = analyzerInfoCache.GetOrCreateHostDiagnosticAnalyzersPerReference(project.Language).SelectMany(v => v.Value); var idsReportedByProjectAnalyzers = GetIdsReportedByProjectAnalyzers(projectAnalyzers, analyzerInfoCache); var fullySkippedHostAnalyzersBuilder = ImmutableHashSet.CreateBuilder(); var partiallySkippedHostAnalyzersBuilder = ImmutableDictionary.CreateBuilder>(); diff --git a/src/VisualStudio/Core/Test.Next/Services/VisualStudioDiagnosticAnalyzerExecutorTests.cs b/src/VisualStudio/Core/Test.Next/Services/VisualStudioDiagnosticAnalyzerExecutorTests.cs index 572c20c5a71870c7d59772f1c09ce84bc7a731d6..08fb9c4493296d54096a9b4f0803040b6535d111 100644 --- a/src/VisualStudio/Core/Test.Next/Services/VisualStudioDiagnosticAnalyzerExecutorTests.cs +++ b/src/VisualStudio/Core/Test.Next/Services/VisualStudioDiagnosticAnalyzerExecutorTests.cs @@ -201,10 +201,10 @@ void Method() new WorkspaceAnalyzerOptions(project.AnalyzerOptions, project.Solution)); // no result for open file only analyzer unless forced - var result = await runner.AnalyzeAsync(compilationWithAnalyzers, project, forcedAnalysis: false, cancellationToken: CancellationToken.None); + var result = await runner.AnalyzeAsync(compilationWithAnalyzers, project, getSkippedAnalyzersInfo: null, forcedAnalysis: false, cancellationToken: CancellationToken.None); Assert.Empty(result.AnalysisResult); - result = await runner.AnalyzeAsync(compilationWithAnalyzers, project, forcedAnalysis: true, cancellationToken: CancellationToken.None); + result = await runner.AnalyzeAsync(compilationWithAnalyzers, project, getSkippedAnalyzersInfo: null, forcedAnalysis: true, cancellationToken: CancellationToken.None); var analyzerResult = result.AnalysisResult[compilationWithAnalyzers.Analyzers[0]]; // check result @@ -253,7 +253,7 @@ void Method() analyzerReference.GetAnalyzers(project.Language).Where(a => a.GetType() == analyzerType).ToImmutableArray(), new WorkspaceAnalyzerOptions(project.AnalyzerOptions, project.Solution)); - var result = await runner.AnalyzeAsync(compilationWithAnalyzers, project, forcedAnalysis: false, cancellationToken: CancellationToken.None); + var result = await runner.AnalyzeAsync(compilationWithAnalyzers, project, getSkippedAnalyzersInfo: null, forcedAnalysis: false, cancellationToken: CancellationToken.None); var analyzerResult = result.AnalysisResult[compilationWithAnalyzers.Analyzers[0]]; @@ -282,7 +282,7 @@ private static async Task AnalyzeAsync(TestWorkspace w analyzerReference.GetAnalyzers(project.Language).Where(a => a.GetType() == analyzerType).ToImmutableArray(), new WorkspaceAnalyzerOptions(project.AnalyzerOptions, project.Solution)); - var result = await executor.AnalyzeAsync(analyzerDriver, project, forcedAnalysis: true, cancellationToken: cancellationToken); + var result = await executor.AnalyzeAsync(analyzerDriver, project, getSkippedAnalyzersInfo: null, forcedAnalysis: true, cancellationToken: cancellationToken); return result.AnalysisResult[analyzerDriver.Analyzers[0]]; } diff --git a/src/Workspaces/Remote/Core/Diagnostics/DiagnosticComputer.cs b/src/Workspaces/Remote/Core/Diagnostics/DiagnosticComputer.cs index c942f64b3c25b748b55faa0874abaa955e903cee..bd000f71fa12f2f602949f2749acfba033741d89 100644 --- a/src/Workspaces/Remote/Core/Diagnostics/DiagnosticComputer.cs +++ b/src/Workspaces/Remote/Core/Diagnostics/DiagnosticComputer.cs @@ -50,12 +50,14 @@ public DiagnosticComputer(Project project, DiagnosticAnalyzerInfoCache analyzerI var cacheService = _project.Solution.Workspace.Services.GetRequiredService(); using var cache = cacheService.EnableCaching(_project.Id); - return await AnalyzeAsync(analyzerMap, analyzers, reportSuppressedDiagnostics, logAnalyzerExecutionTime, cancellationToken).ConfigureAwait(false); + var skippedAnalyzersInfo = _analyzerInfoCache.GetOrCreateSkippedAnalyzersInfo(_project, hostAnalyzers); + return await AnalyzeAsync(analyzerMap, analyzers, skippedAnalyzersInfo, reportSuppressedDiagnostics, logAnalyzerExecutionTime, cancellationToken).ConfigureAwait(false); } private async Task> AnalyzeAsync( BidirectionalMap analyzerMap, ImmutableArray analyzers, + ISkippedAnalyzersInfo skippedAnalyzersInfo, bool reportSuppressedDiagnostics, bool logAnalyzerExecutionTime, CancellationToken cancellationToken) @@ -93,9 +95,6 @@ public DiagnosticComputer(Project project, DiagnosticAnalyzerInfoCache analyzerI _performanceTracker.AddSnapshot(analysisResult.AnalyzerTelemetryInfo.ToAnalyzerPerformanceInfo(_analyzerInfoCache), _project.DocumentIds.Count + 1); } - // get skipped analyzers info - var skippedAnalyzersInfo = _analyzerInfoCache.GetOrCreateSkippedAnalyzersInfo(_project); - var builderMap = analysisResult.ToResultBuilderMap(_project, VersionStamp.Default, compilation, analysisResult.Analyzers, skippedAnalyzersInfo, cancellationToken); return DiagnosticAnalysisResultMap.Create( diff --git a/src/Workspaces/Remote/ServiceHub/Services/CodeAnalysisService_Diagnostics.cs b/src/Workspaces/Remote/ServiceHub/Services/CodeAnalysisService_Diagnostics.cs index 7173740bebccb609c18aba08f60b140c83e67e15..377e2660f336c16bfa8a374853161f5a0f63444b 100644 --- a/src/Workspaces/Remote/ServiceHub/Services/CodeAnalysisService_Diagnostics.cs +++ b/src/Workspaces/Remote/ServiceHub/Services/CodeAnalysisService_Diagnostics.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Diagnostics;