@@ -8,39 +8,14 @@ namespace AsyncUsageAnalyzers.Helpers
88 using System . Collections . Generic ;
99 using System . Collections . Immutable ;
1010 using System . Linq ;
11- using System . Reflection ;
1211 using System . Threading ;
1312 using System . Threading . Tasks ;
1413 using Microsoft . CodeAnalysis ;
1514 using Microsoft . CodeAnalysis . CodeFixes ;
1615 using Microsoft . CodeAnalysis . Diagnostics ;
17- using Microsoft . CodeAnalysis . Text ;
1816
1917 internal static class FixAllContextHelper
2018 {
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-
4419 public static async Task < ImmutableDictionary < Document , ImmutableArray < Diagnostic > > > GetDocumentDiagnosticsToFixAsync ( FixAllContext fixAllContext )
4520 {
4621 var allDiagnostics = ImmutableArray < Diagnostic > . Empty ;
@@ -146,87 +121,7 @@ public static async Task<ImmutableDictionary<Project, ImmutableArray<Diagnostic>
146121
147122 public static async Task < ImmutableArray < Diagnostic > > GetAllDiagnosticsAsync ( Compilation compilation , CompilationWithAnalyzers compilationWithAnalyzers , ImmutableArray < DiagnosticAnalyzer > analyzers , IEnumerable < Document > documents , bool includeCompilerDiagnostics , CancellationToken cancellationToken )
148123 {
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 ) ;
230125 }
231126
232127 /// <summary>
@@ -239,32 +134,7 @@ private static ImmutableArray<DiagnosticAnalyzer> GetDiagnosticAnalyzersForConte
239134 /// successfully, the <see cref="Task{TResult}.Result"/> will contain the requested diagnostics.</returns>
240135 private static async Task < ImmutableArray < Diagnostic > > GetAllDiagnosticsAsync ( FixAllContext fixAllContext , Project project )
241136 {
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 ) ;
268138 }
269139
270140 private static async Task < ImmutableDictionary < Document , ImmutableArray < Diagnostic > > > GetDocumentDiagnosticsToFixAsync (
0 commit comments