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); foreach (var analyzer in ideAnalyzers) { var builder = new DiagnosticAnalysisResultBuilder(project, version); if (analyzer is DocumentDiagnosticAnalyzer documentAnalyzer) { 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)); } } } if (analyzer is ProjectDiagnosticAnalyzer projectAnalyzer) { 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, DiagnosticAnalysisResult.CreateFromBuilder(builder)); } return(result); } catch (Exception e) when(FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } }
private async Task <ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> > MergeProjectDiagnosticAnalyzerDiagnosticsAsync( Project project, ImmutableArray <DiagnosticAnalyzer> ideAnalyzers, Compilation?compilation, ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> result, CancellationToken cancellationToken) { try { // create result map var version = await GetDiagnosticVersionAsync(project, cancellationToken).ConfigureAwait(false); foreach (var analyzer in ideAnalyzers) { var builder = new DiagnosticAnalysisResultBuilder(project, version); if (analyzer is DocumentDiagnosticAnalyzer documentAnalyzer) { foreach (var document in project.Documents) { var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); if (tree != null) { builder.AddSyntaxDiagnostics(tree, await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(document, documentAnalyzer, AnalysisKind.Syntax, compilation, cancellationToken).ConfigureAwait(false)); builder.AddSemanticDiagnostics(tree, await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(document, documentAnalyzer, AnalysisKind.Semantic, compilation, cancellationToken).ConfigureAwait(false)); } else { builder.AddExternalSyntaxDiagnostics(document.Id, await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(document, documentAnalyzer, AnalysisKind.Syntax, compilation, cancellationToken).ConfigureAwait(false)); builder.AddExternalSemanticDiagnostics(document.Id, await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(document, documentAnalyzer, AnalysisKind.Semantic, compilation, cancellationToken).ConfigureAwait(false)); } } } if (analyzer is ProjectDiagnosticAnalyzer projectAnalyzer) { builder.AddCompilationDiagnostics(await ComputeProjectDiagnosticAnalyzerDiagnosticsAsync(project, projectAnalyzer, compilation, 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, DiagnosticAnalysisResult.CreateFromBuilder(builder)); } return(result); } catch (Exception e) when(FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } }
private async Task <DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> > AnalyzeInProcAsync( CompilationWithAnalyzers compilation, Project project, RemoteHostClient?client, CancellationToken cancellationToken) { Debug.Assert(compilation.Analyzers.Length != 0); var version = await GetDiagnosticVersionAsync(project, cancellationToken).ConfigureAwait(false); // PERF: Run all analyzers at once using the new GetAnalysisResultAsync API. var analysisResult = await compilation.GetAnalysisResultAsync(cancellationToken).ConfigureAwait(false); // if remote host is there, report performance data var asyncToken = _asyncOperationListener.BeginAsyncOperation(nameof(AnalyzeInProcAsync)); var _ = FireAndForgetReportAnalyzerPerformanceAsync(project, client, analysisResult, cancellationToken).CompletesAsyncOperation(asyncToken); // get compiler result builder map var builderMap = analysisResult.ToResultBuilderMap(project, version, compilation.Compilation, compilation.Analyzers, cancellationToken); return(DiagnosticAnalysisResultMap.Create( builderMap.ToImmutableDictionary(kv => kv.Key, kv => DiagnosticAnalysisResult.CreateFromBuilder(kv.Value)), analysisResult.AnalyzerTelemetryInfo)); }
private async Task <DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> > AnalyzeInProcAsync( DocumentAnalysisScope?documentAnalysisScope, Project project, CompilationWithAnalyzers compilationWithAnalyzers, RemoteHostClient?client, bool logPerformanceInfo, bool getTelemetryInfo, CancellationToken cancellationToken) { var version = await DiagnosticIncrementalAnalyzer.GetDiagnosticVersionAsync(project, cancellationToken).ConfigureAwait(false); var(analysisResult, additionalPragmaSuppressionDiagnostics) = await compilationWithAnalyzers.GetAnalysisResultAsync( documentAnalysisScope, project, AnalyzerInfoCache, cancellationToken).ConfigureAwait(false); if (logPerformanceInfo) { // if remote host is there, report performance data var asyncToken = _asyncOperationListener.BeginAsyncOperation(nameof(AnalyzeInProcAsync)); var _ = FireAndForgetReportAnalyzerPerformanceAsync(documentAnalysisScope, project, client, analysisResult, cancellationToken).CompletesAsyncOperation(asyncToken); } var analyzers = documentAnalysisScope?.Analyzers ?? compilationWithAnalyzers.Analyzers; var skippedAnalyzersInfo = project.GetSkippedAnalyzersInfo(AnalyzerInfoCache); // get compiler result builder map var builderMap = await analysisResult.ToResultBuilderMapAsync( additionalPragmaSuppressionDiagnostics, documentAnalysisScope, project, version, compilationWithAnalyzers.Compilation, analyzers, skippedAnalyzersInfo, compilationWithAnalyzers.AnalysisOptions.ReportSuppressedDiagnostics, cancellationToken).ConfigureAwait(false); var result = builderMap.ToImmutableDictionary(kv => kv.Key, kv => DiagnosticAnalysisResult.CreateFromBuilder(kv.Value)); var telemetry = getTelemetryInfo ? analysisResult.AnalyzerTelemetryInfo : ImmutableDictionary <DiagnosticAnalyzer, AnalyzerTelemetryInfo> .Empty; return(DiagnosticAnalysisResultMap.Create(result, telemetry)); }
private static async Task <ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> > MergeProjectDiagnosticAnalyzerDiagnosticsAsync( Project project, ImmutableArray <DiagnosticAnalyzer> ideAnalyzers, Compilation?compilation, ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> result, CancellationToken cancellationToken) { try { var version = await GetDiagnosticVersionAsync(project, cancellationToken).ConfigureAwait(false); var(fileLoadAnalysisResult, failedDocuments) = await GetDocumentLoadFailuresAsync(project, version, cancellationToken).ConfigureAwait(false); result = result.SetItem(FileContentLoadAnalyzer.Instance, fileLoadAnalysisResult); foreach (var analyzer in ideAnalyzers) { var builder = new DiagnosticAnalysisResultBuilder(project, version); switch (analyzer) { case DocumentDiagnosticAnalyzer documentAnalyzer: foreach (var document in project.Documents) { // don't analyze documents whose content failed to load if (failedDocuments == null || !failedDocuments.Contains(document)) { var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); if (tree != null) { builder.AddSyntaxDiagnostics(tree, await AnalyzerHelper.ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(documentAnalyzer, document, AnalysisKind.Syntax, compilation, cancellationToken).ConfigureAwait(false)); builder.AddSemanticDiagnostics(tree, await AnalyzerHelper.ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(documentAnalyzer, document, AnalysisKind.Semantic, compilation, cancellationToken).ConfigureAwait(false)); } else { builder.AddExternalSyntaxDiagnostics(document.Id, await AnalyzerHelper.ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(documentAnalyzer, document, AnalysisKind.Syntax, compilation, cancellationToken).ConfigureAwait(false)); builder.AddExternalSemanticDiagnostics(document.Id, await AnalyzerHelper.ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(documentAnalyzer, document, AnalysisKind.Semantic, compilation, cancellationToken).ConfigureAwait(false)); } } } break; case ProjectDiagnosticAnalyzer projectAnalyzer: builder.AddCompilationDiagnostics(await AnalyzerHelper.ComputeProjectDiagnosticAnalyzerDiagnosticsAsync(projectAnalyzer, project, compilation, cancellationToken).ConfigureAwait(false)); break; } // 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, DiagnosticAnalysisResult.CreateFromBuilder(builder)); } return(result); } catch (Exception e) when(FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } }
private async Task <DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> > AnalyzeInProcAsync( CompilationWithAnalyzers analyzerDriver, Project project, RemoteHostClient client, CancellationToken cancellationToken) { if (analyzerDriver == null || analyzerDriver.Analyzers.Length == 0) { // quick bail out return(DiagnosticAnalysisResultMap.Create(ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty, ImmutableDictionary <DiagnosticAnalyzer, AnalyzerTelemetryInfo> .Empty)); } var version = await DiagnosticIncrementalAnalyzer.GetDiagnosticVersionAsync(project, cancellationToken).ConfigureAwait(false); // PERF: Run all analyzers at once using the new GetAnalysisResultAsync API. var analysisResult = await analyzerDriver.GetAnalysisResultAsync(cancellationToken).ConfigureAwait(false); // if remote host is there, report performance data var asyncToken = _owner?.Listener.BeginAsyncOperation(nameof(AnalyzeInProcAsync)); var _ = FireAndForgetReportAnalyzerPerformanceAsync(project, client, analysisResult, cancellationToken).CompletesAsyncOperation(asyncToken); // get compiler result builder map var builderMap = analysisResult.ToResultBuilderMap(project, version, analyzerDriver.Compilation, analyzerDriver.Analyzers, cancellationToken); return(DiagnosticAnalysisResultMap.Create(builderMap.ToImmutableDictionary(kv => kv.Key, kv => DiagnosticAnalysisResult.CreateFromBuilder(kv.Value)), analysisResult.AnalyzerTelemetryInfo)); }