private void OnCompilationEventsGenerated_NoLock(ImmutableArray <CompilationEvent> compilationEvents, SyntaxTree filterTreeOpt, AnalyzerDriver driver, CancellationToken cancellationToken) { Debug.Assert(_lazyAnalyzerActionCountsMap != null); // Add the events to our global pending events map. AddToEventsMap_NoLock(compilationEvents, filterTreeOpt); // Mark the events for analysis for each analyzer. ArrayBuilder <ISymbol> newPartialSymbols = null; Debug.Assert(_pooledEventsWithAnyActionsSet.Count == 0); foreach (KeyValuePair <DiagnosticAnalyzer, int> kvp in _analyzerStateMap) { DiagnosticAnalyzer analyzer = kvp.Key; PerAnalyzerState analyzerState = _analyzerStates[kvp.Value]; AnalyzerActionCounts actionCounts = _lazyAnalyzerActionCountsMap[analyzer]; foreach (CompilationEvent compilationEvent in compilationEvents) { if (HasActionsForEvent(compilationEvent, actionCounts)) { _pooledEventsWithAnyActionsSet.Add(compilationEvent); SymbolDeclaredCompilationEvent symbolDeclaredEvent = compilationEvent as SymbolDeclaredCompilationEvent; if (symbolDeclaredEvent?.DeclaringSyntaxReferences.Length > 1) { if (_partialSymbolsWithGeneratedSourceEvents.Contains(symbolDeclaredEvent.Symbol)) { // already processed. continue; } else { newPartialSymbols = newPartialSymbols ?? ArrayBuilder <ISymbol> .GetInstance(); newPartialSymbols.Add(symbolDeclaredEvent.Symbol); } } analyzerState.OnCompilationEventGenerated(compilationEvent, actionCounts); } } } foreach (CompilationEvent compilationEvent in compilationEvents) { if (!_pooledEventsWithAnyActionsSet.Remove(compilationEvent)) { // Event has no relevant actions to execute, so mark it as complete. UpdateEventsMap_NoLock(compilationEvent, add: false); } } if (newPartialSymbols != null) { _partialSymbolsWithGeneratedSourceEvents.AddAll(newPartialSymbols); newPartialSymbols.Free(); } }
private static bool HasActionsForEvent(CompilationEvent compilationEvent, AnalyzerActionCounts actionCounts) { return(compilationEvent switch { CompilationStartedEvent => actionCounts.CompilationActionsCount > 0 || actionCounts.SyntaxTreeActionsCount > 0 || actionCounts.AdditionalFileActionsCount > 0, CompilationCompletedEvent => actionCounts.CompilationEndActionsCount > 0, SymbolDeclaredCompilationEvent => actionCounts.SymbolActionsCount > 0 || actionCounts.HasAnyExecutableCodeActions, _ => actionCounts.SemanticModelActionsCount > 0 });
private async Task EnsureAnalyzerActionCountsInitializedAsync(AnalyzerDriver driver, CancellationToken cancellationToken) { if (_lazyAnalyzerActionCountsMap == null) { ImmutableDictionary <DiagnosticAnalyzer, AnalyzerActionCounts> .Builder builder = ImmutableDictionary.CreateBuilder <DiagnosticAnalyzer, AnalyzerActionCounts>(); foreach (DiagnosticAnalyzer analyzer in _analyzerStateMap.Keys) { AnalyzerActionCounts actionCounts = await driver.GetAnalyzerActionCountsAsync(analyzer, _compilationOptions, cancellationToken).ConfigureAwait(false); builder.Add(analyzer, actionCounts); } Interlocked.CompareExchange(ref _lazyAnalyzerActionCountsMap, builder.ToImmutable(), null); } }
private ImmutableDictionary <DiagnosticAnalyzer, AnalyzerTelemetryInfo> GetTelemetryInfo( ImmutableArray <DiagnosticAnalyzer> analyzers, CancellationToken cancellationToken) { ImmutableDictionary <DiagnosticAnalyzer, AnalyzerTelemetryInfo> .Builder builder = ImmutableDictionary.CreateBuilder <DiagnosticAnalyzer, AnalyzerTelemetryInfo>(); lock (_gate) { foreach (DiagnosticAnalyzer analyzer in analyzers) { AnalyzerActionCounts actionCounts = _analyzerActionCounts[analyzer]; TimeSpan executionTime = _analyzerExecutionTimeOpt != null ? _analyzerExecutionTimeOpt[analyzer] : default(TimeSpan); AnalyzerTelemetryInfo telemetryInfo = new AnalyzerTelemetryInfo(actionCounts, executionTime); builder.Add(analyzer, telemetryInfo); } } return(builder.ToImmutable()); }
private static bool HasActionsForEvent(CompilationEvent compilationEvent, AnalyzerActionCounts actionCounts) { if (compilationEvent is CompilationStartedEvent) { return(actionCounts.CompilationActionsCount > 0 || actionCounts.SyntaxTreeActionsCount > 0); } else if (compilationEvent is CompilationCompletedEvent) { return(actionCounts.CompilationEndActionsCount > 0); } else if (compilationEvent is SymbolDeclaredCompilationEvent) { return(actionCounts.SymbolActionsCount > 0 || actionCounts.HasAnyExecutableCodeActions); } else { return(actionCounts.SemanticModelActionsCount > 0); } }
public void OnCompilationEventGenerated(CompilationEvent compilationEvent, AnalyzerActionCounts actionCounts) { lock (_gate) { var symbolEvent = compilationEvent as SymbolDeclaredCompilationEvent; if (symbolEvent != null) { var needsAnalysis = false; var symbol = symbolEvent.Symbol; if (!AnalysisScope.ShouldSkipSymbolAnalysis(symbolEvent) && actionCounts.SymbolActionsCount > 0) { needsAnalysis = true; _pendingSymbols[symbol] = null; } if (!AnalysisScope.ShouldSkipDeclarationAnalysis(symbol) && actionCounts.HasAnyExecutableCodeActions) { needsAnalysis = true; _pendingDeclarations[symbol] = _currentlyAnalyzingDeclarationsMapPool.Allocate(); } 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; } }
public void OnCompilationEventGenerated(CompilationEvent compilationEvent, AnalyzerActionCounts actionCounts) { lock (_gate) { if (compilationEvent is SymbolDeclaredCompilationEvent symbolEvent) { 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] = null; } if (actionCounts.SymbolStartActionsCount > 0 && (!skipSymbolAnalysis || !skipDeclarationAnalysis)) { needsAnalysis = true; _lazyPendingSymbolEndAnalyses ??= new Dictionary <ISymbol, AnalyzerStateData?>(); _lazyPendingSymbolEndAnalyses[symbol] = null; } if (!needsAnalysis) { return; } } else if (compilationEvent is CompilationStartedEvent compilationStartedEvent) { var fileCount = actionCounts.SyntaxTreeActionsCount > 0 ? compilationEvent.Compilation.SyntaxTrees.Count() : 0; fileCount += actionCounts.AdditionalFileActionsCount > 0 ? compilationStartedEvent.AdditionalFiles.Length : 0; if (fileCount > 0) { _lazyFilesWithAnalysisData = new Dictionary <SourceOrAdditionalFile, AnalyzerStateData>(); _pendingSyntaxAnalysisFilesCount = fileCount; } if (actionCounts.CompilationActionsCount == 0) { return; } } _pendingEvents[compilationEvent] = null; } }
public void OnCompilationEventGenerated(CompilationEvent compilationEvent, AnalyzerActionCounts actionCounts) { lock (_gate) { var symbolEvent = compilationEvent as SymbolDeclaredCompilationEvent; if (symbolEvent != null) { var needsAnalysis = false; var symbol = symbolEvent.Symbol; if (!AnalysisScope.ShouldSkipSymbolAnalysis(symbolEvent) && actionCounts.SymbolActionsCount > 0) { needsAnalysis = true; _pendingSymbols[symbol] = null; } if (!AnalysisScope.ShouldSkipDeclarationAnalysis(symbol) && (actionCounts.SyntaxNodeActionsCount > 0 || actionCounts.CodeBlockActionsCount > 0 || actionCounts.CodeBlockStartActionsCount > 0)) { foreach (var syntaxRef in symbolEvent.DeclaringSyntaxReferences) { needsAnalysis = true; _pendingDeclarations[syntaxRef.GetSyntax()] = null; } } if (!needsAnalysis) { return; } } else if (compilationEvent is CompilationStartedEvent) { if (actionCounts.SyntaxTreeActionsCount > 0) { var trees = compilationEvent.Compilation.SyntaxTrees; var map = new Dictionary <SyntaxTree, AnalyzerStateData>(trees.Count()); foreach (var tree in trees) { map[tree] = null; } _lazyPendingSyntaxAnalysisTrees = map; } if (actionCounts.CompilationActionsCount == 0) { return; } } _pendingEvents[compilationEvent] = null; } }