private Task ProcessCompilationUnitCompleted(CompilationUnitCompletedEvent completedEvent, CancellationToken cancellationToken) { // When the compiler is finished with a compilation unit, we can run user diagnostics which // might want to ask the compiler for all the diagnostics in the source file, for example // to get information about unnecessary usings. try { var tasks = ArrayBuilder <Task> .GetInstance(); var semanticModel = completedEvent.SemanticModel; foreach (var da in semanticModelAnalyzers) { // TODO: is the overhead of creating tasks here too high compared to the cost of running them sequentially? tasks.Add(Task.Run(() => { // Catch Exception from da.AnalyzeSemanticModel ExecuteAndCatchIfThrows(da, addDiagnostic, continueOnError, cancellationToken, () => { cancellationToken.ThrowIfCancellationRequested(); da.AnalyzeSemanticModel(semanticModel, addDiagnostic, this.analyzerOptions, cancellationToken); }); })); } return(Task.WhenAll(tasks.ToImmutableAndFree())); } finally { completedEvent.FlushCache(); } }
private Task ProcessCompilationUnitCompleted(CompilationUnitCompletedEvent completedEvent, CancellationToken cancellationToken) { // When the compiler is finished with a compilation unit, we can run user diagnostics which // might want to ask the compiler for all the diagnostics in the source file, for example // to get information about unnecessary usings. try { // Execute analyzers in parallel. var tasks = ArrayBuilder <Task> .GetInstance(); var semanticModel = completedEvent.SemanticModel; foreach (var analyzerAndActions in _semanticModelActionsMap) { var task = Task.Run(() => { // Execute actions for a given analyzer sequentially. analyzerExecutor.ExecuteSemanticModelActions(analyzerAndActions.Value, semanticModel); }, cancellationToken); tasks.Add(task); } return(Task.WhenAll(tasks.ToArrayAndFree())); } finally { completedEvent.FlushCache(); } }
private void UpdateEventsMap_NoLock(CompilationEvent compilationEvent, bool add) { SymbolDeclaredCompilationEvent symbolEvent = compilationEvent as SymbolDeclaredCompilationEvent; if (symbolEvent != null) { // Add/remove symbol events. // Any diagnostics request for a tree should trigger symbol and syntax node analysis for symbols with at least one declaring reference in the tree. foreach (Location location in symbolEvent.Symbol.Locations) { if (location.SourceTree != null) { if (add) { AddPendingSourceEvent_NoLock(location.SourceTree, compilationEvent); } else { RemovePendingSourceEvent_NoLock(location.SourceTree, compilationEvent); } } } } else { // Add/remove compilation unit completed events. CompilationUnitCompletedEvent compilationUnitCompletedEvent = compilationEvent as CompilationUnitCompletedEvent; if (compilationUnitCompletedEvent != null) { SyntaxTree tree = compilationUnitCompletedEvent.SemanticModel.SyntaxTree; if (add) { AddPendingSourceEvent_NoLock(tree, compilationEvent); } else { RemovePendingSourceEvent_NoLock(tree, compilationEvent); } } else if (compilationEvent is CompilationStartedEvent || compilationEvent is CompilationCompletedEvent) { // Add/remove compilation events. if (add) { _pendingNonSourceEvents.Add(compilationEvent); } else { _pendingNonSourceEvents.Remove(compilationEvent); } } else { throw new InvalidOperationException("Unexpected compilation event of type " + compilationEvent.GetType().Name); } } }
private void ProcessCompilationUnitCompleted(CompilationUnitCompletedEvent completedEvent, AnalysisScope analysisScope, AnalysisState analysisStateOpt, CancellationToken cancellationToken) { // When the compiler is finished with a compilation unit, we can run user diagnostics which // might want to ask the compiler for all the diagnostics in the source file, for example // to get information about unnecessary usings. var semanticModel = analysisStateOpt != null ? GetOrCreateCachedSemanticModel(completedEvent.CompilationUnit, completedEvent.Compilation, cancellationToken) : completedEvent.SemanticModel; if (!analysisScope.ShouldAnalyze(semanticModel.SyntaxTree)) { return; } try { foreach (var analyzer in analysisScope.Analyzers) { ImmutableArray<SemanticModelAnalyzerAction> semanticModelActions; if (_semanticModelActionsMap.TryGetValue(analyzer, out semanticModelActions)) { // Execute actions for a given analyzer sequentially. analyzerExecutor.ExecuteSemanticModelActions(semanticModelActions, analyzer, semanticModel, completedEvent, analysisScope, analysisStateOpt); } else { analysisStateOpt?.MarkEventComplete(completedEvent, analyzer); } } } finally { completedEvent.FlushCache(); } }
public CompilationUnitCompletedEvent(CompilationUnitCompletedEvent original, SemanticModel newSemanticModel) : this(original.Compilation, original.CompilationUnit) { SemanticModel = newSemanticModel; }
private Task ProcessCompilationUnitCompleted(CompilationUnitCompletedEvent completedEvent, CancellationToken cancellationToken) { // When the compiler is finished with a compilation unit, we can run user diagnostics which // might want to ask the compiler for all the diagnostics in the source file, for example // to get information about unnecessary usings. try { var tasks = ArrayBuilder<Task>.GetInstance(); var semanticModel = completedEvent.SemanticModel; foreach (var da in semanticModelAnalyzers) { // TODO: is the overhead of creating tasks here too high compared to the cost of running them sequentially? tasks.Add(Task.Run(() => { // Catch Exception from da.AnalyzeSemanticModel ExecuteAndCatchIfThrows(da, addDiagnostic, continueOnAnalyzerException, cancellationToken, () => { cancellationToken.ThrowIfCancellationRequested(); da.AnalyzeSemanticModel(semanticModel, addDiagnostic, this.analyzerOptions, cancellationToken); }); })); } return Task.WhenAll(tasks.ToImmutableAndFree()); } finally { completedEvent.FlushCache(); } }
private async Task ProcessCompilationUnitCompletedAsync(CompilationUnitCompletedEvent completedEvent, CancellationToken cancellationToken) { // When the compiler is finished with a compilation unit, we can run user diagnostics which // might want to ask the compiler for all the diagnostics in the source file, for example // to get information about unnecessary usings. try { // Execute analyzers in parallel. var tasks = ArrayBuilder<Task>.GetInstance(); var semanticModel = completedEvent.SemanticModel; foreach (var analyzerAndActions in _semanticModelActionsMap) { var task = Task.Run(() => { // Execute actions for a given analyzer sequentially. analyzerExecutor.ExecuteSemanticModelActions(analyzerAndActions.Value, semanticModel); }, cancellationToken); tasks.Add(task); } await Task.WhenAll(tasks.ToArrayAndFree()).ConfigureAwait(false); } finally { completedEvent.FlushCache(); } }
private Task ProcessCompilationUnitCompleted(CompilationUnitCompletedEvent completedEvent, CancellationToken cancellationToken) { // When the compiler is finished with a compilation unit, we can run user diagnostics which // might want to ask the compiler for all the diagnostics in the source file, for example // to get information about unnecessary usings. try { // Execute analyzers in parallel. var tasks = ArrayBuilder<Task>.GetInstance(); var semanticModel = completedEvent.SemanticModel; foreach (var analyzerAndActions in _semanticModelActionsMap) { var task = Task.Run(() => { // Execute actions for a given analyzer sequentially. foreach (var semanticModelAction in analyzerAndActions.Value) { Debug.Assert(semanticModelAction.Analyzer == analyzerAndActions.Key); // Catch Exception from semanticModelAction AnalyzerDriverHelper.ExecuteAndCatchIfThrows(semanticModelAction.Analyzer, _addDiagnostic, continueOnAnalyzerException, () => { cancellationToken.ThrowIfCancellationRequested(); var semanticModelContext = new SemanticModelAnalysisContext(semanticModel, this.analyzerOptions, _addDiagnostic, cancellationToken); semanticModelAction.Action(semanticModelContext); }, cancellationToken); } }, cancellationToken); tasks.Add(task); } return Task.WhenAll(tasks.ToArrayAndFree()); } finally { completedEvent.FlushCache(); } }