private AnalyzerActions GetPerCompilationAnalyzerActions( DiagnosticAnalyzer analyzer, AnalyzerActions sessionActions, Compilation compilation, Action <Diagnostic> addDiagnostic) { Contract.ThrowIfFalse(sessionActions.CompilationStartActionsCount > 0); var compilationActionsMap = s_compilationActionsTable.GetOrCreateValue(compilation); AnalyzerActions result; if (compilationActionsMap.TryGetValue(analyzer, out result)) { return(result); } result = AnalyzerDriverHelper.ExecuteCompilationStartActions(sessionActions, analyzer, compilation, _analyzerOptions, addDiagnostic, CatchAnalyzerException, _cancellationToken); if (!compilationActionsMap.TryAdd(analyzer, result)) { return(compilationActionsMap[analyzer]); } return(result); }
private static ImmutableArray <Diagnostic> AnalyzerExceptionToDiagnostics(DiagnosticAnalyzer analyzer, Exception e, CancellationToken cancellationToken) { if (!IsCanceled(e, cancellationToken)) { // Create a info diagnostic saying that the analyzer failed return(ImmutableArray.Create(AnalyzerDriverHelper.GetAnalyzerDiagnostic(analyzer, e))); } return(ImmutableArray <Diagnostic> .Empty); }
private Tuple <AnalyzerActions, ImmutableArray <Diagnostic> > GetSessionAnalyzerActionsAndDiagnosticsCore(DiagnosticAnalyzer analyzer) { using (var pooledObject = SharedPools.Default <List <Diagnostic> >().GetPooledObject()) { var diagnostics = pooledObject.Object; var actions = AnalyzerDriverHelper.GetSessionAnalyzerActions(analyzer, diagnostics.Add, CatchAnalyzerException, _cancellationToken); var diagArray = diagnostics.ToImmutableArrayOrEmpty(); return(Tuple.Create(actions, diagArray)); } }
public void ExecuteCodeBlockActions( AnalyzerActions actions, IEnumerable <DeclarationInfo> declarationsInNode, SemanticModel semanticModel, AnalyzerOptions analyzerOptions, Action <Diagnostic> reportDiagnostic, Func <Exception, DiagnosticAnalyzer, bool> continueOnAnalyzerException, CancellationToken cancellationToken) { AnalyzerDriverHelper.ExecuteCodeBlockActions(actions, declarationsInNode, semanticModel, analyzerOptions, reportDiagnostic, continueOnAnalyzerException, this.GetKind, cancellationToken); }
public void ExecuteSyntaxNodeActions( AnalyzerActions actions, IEnumerable <SyntaxNode> descendantNodes, SemanticModel semanticModel, AnalyzerOptions analyzerOptions, Action <Diagnostic> reportDiagnostic, Func <Exception, DiagnosticAnalyzer, bool> continueOnAnalyzerException, CancellationToken cancellationToken) { AnalyzerDriverHelper.ExecuteSyntaxNodeActions(actions, descendantNodes, semanticModel, analyzerOptions, reportDiagnostic, continueOnAnalyzerException, this.GetKind, cancellationToken); }
public async Task <IEnumerable <Diagnostic> > GetSyntaxDiagnosticsAsync(DiagnosticAnalyzer analyzer) { var compilation = _document.Project.SupportsCompilation ? await _document.Project.GetCompilationAsync(_cancellationToken).ConfigureAwait(false) : null; Contract.ThrowIfNull(_document); Contract.ThrowIfFalse(analyzer.SupportsSyntaxDiagnosticAnalysis(this)); using (var pooledObject = SharedPools.Default <List <Diagnostic> >().GetPooledObject()) { var diagnostics = pooledObject.Object; _cancellationToken.ThrowIfCancellationRequested(); var documentAnalyzer = analyzer as DocumentDiagnosticAnalyzer; if (documentAnalyzer != null) { try { await documentAnalyzer.AnalyzeSyntaxAsync(_document, diagnostics.Add, _cancellationToken).ConfigureAwait(false); return(diagnostics.ToImmutableArrayOrEmpty()); } catch (Exception e) when(CatchAnalyzerException(e, analyzer)) { var exceptionDiagnostics = AnalyzerExceptionToDiagnostics(analyzer, e, _cancellationToken); return(GetFilteredDocumentDiagnostics(exceptionDiagnostics, compilation).ToImmutableArray()); } } var analyzerActions = await this.GetAnalyzerActionsAsync(analyzer, diagnostics.Add).ConfigureAwait(false); DiagnosticAnalyzerLogger.UpdateAnalyzerTypeCount(analyzer, analyzerActions, (DiagnosticLogAggregator)_logAggregator); if (analyzerActions != null) { if (_document.SupportsSyntaxTree) { AnalyzerDriverHelper.ExecuteSyntaxTreeActions(analyzerActions, _root.SyntaxTree, _analyzerOptions, diagnostics.Add, CatchAnalyzerException, _cancellationToken); } } if (diagnostics.Count == 0) { return(SpecializedCollections.EmptyEnumerable <Diagnostic>()); } return(GetFilteredDocumentDiagnostics(diagnostics, compilation).ToImmutableArray()); } }
private async Task GetCompilationDiagnosticsAsync(DiagnosticAnalyzer analyzer, List <Diagnostic> diagnostics, Action <Project, DiagnosticAnalyzer, CancellationToken> forceAnalyzeAllDocuments) { Contract.ThrowIfFalse(_project.SupportsCompilation); var analyzerActionsAndDiagnostics = GetSessionAnalyzerActionsAndDiagnostics(analyzer); var analyzerActions = analyzerActionsAndDiagnostics.Item1; var compilation = await _project.GetCompilationAsync(_cancellationToken).ConfigureAwait(false); diagnostics.AddRange(CompilationWithAnalyzers.GetEffectiveDiagnostics(analyzerActionsAndDiagnostics.Item2, compilation)); DiagnosticAnalyzerLogger.UpdateAnalyzerTypeCount(analyzer, analyzerActions, (DiagnosticLogAggregator)_logAggregator); if (analyzerActions == null || (analyzerActions.CompilationStartActionsCount == 0 && analyzerActions.CompilationEndActionsCount == 0)) { return; } using (var pooledObject = SharedPools.Default <List <Diagnostic> >().GetPooledObject()) { var localDiagnostics = pooledObject.Object; // Get all the analyzer actions, including the per-compilation actions. var allAnalyzerActions = await GetAnalyzerActionsAsync(analyzer, localDiagnostics.Add).ConfigureAwait(false); if (analyzerActions.CompilationEndActionsCount < allAnalyzerActions.CompilationEndActionsCount && forceAnalyzeAllDocuments != null) { if (allAnalyzerActions.CodeBlockEndActionsCount > analyzerActions.CodeBlockEndActionsCount || allAnalyzerActions.CodeBlockStartActionsCount > analyzerActions.CodeBlockStartActionsCount || allAnalyzerActions.SemanticModelActionsCount > analyzerActions.SemanticModelActionsCount || allAnalyzerActions.SymbolActionsCount > analyzerActions.SymbolActionsCount || allAnalyzerActions.SyntaxNodeActionsCount > analyzerActions.SyntaxNodeActionsCount || allAnalyzerActions.SyntaxTreeActionsCount > analyzerActions.SyntaxTreeActionsCount) { // Analyzer registered a compilation end action and at least one other analyzer action during it's compilation start action. // We need to ensure that we have force analyzed all documents in this project for this analyzer before executing the end actions. forceAnalyzeAllDocuments(_project, analyzer, _cancellationToken); } } // CompilationEnd actions. AnalyzerDriverHelper.ExecuteCompilationEndActions(allAnalyzerActions, compilation, _analyzerOptions, localDiagnostics.Add, CatchAnalyzerException, _cancellationToken); diagnostics.AddRange(CompilationWithAnalyzers.GetEffectiveDiagnostics(localDiagnostics, compilation)); } }
public async Task <IEnumerable <Diagnostic> > GetSemanticDiagnosticsAsync(DiagnosticAnalyzer analyzer) { var model = await _document.GetSemanticModelAsync(_cancellationToken).ConfigureAwait(false); Contract.ThrowIfNull(_document); Contract.ThrowIfFalse(analyzer.SupportsSemanticDiagnosticAnalysis(this)); using (var pooledObject = SharedPools.Default <List <Diagnostic> >().GetPooledObject()) { var diagnostics = pooledObject.Object; // Stateless semantic analyzers: // 1) ISemanticModelAnalyzer/IDocumentBasedDiagnosticAnalyzer // 2) ISymbolAnalyzer // 3) ISyntaxNodeAnalyzer _cancellationToken.ThrowIfCancellationRequested(); var documentAnalyzer = analyzer as DocumentDiagnosticAnalyzer; if (documentAnalyzer != null) { try { await documentAnalyzer.AnalyzeSemanticsAsync(_document, diagnostics.Add, _cancellationToken).ConfigureAwait(false); } catch (Exception e) when(CatchAnalyzerException(e, analyzer)) { var exceptionDiagnostics = AnalyzerExceptionToDiagnostics(analyzer, e, _cancellationToken); return(model == null ? exceptionDiagnostics : GetFilteredDocumentDiagnostics(exceptionDiagnostics, model.Compilation)); } } else { var analyzerActions = await GetAnalyzerActionsAsync(analyzer, diagnostics.Add).ConfigureAwait(false); if (analyzerActions != null) { // SemanticModel actions. if (analyzerActions.SemanticModelActionsCount > 0) { AnalyzerDriverHelper.ExecuteSemanticModelActions(analyzerActions, model, _analyzerOptions, diagnostics.Add, CatchAnalyzerException, _cancellationToken); } var compilation = model.Compilation; // Symbol actions. if (analyzerActions.SymbolActionsCount > 0) { var symbols = this.GetSymbolsToAnalyze(model); AnalyzerDriverHelper.ExecuteSymbolActions(analyzerActions, symbols, compilation, _analyzerOptions, diagnostics.Add, CatchAnalyzerException, _cancellationToken); } if (this.SyntaxNodeAnalyzerService != null) { // SyntaxNode actions. if (analyzerActions.SyntaxNodeActionsCount > 0) { this.SyntaxNodeAnalyzerService.ExecuteSyntaxNodeActions(analyzerActions, GetSyntaxNodesToAnalyze(), model, _analyzerOptions, diagnostics.Add, CatchAnalyzerException, _cancellationToken); } // CodeBlockStart, CodeBlockEnd, and generated SyntaxNode actions. if (analyzerActions.CodeBlockStartActionsCount > 0 || analyzerActions.CodeBlockEndActionsCount > 0) { this.SyntaxNodeAnalyzerService.ExecuteCodeBlockActions(analyzerActions, this.GetDeclarationInfos(model), model, _analyzerOptions, diagnostics.Add, CatchAnalyzerException, _cancellationToken); } } } } var result = model == null ? diagnostics : GetFilteredDocumentDiagnostics(diagnostics, model.Compilation); return(result.ToImmutableArray()); } }