diff --git a/Src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerDriver.cs b/Src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerDriver.cs index d9d81010f1c94947d943c4c25bcb5060eadb67f9..c55359568da36492c25c49061394e4fbb79e944a 100644 --- a/Src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerDriver.cs +++ b/Src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerDriver.cs @@ -765,30 +765,54 @@ protected override async Task AnalyzeDeclaringReferenceAsync(SymbolDeclaredCompi declaredNode.DescendantNodesAndSelf(descendIntoTrivia: true) : declaredNode.DescendantNodesAndSelf(n => !descendantDeclsToSkip.Contains(n), descendIntoTrivia: true).Except(descendantDeclsToSkip); - ExecuteSyntaxAnalyzers(nodesToAnalyze, analyzersByKind, semanticModel, - addDiagnostic, continueOnAnalyzerException, analyzerOptions, getKind, cancellationToken); + ExecuteSyntaxNodeActions(nodesToAnalyze, analyzersByKind, semanticModel, + analyzerOptions, addDiagnostic, continueOnAnalyzerException, getKind, cancellationToken); } /// - /// Executes the given code block analyzers on all the executable code blocks for each declaration info in . + /// Executes the given syntax node action on the given syntax node. + /// + /// Action to execute. + /// Syntax node to be analyzed. + /// SemanticModel to be used in the analysis. + /// Analyzer options. + /// Delegate to add diagnostics. + /// Predicate to decide if exceptions from the action should be handled or not. + /// Cancellation token. + public static void ExecuteSyntaxNodeAction( + SyntaxNodeAnalyzerAction syntaxNodeAction, + SyntaxNode node, + SemanticModel semanticModel, + AnalyzerOptions analyzerOptions, + Action addDiagnostic, + Func continueOnAnalyzerException, + CancellationToken cancellationToken) + { + var syntaxNodeContext = new SyntaxNodeAnalysisContext(node, semanticModel, analyzerOptions, addDiagnostic, cancellationToken); + // Catch Exception from action. + ExecuteAndCatchIfThrows(syntaxNodeAction.Analyzer, addDiagnostic, continueOnAnalyzerException, cancellationToken, () => syntaxNodeAction.Action(syntaxNodeContext)); + } + + /// + /// Executes the given code block actions on all the executable code blocks for each declaration info in . /// /// Code block analyzer factories. /// Stateless code block analyzers. /// Declarations to be analyzed. + /// SemanticModel to be shared amongst all actions. /// Analyzer options. - /// SemanticModel to be shared amongst all analyzers. /// Delegate to add diagnostics. - /// Predicate to decide if exceptions from any analyzer should be handled or not. + /// Predicate to decide if exceptions from any action should be handled or not. /// Delegate to compute language specific syntax kind for a syntax node. /// Cancellation token. /// Optional delegate to return cached syntax kinds. /// If null, then this property is explicitly invoked by the driver to compute syntax kinds of interest. - public static void ExecuteCodeBlockAnalyzers( + public static void ExecuteCodeBlockActions( IEnumerable> codeBlockStartedAnalyzers, IEnumerable> codeBlockEndedAnalyzers, IEnumerable declarationsInNode, - AnalyzerOptions analyzerOptions, SemanticModel semanticModel, + AnalyzerOptions analyzerOptions, Action addDiagnostic, Func continueOnAnalyzerException, Func getKind, @@ -862,8 +886,8 @@ protected override async Task AnalyzeDeclaringReferenceAsync(SymbolDeclaredCompi GetNodeAnalyzersByKind(executableNodeAnalyzers, executableNodeAnalyzersByKind, addDiagnostic, getAnalyzerKindsOfInterest); var nodesToAnalyze = executableCodeBlocks.SelectMany(cb => cb.DescendantNodesAndSelf()); - ExecuteSyntaxAnalyzers(nodesToAnalyze, executableNodeAnalyzersByKind, semanticModel, - addDiagnostic, continueOnAnalyzerException, analyzerOptions, getKind, cancellationToken); + ExecuteSyntaxNodeActions(nodesToAnalyze, executableNodeAnalyzersByKind, semanticModel, + analyzerOptions, addDiagnostic, continueOnAnalyzerException, getKind, cancellationToken); foreach (var b in executableNodeAnalyzersByKind.Values) { @@ -949,29 +973,27 @@ protected override async Task AnalyzeDeclaringReferenceAsync(SymbolDeclaredCompi } } - private static void ExecuteSyntaxAnalyzers( + private static void ExecuteSyntaxNodeActions( IEnumerable nodesToAnalyze, - IDictionary>> nodeAnalyzersByKind, + IDictionary>> nodeActionsByKind, SemanticModel model, - Action addDiagnostic, - Func continueOnAnalyzerException, AnalyzerOptions analyzerOptions, + Action addDiagnostic, + Func continueOnException, Func getKind, CancellationToken cancellationToken) { - Debug.Assert(nodeAnalyzersByKind != null); - Debug.Assert(nodeAnalyzersByKind.Any()); + Debug.Assert(nodeActionsByKind != null); + Debug.Assert(nodeActionsByKind.Any()); foreach (var child in nodesToAnalyze) { - ArrayBuilder> analyzersForKind; - if (nodeAnalyzersByKind.TryGetValue(getKind(child), out analyzersForKind)) + ArrayBuilder> actionsForKind; + if (nodeActionsByKind.TryGetValue(getKind(child), out actionsForKind)) { - foreach (var analyzer in analyzersForKind) + foreach (var analyzer in actionsForKind) { - var syntaxNodeContext = new SyntaxNodeAnalysisContext(child, model, analyzerOptions, addDiagnostic, cancellationToken); - // Catch Exception from analyzer. - ExecuteAndCatchIfThrows(analyzer.Analyzer, addDiagnostic, continueOnAnalyzerException, cancellationToken, () => analyzer.Action(syntaxNodeContext)); + ExecuteSyntaxNodeAction(analyzer, child, model, analyzerOptions, addDiagnostic, continueOnException, cancellationToken); } } }