private void ExecuteSymbolActionsCore( ImmutableArray <SymbolAnalyzerAction> symbolActions, DiagnosticAnalyzer analyzer, ISymbol symbol, Func <ISymbol, SyntaxReference, Compilation, SyntaxNode> getTopMostNodeForAnalysis, AnalyzerStateData analyzerStateOpt) { Debug.Assert(getTopMostNodeForAnalysis != null); var addDiagnostic = GetAddDiagnostic(symbol, _compilation, analyzer, _addDiagnostic, _addLocalDiagnosticOpt, _addNonLocalDiagnosticOpt, getTopMostNodeForAnalysis); foreach (var symbolAction in symbolActions) { var action = symbolAction.Action; var kinds = symbolAction.Kinds; if (kinds.Contains(symbol.Kind)) { if (ShouldExecuteAction(analyzerStateOpt, symbolAction)) { _cancellationToken.ThrowIfCancellationRequested(); ExecuteAndCatchIfThrows(symbolAction.Analyzer, () => action(new SymbolAnalysisContext(symbol, _compilation, _analyzerOptions, addDiagnostic, d => IsSupportedDiagnostic(symbolAction.Analyzer, d), _cancellationToken))); analyzerStateOpt?.ProcessedActions.Add(symbolAction); } } } }
/// <summary> /// Executes the symbol actions on the given symbol. /// </summary> /// <param name="symbolActions">Symbol actions to be executed.</param> /// <param name="analyzer">Analyzer whose actions are to be executed.</param> /// <param name="symbol">Symbol to be analyzed.</param> /// <param name="overriddenAddDiagnostic">Overridden add diagnostic delegate.</param> /// <param name="overriddenAddLocalDiagnostic">Overridden add local diagnostic delegate.</param> /// <param name="overriddenAddNonLocalDiagnostic">Overridden add non-local diagnostic delegate.</param> /// <param name="getTopMostNodeForAnalysis">Delegate to get topmost declaration node for a symbol declaration reference.</param> /// <param name="analysisScope">Scope for analyzer execution.</param> /// <param name="analysisStateOpt">An optional object to track analysis state.</param> public void ExecuteSymbolActions( ImmutableArray <SymbolAnalyzerAction> symbolActions, DiagnosticAnalyzer analyzer, ISymbol symbol, Action <Diagnostic> overriddenAddDiagnostic, Action <Diagnostic, DiagnosticAnalyzer, bool> overriddenAddLocalDiagnostic, Action <Diagnostic, DiagnosticAnalyzer> overriddenAddNonLocalDiagnostic, Func <ISymbol, SyntaxReference, Compilation, SyntaxNode> getTopMostNodeForAnalysis, AnalysisScope analysisScope, AnalysisState analysisStateOpt) { AnalyzerStateData analyzerStateOpt = null; try { if (TryStartAnalyzingSymbol(symbol, analyzer, analysisScope, analysisStateOpt, out analyzerStateOpt)) { ExecuteSymbolActionsCore(symbolActions, analyzer, symbol, overriddenAddDiagnostic, overriddenAddLocalDiagnostic, overriddenAddNonLocalDiagnostic, getTopMostNodeForAnalysis, analyzerStateOpt); analysisStateOpt?.MarkSymbolComplete(symbol, analyzer); } } finally { analyzerStateOpt?.ResetToReadyState(); } }
/// <summary> /// Executes the syntax tree actions on the given syntax tree. /// </summary> /// <param name="syntaxTreeActions">Syntax tree actions to be executed.</param> /// <param name="analyzer">Analyzer whose actions are to be executed.</param> /// <param name="tree">Syntax tree to analyze.</param> /// <param name="analysisScope">Scope for analyzer execution.</param> /// <param name="analysisStateOpt">An optional object to track analysis state.</param> public void ExecuteSyntaxTreeActions( ImmutableArray <SyntaxTreeAnalyzerAction> syntaxTreeActions, DiagnosticAnalyzer analyzer, SyntaxTree tree, AnalysisScope analysisScope, AnalysisState analysisStateOpt) { AnalyzerStateData analyzerStateOpt = null; try { if (TryStartSyntaxAnalysis(tree, analyzer, analysisScope, analysisStateOpt, out analyzerStateOpt)) { ExecuteSyntaxTreeActionsCore(syntaxTreeActions, analyzer, tree, analyzerStateOpt); analysisStateOpt?.MarkSyntaxAnalysisComplete(tree, analyzer); } } finally { analyzerStateOpt?.ResetToReadyState(); } }
private void ExecuteSyntaxTreeActionsCore( ImmutableArray <SyntaxTreeAnalyzerAction> syntaxTreeActions, DiagnosticAnalyzer analyzer, SyntaxTree tree, AnalyzerStateData analyzerStateOpt) { var addDiagnostic = GetAddDiagnostic(tree, analyzer, isSyntaxDiagnostic: true); foreach (var syntaxTreeAction in syntaxTreeActions) { if (ShouldExecuteAction(analyzerStateOpt, syntaxTreeAction)) { _cancellationToken.ThrowIfCancellationRequested(); // Catch Exception from action. ExecuteAndCatchIfThrows(syntaxTreeAction.Analyzer, () => syntaxTreeAction.Action(new SyntaxTreeAnalysisContext(tree, _analyzerOptions, addDiagnostic, d => IsSupportedDiagnostic(syntaxTreeAction.Analyzer, d), _cancellationToken))); analyzerStateOpt?.ProcessedActions.Add(syntaxTreeAction); } } }
/// <summary> /// Executes the semantic model actions on the given semantic model. /// </summary> /// <param name="semanticModelActions">Semantic model actions to be executed.</param> /// <param name="analyzer">Analyzer whose actions are to be executed.</param> /// <param name="semanticModel">Semantic model to analyze.</param> /// <param name="compilationUnitCompletedEvent">Compilation event for semantic model analysis.</param> /// <param name="analysisScope">Scope for analyzer execution.</param> /// <param name="analysisStateOpt">An optional object to track analysis state.</param> public void ExecuteSemanticModelActions( ImmutableArray <SemanticModelAnalyzerAction> semanticModelActions, DiagnosticAnalyzer analyzer, SemanticModel semanticModel, CompilationEvent compilationUnitCompletedEvent, AnalysisScope analysisScope, AnalysisState analysisStateOpt) { AnalyzerStateData analyzerStateOpt = null; try { if (TryStartProcessingEvent(compilationUnitCompletedEvent, analyzer, analysisScope, analysisStateOpt, out analyzerStateOpt)) { ExecuteSemanticModelActionsCore(semanticModelActions, analyzer, semanticModel, analyzerStateOpt); analysisStateOpt?.MarkEventComplete(compilationUnitCompletedEvent, analyzer); } } finally { analyzerStateOpt?.ResetToReadyState(); } }
/// <summary> /// Executes compilation actions or compilation end actions. /// </summary> /// <param name="compilationActions">Compilation actions to be executed.</param> /// <param name="analyzer">Analyzer whose actions are to be executed.</param> /// <param name="compilationEvent">Compilation event.</param> /// <param name="analysisScope">Scope for analyzer execution.</param> /// <param name="analysisStateOpt">An optional object to track analysis state.</param> public void ExecuteCompilationActions( ImmutableArray <CompilationAnalyzerAction> compilationActions, DiagnosticAnalyzer analyzer, CompilationEvent compilationEvent, AnalysisScope analysisScope, AnalysisState analysisStateOpt) { Debug.Assert(compilationEvent is CompilationStartedEvent || compilationEvent is CompilationCompletedEvent); AnalyzerStateData analyzerStateOpt = null; try { if (TryStartProcessingEvent(compilationEvent, analyzer, analysisScope, analysisStateOpt, out analyzerStateOpt)) { ExecuteCompilationActionsCore(compilationActions, analyzer, analyzerStateOpt); analysisStateOpt?.MarkEventComplete(compilationEvent, analyzer); } } finally { analyzerStateOpt?.ResetToReadyState(); } }
private static bool TryStartAnalyzingSymbol(ISymbol symbol, DiagnosticAnalyzer analyzer, AnalysisScope analysisScope, AnalysisState analysisStateOpt, out AnalyzerStateData analyzerStateOpt) { Debug.Assert(analysisScope.Analyzers.Contains(analyzer)); analyzerStateOpt = null; return(analysisStateOpt == null || analysisStateOpt.TryStartAnalyzingSymbol(symbol, analyzer, out analyzerStateOpt)); }
private static bool TryStartSyntaxAnalysis(SyntaxTree tree, DiagnosticAnalyzer analyzer, AnalysisScope analysisScope, AnalysisState analysisStateOpt, out AnalyzerStateData analyzerStateOpt) { Debug.Assert(analysisScope.Analyzers.Contains(analyzer)); analyzerStateOpt = null; return(analysisStateOpt == null || analysisStateOpt.TryStartSyntaxAnalysis(tree, analyzer, out analyzerStateOpt)); }
private static bool TryStartProcessingEvent(CompilationEvent nonSymbolCompilationEvent, DiagnosticAnalyzer analyzer, AnalysisScope analysisScope, AnalysisState analysisStateOpt, out AnalyzerStateData analyzerStateOpt) { Debug.Assert(!(nonSymbolCompilationEvent is SymbolDeclaredCompilationEvent)); Debug.Assert(analysisScope.Analyzers.Contains(analyzer)); analyzerStateOpt = null; return(analysisStateOpt == null || analysisStateOpt.TryStartProcessingEvent(nonSymbolCompilationEvent, analyzer, out analyzerStateOpt)); }
private static bool ShouldExecuteAction(AnalyzerStateData analyzerStateOpt, AnalyzerAction action) { return(analyzerStateOpt == null || !analyzerStateOpt.ProcessedActions.Contains(action)); }
private void ExecuteCompilationActionsCore(ImmutableArray <CompilationAnalyzerAction> compilationActions, DiagnosticAnalyzer analyzer, AnalyzerStateData analyzerStateOpt) { var addDiagnostic = GetAddCompilationDiagnostic(analyzer); foreach (var endAction in compilationActions) { _cancellationToken.ThrowIfCancellationRequested(); if (ShouldExecuteAction(analyzerStateOpt, endAction)) { ExecuteAndCatchIfThrows(endAction.Analyzer, () => endAction.Action(new CompilationAnalysisContext(_compilation, _analyzerOptions, addDiagnostic, d => IsSupportedDiagnostic(endAction.Analyzer, d), _cancellationToken))); analyzerStateOpt?.ProcessedActions.Add(endAction); } } }