Esempio n. 1
0
        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;
            }
        }
Esempio n. 2
0
        /// <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();
                }
            });
        }
Esempio n. 3
0
 public SimpleDiagnosticQueue(Diagnostic diagnostic)
 {
     _queue = new AsyncQueue <Diagnostic>();
     _queue.Enqueue(diagnostic);
 }
Esempio n. 4
0
 public SimpleDiagnosticQueue()
 {
     _queue = new AsyncQueue <Diagnostic>();
 }
Esempio n. 5
0
        /// <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);
                }
            }
        }
Esempio n. 6
0
        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);
            }
        }
Esempio n. 7
0
 public WaiterTaskArguments(TaskCompletionSourceWithCancellation <TElement> waiter, TElement value, AsyncQueue <TElement> @this)
 {
     this.waiter = waiter;
     this.value  = value;
     this.@this  = @this;
 }