/// <summary> /// Return all diagnostics that belong to given project for the given StateSets (analyzers) either from cache or by calculating them /// </summary> public async Task <ProjectAnalysisData> GetProjectAnalysisDataAsync( CompilationWithAnalyzers analyzerDriverOpt, Project project, IEnumerable <StateSet> stateSets, bool forceAnalyzerRun, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.Diagnostics_ProjectDiagnostic, GetProjectLogMessage, project, stateSets, cancellationToken)) { try { // PERF: we need to flip this to false when we do actual diffing. var avoidLoadingData = true; var version = await GetDiagnosticVersionAsync(project, cancellationToken).ConfigureAwait(false); var existingData = await ProjectAnalysisData.CreateAsync(project, stateSets, avoidLoadingData, cancellationToken).ConfigureAwait(false); // we can't return here if we have open file only analyzers sine saved data for open file only analyzer // is wrong. (since it only contains info on open files rather than whole project) if (existingData.Version == version && !analyzerDriverOpt.ContainsOpenFileOnlyAnalyzers(project.Solution.Workspace)) { return(existingData); } // perf optimization. check whether we want to analyze this project or not. if (!FullAnalysisEnabled(project, forceAnalyzerRun)) { Logger.Log(FunctionId.Diagnostics_ProjectDiagnostic, p => $"FSA off ({p.FilePath ?? p.Name})", project); return(new ProjectAnalysisData(project.Id, VersionStamp.Default, existingData.Result, ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty)); } var result = await ComputeDiagnosticsAsync(analyzerDriverOpt, project, stateSets, forceAnalyzerRun, existingData.Result, cancellationToken).ConfigureAwait(false); // if project is not loaded successfully, get rid of any semantic errors from compiler analyzer // * NOTE * previously when project is not loaded successfully, we actually dropped doing anything on the project, but now // we do everything but filter out some information. so on such projects, there will be some perf degradation. result = await FilterOutCompilerSemanticErrorsIfNeccessaryAsync(project, result, cancellationToken).ConfigureAwait(false); return(new ProjectAnalysisData(project.Id, version, existingData.Result, result)); } catch (Exception e) when(FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } } }