forked from dotnet/format
/
AnalyzerFinderHelpers.cs
83 lines (71 loc) · 3.52 KB
/
AnalyzerFinderHelpers.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.Extensions.Logging;
namespace Microsoft.CodeAnalysis.Tools.Analyzers
{
internal static class AnalyzerFinderHelpers
{
public static ImmutableArray<(DiagnosticAnalyzer Analyzer, CodeFixProvider? Fixer)> LoadAnalyzersAndFixers(
IEnumerable<Assembly> assemblies,
ILogger logger)
{
var types = assemblies
.SelectMany(assembly => assembly.GetTypes()
.Where(type => !type.GetTypeInfo().IsInterface &&
!type.GetTypeInfo().IsAbstract &&
!type.GetTypeInfo().ContainsGenericParameters));
var codeFixProviders = types
.Where(t => typeof(CodeFixProvider).IsAssignableFrom(t))
.Select(type => type.TryCreateInstance<CodeFixProvider>(out var instance) ? instance : null)
.OfType<CodeFixProvider>()
.ToImmutableArray();
var diagnosticAnalyzers = types
.Where(t => typeof(DiagnosticAnalyzer).IsAssignableFrom(t))
.Select(type => type.TryCreateInstance<DiagnosticAnalyzer>(out var instance) ? instance : null)
.OfType<DiagnosticAnalyzer>()
.ToImmutableArray();
var builder = ImmutableArray.CreateBuilder<(DiagnosticAnalyzer Analyzer, CodeFixProvider? Fixer)>();
foreach (var diagnosticAnalyzer in diagnosticAnalyzers)
{
var diagnosticIds = diagnosticAnalyzer.SupportedDiagnostics.Select(diagnostic => diagnostic.Id).ToImmutableHashSet();
var codeFixProvider = codeFixProviders.FirstOrDefault(codeFixProvider => codeFixProvider.FixableDiagnosticIds.Any(id => diagnosticIds.Contains(id)));
if (codeFixProvider is null)
{
continue;
}
builder.Add((diagnosticAnalyzer, codeFixProvider));
}
return builder.ToImmutableArray();
}
public static async Task<ImmutableDictionary<Project, ImmutableArray<DiagnosticAnalyzer>>> FilterBySeverityAsync(
IEnumerable<Project> projects,
ImmutableArray<DiagnosticAnalyzer> allAnalyzers,
ImmutableHashSet<string> formattablePaths,
DiagnosticSeverity minimumSeverity,
CancellationToken cancellationToken)
{
var projectAnalyzers = ImmutableDictionary.CreateBuilder<Project, ImmutableArray<DiagnosticAnalyzer>>();
foreach (var project in projects)
{
var analyzers = ImmutableArray.CreateBuilder<DiagnosticAnalyzer>();
foreach (var analyzer in allAnalyzers)
{
var severity = await analyzer.GetSeverityAsync(project, formattablePaths, cancellationToken).ConfigureAwait(false);
if (severity >= minimumSeverity)
{
analyzers.Add(analyzer);
}
}
projectAnalyzers.Add(project, analyzers.ToImmutableArray());
}
return projectAnalyzers.ToImmutableDictionary();
}
}
}