public static ImmutableDictionary<DiagnosticAnalyzer, DiagnosticAnalysisResultBuilder> ToResultBuilderMap( this AnalysisResult analysisResult, Project project, VersionStamp version, Compilation compilation, IEnumerable<DiagnosticAnalyzer> analyzers, CancellationToken cancellationToken) { var builder = ImmutableDictionary.CreateBuilder<DiagnosticAnalyzer, DiagnosticAnalysisResultBuilder>(); ImmutableArray<Diagnostic> diagnostics; ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>> diagnosticsByAnalyzerMap; foreach (var analyzer in analyzers) { cancellationToken.ThrowIfCancellationRequested(); var result = new DiagnosticAnalysisResultBuilder(project, version); foreach (var tree in analysisResult.SyntaxDiagnostics.Keys) { if (analysisResult.SyntaxDiagnostics.TryGetValue(tree, out diagnosticsByAnalyzerMap) && diagnosticsByAnalyzerMap.TryGetValue(analyzer, out diagnostics)) { Contract.Requires(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilation).Count()); result.AddSyntaxDiagnostics(tree, diagnostics); } } foreach (var tree in analysisResult.SemanticDiagnostics.Keys) { if (analysisResult.SemanticDiagnostics.TryGetValue(tree, out diagnosticsByAnalyzerMap) && diagnosticsByAnalyzerMap.TryGetValue(analyzer, out diagnostics)) { Contract.Requires(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilation).Count()); result.AddSemanticDiagnostics(tree, diagnostics); } } if (analysisResult.CompilationDiagnostics.TryGetValue(analyzer, out diagnostics)) { Contract.Requires(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilation).Count()); result.AddCompilationDiagnostics(diagnostics); } builder.Add(analyzer, result); } return builder.ToImmutable(); }
private async Task<ImmutableDictionary<DiagnosticAnalyzer, DiagnosticAnalysisResult>> MergeProjectDiagnosticAnalyzerDiagnosticsAsync( Project project, IEnumerable<StateSet> stateSets, Compilation compilationOpt, ImmutableDictionary<DiagnosticAnalyzer, DiagnosticAnalysisResult> result, CancellationToken cancellationToken) { try { // check whether there is IDE specific project diagnostic analyzer var ideAnalyzers = stateSets.Select(s => s.Analyzer).Where(a => a is ProjectDiagnosticAnalyzer || a is DocumentDiagnosticAnalyzer).ToImmutableArrayOrEmpty(); if (ideAnalyzers.Length <= 0) { return result; } // create result map var version = await GetDiagnosticVersionAsync(project, cancellationToken).ConfigureAwait(false); var builder = new DiagnosticAnalysisResultBuilder(project, version); foreach (var analyzer in ideAnalyzers) { var documentAnalyzer = analyzer as DocumentDiagnosticAnalyzer; if (documentAnalyzer != null) { foreach (var document in project.Documents) { if (document.SupportsSyntaxTree) { var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); builder.AddSyntaxDiagnostics(tree, await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(document, documentAnalyzer, AnalysisKind.Syntax, compilationOpt, cancellationToken).ConfigureAwait(false)); builder.AddSemanticDiagnostics(tree, await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(document, documentAnalyzer, AnalysisKind.Semantic, compilationOpt, cancellationToken).ConfigureAwait(false)); } else { builder.AddExternalSyntaxDiagnostics(document.Id, await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(document, documentAnalyzer, AnalysisKind.Syntax, compilationOpt, cancellationToken).ConfigureAwait(false)); builder.AddExternalSemanticDiagnostics(document.Id, await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(document, documentAnalyzer, AnalysisKind.Semantic, compilationOpt, cancellationToken).ConfigureAwait(false)); } } } var projectAnalyzer = analyzer as ProjectDiagnosticAnalyzer; if (projectAnalyzer != null) { builder.AddCompilationDiagnostics(await ComputeProjectDiagnosticAnalyzerDiagnosticsAsync(project, projectAnalyzer, compilationOpt, cancellationToken).ConfigureAwait(false)); } // merge the result to existing one. // there can be existing one from compiler driver with empty set. overwrite it with // ide one. result = result.SetItem(analyzer, new DiagnosticAnalysisResult(builder)); } return result; } catch (Exception e) when (FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } }