private bool IsCandidateForFullSolutionAnalysis(DiagnosticAnalyzer analyzer, Project project, ImmutableDictionary <string, ReportDiagnostic> analyzerConfigSpecialDiagnosticOptions) { // PERF: Don't query descriptors for compiler analyzer or file content load analyzer, always execute them. if (analyzer == FileContentLoadAnalyzer.Instance || analyzer.IsCompilerAnalyzer()) { return(true); } if (analyzer.IsBuiltInAnalyzer()) { // always return true for builtin analyzer. we can't use // descriptor check since many builtin analyzer always return // hidden descriptor regardless what descriptor it actually // return on runtime. they do this so that they can control // severity through option page rather than rule set editor. // this is special behavior only ide analyzer can do. we hope // once we support editorconfig fully, third party can use this // ability as well and we can remove this kind special treatment on builtin // analyzer. return(true); } if (analyzer is DiagnosticSuppressor) { // Always execute diagnostic suppressors. return(true); } // For most of analyzers, the number of diagnostic descriptors is small, so this should be cheap. var descriptors = DiagnosticAnalyzerInfoCache.GetDiagnosticDescriptors(analyzer); return(descriptors.Any(d => d.GetEffectiveSeverity(project.CompilationOptions !, analyzerConfigSpecialDiagnosticOptions) != ReportDiagnostic.Hidden)); }
private static bool CheckTelemetry(DiagnosticAnalyzerService service, DiagnosticAnalyzer analyzer) { if (analyzer.IsCompilerAnalyzer()) { return(true); } ImmutableArray <DiagnosticDescriptor> diagDescriptors; try { // SupportedDiagnostics is potentially user code and can throw an exception. diagDescriptors = service != null?service.GetDiagnosticDescriptors(analyzer) : analyzer.SupportedDiagnostics; } catch (Exception) { return(false); } if (diagDescriptors == null) { return(false); } // find if the first diagnostic in this analyzer allows telemetry DiagnosticDescriptor diagnostic = diagDescriptors.Length > 0 ? diagDescriptors[0] : null; return(diagnostic == null ? false : diagnostic.CustomTags.Any(t => t == WellKnownDiagnosticTags.Telemetry)); }
private static bool ShouldRunAnalyzerForStateType(DiagnosticAnalyzer analyzer, StateType stateTypeId, ImmutableHashSet <string> diagnosticIds = null, Func <DiagnosticAnalyzer, ImmutableArray <DiagnosticDescriptor> > getDescriptors = null) { // PERF: Don't query descriptors for compiler analyzer, always execute it for all state types. if (analyzer.IsCompilerAnalyzer()) { return(true); } if (diagnosticIds != null && getDescriptors(analyzer).All(d => !diagnosticIds.Contains(d.Id))) { return(false); } switch (stateTypeId) { case StateType.Syntax: return(analyzer.SupportsSyntaxDiagnosticAnalysis()); case StateType.Document: return(analyzer.SupportsSemanticDiagnosticAnalysis()); case StateType.Project: return(analyzer.SupportsProjectDiagnosticAnalysis()); default: throw ExceptionUtilities.Unreachable; } }
private bool MatchesPriority(DiagnosticAnalyzer analyzer) { // If caller isn't asking for prioritized result, then run all analyzers. if (_priority == CodeActionRequestPriority.None) { return(true); } // 'CodeActionRequestPriority.Lowest' is used for suppression/configuration fixes, // which requires all analyzer diagnostics. if (_priority == CodeActionRequestPriority.Lowest) { return(true); } // The compiler analyzer always counts for any priority. It's diagnostics may be fixed // by high pri or normal pri fixers. if (analyzer.IsCompilerAnalyzer()) { return(true); } var analyzerPriority = analyzer is IBuiltInAnalyzer { RequestPriority : var requestPriority }
private bool ShouldRunAnalyzerForClosedFile(CompilationOptions options, bool openedDocument, DiagnosticAnalyzer analyzer) { // we have opened document, doesnt matter if (openedDocument || analyzer.IsCompilerAnalyzer()) { return(true); } // PERF: Don't query descriptors for compiler analyzer, always execute it. if (analyzer.IsCompilerAnalyzer()) { return(true); } return(Owner.GetDiagnosticDescriptors(analyzer).Any(d => GetEffectiveSeverity(d, options) != ReportDiagnostic.Hidden)); }
static bool IsAnalyzerEnabledForDocument( DiagnosticAnalyzer analyzer, BackgroundAnalysisScope analysisScope, bool isActiveDocument, bool isOpenDocument, bool isGeneratedRazorDocument) { Debug.Assert(!isActiveDocument || isOpenDocument || isGeneratedRazorDocument); if (isGeneratedRazorDocument) { // This is a generated Razor document, and they always want all analyzer diagnostics. return(true); } if (analyzer.IsCompilerAnalyzer()) { // Compiler analyzer is treated specially. // It is executed for all documents (open and closed) for 'BackgroundAnalysisScope.FullSolution' // and executed for just open documents for other analysis scopes. return(analysisScope == BackgroundAnalysisScope.FullSolution || isOpenDocument); } else { return(analysisScope switch { // Analyzers are disabled for all documents. BackgroundAnalysisScope.None => false, // Analyzers are enabled for active document. BackgroundAnalysisScope.ActiveFile => isActiveDocument, // Analyzers are enabled for all open documents. BackgroundAnalysisScope.OpenFiles => isOpenDocument, // Analyzers are enabled for all documents. BackgroundAnalysisScope.FullSolution => true, _ => throw ExceptionUtilities.UnexpectedValue(analysisScope) });
static bool IsAnalyzerEnabledForDocument( DiagnosticAnalyzer analyzer, DocumentAnalysisData previousData, BackgroundAnalysisScope analysisScope, CompilerDiagnosticsScope compilerDiagnosticsScope, bool isActiveDocument, bool isVisibleDocument, bool isOpenDocument, bool isGeneratedRazorDocument) { Debug.Assert(!isActiveDocument || isOpenDocument || isGeneratedRazorDocument); if (isGeneratedRazorDocument) { // This is a generated Razor document, and they always want all analyzer diagnostics. return(true); } if (analyzer.IsCompilerAnalyzer()) { return(compilerDiagnosticsScope switch { // Compiler diagnostics are disabled for all documents. CompilerDiagnosticsScope.None => false, // Compiler diagnostics are enabled for visible documents and open documents which had errors/warnings in prior snapshot. CompilerDiagnosticsScope.VisibleFilesAndFilesWithPreviouslyReportedDiagnostics => isVisibleDocument || (isOpenDocument && !previousData.Items.IsEmpty), // Compiler diagnostics are enabled for all open documents. CompilerDiagnosticsScope.OpenFiles => isOpenDocument, // Compiler diagnostics are enabled for all documents. CompilerDiagnosticsScope.FullSolution => true, _ => throw ExceptionUtilities.UnexpectedValue(analysisScope) });
private static bool ShouldRunAnalyzerForStateType(DiagnosticAnalyzer analyzer, StateType stateTypeId, ImmutableHashSet<string> diagnosticIds = null, Func<DiagnosticAnalyzer, ImmutableArray<DiagnosticDescriptor>> getDescriptors = null) { // PERF: Don't query descriptors for compiler analyzer, always execute it for all state types. if (analyzer.IsCompilerAnalyzer()) { return true; } if (diagnosticIds != null && getDescriptors(analyzer).All(d => !diagnosticIds.Contains(d.Id))) { return false; } switch (stateTypeId) { case StateType.Syntax: return analyzer.SupportsSyntaxDiagnosticAnalysis(); case StateType.Document: return analyzer.SupportsSemanticDiagnosticAnalysis(); case StateType.Project: return analyzer.SupportsProjectDiagnosticAnalysis(); default: throw ExceptionUtilities.Unreachable; } }
private bool ShouldRunAnalyzerForClosedFile(DiagnosticAnalyzer analyzer, CompilationOptions options, bool openedDocument) { // we have opened document, doesn't matter // PERF: Don't query descriptors for compiler analyzer, always execute it. if (openedDocument || analyzer.IsCompilerAnalyzer()) { return true; } // most of analyzers, number of descriptor is quite small, so this should be cheap. return Owner.GetDiagnosticDescriptors(analyzer).Any(d => GetEffectiveSeverity(d, options) != ReportDiagnostic.Hidden); }
private static bool CheckTelemetry(DiagnosticAnalyzerService service, DiagnosticAnalyzer analyzer) { if (analyzer.IsCompilerAnalyzer()) { return true; } ImmutableArray<DiagnosticDescriptor> diagDescriptors; try { // SupportedDiagnostics is potentially user code and can throw an exception. diagDescriptors = service != null ? service.GetDiagnosticDescriptors(analyzer) : analyzer.SupportedDiagnostics; } catch (Exception) { return false; } if (diagDescriptors == null) { return false; } // find if the first diagnostic in this analyzer allows telemetry DiagnosticDescriptor diagnostic = diagDescriptors.Length > 0 ? diagDescriptors[0] : null; return diagnostic == null ? false : diagnostic.CustomTags.Any(t => t == WellKnownDiagnosticTags.Telemetry); }
private bool ShouldRunAnalyzerForClosedFile(CompilationOptions options, bool openedDocument, DiagnosticAnalyzer analyzer) { // we have opened document, doesnt matter if (openedDocument || analyzer.IsCompilerAnalyzer()) { return true; } // PERF: Don't query descriptors for compiler analyzer, always execute it. if (analyzer.IsCompilerAnalyzer()) { return true; } return Owner.GetDiagnosticDescriptors(analyzer).Any(d => GetEffectiveSeverity(d, options) != ReportDiagnostic.Hidden); }