@@ -8,39 +8,14 @@ namespace AsyncUsageAnalyzers.Helpers
8
8
using System . Collections . Generic ;
9
9
using System . Collections . Immutable ;
10
10
using System . Linq ;
11
- using System . Reflection ;
12
11
using System . Threading ;
13
12
using System . Threading . Tasks ;
14
13
using Microsoft . CodeAnalysis ;
15
14
using Microsoft . CodeAnalysis . CodeFixes ;
16
15
using Microsoft . CodeAnalysis . Diagnostics ;
17
- using Microsoft . CodeAnalysis . Text ;
18
16
19
17
internal static class FixAllContextHelper
20
18
{
21
- private static readonly ImmutableDictionary < string , ImmutableArray < Type > > DiagnosticAnalyzers = GetAllAnalyzers ( ) ;
22
-
23
- private static readonly Func < CompilationWithAnalyzers , SyntaxTree , CancellationToken , Task < ImmutableArray < Diagnostic > > > GetAnalyzerSyntaxDiagnosticsAsync ;
24
- private static readonly Func < CompilationWithAnalyzers , SemanticModel , TextSpan ? , CancellationToken , Task < ImmutableArray < Diagnostic > > > GetAnalyzerSemanticDiagnosticsAsync ;
25
- private static readonly Func < CompilationWithAnalyzers , ImmutableArray < DiagnosticAnalyzer > , CancellationToken , Task < ImmutableArray < Diagnostic > > > GetAnalyzerCompilationDiagnosticsAsync ;
26
-
27
- static FixAllContextHelper ( )
28
- {
29
- Version roslynVersion = typeof ( AdditionalText ) . GetTypeInfo ( ) . Assembly . GetName ( ) . Version ;
30
- bool avoidGetAnalyzerDiagnosticsAsync = roslynVersion >= new Version ( 1 , 1 , 0 , 0 ) && roslynVersion < new Version ( 1 , 2 , 0 , 0 ) ;
31
- if ( avoidGetAnalyzerDiagnosticsAsync )
32
- {
33
- var methodInfo = typeof ( CompilationWithAnalyzers ) . GetRuntimeMethod ( nameof ( GetAnalyzerSyntaxDiagnosticsAsync ) , new [ ] { typeof ( SyntaxTree ) , typeof ( CancellationToken ) } ) ;
34
- GetAnalyzerSyntaxDiagnosticsAsync = ( Func < CompilationWithAnalyzers , SyntaxTree , CancellationToken , Task < ImmutableArray < Diagnostic > > > ) methodInfo ? . CreateDelegate ( typeof ( Func < CompilationWithAnalyzers , SyntaxTree , CancellationToken , Task < ImmutableArray < Diagnostic > > > ) ) ;
35
-
36
- methodInfo = typeof ( CompilationWithAnalyzers ) . GetRuntimeMethod ( nameof ( GetAnalyzerSemanticDiagnosticsAsync ) , new [ ] { typeof ( SemanticModel ) , typeof ( TextSpan ? ) , typeof ( CancellationToken ) } ) ;
37
- GetAnalyzerSemanticDiagnosticsAsync = ( Func < CompilationWithAnalyzers , SemanticModel , TextSpan ? , CancellationToken , Task < ImmutableArray < Diagnostic > > > ) methodInfo ? . CreateDelegate ( typeof ( Func < CompilationWithAnalyzers , SemanticModel , TextSpan ? , CancellationToken , Task < ImmutableArray < Diagnostic > > > ) ) ;
38
-
39
- methodInfo = typeof ( CompilationWithAnalyzers ) . GetRuntimeMethod ( nameof ( GetAnalyzerCompilationDiagnosticsAsync ) , new [ ] { typeof ( ImmutableArray < DiagnosticAnalyzer > ) , typeof ( CancellationToken ) } ) ;
40
- GetAnalyzerCompilationDiagnosticsAsync = ( Func < CompilationWithAnalyzers , ImmutableArray < DiagnosticAnalyzer > , CancellationToken , Task < ImmutableArray < Diagnostic > > > ) methodInfo ? . CreateDelegate ( typeof ( Func < CompilationWithAnalyzers , ImmutableArray < DiagnosticAnalyzer > , CancellationToken , Task < ImmutableArray < Diagnostic > > > ) ) ;
41
- }
42
- }
43
-
44
19
public static async Task < ImmutableDictionary < Document , ImmutableArray < Diagnostic > > > GetDocumentDiagnosticsToFixAsync ( FixAllContext fixAllContext )
45
20
{
46
21
var allDiagnostics = ImmutableArray < Diagnostic > . Empty ;
@@ -146,87 +121,7 @@ public static async Task<ImmutableDictionary<Project, ImmutableArray<Diagnostic>
146
121
147
122
public static async Task < ImmutableArray < Diagnostic > > GetAllDiagnosticsAsync ( Compilation compilation , CompilationWithAnalyzers compilationWithAnalyzers , ImmutableArray < DiagnosticAnalyzer > analyzers , IEnumerable < Document > documents , bool includeCompilerDiagnostics , CancellationToken cancellationToken )
148
123
{
149
- if ( GetAnalyzerSyntaxDiagnosticsAsync == null || GetAnalyzerSemanticDiagnosticsAsync == null )
150
- {
151
- // In everything except Roslyn 1.1, we use GetAllDiagnosticsAsync and return the result.
152
- var allDiagnostics = await compilationWithAnalyzers . GetAllDiagnosticsAsync ( ) . ConfigureAwait ( false ) ;
153
- return allDiagnostics ;
154
- }
155
-
156
- compilationWithAnalyzers . Compilation . GetDeclarationDiagnostics ( cancellationToken ) ;
157
-
158
- // Note that the following loop to obtain syntax and semantic diagnostics for each document cannot operate
159
- // on parallel due to our use of a single CompilationWithAnalyzers instance.
160
- var diagnostics = ImmutableArray . CreateBuilder < Diagnostic > ( ) ;
161
- foreach ( var document in documents )
162
- {
163
- var syntaxTree = await document . GetSyntaxTreeAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
164
- var syntaxDiagnostics = await GetAnalyzerSyntaxDiagnosticsAsync ( compilationWithAnalyzers , syntaxTree , cancellationToken ) . ConfigureAwait ( false ) ;
165
- diagnostics . AddRange ( syntaxDiagnostics ) ;
166
-
167
- var semanticModel = await document . GetSemanticModelAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
168
- var semanticDiagnostics = await GetAnalyzerSemanticDiagnosticsAsync ( compilationWithAnalyzers , semanticModel , default ( TextSpan ? ) , cancellationToken ) . ConfigureAwait ( false ) ;
169
- diagnostics . AddRange ( semanticDiagnostics ) ;
170
- }
171
-
172
- foreach ( var analyzer in analyzers )
173
- {
174
- diagnostics . AddRange ( await GetAnalyzerCompilationDiagnosticsAsync ( compilationWithAnalyzers , ImmutableArray . Create ( analyzer ) , cancellationToken ) . ConfigureAwait ( false ) ) ;
175
- }
176
-
177
- if ( includeCompilerDiagnostics )
178
- {
179
- // This is the special handling for cases where code fixes operate on warnings produced by the C#
180
- // compiler, as opposed to being created by specific analyzers.
181
- var compilerDiagnostics = compilation . GetDiagnostics ( cancellationToken ) ;
182
- diagnostics . AddRange ( compilerDiagnostics ) ;
183
- }
184
-
185
- return diagnostics . ToImmutable ( ) ;
186
- }
187
-
188
- private static ImmutableDictionary < string , ImmutableArray < Type > > GetAllAnalyzers ( )
189
- {
190
- Assembly assembly = typeof ( NoCodeFixAttribute ) . GetTypeInfo ( ) . Assembly ;
191
-
192
- var diagnosticAnalyzerType = typeof ( DiagnosticAnalyzer ) ;
193
-
194
- var analyzers = ImmutableDictionary . CreateBuilder < string , ImmutableArray < Type > > ( ) ;
195
-
196
- foreach ( var type in assembly . DefinedTypes )
197
- {
198
- if ( type . IsSubclassOf ( diagnosticAnalyzerType ) && ! type . IsAbstract )
199
- {
200
- Type analyzerType = type . AsType ( ) ;
201
- DiagnosticAnalyzer analyzer = ( DiagnosticAnalyzer ) Activator . CreateInstance ( analyzerType ) ;
202
- foreach ( var descriptor in analyzer . SupportedDiagnostics )
203
- {
204
- ImmutableArray < Type > types ;
205
- if ( analyzers . TryGetValue ( descriptor . Id , out types ) )
206
- {
207
- types = types . Add ( analyzerType ) ;
208
- }
209
- else
210
- {
211
- types = ImmutableArray . Create ( analyzerType ) ;
212
- }
213
-
214
- analyzers [ descriptor . Id ] = types ;
215
- }
216
- }
217
- }
218
-
219
- return analyzers . ToImmutable ( ) ;
220
- }
221
-
222
- private static ImmutableArray < DiagnosticAnalyzer > GetDiagnosticAnalyzersForContext ( FixAllContext fixAllContext )
223
- {
224
- return DiagnosticAnalyzers
225
- . Where ( x => fixAllContext . DiagnosticIds . Contains ( x . Key ) )
226
- . SelectMany ( x => x . Value )
227
- . Distinct ( )
228
- . Select ( type => ( DiagnosticAnalyzer ) Activator . CreateInstance ( type ) )
229
- . ToImmutableArray ( ) ;
124
+ return await compilationWithAnalyzers . GetAllDiagnosticsAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
230
125
}
231
126
232
127
/// <summary>
@@ -239,32 +134,7 @@ private static ImmutableArray<DiagnosticAnalyzer> GetDiagnosticAnalyzersForConte
239
134
/// successfully, the <see cref="Task{TResult}.Result"/> will contain the requested diagnostics.</returns>
240
135
private static async Task < ImmutableArray < Diagnostic > > GetAllDiagnosticsAsync ( FixAllContext fixAllContext , Project project )
241
136
{
242
- if ( GetAnalyzerSyntaxDiagnosticsAsync == null || GetAnalyzerSemanticDiagnosticsAsync == null )
243
- {
244
- return await fixAllContext . GetAllDiagnosticsAsync ( project ) . ConfigureAwait ( false ) ;
245
- }
246
-
247
- /*
248
- * The rest of this method is workaround code for issues with Roslyn 1.1...
249
- */
250
-
251
- var analyzers = GetDiagnosticAnalyzersForContext ( fixAllContext ) ;
252
-
253
- // Most code fixes in this project operate on diagnostics reported by analyzers in this project. However, a
254
- // few code fixes also operate on standard warnings produced by the C# compiler. Special handling is
255
- // required for the latter case since these warnings are not considered "analyzer diagnostics".
256
- bool includeCompilerDiagnostics = fixAllContext . DiagnosticIds . Any ( x => x . StartsWith ( "CS" , StringComparison . Ordinal ) ) ;
257
-
258
- // Use a single CompilationWithAnalyzers for the entire operation. This allows us to use the
259
- // GetDeclarationDiagnostics workaround for dotnet/roslyn#7446 a single time, rather than once per document.
260
- var compilation = await project . GetCompilationAsync ( fixAllContext . CancellationToken ) . ConfigureAwait ( false ) ;
261
- var compilationWithAnalyzers = compilation . WithAnalyzers ( analyzers , project . AnalyzerOptions , fixAllContext . CancellationToken ) ;
262
- ImmutableArray < Diagnostic > diagnostics = await GetAllDiagnosticsAsync ( compilation , compilationWithAnalyzers , analyzers , project . Documents , includeCompilerDiagnostics , fixAllContext . CancellationToken ) . ConfigureAwait ( false ) ;
263
-
264
- // Make sure to filter the results to the set requested for the Fix All operation, since analyzers can
265
- // report diagnostics with different IDs.
266
- diagnostics = diagnostics . RemoveAll ( x => ! fixAllContext . DiagnosticIds . Contains ( x . Id ) ) ;
267
- return diagnostics ;
137
+ return await fixAllContext . GetAllDiagnosticsAsync ( project ) . ConfigureAwait ( false ) ;
268
138
}
269
139
270
140
private static async Task < ImmutableDictionary < Document , ImmutableArray < Diagnostic > > > GetDocumentDiagnosticsToFixAsync (
0 commit comments