1313using Microsoft . CodeAnalysis . Editor . EditorConfigSettings . Updater ;
1414using Microsoft . CodeAnalysis . EditorConfig ;
1515using Microsoft . CodeAnalysis . Options ;
16+ using Microsoft . CodeAnalysis . PooledObjects ;
1617using Microsoft . CodeAnalysis . Shared . Extensions ;
1718using RoslynEnumerableExtensions = Microsoft . CodeAnalysis . Editor . EditorConfigSettings . Extensions . EnumerableExtensions ;
1819
1920namespace Microsoft . CodeAnalysis . Editor . EditorConfigSettings . DataProvider . Analyzer ;
2021
2122internal sealed class AnalyzerSettingsProvider : SettingsProviderBase < AnalyzerSetting , AnalyzerSettingsUpdater , AnalyzerSetting , ReportDiagnostic >
2223{
23- private readonly IDiagnosticAnalyzerService _analyzerService ;
24-
2524 public AnalyzerSettingsProvider (
2625 string fileName ,
2726 AnalyzerSettingsUpdater settingsUpdater ,
2827 Workspace workspace ,
2928 IGlobalOptionService optionService )
3029 : base ( fileName , settingsUpdater , workspace , optionService )
3130 {
32- _analyzerService = workspace . Services . GetRequiredService < IDiagnosticAnalyzerService > ( ) ;
3331 Update ( ) ;
3432 }
3533
36- protected override void UpdateOptions ( TieredAnalyzerConfigOptions options , ImmutableArray < Project > projectsInScope )
34+ protected override void UpdateOptions (
35+ TieredAnalyzerConfigOptions options , Solution solution , ImmutableArray < Project > projectsInScope )
3736 {
3837 var analyzerReferences = RoslynEnumerableExtensions . DistinctBy ( projectsInScope . SelectMany ( p => p . AnalyzerReferences ) , a => a . Id ) . ToImmutableArray ( ) ;
3938 foreach ( var analyzerReference in analyzerReferences )
4039 {
41- var configSettings = GetSettings ( analyzerReference , options . EditorConfigOptions ) ;
40+ var configSettings = GetSettings ( solution , analyzerReference , options . EditorConfigOptions ) ;
4241 AddRange ( configSettings ) ;
4342 }
4443 }
4544
46- private IEnumerable < AnalyzerSetting > GetSettings ( AnalyzerReference analyzerReference , AnalyzerConfigOptions editorConfigOptions )
45+ private ImmutableArray < AnalyzerSetting > GetSettings (
46+ Solution solution , AnalyzerReference analyzerReference , AnalyzerConfigOptions editorConfigOptions )
4747 {
48- IEnumerable < DiagnosticAnalyzer > csharpAnalyzers = analyzerReference . GetAnalyzers ( LanguageNames . CSharp ) ;
49- IEnumerable < DiagnosticAnalyzer > visualBasicAnalyzers = analyzerReference . GetAnalyzers ( LanguageNames . VisualBasic ) ;
50- var dotnetAnalyzers = csharpAnalyzers . Intersect ( visualBasicAnalyzers , DiagnosticAnalyzerComparer . Instance ) ;
51- csharpAnalyzers = csharpAnalyzers . Except ( dotnetAnalyzers , DiagnosticAnalyzerComparer . Instance ) ;
52- visualBasicAnalyzers = visualBasicAnalyzers . Except ( dotnetAnalyzers , DiagnosticAnalyzerComparer . Instance ) ;
48+ var service = solution . Services . GetRequiredService < IDiagnosticAnalyzerService > ( ) ;
49+ var map = service . GetDiagnosticDescriptors ( solution , analyzerReference ) ;
50+
51+ using var _ = ArrayBuilder < AnalyzerSetting > . GetInstance ( out var allSettings ) ;
52+
53+ foreach ( var ( languages , descriptors ) in map )
54+ allSettings . AddRange ( ToAnalyzerSettings ( descriptors , ConvertToLanguage ( languages ) ) ) ;
55+
56+ return allSettings . ToImmutableAndClear ( ) ;
57+
58+ Language ConvertToLanguage ( ImmutableArray < string > languages )
59+ {
60+ Contract . ThrowIfTrue ( languages . Length == 0 ) ;
61+ var language = ( Language ) 0 ;
5362
54- var csharpSettings = ToAnalyzerSetting ( csharpAnalyzers , Language . CSharp ) ;
55- var csharpAndVisualBasicSettings = csharpSettings . Concat ( ToAnalyzerSetting ( visualBasicAnalyzers , Language . VisualBasic ) ) ;
56- return csharpAndVisualBasicSettings . Concat ( ToAnalyzerSetting ( dotnetAnalyzers , Language . CSharp | Language . VisualBasic ) ) ;
63+ foreach ( var languageString in languages )
64+ {
65+ language |= languageString switch
66+ {
67+ LanguageNames . CSharp => Language . CSharp ,
68+ LanguageNames . VisualBasic => Language . VisualBasic ,
69+ _ => throw new ArgumentException ( $ "Unsupported language: { languageString } ")
70+ } ;
71+ }
72+
73+ return language ;
74+ }
5775
58- IEnumerable < AnalyzerSetting > ToAnalyzerSetting ( IEnumerable < DiagnosticAnalyzer > analyzers ,
59- Language language )
76+ IEnumerable < AnalyzerSetting > ToAnalyzerSettings (
77+ IEnumerable < DiagnosticDescriptor > descriptors , Language language )
6078 {
61- return analyzers
62- . SelectMany ( a => _analyzerService . AnalyzerInfoCache . GetDiagnosticDescriptors ( a ) )
79+ return descriptors
6380 . GroupBy ( d => d . Id )
6481 . OrderBy ( g => g . Key , StringComparer . CurrentCulture )
6582 . Select ( g =>
@@ -72,36 +89,4 @@ IEnumerable<AnalyzerSetting> ToAnalyzerSetting(IEnumerable<DiagnosticAnalyzer> a
7289 } ) ;
7390 }
7491 }
75-
76- private sealed class DiagnosticAnalyzerComparer : IEqualityComparer < DiagnosticAnalyzer >
77- {
78- public static readonly DiagnosticAnalyzerComparer Instance = new ( ) ;
79-
80- public bool Equals ( DiagnosticAnalyzer ? x , DiagnosticAnalyzer ? y )
81- => ( x , y ) switch
82- {
83- ( null , null ) => true ,
84- ( null , _ ) => false ,
85- ( _, null ) => false ,
86- _ => GetAnalyzerIdAndLastWriteTime ( x ) == GetAnalyzerIdAndLastWriteTime ( y )
87- } ;
88-
89- public int GetHashCode ( DiagnosticAnalyzer obj ) => GetAnalyzerIdAndLastWriteTime ( obj ) . GetHashCode ( ) ;
90-
91- private static ( string analyzerId , DateTime lastWriteTime ) GetAnalyzerIdAndLastWriteTime ( DiagnosticAnalyzer analyzer )
92- {
93- // Get the unique ID for given diagnostic analyzer.
94- // note that we also put version stamp so that we can detect changed analyzer.
95- var typeInfo = analyzer . GetType ( ) . GetTypeInfo ( ) ;
96- return ( analyzer . GetAnalyzerId ( ) , GetAnalyzerLastWriteTime ( typeInfo . Assembly . Location ) ) ;
97- }
98-
99- private static DateTime GetAnalyzerLastWriteTime ( string path )
100- {
101- if ( path == null || ! File . Exists ( path ) )
102- return default ;
103-
104- return File . GetLastWriteTimeUtc ( path ) ;
105- }
106- }
10792}
0 commit comments