예제 #1
0
        // internal for testing purposes
        internal static AnalyzerDriver Create(
            Compilation compilation,
            ImmutableArray <DiagnosticAnalyzer> analyzers,
            AnalyzerOptions options,
            AnalyzerManager analyzerManager,
            Action <Diagnostic> addExceptionDiagnostic,
            out Compilation newCompilation,
            Func <Exception, DiagnosticAnalyzer, bool> continueOnAnalyzerException,
            CancellationToken cancellationToken)
        {
            options = options ?? AnalyzerOptions.Empty;
            AnalyzerDriver analyzerDriver = compilation.AnalyzerForLanguage(analyzers, analyzerManager, cancellationToken);

            newCompilation = compilation.WithEventQueue(analyzerDriver.CompilationEventQueue);

            continueOnAnalyzerException = continueOnAnalyzerException ?? ((exception, analyzer) => true);
            var addDiagnostic = GetDiagnosticSinkWithSuppression(analyzerDriver.DiagnosticQueue.Enqueue, newCompilation);

            addExceptionDiagnostic = addExceptionDiagnostic != null?
                                     GetDiagnosticSinkWithSuppression(addExceptionDiagnostic, newCompilation) :
                                         addDiagnostic;

            var analyzerExecutor = AnalyzerExecutor.Create(newCompilation, options, addDiagnostic, addExceptionDiagnostic, continueOnAnalyzerException, cancellationToken);

            analyzerDriver.Initialize(newCompilation, analyzerExecutor, cancellationToken);

            return(analyzerDriver);
        }
예제 #2
0
        private async Task <AnalyzerDriver> GetAnalyzerDriverAsync(CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            // Get instance of analyzer driver from the driver pool.
            AnalyzerDriver driver = _driverPool.Allocate();

            try
            {
                // Start the initialization task, if required.
                if (driver.WhenInitializedTask == null)
                {
                    driver.Initialize(_compilation, _analysisOptions, categorizeDiagnostics: true, cancellationToken: cancellationToken);
                }

                // Wait for driver initilization to complete: this executes the Initialize and CompilationStartActions to compute all registered actions per-analyzer.
                await driver.WhenInitializedTask.ConfigureAwait(false);
            }
            finally
            {
                if (driver.WhenInitializedTask.IsCanceled)
                {
                    // If the initialization task was cancelled, we retry again with our own cancellation token.
                    // This can happen if the task that started the initialization was cancelled by the callee, and the new request picked up this driver instance.
                    _driverPool.ForgetTrackedObject(driver);
                    driver = await GetAnalyzerDriverAsync(cancellationToken).ConfigureAwait(false);
                }
            }

            return(driver);
        }
예제 #3
0
        // internal for testing purposes
        internal static AnalyzerDriver Create(
            Compilation compilation,
            ImmutableArray <DiagnosticAnalyzer> analyzers,
            AnalyzerOptions options,
            AnalyzerManager analyzerManager,
            Action <Exception, DiagnosticAnalyzer, Diagnostic> onAnalyzerException,
            out Compilation newCompilation,
            CancellationToken cancellationToken)
        {
            options = options ?? AnalyzerOptions.Empty;
            AnalyzerDriver analyzerDriver = compilation.AnalyzerForLanguage(analyzers, analyzerManager, cancellationToken);

            newCompilation = compilation.WithEventQueue(analyzerDriver.CompilationEventQueue);

            var addDiagnostic = GetDiagnosticSinkWithSuppression(analyzerDriver.DiagnosticQueue.Enqueue, newCompilation);

            Action <Exception, DiagnosticAnalyzer, Diagnostic> newOnAnalyzerException;

            if (onAnalyzerException != null)
            {
                // Wrap onAnalyzerException to pass in filtered diagnostic.
                var comp = newCompilation;
                newOnAnalyzerException = (ex, analyzer, diagnostic) =>
                                         onAnalyzerException(ex, analyzer, GetFilteredDiagnostic(diagnostic, comp));
            }
            else
            {
                // Add exception diagnostic to regular diagnostic bag.
                newOnAnalyzerException = (ex, analyzer, diagnostic) => addDiagnostic(diagnostic);
            }

            var analyzerExecutor = AnalyzerExecutor.Create(newCompilation, options, addDiagnostic, newOnAnalyzerException, cancellationToken);

            analyzerDriver.Initialize(newCompilation, analyzerExecutor, cancellationToken);

            return(analyzerDriver);
        }