Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(290)

Side by Side Diff: pkg/analyzer/lib/src/task/driver.dart

Issue 1311773005: Extension point for WorkManagerFactory(s). (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library analyzer.src.task.driver; 5 library analyzer.src.task.driver;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 9
10 import 'package:analyzer/src/context/cache.dart'; 10 import 'package:analyzer/src/context/cache.dart';
11 import 'package:analyzer/src/generated/engine.dart' 11 import 'package:analyzer/src/generated/engine.dart'
12 hide AnalysisTask, AnalysisContextImpl; 12 hide AnalysisTask, AnalysisContextImpl;
13 import 'package:analyzer/src/generated/java_engine.dart'; 13 import 'package:analyzer/src/generated/java_engine.dart';
14 import 'package:analyzer/src/generated/resolver.dart'; 14 import 'package:analyzer/src/generated/resolver.dart';
15 import 'package:analyzer/src/generated/source.dart';
15 import 'package:analyzer/src/generated/utilities_general.dart'; 16 import 'package:analyzer/src/generated/utilities_general.dart';
16 import 'package:analyzer/src/task/inputs.dart'; 17 import 'package:analyzer/src/task/inputs.dart';
17 import 'package:analyzer/src/task/manager.dart'; 18 import 'package:analyzer/src/task/manager.dart';
18 import 'package:analyzer/task/model.dart'; 19 import 'package:analyzer/task/model.dart';
20 import 'package:analyzer/src/generated/error.dart';
19 21
20 final PerformanceTag workOrderMoveNextPerfTag = 22 final PerformanceTag workOrderMoveNextPerfTag =
21 new PerformanceTag('WorkOrder.moveNext'); 23 new PerformanceTag('WorkOrder.moveNext');
22 24
23 /** 25 /**
24 * An object that is used to cause analysis to be performed until all of the 26 * An object that is used to cause analysis to be performed until all of the
25 * required analysis information has been computed. 27 * required analysis information has been computed.
26 */ 28 */
27 class AnalysisDriver { 29 class AnalysisDriver {
28 /** 30 /**
29 * The task manager used to figure out how to compute analysis results. 31 * The task manager used to figure out how to compute analysis results.
30 */ 32 */
31 final TaskManager taskManager; 33 final TaskManager taskManager;
32 34
33 /** 35 /**
34 * The list of [WorkManager] used to figure out which analysis results to 36 * The list of [WorkManager] used to figure out which analysis results to
35 * compute. 37 * compute.
36 */ 38 */
37 final List<WorkManager> workManagers; 39 final List<WorkManager> workManagers;
38 40
39 /** 41 /**
40 * The context in which analysis is to be performed. 42 * The context in which analysis is to be performed.
41 */ 43 */
42 final InternalAnalysisContext context; 44 final InternalAnalysisContext context;
43 45
44 /** 46 /**
45 * The map of [ComputedResult] controllers. 47 * The map of [ComputedResult] controllers.
46 */ 48 */
47 final Map<ResultDescriptor, StreamController<ComputedResult>> resultComputedCo ntrollers = 49 final Map<ResultDescriptor,
50 StreamController<ComputedResult>> resultComputedControllers =
48 <ResultDescriptor, StreamController<ComputedResult>>{}; 51 <ResultDescriptor, StreamController<ComputedResult>>{};
49 52
50 /** 53 /**
51 * The work order that was previously computed but that has not yet been 54 * The work order that was previously computed but that has not yet been
52 * completed. 55 * completed.
53 */ 56 */
54 WorkOrder currentWorkOrder; 57 WorkOrder currentWorkOrder;
55 58
56 /** 59 /**
57 * Indicates whether any tasks are currently being performed (or building 60 * Indicates whether any tasks are currently being performed (or building
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 } 193 }
191 } 194 }
192 return null; 195 return null;
193 } 196 }
194 197
195 /** 198 /**
196 * Return the stream that is notified when a new value for the given 199 * Return the stream that is notified when a new value for the given
197 * [descriptor] is computed. 200 * [descriptor] is computed.
198 */ 201 */
199 Stream<ComputedResult> onResultComputed(ResultDescriptor descriptor) { 202 Stream<ComputedResult> onResultComputed(ResultDescriptor descriptor) {
200 return resultComputedControllers.putIfAbsent(descriptor, () => 203 return resultComputedControllers
201 new StreamController<ComputedResult>.broadcast(sync: true)).stream; 204 .putIfAbsent(descriptor,
205 () => new StreamController<ComputedResult>.broadcast(sync: true))
206 .stream;
202 } 207 }
203 208
204 /** 209 /**
205 * Perform the next analysis task, and return `true` if there is more work to 210 * Perform the next analysis task, and return `true` if there is more work to
206 * be done in order to compute all of the required analysis information. 211 * be done in order to compute all of the required analysis information.
207 */ 212 */
208 bool performAnalysisTask() { 213 bool performAnalysisTask() {
209 // 214 //
210 // TODO(brianwilkerson) This implementaiton does not allow us to prioritize 215 // TODO(brianwilkerson) This implementaiton does not allow us to prioritize
211 // work across contexts. What we need is a way for an external client to ask 216 // work across contexts. What we need is a way for an external client to ask
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 * the set of [WorkItem]s contained in the cycle (if there are overlapping 474 * the set of [WorkItem]s contained in the cycle (if there are overlapping
470 * cycles, this is the set of all [WorkItem]s in the entire strongly 475 * cycles, this is the set of all [WorkItem]s in the entire strongly
471 * connected component). Otherwise, `null`. 476 * connected component). Otherwise, `null`.
472 */ 477 */
473 final List<WorkItem> dependencyCycle; 478 final List<WorkItem> dependencyCycle;
474 479
475 /** 480 /**
476 * Initialize a newly created exception to represent a failed attempt to 481 * Initialize a newly created exception to represent a failed attempt to
477 * perform the given [task] due to the given [dependencyCycle]. 482 * perform the given [task] due to the given [dependencyCycle].
478 */ 483 */
479 InfiniteTaskLoopException(AnalysisTask task, this.dependencyCycle) : super( 484 InfiniteTaskLoopException(AnalysisTask task, this.dependencyCycle)
480 'Infinite loop while performing task ${task.descriptor.name} for ${tas k.target}'); 485 : super(
486 'Infinite loop while performing task ${task.descriptor.name} for ${t ask.target}');
481 } 487 }
482 488
483 /** 489 /**
484 * Object used by CycleAwareDependencyWalker to report a single strongly 490 * Object used by CycleAwareDependencyWalker to report a single strongly
485 * connected component of nodes. 491 * connected component of nodes.
486 */ 492 */
487 class StronglyConnectedComponent<Node> { 493 class StronglyConnectedComponent<Node> {
488 /** 494 /**
489 * The nodes contained in the strongly connected component. 495 * The nodes contained in the strongly connected component.
490 */ 496 */
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 * cycles, this is the set of all [WorkItem]s in the entire strongly 564 * cycles, this is the set of all [WorkItem]s in the entire strongly
559 * connected component). Otherwise, `null`. 565 * connected component). Otherwise, `null`.
560 */ 566 */
561 List<WorkItem> dependencyCycle; 567 List<WorkItem> dependencyCycle;
562 568
563 /** 569 /**
564 * Initialize a newly created work item to compute the inputs for the task 570 * Initialize a newly created work item to compute the inputs for the task
565 * described by the given descriptor. 571 * described by the given descriptor.
566 */ 572 */
567 WorkItem(this.context, this.target, this.descriptor, this.spawningResult) { 573 WorkItem(this.context, this.target, this.descriptor, this.spawningResult) {
568 AnalysisTarget actualTarget = identical( 574 AnalysisTarget actualTarget =
569 target, AnalysisContextTarget.request) 575 identical(target, AnalysisContextTarget.request)
570 ? new AnalysisContextTarget(context) 576 ? new AnalysisContextTarget(context)
571 : target; 577 : target;
572 Map<String, TaskInput> inputDescriptors = 578 Map<String, TaskInput> inputDescriptors =
573 descriptor.createTaskInputs(actualTarget); 579 descriptor.createTaskInputs(actualTarget);
574 builder = new TopLevelTaskInputBuilder(inputDescriptors); 580 builder = new TopLevelTaskInputBuilder(inputDescriptors);
575 if (!builder.moveNext()) { 581 if (!builder.moveNext()) {
576 builder = null; 582 builder = null;
577 } 583 }
578 inputs = new HashMap<String, dynamic>(); 584 inputs = new HashMap<String, dynamic>();
579 } 585 }
580 586
581 @override 587 @override
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 } 678 }
673 679
674 /** 680 /**
675 * [AnalysisDriver] uses [WorkManager]s to select results to compute. 681 * [AnalysisDriver] uses [WorkManager]s to select results to compute.
676 * 682 *
677 * They know specific of the targets and results they care about, 683 * They know specific of the targets and results they care about,
678 * so they can request analysis results in optimal order. 684 * so they can request analysis results in optimal order.
679 */ 685 */
680 abstract class WorkManager { 686 abstract class WorkManager {
681 /** 687 /**
688 * Notifies the manager about changes in the explicit source list.
689 */
690 void applyChange(List<Source> addedSources, List<Source> changedSources,
691 List<Source> removedSources);
692
693 /**
682 * Notifies the managers that the given set of priority [targets] was set. 694 * Notifies the managers that the given set of priority [targets] was set.
683 */ 695 */
684 void applyPriorityTargets(List<AnalysisTarget> targets); 696 void applyPriorityTargets(List<AnalysisTarget> targets);
685 697
686 /** 698 /**
699 * Return a list of all of the errors associated with the given [source].
700 * The list of errors will be empty if the source is not known to the context
701 * or if there are no errors in the source. The errors contained in the list
702 * can be incomplete.
703 */
704 List<AnalysisError> getErrors(Source source);
705
706 /**
687 * Return the next [TargetedResult] that this work manager wants to be 707 * Return the next [TargetedResult] that this work manager wants to be
688 * computed, or `null` if this manager doesn't need any new results. 708 * computed, or `null` if this manager doesn't need any new results.
689 */ 709 */
690 TargetedResult getNextResult(); 710 TargetedResult getNextResult();
691 711
692 /** 712 /**
693 * Return the priority if the next work order this work manager want to be 713 * Return the priority if the next work order this work manager want to be
694 * computed. The [AnalysisDriver] will perform the work order with 714 * computed. The [AnalysisDriver] will perform the work order with
695 * the highest priority. 715 * the highest priority.
696 * 716 *
697 * Even if the returned value is [WorkOrderPriority.NONE], it still does not 717 * Even if the returned value is [WorkOrderPriority.NONE], it still does not
698 * guarantee that [getNextResult] will return not `null`. 718 * guarantee that [getNextResult] will return not `null`.
699 */ 719 */
700 WorkOrderPriority getNextResultPriority(); 720 WorkOrderPriority getNextResultPriority();
701 721
702 /** 722 /**
723 * Notifies the manager about analysis options changes.
724 */
725 void onAnalysisOptionsChanged();
726
727 /**
728 * Notifies the manager about [SourceFactory] changes.
729 */
730 void onSourceFactoryChanged();
731
732 /**
703 * Notifies the manager that the given [outputs] were produced for 733 * Notifies the manager that the given [outputs] were produced for
704 * the given [target]. 734 * the given [target].
705 */ 735 */
706 void resultsComputed( 736 void resultsComputed(
707 AnalysisTarget target, Map<ResultDescriptor, dynamic> outputs); 737 AnalysisTarget target, Map<ResultDescriptor, dynamic> outputs);
708 } 738 }
709 739
710 /** 740 /**
711 * A description of the work to be done to compute a desired analysis result. 741 * A description of the work to be done to compute a desired analysis result.
712 * The class implements a lazy depth-first traversal of the work item's input. 742 * The class implements a lazy depth-first traversal of the work item's input.
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 final TaskManager taskManager; 838 final TaskManager taskManager;
809 839
810 _WorkOrderDependencyWalker(this.taskManager, WorkItem startingNode) 840 _WorkOrderDependencyWalker(this.taskManager, WorkItem startingNode)
811 : super(startingNode); 841 : super(startingNode);
812 842
813 @override 843 @override
814 WorkItem getNextInput(WorkItem node, List<WorkItem> skipInputs) { 844 WorkItem getNextInput(WorkItem node, List<WorkItem> skipInputs) {
815 return node.gatherInputs(taskManager, skipInputs); 845 return node.gatherInputs(taskManager, skipInputs);
816 } 846 }
817 } 847 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698