diff --git a/src/Analyzers/AnalyzerFormatter.cs b/src/Analyzers/AnalyzerFormatter.cs index 7af5930820..6cd013c06a 100644 --- a/src/Analyzers/AnalyzerFormatter.cs +++ b/src/Analyzers/AnalyzerFormatter.cs @@ -16,6 +16,8 @@ namespace Microsoft.CodeAnalysis.Tools.Analyzers { internal class AnalyzerFormatter : ICodeFormatter { + private static readonly ImmutableArray _supportedLanguages = ImmutableArray.Create(LanguageNames.CSharp, LanguageNames.VisualBasic); + private readonly string _name; private readonly IAnalyzerInformationProvider _informationProvider; private readonly IAnalyzerRunner _runner; @@ -42,6 +44,10 @@ public async Task FormatAsync( CancellationToken cancellationToken) { var (analyzers, fixers) = _informationProvider.GetAnalyzersAndFixers(solution, formatOptions, logger); + if (analyzers.IsEmpty && fixers.IsEmpty) + { + return solution; + } var analysisStopwatch = Stopwatch.StartNew(); logger.LogTrace(Resources.Running_0_analysis, _name); @@ -148,13 +154,13 @@ private async Task FixDiagnosticsAsync( } // Build maps between diagnostic id and the associated analyzers and codefixes - var analyzersById = CreateAnalyzerMap(reportedDiagnostics, allAnalyzers); + var analyzersByIdAndLanguage = CreateAnalyzerMap(reportedDiagnostics, allAnalyzers); var fixersById = CreateFixerMap(reportedDiagnostics, allCodefixes); // We need to run each codefix iteratively so ensure that all diagnostics are found and fixed. foreach (var diagnosticId in reportedDiagnostics) { - var analyzers = analyzersById[diagnosticId]; + var analyzersByLanguage = analyzersByIdAndLanguage[diagnosticId]; var codefixes = fixersById[diagnosticId]; // If there is no codefix, there is no reason to run analysis again. @@ -173,6 +179,7 @@ private async Task FixDiagnosticsAsync( continue; } + var analyzers = analyzersByLanguage[project.Language]; await _runner.RunCodeAnalysisAsync(result, analyzers, project, formattablePaths, severity, logger, cancellationToken).ConfigureAwait(false); } @@ -193,13 +200,18 @@ private async Task FixDiagnosticsAsync( return solution; - static ImmutableDictionary> CreateAnalyzerMap( + static ImmutableDictionary>> CreateAnalyzerMap( ImmutableArray diagnosticIds, ImmutableArray analyzers) { return diagnosticIds.ToImmutableDictionary( id => id, - id => analyzers.Where(analyzer => analyzer.SupportedDiagnostics.Any(diagnostic => diagnostic.Id == id)).ToImmutableArray()); + id => _supportedLanguages.ToImmutableDictionary( + language => language, + language => analyzers + .Where(analyzer => DoesAnalyzerSupportLanguage(analyzer, language)) + .Where(analyzer => analyzer.SupportedDiagnostics.Any(diagnostic => diagnostic.Id == id)) + .ToImmutableArray())); } static ImmutableDictionary> CreateFixerMap( @@ -226,7 +238,9 @@ internal static async Task(); - foreach (var analyzer in allAnalyzers) + // Filter analyzers by project's language + var filteredAnalyzer = allAnalyzers.Where(analyzer => DoesAnalyzerSupportLanguage(analyzer, project.Language)); + foreach (var analyzer in filteredAnalyzer) { // Always run naming style analyzers because we cannot determine potential severity. // The reported diagnostics will be filtered by severity when they are run. @@ -248,5 +262,13 @@ internal static async Task() + .Any(attribute => attribute.Languages.Contains(language)); + } } }