/// <summary> /// Return all cached local diagnostics (syntax, semantic) that belong to given document for the given StateSet (analyzer). /// Also returns empty diagnostics for suppressed analyzer. /// Returns null if the diagnostics need to be computed. /// </summary> private DocumentAnalysisData?TryGetCachedDocumentAnalysisData( TextDocument document, StateSet stateSet, AnalysisKind kind, VersionStamp version, BackgroundAnalysisScope analysisScope, bool isActiveDocument, bool isOpenDocument, bool isGeneratedRazorDocument, CancellationToken cancellationToken) { Debug.Assert(isActiveDocument || isOpenDocument || isGeneratedRazorDocument); try { var state = stateSet.GetOrCreateActiveFileState(document.Id); var existingData = state.GetAnalysisData(kind); if (existingData.Version == version) { return(existingData); } // Perf optimization: Check whether analyzer is suppressed for project or document and avoid getting diagnostics if suppressed. if (!DocumentAnalysisExecutor.IsAnalyzerEnabledForProject(stateSet.Analyzer, document.Project, GlobalOptions) || !IsAnalyzerEnabledForDocument(stateSet.Analyzer, analysisScope, isActiveDocument, isOpenDocument, isGeneratedRazorDocument)) { return(new DocumentAnalysisData(version, existingData.Items, ImmutableArray <DiagnosticData> .Empty)); } return(null); } catch (Exception e) when(FatalError.ReportAndPropagateUnlessCanceled(e, cancellationToken)) { throw ExceptionUtilities.Unreachable; }
private bool ShouldIncludeStateSet(Project project, StateSet stateSet) { if (!DocumentAnalysisExecutor.IsAnalyzerEnabledForProject(stateSet.Analyzer, project, Owner.GlobalOptions)) { return(false); } if (_diagnosticIds != null && Owner.DiagnosticAnalyzerInfoCache.GetDiagnosticDescriptors(stateSet.Analyzer).All(d => !_diagnosticIds.Contains(d.Id))) { return(false); } return(true); }
private async Task AnalyzeProjectAsync(Project project, bool forceAnalyzerRun, CancellationToken cancellationToken) { try { var stateSets = GetStateSetsForFullSolutionAnalysis(_stateManager.GetOrUpdateStateSets(project), project); // get driver only with active analyzers. var ideOptions = AnalyzerService.GlobalOptions.GetIdeAnalyzerOptions(project); // PERF: get analyzers that are not suppressed and marked as open file only // this is perf optimization. we cache these result since we know the result. (no diagnostics) var activeAnalyzers = stateSets .Select(s => s.Analyzer) .Where(a => DocumentAnalysisExecutor.IsAnalyzerEnabledForProject(a, project, GlobalOptions) && !a.IsOpenFileOnly(ideOptions.CleanupOptions?.SimplifierOptions)); CompilationWithAnalyzers?compilationWithAnalyzers = null; if (forceAnalyzerRun || GlobalOptions.IsFullSolutionAnalysisEnabled(project.Language)) { compilationWithAnalyzers = await DocumentAnalysisExecutor.CreateCompilationWithAnalyzersAsync(project, ideOptions, activeAnalyzers, includeSuppressedDiagnostics : true, cancellationToken).ConfigureAwait(false); } var result = await GetProjectAnalysisDataAsync(compilationWithAnalyzers, project, ideOptions, stateSets, forceAnalyzerRun, cancellationToken).ConfigureAwait(false); if (result.OldResult == null) { RaiseProjectDiagnosticsIfNeeded(project, stateSets, result.Result); return; } // no cancellation after this point. // any analyzer that doesn't have result will be treated as returned empty set // which means we will remove those from error list foreach (var stateSet in stateSets) { var state = stateSet.GetOrCreateProjectState(project.Id); await state.SaveToInMemoryStorageAsync(project, result.GetResult(stateSet.Analyzer)).ConfigureAwait(false); } RaiseProjectDiagnosticsIfNeeded(project, stateSets, result.OldResult, result.Result); } catch (Exception e) when(FatalError.ReportAndPropagateUnlessCanceled(e, cancellationToken)) { throw ExceptionUtilities.Unreachable; } }
public static async Task <LatestDiagnosticsForSpanGetter> CreateAsync( DiagnosticIncrementalAnalyzer owner, Document document, TextSpan?range, bool blockForData, Func <string, IDisposable?>?addOperationScope, bool includeSuppressedDiagnostics, CodeActionRequestPriority priority, Func <string, bool>?shouldIncludeDiagnostic, CancellationToken cancellationToken) { var stateSets = owner._stateManager .GetOrCreateStateSets(document.Project).Where(s => DocumentAnalysisExecutor.IsAnalyzerEnabledForProject(s.Analyzer, document.Project, owner.GlobalOptions)); var crashOnAnalyzerException = owner.GlobalOptions.GetOption(InternalDiagnosticsOptions.CrashOnAnalyzerException); var compilationWithAnalyzers = await GetOrCreateCompilationWithAnalyzersAsync(document.Project, stateSets, includeSuppressedDiagnostics, crashOnAnalyzerException, cancellationToken).ConfigureAwait(false); return(new LatestDiagnosticsForSpanGetter( owner, compilationWithAnalyzers, document, stateSets, shouldIncludeDiagnostic, range, blockForData, addOperationScope, includeSuppressedDiagnostics, priority)); }