/// <summary> /// Get diagnostics for the given document. /// /// This is a simple API to get all diagnostics for the given document. /// /// The intended audience for this API is for ones that pefer simplicity over performance such as document that belong to misc project. /// this doesn't cache nor use cache for anything. it will re-caculate new diagnostics every time for the given document. /// it will not persist any data on disk nor use OOP to calcuate the data. /// /// This should never be used when performance is a big concern. for such context, use much complex API from IDiagnosticAnalyzerService /// that provide all kinds of knobs/cache/persistency/OOP to get better perf over simplicity. /// </summary> private async Task <ImmutableArray <DiagnosticData> > GetDiagnosticsAsync( TextDocument document, AnalysisKind kind, CancellationToken cancellationToken) { var loadDiagnostic = await document.State.GetLoadDiagnosticAsync(cancellationToken).ConfigureAwait(false); if (loadDiagnostic != null) { return(ImmutableArray.Create(DiagnosticData.Create(loadDiagnostic, document))); } var project = document.Project; var analyzers = GetAnalyzers(project.Solution.State.Analyzers, project); if (analyzers.IsEmpty) { return(ImmutableArray <DiagnosticData> .Empty); } var compilationWithAnalyzers = await AnalyzerHelper.CreateCompilationWithAnalyzersAsync( project, analyzers, includeSuppressedDiagnostics : false, cancellationToken).ConfigureAwait(false); var analysisScope = new DocumentAnalysisScope(document, span: null, analyzers, kind); var executor = new DocumentAnalysisExecutor(analysisScope, compilationWithAnalyzers, _service._analyzerInfoCache); var builder = ArrayBuilder <DiagnosticData> .GetInstance(); foreach (var analyzer in analyzers) { builder.AddRange(await executor.ComputeDiagnosticsAsync(analyzer, cancellationToken).ConfigureAwait(false)); } return(builder.ToImmutableAndFree()); }
private async Task <ImmutableArray <DiagnosticData> > GetDiagnosticsAsync( TextDocument document, AnalysisKind kind, CancellationToken cancellationToken) { var loadDiagnostic = await document.State.GetLoadDiagnosticAsync(cancellationToken).ConfigureAwait(false); if (loadDiagnostic != null) { return(ImmutableArray.Create(DiagnosticData.Create(loadDiagnostic, document))); } var project = document.Project; var analyzers = GetAnalyzers(project.Solution.State.Analyzers, project); if (analyzers.IsEmpty) { return(ImmutableArray <DiagnosticData> .Empty); } var crashOnAnalyzerException = _service._globalOptions.GetOption(InternalDiagnosticsOptions.CrashOnAnalyzerException); var compilationWithAnalyzers = await DocumentAnalysisExecutor.CreateCompilationWithAnalyzersAsync( project, analyzers, includeSuppressedDiagnostics : false, crashOnAnalyzerException, cancellationToken).ConfigureAwait(false); var analysisScope = new DocumentAnalysisScope(document, span: null, analyzers, kind); var executor = new DocumentAnalysisExecutor(analysisScope, compilationWithAnalyzers, _diagnosticAnalyzerRunner, logPerformanceInfo: true); using var _ = ArrayBuilder <DiagnosticData> .GetInstance(out var builder); foreach (var analyzer in analyzers) { builder.AddRange(await executor.ComputeDiagnosticsAsync(analyzer, cancellationToken).ConfigureAwait(false)); } return(builder.ToImmutable()); }