public async Task OnCompilationEventsGeneratedAsync( Func <AsyncQueue <CompilationEvent>, ImmutableArray <AdditionalText>, ImmutableArray <CompilationEvent> > getCompilationEvents, AsyncQueue <CompilationEvent> eventQueue, ImmutableArray <AdditionalText> additionalFiles, AnalyzerDriver driver, CancellationToken cancellationToken) { try { await EnsureAnalyzerActionCountsInitializedAsync(driver, cancellationToken).ConfigureAwait(false); using (_gate.DisposableWait(cancellationToken)) { // Defer the call to 'getCompilationEvents' until we know cancellation is no longer possible OnCompilationEventsGenerated_NoLock(getCompilationEvents(eventQueue, additionalFiles)); } } catch (Exception e) when(FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } }
/// <summary> /// Create an analyzer driver. /// </summary> /// <param name="analyzers">The set of analyzers to include in the analysis</param> /// <param name="options">Options that are passed to analyzers</param> /// <param name="cancellationToken">a cancellation token that can be used to abort analysis</param> protected AnalyzerDriver3(ImmutableArray <IDiagnosticAnalyzer> analyzers, AnalyzerOptions options, CancellationToken cancellationToken) { CompilationEventQueue = new AsyncQueue <CompilationEvent>(); DiagnosticQueue = new AsyncQueue <Diagnostic>(); addDiagnostic = GetDiagnosticSinkWithSuppression(); analyzerOptions = options; // start the first task to drain the event queue. The first compilation event is to be handled before // any other ones, so we cannot have more than one event processing task until the first event has been handled. initialWorker = Task.Run(async() => { try { await InitialWorker(analyzers, continueOnError, cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { // If creation is cancelled we had better not use the driver any longer this.Dispose(); } }); }
public SimpleDiagnosticQueue(Diagnostic diagnostic) { _queue = new AsyncQueue <Diagnostic>(); _queue.Enqueue(diagnostic); }
public SimpleDiagnosticQueue() { _queue = new AsyncQueue <Diagnostic>(); }
/// <summary> /// Core method for executing analyzers. /// </summary> private async Task ComputeAnalyzerDiagnosticsCoreAsync(AnalyzerDriver driver, AsyncQueue <CompilationEvent> eventQueue, AnalysisScope analysisScope, CancellationToken cancellationToken) { Debug.Assert(!driver.WhenInitializedTask.IsCanceled); if (eventQueue.Count > 0 || _analysisState.HasPendingSyntaxAnalysis(analysisScope)) { try { // Perform analysis to compute new diagnostics. Debug.Assert(!eventQueue.IsCompleted); await driver.AttachQueueAndProcessAllEventsAsync(eventQueue, analysisScope, _analysisState, cancellationToken : cancellationToken).ConfigureAwait(false); } finally { // Update the diagnostic results based on the diagnostics reported on the driver. _analysisResult.StoreAnalysisResult(analysisScope, driver); } } }
private async Task ComputeAnalyzerDiagnosticsAsync(AnalysisScope analysisScope, Action generateCompilationEventsOpt, Func <AsyncQueue <CompilationEvent> > getEventQueue, int newTaskToken, CancellationToken cancellationToken) { AnalyzerDriver driver = null; Task computeTask = null; CancellationTokenSource cts; // Generate compilation events, if required. if (generateCompilationEventsOpt != null) { generateCompilationEventsOpt(); } // Populate the events cache from the generated compilation events. await PopulateEventsCacheAsync(cancellationToken).ConfigureAwait(false); try { // Get the analyzer driver to execute analysis. driver = await GetAnalyzerDriverAsync(cancellationToken).ConfigureAwait(false); // Driver must have been initialized. Debug.Assert(driver.WhenInitializedTask != null); Debug.Assert(!driver.WhenInitializedTask.IsCanceled); cancellationToken.ThrowIfCancellationRequested(); // Track if this task was suspended by another tree diagnostics request for the same tree. // If so, we wait for the high priority requests to complete before restarting analysis. bool suspendend; do { suspendend = false; // Create a new cancellation source to allow higher priority requests to suspend our analysis. cts = new CancellationTokenSource(); // Link the cancellation source with client supplied cancellation source, so the public API callee can also cancel analysis. using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, cancellationToken)) { try { // Core task to compute analyzer diagnostics. Func <Tuple <Task, CancellationTokenSource> > getComputeTask = () => Tuple.Create( Task.Run(async() => { AsyncQueue <CompilationEvent> eventQueue = null; try { // Get event queue with pending events to analyze. eventQueue = getEventQueue(); // Execute analyzer driver on the given analysis scope with the given event queue. await ComputeAnalyzerDiagnosticsCoreAsync(driver, eventQueue, analysisScope, cancellationToken: linkedCts.Token).ConfigureAwait(false); } finally { FreeEventQueue(eventQueue); } }, linkedCts.Token), cts); // Wait for higher priority tree document tasks to complete. computeTask = await SetActiveAnalysisTaskAsync(getComputeTask, analysisScope.FilterTreeOpt, newTaskToken, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); await computeTask.ConfigureAwait(false); } catch (OperationCanceledException) { cancellationToken.ThrowIfCancellationRequested(); suspendend = cts.IsCancellationRequested; } finally { cts.Dispose(); ClearExecutingTask(computeTask, analysisScope.FilterTreeOpt); computeTask = null; } } } while (suspendend); } finally { FreeDriver(driver); } }
public WaiterTaskArguments(TaskCompletionSourceWithCancellation <TElement> waiter, TElement value, AsyncQueue <TElement> @this) { this.waiter = waiter; this.value = value; this.@this = @this; }