private ImmutableArray <Diagnostic> GetDiagnostics_NoLock(AnalysisScope analysisScope, bool getLocalDiagnostics, bool getNonLocalDiagnostics) { Debug.Assert(getLocalDiagnostics || getNonLocalDiagnostics); var builder = ImmutableArray.CreateBuilder <Diagnostic>(); if (getLocalDiagnostics) { if (!analysisScope.IsTreeAnalysis) { AddAllLocalDiagnostics_NoLock(_localSyntaxDiagnosticsOpt, analysisScope, builder); AddAllLocalDiagnostics_NoLock(_localSemanticDiagnosticsOpt, analysisScope, builder); } else if (analysisScope.IsSyntaxOnlyTreeAnalysis) { AddLocalDiagnosticsForPartialAnalysis_NoLock(_localSyntaxDiagnosticsOpt, analysisScope, builder); } else { AddLocalDiagnosticsForPartialAnalysis_NoLock(_localSemanticDiagnosticsOpt, analysisScope, builder); } } if (getNonLocalDiagnostics && _nonLocalDiagnosticsOpt != null) { AddDiagnostics_NoLock(_nonLocalDiagnosticsOpt, analysisScope, builder); } return(builder.ToImmutableArray()); }
internal ImmutableArray <Diagnostic> GetDiagnostics(AnalysisScope analysisScope, bool getLocalDiagnostics, bool getNonLocalDiagnostics) { lock (_gate) { return(GetDiagnostics_NoLock(analysisScope, getLocalDiagnostics, getNonLocalDiagnostics)); } }
public void OnCompilationEventGenerated(CompilationEvent compilationEvent, AnalyzerActionCounts actionCounts) { lock (_gate) { var symbolEvent = compilationEvent as SymbolDeclaredCompilationEvent; if (symbolEvent != null) { var needsAnalysis = false; var symbol = symbolEvent.Symbol; var skipSymbolAnalysis = AnalysisScope.ShouldSkipSymbolAnalysis(symbolEvent); if (!skipSymbolAnalysis && actionCounts.SymbolActionsCount > 0) { needsAnalysis = true; _pendingSymbols[symbol] = null; } var skipDeclarationAnalysis = AnalysisScope.ShouldSkipDeclarationAnalysis(symbol); if (!skipDeclarationAnalysis && actionCounts.HasAnyExecutableCodeActions) { needsAnalysis = true; _pendingDeclarations[symbol] = _currentlyAnalyzingDeclarationsMapPool.Allocate(); } if (actionCounts.SymbolStartActionsCount > 0 && (!skipSymbolAnalysis || !skipDeclarationAnalysis)) { needsAnalysis = true; _lazyPendingSymbolEndAnalyses = _lazyPendingSymbolEndAnalyses ?? new Dictionary <ISymbol, AnalyzerStateData>(); _lazyPendingSymbolEndAnalyses[symbol] = null; } if (!needsAnalysis) { return; } } else if (compilationEvent is CompilationStartedEvent) { if (actionCounts.SyntaxTreeActionsCount > 0) { _lazySyntaxTreesWithAnalysisData = new Dictionary <SyntaxTree, AnalyzerStateData>(); _pendingSyntaxAnalysisTreesCount = compilationEvent.Compilation.SyntaxTrees.Count(); } if (actionCounts.CompilationActionsCount == 0) { return; } } _pendingEvents[compilationEvent] = null; } }
private static void AddLocalDiagnosticsForPartialAnalysis_NoLock( Dictionary <SyntaxTree, Dictionary <DiagnosticAnalyzer, ImmutableArray <Diagnostic> .Builder> > localDiagnostics, AnalysisScope analysisScope, ImmutableArray <Diagnostic> .Builder builder) { Dictionary <DiagnosticAnalyzer, ImmutableArray <Diagnostic> .Builder> diagnosticsForTree; if (localDiagnostics != null && localDiagnostics.TryGetValue(analysisScope.FilterTreeOpt, out diagnosticsForTree)) { AddDiagnostics_NoLock(diagnosticsForTree, analysisScope, builder); } }
private static void AddAllLocalDiagnostics_NoLock( Dictionary <SyntaxTree, Dictionary <DiagnosticAnalyzer, ImmutableArray <Diagnostic> .Builder> > localDiagnostics, AnalysisScope analysisScope, ImmutableArray <Diagnostic> .Builder builder) { if (localDiagnostics != null) { foreach (var localDiagsByTree in localDiagnostics.Values) { AddDiagnostics_NoLock(localDiagsByTree, analysisScope, builder); } } }
public bool ShouldExecuteOperationActions(AnalysisScope analysisScope) { if (!this.OperationActionsByAnalyzerAndKind.IsEmpty) { foreach (var analyzer in analysisScope.Analyzers) { if (this.OperationActionsByAnalyzerAndKind.ContainsKey(analyzer)) { return(true); } } } return(false); }
private static void AddDiagnostics_NoLock( Dictionary <DiagnosticAnalyzer, ImmutableArray <Diagnostic> .Builder> diagnostics, AnalysisScope analysisScope, ImmutableArray <Diagnostic> .Builder builder) { Debug.Assert(diagnostics != null); foreach (var analyzer in analysisScope.Analyzers) { ImmutableArray <Diagnostic> .Builder diagnosticsByAnalyzer; if (diagnostics.TryGetValue(analyzer, out diagnosticsByAnalyzer)) { builder.AddRange(diagnosticsByAnalyzer); } } }
internal void StoreAnalysisResult(AnalysisScope analysisScope, AnalyzerDriver driver, Compilation compilation, Func <DiagnosticAnalyzer, AnalyzerActionCounts> getAnalyzerActionCounts, bool fullAnalysisResultForAnalyzersInScope) { Debug.Assert(!fullAnalysisResultForAnalyzersInScope || analysisScope.FilterTreeOpt == null, "Full analysis result cannot come from partial (tree) analysis."); foreach (var analyzer in analysisScope.Analyzers) { // Dequeue reported analyzer diagnostics from the driver and store them in our maps. var syntaxDiagnostics = driver.DequeueLocalDiagnostics(analyzer, syntax: true, compilation: compilation); var semanticDiagnostics = driver.DequeueLocalDiagnostics(analyzer, syntax: false, compilation: compilation); var compilationDiagnostics = driver.DequeueNonLocalDiagnostics(analyzer, compilation); lock (_gate) { if (_completedAnalyzers.Contains(analyzer)) { // Already stored full analysis result for this analyzer. continue; } if (syntaxDiagnostics.Length > 0 || semanticDiagnostics.Length > 0 || compilationDiagnostics.Length > 0 || fullAnalysisResultForAnalyzersInScope) { UpdateLocalDiagnostics_NoLock(analyzer, syntaxDiagnostics, fullAnalysisResultForAnalyzersInScope, ref _localSyntaxDiagnosticsOpt); UpdateLocalDiagnostics_NoLock(analyzer, semanticDiagnostics, fullAnalysisResultForAnalyzersInScope, ref _localSemanticDiagnosticsOpt); UpdateNonLocalDiagnostics_NoLock(analyzer, compilationDiagnostics, fullAnalysisResultForAnalyzersInScope); } if (_analyzerExecutionTimeOpt != null) { var timeSpan = driver.ResetAnalyzerExecutionTime(analyzer); _analyzerExecutionTimeOpt[analyzer] = fullAnalysisResultForAnalyzersInScope ? timeSpan : _analyzerExecutionTimeOpt[analyzer] + timeSpan; } if (!_analyzerActionCounts.ContainsKey(analyzer)) { _analyzerActionCounts.Add(analyzer, getAnalyzerActionCounts(analyzer)); } if (fullAnalysisResultForAnalyzersInScope) { _completedAnalyzers.Add(analyzer); } } } }
/// <summary> /// Returns true if we have any pending syntax analysis for given analysis scope. /// </summary> public bool HasPendingSyntaxAnalysis(AnalysisScope analysisScope) { if (analysisScope.IsTreeAnalysis && !analysisScope.IsSyntaxOnlyTreeAnalysis) { return(false); } foreach (var analyzer in analysisScope.Analyzers) { var analyzerState = GetAnalyzerState(analyzer); if (analyzerState.HasPendingSyntaxAnalysis(analysisScope.FilterTreeOpt)) { return(true); } } return(false); }
/// <summary> /// Returns true if we have any pending symbol analysis for given analysis scope. /// </summary> public bool HasPendingSymbolAnalysis(AnalysisScope analysisScope, CancellationToken cancellationToken) { Debug.Assert(analysisScope.FilterTreeOpt != null); var symbolDeclaredEvents = GetPendingSymbolDeclaredEvents(analysisScope.FilterTreeOpt, cancellationToken); foreach (var symbolDeclaredEvent in symbolDeclaredEvents) { if (analysisScope.ShouldAnalyze(symbolDeclaredEvent.Symbol)) { foreach (var analyzer in analysisScope.Analyzers) { var analyzerState = GetAnalyzerState(analyzer); if (analyzerState.HasPendingSymbolAnalysis(symbolDeclaredEvent.Symbol)) { return(true); } } } } return(false); }
public async Task GenerateSimulatedCompilationEventsAsync( AnalysisScope analysisScope, Compilation compilation, Func <SyntaxTree, Compilation, CancellationToken, SemanticModel> getCachedSemanticModel, AnalyzerDriver driver, CancellationToken cancellationToken) { await EnsureAnalyzerActionCountsInitializedAsync(driver, cancellationToken).ConfigureAwait(false); // Compilation started event. GenerateSimulatedCompilationNonSourceEvent(compilation, driver, started: true, cancellationToken: cancellationToken); // Symbol declared and compilation unit completed events. foreach (var tree in analysisScope.SyntaxTrees) { GenerateSimulatedCompilationSourceEvents(tree, compilation, getCachedSemanticModel, driver, cancellationToken); } // Compilation ended event. if (analysisScope.FilterTreeOpt == null) { GenerateSimulatedCompilationNonSourceEvent(compilation, driver, started: false, cancellationToken: cancellationToken); } }
public IEnumerable <CodeBlockAnalyzerActions> GetCodeBlockActions(AnalysisScope analysisScope) { if (_analyzerActions.IsEmpty) { yield break; } foreach (var analyzer in analysisScope.Analyzers) { ImmutableArray <CodeBlockStartAnalyzerAction <TLanguageKindEnum> > codeBlockStartActions; if (!this.CodeBlockStartActionsByAnalyzer.TryGetValue(analyzer, out codeBlockStartActions)) { codeBlockStartActions = ImmutableArray <CodeBlockStartAnalyzerAction <TLanguageKindEnum> > .Empty; } ImmutableArray <CodeBlockAnalyzerAction> codeBlockActions; if (!this.CodeBlockActionsByAnalyzer.TryGetValue(analyzer, out codeBlockActions)) { codeBlockActions = ImmutableArray <CodeBlockAnalyzerAction> .Empty; } ImmutableArray <CodeBlockAnalyzerAction> codeBlockEndActions; if (!this.CodeBlockEndActionsByAnalyzer.TryGetValue(analyzer, out codeBlockEndActions)) { codeBlockEndActions = ImmutableArray <CodeBlockAnalyzerAction> .Empty; } ImmutableArray <OperationBlockStartAnalyzerAction> operationBlockStartActions; if (!this.OperationBlockStartActionsByAnalyzer.TryGetValue(analyzer, out operationBlockStartActions)) { operationBlockStartActions = ImmutableArray <OperationBlockStartAnalyzerAction> .Empty; } ImmutableArray <OperationBlockAnalyzerAction> operationBlockActions; if (!this.OperationBlockActionsByAnalyzer.TryGetValue(analyzer, out operationBlockActions)) { operationBlockActions = ImmutableArray <OperationBlockAnalyzerAction> .Empty; } ImmutableArray <OperationBlockAnalyzerAction> operationBlockEndActions; if (!this.OperationBlockEndActionsByAnalyzer.TryGetValue(analyzer, out operationBlockEndActions)) { operationBlockEndActions = ImmutableArray <OperationBlockAnalyzerAction> .Empty; } if (!codeBlockStartActions.IsEmpty || !codeBlockActions.IsEmpty || !codeBlockEndActions.IsEmpty || !operationBlockStartActions.IsEmpty || !operationBlockActions.IsEmpty || !operationBlockEndActions.IsEmpty) { yield return (new CodeBlockAnalyzerActions { Analyzer = analyzer, CodeBlockStartActions = codeBlockStartActions, CodeBlockActions = codeBlockActions, CodeBlockEndActions = codeBlockEndActions, OperationBlockStartActions = operationBlockStartActions, OperationBlockActions = operationBlockActions, OperationBlockEndActions = operationBlockEndActions }); } } }
public bool ShouldExecuteOperationBlockActions(AnalysisScope analysisScope, ISymbol symbol) { return(ShouldExecuteBlockActions(this.OperationBlockStartActionsByAnalyzer, this.OperationBlockActionsByAnalyzer, analysisScope, symbol)); }
public bool ShouldExecuteBlockActions <T0, T1>(ImmutableDictionary <DiagnosticAnalyzer, ImmutableArray <T0> > blockStartActions, ImmutableDictionary <DiagnosticAnalyzer, ImmutableArray <T1> > blockActions, AnalysisScope analysisScope, ISymbol symbol) { if ((!blockStartActions.IsEmpty || !blockActions.IsEmpty) && AnalyzerExecutor.CanHaveExecutableCodeBlock(symbol)) { foreach (var analyzer in analysisScope.Analyzers) { if (blockStartActions.ContainsKey(analyzer) || blockActions.ContainsKey(analyzer)) { return(true); } } } return(false); }