public static ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResultBuilder> ToResultBuilderMap( this AnalysisResult analysisResult, Project project, VersionStamp version, Compilation compilation, IEnumerable <DiagnosticAnalyzer> analyzers, ISkippedAnalyzersInfo skippedAnalyzersInfo, CancellationToken cancellationToken) { var builder = ImmutableDictionary.CreateBuilder <DiagnosticAnalyzer, DiagnosticAnalysisResultBuilder>(); ImmutableArray <Diagnostic> diagnostics; foreach (var analyzer in analyzers) { cancellationToken.ThrowIfCancellationRequested(); if (skippedAnalyzersInfo.SkippedAnalyzers.Contains(analyzer)) { continue; } var result = new DiagnosticAnalysisResultBuilder(project, version); var diagnosticIdsToFilter = skippedAnalyzersInfo.FilteredDiagnosticIdsForAnalyzers.GetValueOrDefault( analyzer, ImmutableArray <string> .Empty); foreach (var(tree, diagnosticsByAnalyzerMap) in analysisResult.SyntaxDiagnostics) { if (diagnosticsByAnalyzerMap.TryGetValue(analyzer, out diagnostics)) { diagnostics = diagnostics.Filter(diagnosticIdsToFilter); Debug.Assert(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilation).Count()); result.AddSyntaxDiagnostics(tree, diagnostics); } } foreach (var(tree, diagnosticsByAnalyzerMap) in analysisResult.SemanticDiagnostics) { if (diagnosticsByAnalyzerMap.TryGetValue(analyzer, out diagnostics)) { diagnostics = diagnostics.Filter(diagnosticIdsToFilter); Debug.Assert(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilation).Count()); result.AddSemanticDiagnostics(tree, diagnostics); } } if (analysisResult.CompilationDiagnostics.TryGetValue(analyzer, out diagnostics)) { diagnostics = diagnostics.Filter(diagnosticIdsToFilter); Debug.Assert(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilation).Count()); result.AddCompilationDiagnostics(diagnostics); } builder.Add(analyzer, result); } return(builder.ToImmutable()); }
private ProjectAnalyzerStateSets( IReadOnlyList <AnalyzerReference> analyzerReferences, ImmutableDictionary <object, ImmutableArray <DiagnosticAnalyzer> > mapPerReferences, ImmutableDictionary <DiagnosticAnalyzer, StateSet> stateSetMap, ISkippedAnalyzersInfo skippedAnalyzersInfo) { AnalyzerReferences = analyzerReferences; MapPerReferences = mapPerReferences; StateSetMap = stateSetMap; SkippedAnalyzersInfo = skippedAnalyzersInfo; }
private async Task <DiagnosticAnalysisResultMap <string, DiagnosticAnalysisResultBuilder> > AnalyzeAsync( BidirectionalMap <string, DiagnosticAnalyzer> analyzerMap, ImmutableArray <DiagnosticAnalyzer> analyzers, ISkippedAnalyzersInfo skippedAnalyzersInfo, bool reportSuppressedDiagnostics, bool logAnalyzerExecutionTime, CancellationToken cancellationToken) { // flag that controls concurrency var useConcurrent = true; // get original compilation var compilation = await _project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); // fork compilation with concurrent build. this is okay since WithAnalyzers will fork compilation // anyway to attach event queue. this should make compiling compilation concurrent and make things // faster compilation = compilation.WithOptions(compilation.Options.WithConcurrentBuild(useConcurrent)); // TODO: can we support analyzerExceptionFilter in remote host? // right now, host doesn't support watson, we might try to use new NonFatal watson API? var analyzerOptions = new CompilationWithAnalyzersOptions( options: new WorkspaceAnalyzerOptions(_project.AnalyzerOptions, _project.Solution), onAnalyzerException: null, analyzerExceptionFilter: null, concurrentAnalysis: useConcurrent, logAnalyzerExecutionTime: logAnalyzerExecutionTime, reportSuppressedDiagnostics: reportSuppressedDiagnostics); var analyzerDriver = compilation.WithAnalyzers(analyzers, analyzerOptions); // PERF: Run all analyzers at once using the new GetAnalysisResultAsync API. var analysisResult = await analyzerDriver.GetAnalysisResultAsync(cancellationToken).ConfigureAwait(false); // record performance if tracker is available if (_performanceTracker != null) { // +1 to include project itself _performanceTracker.AddSnapshot(analysisResult.AnalyzerTelemetryInfo.ToAnalyzerPerformanceInfo(_analyzerInfoCache), _project.DocumentIds.Count + 1); } var builderMap = analysisResult.ToResultBuilderMap(_project, VersionStamp.Default, compilation, analysisResult.Analyzers, skippedAnalyzersInfo, cancellationToken); return(DiagnosticAnalysisResultMap.Create( builderMap.ToImmutableDictionary(kv => GetAnalyzerId(analyzerMap, kv.Key), kv => kv.Value), analysisResult.AnalyzerTelemetryInfo.ToImmutableDictionary(kv => GetAnalyzerId(analyzerMap, kv.Key), kv => kv.Value))); }