Support for out-of-band worker in AnalysisDriverScheduler.

It will be used to perform work of searching for available declarations
and sending corresponding completion libraris notifications.

R=brianwilkerson@google.com

Change-Id: I21b23c4fadf1dc679c16ff00a47149d62707ae51
Reviewed-on: https://dart-review.googlesource.com/c/91581
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index d8bdecf..895a8ec 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -1989,6 +1989,14 @@
 
   bool _started = false;
 
+  /**
+   * The optional worker that is invoked when its work priority is higher
+   * than work priorities in drivers.
+   *
+   * Don't use outside of Analyzer and Analysis Server.
+   */
+  SchedulerWorker outOfBandWorker;
+
   AnalysisDriverScheduler(this._logger, {this.driverWatcher});
 
   /**
@@ -2100,6 +2108,17 @@
         }
       }
 
+      if (outOfBandWorker != null) {
+        var workerPriority = outOfBandWorker.workPriority;
+        if (workerPriority != AnalysisDriverPriority.nothing) {
+          if (workerPriority.index > bestPriority.index) {
+            await outOfBandWorker.performWork();
+            _hasWork.notify();
+            continue;
+          }
+        }
+      }
+
       // Transition to idle if no files to analyze.
       if (!_hasFilesToAnalyze) {
         _statusSupport.transitionToIdle();
@@ -2262,6 +2281,15 @@
   ExceptionResult(this.path, this.exception, this.contextKey);
 }
 
+/// Worker in [AnalysisDriverScheduler].
+abstract class SchedulerWorker {
+  /// Return the priority of work that this worker needs to perform.
+  AnalysisDriverPriority get workPriority;
+
+  /// Perform a single chunk of work.
+  Future<void> performWork();
+}
+
 /**
  * Task that discovers all files that are available to the driver, and makes
  * them known.