| Index: pkg/analyzer/lib/src/task/driver.dart
|
| diff --git a/pkg/analyzer/lib/src/task/driver.dart b/pkg/analyzer/lib/src/task/driver.dart
|
| index 17149227675dfbc60c8db9427e19f6d0ddbb5ea1..58aa4af9466798f5913460d05e68724344da1c01 100644
|
| --- a/pkg/analyzer/lib/src/task/driver.dart
|
| +++ b/pkg/analyzer/lib/src/task/driver.dart
|
| @@ -25,11 +25,11 @@ class AnalysisDriver {
|
| */
|
| final TaskManager taskManager;
|
|
|
| -// /**
|
| -// * The list of [WorkManager] used to figure out which analysis results to
|
| -// * compute.
|
| -// */
|
| -// final List<WorkManager> workManagers;
|
| + /**
|
| + * The list of [WorkManager] used to figure out which analysis results to
|
| + * compute.
|
| + */
|
| + final List<WorkManager> workManagers;
|
|
|
| /**
|
| * The context in which analysis is to be performed.
|
| @@ -56,7 +56,7 @@ class AnalysisDriver {
|
| * Initialize a newly created driver to use the tasks know to the given
|
| * [taskManager] to perform analysis in the given [context].
|
| */
|
| - AnalysisDriver(this.taskManager, this.context) {
|
| + AnalysisDriver(this.taskManager, this.workManagers, this.context) {
|
| _onTaskStartedController = new StreamController.broadcast();
|
| _onTaskCompletedController = new StreamController.broadcast();
|
| }
|
| @@ -91,28 +91,31 @@ class AnalysisDriver {
|
| * or `null` if there is currently no work to be done.
|
| */
|
| WorkOrder createNextWorkOrder() {
|
| - //
|
| - // TODO(brianwilkerson) This is an inefficient implementation. We need to
|
| - // port over the concept of the WorkManager to manage the list of sources
|
| - // for which some work needs to be performed so that we do not waste time
|
| - // repeatedly looking at the same completed sources to see whether there is
|
| - // work that needs to be done.
|
| - //
|
| - for (AnalysisTarget target in context.priorityTargets) {
|
| - WorkOrder workOrder = createWorkOrderForTarget(target, true);
|
| - if (workOrder != null) {
|
| - return workOrder;
|
| + while (true) {
|
| + // Find the WorkManager with the highest priority.
|
| + WorkOrderPriority highestPriority = null;
|
| + WorkManager highestManager = null;
|
| + for (WorkManager manager in workManagers) {
|
| + WorkOrderPriority priority = manager.getNextResultPriority();
|
| + if (highestPriority == null || highestPriority.index > priority.index) {
|
| + highestPriority = priority;
|
| + highestManager = manager;
|
| + }
|
| }
|
| - }
|
| - // TODO(brianwilkerson) Add a third priority, corresponding to
|
| - // AnalysisContextImpl._pendingFutureSources to support code completion.
|
| - for (AnalysisTarget target in context.explicitTargets) {
|
| - WorkOrder workOrder = createWorkOrderForTarget(target, false);
|
| - if (workOrder != null) {
|
| - return workOrder;
|
| + // Nothing to do.
|
| + if (highestPriority == WorkOrderPriority.NONE) {
|
| + return null;
|
| + }
|
| + // Create a new WorkOrder.
|
| + TargetedResult request = highestManager.getNextResult();
|
| + if (request != null) {
|
| + WorkOrder workOrder =
|
| + createWorkOrderForResult(request.target, request.result);
|
| + if (workOrder != null) {
|
| + return workOrder;
|
| + }
|
| }
|
| }
|
| - return null;
|
| }
|
|
|
| /**
|
| @@ -224,6 +227,9 @@ class AnalysisDriver {
|
| // and throw an exception if not (unless we want to allow null values).
|
| entry.setValue(result, outputs[result], dependedOn);
|
| }
|
| + for (WorkManager manager in workManagers) {
|
| + manager.resultsComputed(task.target, outputs);
|
| + }
|
| } else {
|
| entry.setErrorState(task.caughtException, item.descriptor.results);
|
| }
|
| @@ -402,6 +408,62 @@ class WorkItem {
|
| }
|
|
|
| /**
|
| + * [AnalysisDriver] uses [WorkManager]s to select results to compute.
|
| + *
|
| + * They know specific of the targets and results they care about,
|
| + * so they can request analysis results in optimal order.
|
| + */
|
| +abstract class WorkManager {
|
| + /**
|
| + * Return the next [TargetedResult] that this work manager wants to be
|
| + * computed, or `null` if this manager doesn't need any new results.
|
| + */
|
| + TargetedResult getNextResult();
|
| +
|
| + /**
|
| + * Return the priority if the next work order this work manager want to be
|
| + * computed. The [AnalysisDriver] will perform the work order with
|
| + * the highest priority.
|
| + *
|
| + * Even if the returned value is [WorkOrderPriority.NONE], it still does not
|
| + * guarantee that [getNextResult] will return not `null`.
|
| + */
|
| + WorkOrderPriority getNextResultPriority();
|
| +
|
| + /**
|
| + * Notifies the manager that the given [outputs] were produced for
|
| + * the given [target].
|
| + */
|
| + void resultsComputed(
|
| + AnalysisTarget target, Map<ResultDescriptor, dynamic> outputs);
|
| +}
|
| +
|
| +/**
|
| + * The priorities of work orders returned by [WorkManager]s.
|
| + */
|
| +enum WorkOrderPriority {
|
| + /**
|
| + * Responding to an user's action.
|
| + */
|
| + INTERACTIVE,
|
| +
|
| + /**
|
| + * Computing information for priority sources.
|
| + */
|
| + PRIORITY,
|
| +
|
| + /**
|
| + * A work should be done, but without any special urgency.
|
| + */
|
| + NORMAL,
|
| +
|
| + /**
|
| + * Nothing to do.
|
| + */
|
| + NONE
|
| +}
|
| +
|
| +/**
|
| * A description of the work to be done to compute a desired analysis result.
|
| * The class implements a lazy depth-first traversal of the work item's input.
|
| */
|
| @@ -475,24 +537,3 @@ class WorkOrder implements Iterator<WorkItem> {
|
| return false;
|
| }
|
| }
|
| -
|
| -/**
|
| - * [AnalysisDriver] uses [WorkManager]s to select results to compute.
|
| - *
|
| - * They know specific of the targets and results they care about,
|
| - * so they can request analysis results in optimal order.
|
| - */
|
| -abstract class WorkManager {
|
| - /**
|
| - * Return the next [TargetedResult] that this work manager wants to be
|
| - * computed, or `null` if this manager doesn't need any new results.
|
| - */
|
| - TargetedResult getNextResult();
|
| -
|
| - /**
|
| - * Notifies the manager that the given [outputs] were produced for
|
| - * the given [target].
|
| - */
|
| - void resultsComputed(
|
| - AnalysisTarget target, Map<ResultDescriptor, dynamic> outputs);
|
| -}
|
|
|