// 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); }
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); }
// 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); }