diff --git a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Analyzer/AnalyzerSettingsProvider.cs b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Analyzer/AnalyzerSettingsProvider.cs index 503d2b39b5a67..44ae68bf11737 100644 --- a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Analyzer/AnalyzerSettingsProvider.cs +++ b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Analyzer/AnalyzerSettingsProvider.cs @@ -34,23 +34,34 @@ public AnalyzerSettingsProvider( } protected override async Task UpdateOptionsAsync( - TieredAnalyzerConfigOptions options, Solution solution, ImmutableArray projectsInScope, CancellationToken cancellationToken) + TieredAnalyzerConfigOptions options, ImmutableArray projectsInScope, CancellationToken cancellationToken) { var analyzerReferences = RoslynEnumerableExtensions.DistinctBy(projectsInScope.SelectMany(p => p.AnalyzerReferences), a => a.Id).ToImmutableArray(); + using var _ = PooledDictionary.GetInstance(out var analyzerReferenceToSomeReferencingProject); + + foreach (var project in projectsInScope) + { + foreach (var analyzerReference in project.AnalyzerReferences) + analyzerReferenceToSomeReferencingProject[analyzerReference] = project; + + } + foreach (var analyzerReference in analyzerReferences) { + var someReferencingProject = analyzerReferenceToSomeReferencingProject[analyzerReference]; var configSettings = await GetSettingsAsync( - solution, analyzerReference, options.EditorConfigOptions, cancellationToken).ConfigureAwait(false); + someReferencingProject, analyzerReference, options.EditorConfigOptions, cancellationToken).ConfigureAwait(false); AddRange(configSettings); } } private async Task> GetSettingsAsync( - Solution solution, AnalyzerReference analyzerReference, AnalyzerConfigOptions editorConfigOptions, CancellationToken cancellationToken) + Project someReferencingProject, AnalyzerReference analyzerReference, AnalyzerConfigOptions editorConfigOptions, CancellationToken cancellationToken) { + var solution = someReferencingProject.Solution; var service = solution.Services.GetRequiredService(); - var map = await service.GetDiagnosticDescriptorsAsync( - solution, analyzerReference, cancellationToken).ConfigureAwait(false); + var map = await service.GetLanguageKeyedDiagnosticDescriptorsAsync( + solution, someReferencingProject.Id, analyzerReference, cancellationToken).ConfigureAwait(false); using var _ = ArrayBuilder.GetInstance(out var allSettings); diff --git a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/NamingStyles/NamingStyleSettingsProvider.cs b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/NamingStyles/NamingStyleSettingsProvider.cs index b157fdf30506c..61748691b9c3c 100644 --- a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/NamingStyles/NamingStyleSettingsProvider.cs +++ b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/NamingStyles/NamingStyleSettingsProvider.cs @@ -32,7 +32,7 @@ public NamingStyleSettingsProvider( } protected override Task UpdateOptionsAsync( - TieredAnalyzerConfigOptions options, Solution solution, ImmutableArray projectsInScope, CancellationToken cancellationToken) + TieredAnalyzerConfigOptions options, ImmutableArray projectsInScope, CancellationToken cancellationToken) { options.GetInitialLocationAndValue(NamingStyleOptions.NamingPreferences, out var location, out var namingPreferences); diff --git a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/SettingsProviderBase.cs b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/SettingsProviderBase.cs index e4b6be1447139..10129ba50b949 100644 --- a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/SettingsProviderBase.cs +++ b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/SettingsProviderBase.cs @@ -20,7 +20,6 @@ using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Text; -using Microsoft.VisualStudio.Shell; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider; @@ -44,7 +43,7 @@ internal abstract class SettingsProviderBase projectsInScope, CancellationToken cancellationToken); + TieredAnalyzerConfigOptions options, ImmutableArray projectsInScope, CancellationToken cancellationToken); protected void Update() { @@ -74,7 +73,7 @@ protected void Update() language: LanguageNames.CSharp, editorConfigFileName: FileName); - _ = UpdateOptionsAsync(options, solution, projects, cancellationToken) + _ = UpdateOptionsAsync(options, projects, cancellationToken) .ReportNonFatalErrorUnlessCancelledAsync(cancellationToken); } diff --git a/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerExtensions.cs b/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerExtensions.cs index d841b63244c90..603e2e98c8980 100644 --- a/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerExtensions.cs +++ b/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerExtensions.cs @@ -51,6 +51,6 @@ public static Task> GetDiagnosticDescriptor { var diagnosticAnalyzerService = project.Solution.Services.GetRequiredService(); return diagnosticAnalyzerService.GetDiagnosticDescriptorsAsync( - project.Solution, analyzerReference, project.Language, cancellationToken); + project.Solution, project.Id, analyzerReference, project.Language, cancellationToken); } } diff --git a/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs b/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs index 7c45b27c859ee..990d405cd3d4d 100644 --- a/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs +++ b/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs @@ -81,8 +81,9 @@ Task> GetDiagnosticsForSpanAsync( DiagnosticKind diagnosticKind, CancellationToken cancellationToken); + /// A project within where can be found Task> GetDiagnosticDescriptorsAsync( - Solution solution, AnalyzerReference analyzerReference, string language, CancellationToken cancellationToken); + Solution solution, ProjectId projectId, AnalyzerReference analyzerReference, string language, CancellationToken cancellationToken); /// /// Returns all the descriptors for all s defined within . @@ -90,8 +91,9 @@ Task> GetDiagnosticDescriptorsAsync( /// is defined for. This can be [], [], /// or an array containing both languages if the descriptor is defined for both languages. /// - Task, ImmutableArray>> GetDiagnosticDescriptorsAsync( - Solution solution, AnalyzerReference analyzerReference, CancellationToken cancellationToken); + /// A project within where can be found + Task, ImmutableArray>> GetLanguageKeyedDiagnosticDescriptorsAsync( + Solution solution, ProjectId projectId, AnalyzerReference analyzerReference, CancellationToken cancellationToken); /// /// Given a list of errors ids (like CS1234), attempts to find an associated descriptor for each id. diff --git a/src/Features/Core/Portable/Diagnostics/Service/DiagnosticAnalyzerService.cs b/src/Features/Core/Portable/Diagnostics/Service/DiagnosticAnalyzerService.cs index c17c6ef89d59e..69624bb5d1e44 100644 --- a/src/Features/Core/Portable/Diagnostics/Service/DiagnosticAnalyzerService.cs +++ b/src/Features/Core/Portable/Diagnostics/Service/DiagnosticAnalyzerService.cs @@ -16,6 +16,7 @@ using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Options; +using Microsoft.CodeAnalysis.Remote; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.CodeAnalysis.SolutionCrawler; using Microsoft.CodeAnalysis.Text; @@ -138,20 +139,51 @@ public Task> GetProjectDiagnosticsForIdsAsync( return _incrementalAnalyzer.GetProjectDiagnosticsForIdsAsync(project, diagnosticIds, shouldIncludeAnalyzer, includeNonLocalDocumentDiagnostics, cancellationToken); } - public Task> GetDiagnosticDescriptorsAsync( - Solution solution, AnalyzerReference analyzerReference, string language, CancellationToken cancellationToken) + public async Task> GetDiagnosticDescriptorsAsync( + Solution solution, ProjectId projectId, AnalyzerReference analyzerReference, string language, CancellationToken cancellationToken) { - // TODO(cyrusn): Remote this to OOP. - var descriptors = analyzerReference + // Attempt to compute this OOP. + var client = await RemoteHostClient.TryGetClientAsync(solution.Services, cancellationToken).ConfigureAwait(false); + if (client is not null && + analyzerReference is AnalyzerFileReference analyzerFileReference) + { + var descriptors = await client.TryInvokeAsync>( + solution, + (service, solution, cancellationToken) => service.GetDiagnosticDescriptorsAsync(solution, projectId, analyzerFileReference.FullPath, language, cancellationToken), + cancellationToken).ConfigureAwait(false); + if (!descriptors.HasValue) + return []; + + return descriptors.Value.SelectAsArray(d => d.ToDiagnosticDescriptor()); + } + + // Otherwise, fallback to computing in proc. + return analyzerReference .GetAnalyzers(language) .SelectManyAsArray(this._analyzerInfoCache.GetDiagnosticDescriptors); - - return Task.FromResult(descriptors); } - public Task, ImmutableArray>> GetDiagnosticDescriptorsAsync( - Solution solution, AnalyzerReference analyzerReference, CancellationToken cancellationToken) + public async Task, ImmutableArray>> GetLanguageKeyedDiagnosticDescriptorsAsync( + Solution solution, ProjectId projectId, AnalyzerReference analyzerReference, CancellationToken cancellationToken) { + var client = await RemoteHostClient.TryGetClientAsync(solution.Services, cancellationToken).ConfigureAwait(false); + if (client is not null && + analyzerReference is AnalyzerFileReference analyzerFileReference) + { + var map = await client.TryInvokeAsync, ImmutableArray>>( + solution, + (service, solution, cancellationToken) => service.GetLanguageKeyedDiagnosticDescriptorsAsync(solution, projectId, analyzerFileReference.FullPath, cancellationToken), + cancellationToken).ConfigureAwait(false); + + if (!map.HasValue) + return ImmutableDictionary, ImmutableArray>.Empty; + + return map.Value.ToImmutableDictionary( + kvp => kvp.Key, + kvp => kvp.Value.SelectAsArray(d => d.ToDiagnosticDescriptor())); + } + + // Otherwise, fallback to computing in proc. var mapBuilder = ImmutableDictionary.CreateBuilder, ImmutableArray>(); var csharpAnalyzers = analyzerReference.GetAnalyzers(LanguageNames.CSharp); @@ -165,15 +197,31 @@ public Task, ImmutableArray GetDiagnosticDescriptors(ImmutableArray analyzers) => analyzers.SelectManyAsArray(this._analyzerInfoCache.GetDiagnosticDescriptors); } - public Task> TryGetDiagnosticDescriptorsAsync( + public async Task> TryGetDiagnosticDescriptorsAsync( Solution solution, ImmutableArray diagnosticIds, CancellationToken cancellationToken) { + var client = await RemoteHostClient.TryGetClientAsync(solution.Services, cancellationToken).ConfigureAwait(false); + if (client is not null) + { + var map = await client.TryInvokeAsync>( + solution, + (service, solution, cancellationToken) => service.TryGetDiagnosticDescriptorsAsync(solution, diagnosticIds, cancellationToken), + cancellationToken).ConfigureAwait(false); + + if (!map.HasValue) + return ImmutableDictionary.Empty; + + return map.Value.ToImmutableDictionary( + kvp => kvp.Key, + kvp => kvp.Value.ToDiagnosticDescriptor()); + } + var builder = ImmutableDictionary.CreateBuilder(); foreach (var diagnosticId in diagnosticIds) { @@ -181,14 +229,48 @@ public Task> TryGetDiagnosticD builder[diagnosticId] = descriptor; } - return Task.FromResult(builder.ToImmutable()); + return builder.ToImmutable(); + } + + public async Task>> GetDiagnosticDescriptorsPerReferenceAsync(Solution solution, CancellationToken cancellationToken) + { + var client = await RemoteHostClient.TryGetClientAsync(solution.Services, cancellationToken).ConfigureAwait(false); + if (client is not null) + { + var map = await client.TryInvokeAsync>>( + solution, + (service, solution, cancellationToken) => service.GetDiagnosticDescriptorsPerReferenceAsync(solution, cancellationToken), + cancellationToken).ConfigureAwait(false); + if (!map.HasValue) + return ImmutableDictionary>.Empty; + + return map.Value.ToImmutableDictionary( + kvp => kvp.Key, + kvp => kvp.Value.SelectAsArray(d => d.ToDiagnosticDescriptor())); + } + + return solution.SolutionState.Analyzers.GetDiagnosticDescriptorsPerReference(this._analyzerInfoCache); } - public Task>> GetDiagnosticDescriptorsPerReferenceAsync(Solution solution, CancellationToken cancellationToken) - => Task.FromResult(solution.SolutionState.Analyzers.GetDiagnosticDescriptorsPerReference(this._analyzerInfoCache)); + public async Task>> GetDiagnosticDescriptorsPerReferenceAsync(Project project, CancellationToken cancellationToken) + { + var client = await RemoteHostClient.TryGetClientAsync(project, cancellationToken).ConfigureAwait(false); + if (client is not null) + { + var map = await client.TryInvokeAsync>>( + project, + (service, solution, cancellationToken) => service.GetDiagnosticDescriptorsPerReferenceAsync(solution, project.Id, cancellationToken), + cancellationToken).ConfigureAwait(false); + if (!map.HasValue) + return ImmutableDictionary>.Empty; + + return map.Value.ToImmutableDictionary( + kvp => kvp.Key, + kvp => kvp.Value.SelectAsArray(d => d.ToDiagnosticDescriptor())); + } - public Task>> GetDiagnosticDescriptorsPerReferenceAsync(Project project, CancellationToken cancellationToken) - => Task.FromResult(project.Solution.SolutionState.Analyzers.GetDiagnosticDescriptorsPerReference(this._analyzerInfoCache, project)); + return project.Solution.SolutionState.Analyzers.GetDiagnosticDescriptorsPerReference(this._analyzerInfoCache, project); + } private sealed class DiagnosticAnalyzerComparer : IEqualityComparer { diff --git a/src/VisualStudio/CSharp/Impl/EditorConfigSettings/DataProvider/CodeStyle/CSharpCodeStyleSettingsProvider.cs b/src/VisualStudio/CSharp/Impl/EditorConfigSettings/DataProvider/CodeStyle/CSharpCodeStyleSettingsProvider.cs index fc6282d898266..5e539463775bb 100644 --- a/src/VisualStudio/CSharp/Impl/EditorConfigSettings/DataProvider/CodeStyle/CSharpCodeStyleSettingsProvider.cs +++ b/src/VisualStudio/CSharp/Impl/EditorConfigSettings/DataProvider/CodeStyle/CSharpCodeStyleSettingsProvider.cs @@ -34,7 +34,7 @@ public CSharpCodeStyleSettingsProvider( } protected override Task UpdateOptionsAsync( - TieredAnalyzerConfigOptions options, Solution solution, ImmutableArray projectsInScope, CancellationToken cancellationToken) + TieredAnalyzerConfigOptions options, ImmutableArray projectsInScope, CancellationToken cancellationToken) { var varSettings = GetVarCodeStyleOptions(options, SettingsUpdater); AddRange(varSettings); diff --git a/src/VisualStudio/CSharp/Impl/EditorConfigSettings/DataProvider/Whitespace/CSharpWhitespaceSettingsProvider.cs b/src/VisualStudio/CSharp/Impl/EditorConfigSettings/DataProvider/Whitespace/CSharpWhitespaceSettingsProvider.cs index 1436b62ba7304..5b1dec17cb78c 100644 --- a/src/VisualStudio/CSharp/Impl/EditorConfigSettings/DataProvider/Whitespace/CSharpWhitespaceSettingsProvider.cs +++ b/src/VisualStudio/CSharp/Impl/EditorConfigSettings/DataProvider/Whitespace/CSharpWhitespaceSettingsProvider.cs @@ -29,7 +29,7 @@ public CSharpWhitespaceSettingsProvider(IThreadingContext threadingContext, stri } protected override Task UpdateOptionsAsync( - TieredAnalyzerConfigOptions options, Solution solution, ImmutableArray projectsInScope, CancellationToken cancellationToken) + TieredAnalyzerConfigOptions options, ImmutableArray projectsInScope, CancellationToken cancellationToken) { var spacingOptions = GetSpacingOptions(options, SettingsUpdater); AddRange(spacingOptions.ToImmutableArray()); diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/DataProvider/CodeStyle/CommonCodeStyleSettingsProvider.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/DataProvider/CodeStyle/CommonCodeStyleSettingsProvider.cs index ad68b2d66cd26..2852da33b13b2 100644 --- a/src/VisualStudio/Core/Def/EditorConfigSettings/DataProvider/CodeStyle/CommonCodeStyleSettingsProvider.cs +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/DataProvider/CodeStyle/CommonCodeStyleSettingsProvider.cs @@ -30,7 +30,7 @@ public CommonCodeStyleSettingsProvider( } protected override Task UpdateOptionsAsync( - TieredAnalyzerConfigOptions options, Solution solution, ImmutableArray projectsInScope, CancellationToken cancellationToken) + TieredAnalyzerConfigOptions options, ImmutableArray projectsInScope, CancellationToken cancellationToken) { var qualifySettings = GetQualifyCodeStyleOptions(options, SettingsUpdater); AddRange(qualifySettings); diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/DataProvider/Whitespace/CommonWhitespaceSettingsProvider.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/DataProvider/Whitespace/CommonWhitespaceSettingsProvider.cs index 71ddc07891378..24e48ecd29ad2 100644 --- a/src/VisualStudio/Core/Def/EditorConfigSettings/DataProvider/Whitespace/CommonWhitespaceSettingsProvider.cs +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/DataProvider/Whitespace/CommonWhitespaceSettingsProvider.cs @@ -30,7 +30,7 @@ public CommonWhitespaceSettingsProvider( } protected override Task UpdateOptionsAsync( - TieredAnalyzerConfigOptions options, Solution solution, ImmutableArray projectsInScope, CancellationToken cancellationToken) + TieredAnalyzerConfigOptions options, ImmutableArray projectsInScope, CancellationToken cancellationToken) { var defaultOptions = GetDefaultOptions(options, SettingsUpdater); AddRange(defaultOptions); diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/BaseDiagnosticAndGeneratorItemSource.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/BaseDiagnosticAndGeneratorItemSource.cs index 6f7c62f457a4f..b0aaaa264d0f8 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/BaseDiagnosticAndGeneratorItemSource.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/BaseDiagnosticAndGeneratorItemSource.cs @@ -182,7 +182,7 @@ async ValueTask> GetDiagnosticDescriptorsAs var result = await client.TryInvokeAsync>( project, (service, solutionChecksum, cancellationToken) => service.GetDiagnosticDescriptorsAsync( - solutionChecksum, project.Id, analyzerFileReference.FullPath, cancellationToken), + solutionChecksum, project.Id, analyzerFileReference.FullPath, project.Language, cancellationToken), cancellationToken).ConfigureAwait(false); // If the call fails, the OOP substrate will have already reported an error diff --git a/src/Workspaces/Core/Portable/Diagnostics/IRemoteDiagnosticAnalyzerService.cs b/src/Workspaces/Core/Portable/Diagnostics/IRemoteDiagnosticAnalyzerService.cs index 9ac10bf9a965b..de19dad4f749b 100644 --- a/src/Workspaces/Core/Portable/Diagnostics/IRemoteDiagnosticAnalyzerService.cs +++ b/src/Workspaces/Core/Portable/Diagnostics/IRemoteDiagnosticAnalyzerService.cs @@ -15,8 +15,21 @@ internal interface IRemoteDiagnosticAnalyzerService ValueTask CalculateDiagnosticsAsync(Checksum solutionChecksum, DiagnosticArguments arguments, CancellationToken cancellationToken); ValueTask> GetSourceGeneratorDiagnosticsAsync(Checksum solutionChecksum, ProjectId projectId, CancellationToken cancellationToken); ValueTask ReportAnalyzerPerformanceAsync(ImmutableArray snapshot, int unitCount, bool forSpanAnalysis, CancellationToken cancellationToken); + ValueTask> GetDiagnosticDescriptorsAsync( - Checksum solutionChecksum, ProjectId projectId, string analyzerReferenceFullPath, CancellationToken cancellationToken); + Checksum solutionChecksum, ProjectId projectId, string analyzerReferenceFullPath, string language, CancellationToken cancellationToken); + + ValueTask, ImmutableArray>> GetLanguageKeyedDiagnosticDescriptorsAsync( + Checksum solutionChecksum, ProjectId projectId, string analyzerReferenceFullPath, CancellationToken cancellationToken); + + ValueTask> TryGetDiagnosticDescriptorsAsync( + Checksum solutionChecksum, ImmutableArray diagnosticIds, CancellationToken cancellationToken); + + ValueTask>> GetDiagnosticDescriptorsPerReferenceAsync( + Checksum solutionChecksum, CancellationToken cancellationToken); + + ValueTask>> GetDiagnosticDescriptorsPerReferenceAsync( + Checksum solutionChecksum, ProjectId projectId, CancellationToken cancellationToken); } [DataContract] diff --git a/src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/RemoteDiagnosticAnalyzerService.cs b/src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/RemoteDiagnosticAnalyzerService.cs index bd42f009807d5..3dfbd428e0c71 100644 --- a/src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/RemoteDiagnosticAnalyzerService.cs +++ b/src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/RemoteDiagnosticAnalyzerService.cs @@ -13,7 +13,6 @@ using Microsoft.CodeAnalysis.Remote.Diagnostics; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Telemetry; -using Roslyn.Utilities; using RoslynLogger = Microsoft.CodeAnalysis.Internal.Log.Logger; namespace Microsoft.CodeAnalysis.Remote; @@ -136,4 +135,107 @@ public ValueTask> GetDiagnosticDescript }, cancellationToken); } + + public ValueTask> GetDiagnosticDescriptorsAsync( + Checksum solutionChecksum, + ProjectId projectId, + string analyzerReferenceFullPath, + string language, + CancellationToken cancellationToken) + { + return RunWithSolutionAsync( + solutionChecksum, + async solution => + { + var service = solution.Services.GetRequiredService(); + var project = solution.GetRequiredProject(projectId); + var analyzerReference = project.AnalyzerReferences + .First(r => r.FullPath == analyzerReferenceFullPath); + + var descriptors = await service.GetDiagnosticDescriptorsAsync( + solution, projectId, analyzerReference, language, cancellationToken).ConfigureAwait(false); + return descriptors.SelectAsArray(DiagnosticDescriptorData.Create); + }, + cancellationToken); + } + + public ValueTask, ImmutableArray>> GetLanguageKeyedDiagnosticDescriptorsAsync( + Checksum solutionChecksum, + ProjectId projectId, + string analyzerReferenceFullPath, + CancellationToken cancellationToken) + { + return RunWithSolutionAsync( + solutionChecksum, + async solution => + { + var service = solution.Services.GetRequiredService(); + var project = solution.GetRequiredProject(projectId); + var analyzerReference = project.AnalyzerReferences + .First(r => r.FullPath == analyzerReferenceFullPath); + + var map = await service.GetLanguageKeyedDiagnosticDescriptorsAsync( + solution, projectId, analyzerReference, cancellationToken).ConfigureAwait(false); + return map.ToImmutableDictionary( + kvp => kvp.Key, + kvp => kvp.Value.SelectAsArray(DiagnosticDescriptorData.Create)); + }, + cancellationToken); + } + + public ValueTask> TryGetDiagnosticDescriptorsAsync( + Checksum solutionChecksum, + ImmutableArray diagnosticIds, + CancellationToken cancellationToken) + { + return RunWithSolutionAsync( + solutionChecksum, + async solution => + { + var service = solution.Services.GetRequiredService(); + var map = await service.TryGetDiagnosticDescriptorsAsync(solution, diagnosticIds, cancellationToken).ConfigureAwait(false); + return map.ToImmutableDictionary( + kvp => kvp.Key, + kvp => DiagnosticDescriptorData.Create(kvp.Value)); + }, + cancellationToken); + } + + public ValueTask>> GetDiagnosticDescriptorsPerReferenceAsync( + Checksum solutionChecksum, + CancellationToken cancellationToken) + { + return RunWithSolutionAsync( + solutionChecksum, + async solution => + { + var service = solution.Services.GetRequiredService(); + var map = await service.GetDiagnosticDescriptorsPerReferenceAsync(solution, cancellationToken).ConfigureAwait(false); + return map.ToImmutableDictionary( + kvp => kvp.Key, + kvp => kvp.Value.SelectAsArray(DiagnosticDescriptorData.Create)); + + }, + cancellationToken); + } + + public ValueTask>> GetDiagnosticDescriptorsPerReferenceAsync( + Checksum solutionChecksum, + ProjectId projectId, + CancellationToken cancellationToken) + { + return RunWithSolutionAsync( + solutionChecksum, + async solution => + { + var project = solution.GetRequiredProject(projectId); + var service = solution.Services.GetRequiredService(); + var map = await service.GetDiagnosticDescriptorsPerReferenceAsync(project, cancellationToken).ConfigureAwait(false); + return map.ToImmutableDictionary( + kvp => kvp.Key, + kvp => kvp.Value.SelectAsArray(DiagnosticDescriptorData.Create)); + + }, + cancellationToken); + } }