/// <summary> /// Returns true if the given analyzer has enabled concurrent execution by invoking <see cref="AnalysisContext.EnableConcurrentExecution"/>. /// </summary> public async Task <bool> IsConcurrentAnalyzerAsync(DiagnosticAnalyzer analyzer, AnalyzerExecutor analyzerExecutor) { var sessionScope = await GetSessionAnalysisScopeAsync(analyzer, analyzerExecutor).ConfigureAwait(false); return(sessionScope.IsConcurrentAnalyzer(analyzer)); }
public async ValueTask <AnalyzerActions> GetAnalyzerActionsAsync(DiagnosticAnalyzer analyzer, AnalyzerExecutor analyzerExecutor) { var sessionScope = await GetSessionAnalysisScopeAsync(analyzer, analyzerExecutor).ConfigureAwait(false); if (sessionScope.GetAnalyzerActions(analyzer).CompilationStartActionsCount > 0 && analyzerExecutor.Compilation != null) { var compilationScope = await GetCompilationAnalysisScopeAsync(analyzer, sessionScope, analyzerExecutor).ConfigureAwait(false); return(compilationScope.GetAnalyzerActions(analyzer)); } return(sessionScope.GetAnalyzerActions(analyzer)); }
public async ValueTask <AnalyzerActions> GetPerSymbolAnalyzerActionsAsync(ISymbol symbol, DiagnosticAnalyzer analyzer, AnalyzerExecutor analyzerExecutor) { var analyzerActions = await GetAnalyzerActionsAsync(analyzer, analyzerExecutor).ConfigureAwait(false); if (analyzerActions.SymbolStartActionsCount > 0) { var filteredSymbolStartActions = getFilteredActionsByKind(analyzerActions.SymbolStartActions); if (filteredSymbolStartActions.Length > 0) { var symbolScope = await GetSymbolAnalysisScopeAsync(symbol, analyzer, filteredSymbolStartActions, analyzerExecutor).ConfigureAwait(false); return(symbolScope.GetAnalyzerActions(analyzer)); } } return(AnalyzerActions.Empty); ImmutableArray <SymbolStartAnalyzerAction> getFilteredActionsByKind(ImmutableArray <SymbolStartAnalyzerAction> symbolStartActions) { ArrayBuilder <SymbolStartAnalyzerAction> filteredActionsBuilderOpt = null; for (int i = 0; i < symbolStartActions.Length; i++) { var symbolStartAction = symbolStartActions[i]; if (symbolStartAction.Kind != symbol.Kind) { if (filteredActionsBuilderOpt == null) { filteredActionsBuilderOpt = ArrayBuilder <SymbolStartAnalyzerAction> .GetInstance(); filteredActionsBuilderOpt.AddRange(symbolStartActions, i); } } else if (filteredActionsBuilderOpt != null) { filteredActionsBuilderOpt.Add(symbolStartAction); } } return(filteredActionsBuilderOpt != null?filteredActionsBuilderOpt.ToImmutableAndFree() : symbolStartActions); } }
/// <summary> /// Returns true if all the diagnostics that can be produced by this analyzer are suppressed through options. /// </summary> internal bool IsDiagnosticAnalyzerSuppressed( DiagnosticAnalyzer analyzer, CompilationOptions options, Func <DiagnosticAnalyzer, bool> isCompilerAnalyzer, AnalyzerExecutor analyzerExecutor) { if (isCompilerAnalyzer(analyzer)) { // Compiler analyzer must always be executed for compiler errors, which cannot be suppressed or filtered. return(false); } var supportedDiagnostics = GetSupportedDiagnosticDescriptors(analyzer, analyzerExecutor); var diagnosticOptions = options.SpecificDiagnosticOptions; foreach (var diag in supportedDiagnostics) { if (HasNotConfigurableTag(diag.CustomTags)) { if (diag.IsEnabledByDefault) { // Diagnostic descriptor is not configurable, so the diagnostics created through it cannot be suppressed. return(false); } else { // NotConfigurable disabled diagnostic can be ignored as it is never reported. continue; } } // Is this diagnostic suppressed by default (as written by the rule author) var isSuppressed = !diag.IsEnabledByDefault; // Compilation wide user settings from ruleset/nowarn/warnaserror overrides the analyzer author. if (diagnosticOptions.TryGetValue(diag.Id, out var severity)) { isSuppressed = severity == ReportDiagnostic.Suppress; } // Editorconfig user settings override compilation wide settings. if (isSuppressed && isEnabledWithAnalyzerConfigOptions(diag.Id, analyzerExecutor.Compilation)) { isSuppressed = false; } if (!isSuppressed) { return(false); } } if (analyzer is DiagnosticSuppressor suppressor) { foreach (var suppressionDescriptor in GetSupportedSuppressionDescriptors(suppressor, analyzerExecutor)) { if (!suppressionDescriptor.IsDisabled(options)) { return(false); } } } return(true);
static Task <HostSessionStartAnalysisScope> getSessionAnalysisScopeTaskSlow(AnalyzerExecutionContext context, AnalyzerExecutor executor) { return(Task.Run(() => { var sessionScope = new HostSessionStartAnalysisScope(); executor.ExecuteInitializeMethod(context._analyzer, sessionScope); return sessionScope; }, executor.CancellationToken)); }
internal bool IsSupportedDiagnostic(DiagnosticAnalyzer analyzer, Diagnostic diagnostic, Func <DiagnosticAnalyzer, bool> isCompilerAnalyzer, AnalyzerExecutor analyzerExecutor) { // Avoid realizing all the descriptors for all compiler diagnostics by assuming that compiler analyzer doesn't report unsupported diagnostics. if (isCompilerAnalyzer(analyzer)) { return(true); } // Get all the supported diagnostics and scan them linearly to see if the reported diagnostic is supported by the analyzer. // The linear scan is okay, given that this runs only if a diagnostic is being reported and a given analyzer is quite unlikely to have hundreds of thousands of supported diagnostics. var supportedDescriptors = GetSupportedDiagnosticDescriptors(analyzer, analyzerExecutor); foreach (var descriptor in supportedDescriptors) { if (descriptor.Id.Equals(diagnostic.Id, StringComparison.OrdinalIgnoreCase)) { return(true); } } return(false); }
/// <summary> /// Returns <see cref="GeneratedCodeAnalysisFlags"/> for the given analyzer. /// If an analyzer hasn't configured generated code analysis, returns <see cref="AnalyzerDriver.DefaultGeneratedCodeAnalysisFlags"/>. /// </summary> public async Task <GeneratedCodeAnalysisFlags> GetGeneratedCodeAnalysisFlagsAsync(DiagnosticAnalyzer analyzer, AnalyzerExecutor analyzerExecutor) { var sessionScope = await GetSessionAnalysisScopeAsync(analyzer, analyzerExecutor).ConfigureAwait(false); return(sessionScope.GetGeneratedCodeAnalysisFlags(analyzer)); }
/// <summary> /// Returns true if analyzer registered a compilation start action during <see cref="DiagnosticAnalyzer.Initialize(AnalysisContext)"/> /// which registered a compilation end action and at least one other analyzer action, that the end action depends upon. /// </summary> public async Task <bool> GetAnalyzerHasDependentCompilationEndAsync(DiagnosticAnalyzer analyzer, AnalyzerExecutor analyzerExecutor) { var sessionScope = await GetSessionAnalysisScopeAsync(analyzer, analyzerExecutor).ConfigureAwait(false); if (sessionScope.CompilationStartActions.Length > 0 && analyzerExecutor.Compilation != null) { var compilationScope = await GetCompilationAnalysisScopeAsync(analyzer, sessionScope, analyzerExecutor).ConfigureAwait(false); var compilationActions = compilationScope.GetCompilationOnlyAnalyzerActions(analyzer); return(compilationActions != null && compilationActions.CompilationEndActionsCount > 0 && (compilationActions.CodeBlockEndActionsCount > 0 || compilationActions.CodeBlockStartActionsCount > 0 || compilationActions.SemanticModelActionsCount > 0 || compilationActions.SymbolActionsCount > 0 || compilationActions.SyntaxNodeActionsCount > 0 || compilationActions.SyntaxTreeActionsCount > 0)); } return(false); }
public Task <HostSessionStartAnalysisScope> GetSessionAnalysisScopeTask(DiagnosticAnalyzer analyzer, AnalyzerExecutor analyzerExecutor) { lock (_gate) { Task <HostSessionStartAnalysisScope> task; if (_lazySessionScopeTask != null) { return(_lazySessionScopeTask); } task = Task.Run(() => { HostSessionStartAnalysisScope sessionScope = new HostSessionStartAnalysisScope(); analyzerExecutor.ExecuteInitializeMethod(analyzer, sessionScope); return(sessionScope); }, analyzerExecutor.CancellationToken); _lazySessionScopeTask = task; return(task); } }
public ImmutableArray <DiagnosticDescriptor> GetOrComputeDescriptors(DiagnosticAnalyzer analyzer, AnalyzerExecutor analyzerExecutor) { lock (_gate) { if (!_lazyDescriptors.IsDefault) { return(_lazyDescriptors); } } // Otherwise, compute the value. // We do so outside the lock statement as we are calling into user code, which may be a long running operation. ImmutableArray <DiagnosticDescriptor> descriptors = ComputeDescriptors(analyzer, analyzerExecutor); lock (_gate) { // Check if another thread already stored the computed value. if (!_lazyDescriptors.IsDefault) { // If so, we return the stored value. descriptors = _lazyDescriptors; } else { // Otherwise, store the value computed here. _lazyDescriptors = descriptors; } } return(descriptors); }