OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |