| 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, WorkManager; | 
| 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/utilities_general.dart'; | 15 import 'package:analyzer/src/generated/utilities_general.dart'; | 
| 16 import 'package:analyzer/src/task/inputs.dart'; | 16 import 'package:analyzer/src/task/inputs.dart'; | 
| 17 import 'package:analyzer/src/task/manager.dart'; | 17 import 'package:analyzer/src/task/manager.dart'; | 
| 18 import 'package:analyzer/task/model.dart'; | 18 import 'package:analyzer/task/model.dart'; | 
| 19 | 19 | 
| 20 final PerformanceTag workOrderMoveNextPerfTag = | 20 final PerformanceTag workOrderMoveNextPerfTag = | 
| 21     new PerformanceTag('WorkOrder.moveNext'); | 21     new PerformanceTag('WorkOrder.moveNext'); | 
| 22 | 22 | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 37   final List<WorkManager> workManagers; | 37   final List<WorkManager> workManagers; | 
| 38 | 38 | 
| 39   /** | 39   /** | 
| 40    * The context in which analysis is to be performed. | 40    * The context in which analysis is to be performed. | 
| 41    */ | 41    */ | 
| 42   final InternalAnalysisContext context; | 42   final InternalAnalysisContext context; | 
| 43 | 43 | 
| 44   /** | 44   /** | 
| 45    * The map of [ComputedResult] controllers. | 45    * The map of [ComputedResult] controllers. | 
| 46    */ | 46    */ | 
| 47   final Map<ResultDescriptor, StreamController<ComputedResult>> resultComputedCo
     ntrollers = | 47   final Map<ResultDescriptor, | 
|  | 48           StreamController<ComputedResult>> resultComputedControllers = | 
| 48       <ResultDescriptor, StreamController<ComputedResult>>{}; | 49       <ResultDescriptor, StreamController<ComputedResult>>{}; | 
| 49 | 50 | 
| 50   /** | 51   /** | 
| 51    * The work order that was previously computed but that has not yet been | 52    * The work order that was previously computed but that has not yet been | 
| 52    * completed. | 53    * completed. | 
| 53    */ | 54    */ | 
| 54   WorkOrder currentWorkOrder; | 55   WorkOrder currentWorkOrder; | 
| 55 | 56 | 
| 56   /** | 57   /** | 
| 57    * Indicates whether any tasks are currently being performed (or building | 58    * Indicates whether any tasks are currently being performed (or building | 
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 190       } | 191       } | 
| 191     } | 192     } | 
| 192     return null; | 193     return null; | 
| 193   } | 194   } | 
| 194 | 195 | 
| 195   /** | 196   /** | 
| 196    * Return the stream that is notified when a new value for the given | 197    * Return the stream that is notified when a new value for the given | 
| 197    * [descriptor] is computed. | 198    * [descriptor] is computed. | 
| 198    */ | 199    */ | 
| 199   Stream<ComputedResult> onResultComputed(ResultDescriptor descriptor) { | 200   Stream<ComputedResult> onResultComputed(ResultDescriptor descriptor) { | 
| 200     return resultComputedControllers.putIfAbsent(descriptor, () => | 201     return resultComputedControllers | 
| 201         new StreamController<ComputedResult>.broadcast(sync: true)).stream; | 202         .putIfAbsent(descriptor, | 
|  | 203             () => new StreamController<ComputedResult>.broadcast(sync: true)) | 
|  | 204         .stream; | 
| 202   } | 205   } | 
| 203 | 206 | 
| 204   /** | 207   /** | 
| 205    * Perform the next analysis task, and return `true` if there is more work to | 208    * 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. | 209    * be done in order to compute all of the required analysis information. | 
| 207    */ | 210    */ | 
| 208   bool performAnalysisTask() { | 211   bool performAnalysisTask() { | 
| 209     // | 212     // | 
| 210     // TODO(brianwilkerson) This implementaiton does not allow us to prioritize | 213     // 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 | 214     // 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 | 472    * 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 | 473    * cycles, this is the set of all [WorkItem]s in the entire strongly | 
| 471    * connected component).  Otherwise, `null`. | 474    * connected component).  Otherwise, `null`. | 
| 472    */ | 475    */ | 
| 473   final List<WorkItem> dependencyCycle; | 476   final List<WorkItem> dependencyCycle; | 
| 474 | 477 | 
| 475   /** | 478   /** | 
| 476    * Initialize a newly created exception to represent a failed attempt to | 479    * Initialize a newly created exception to represent a failed attempt to | 
| 477    * perform the given [task] due to the given [dependencyCycle]. | 480    * perform the given [task] due to the given [dependencyCycle]. | 
| 478    */ | 481    */ | 
| 479   InfiniteTaskLoopException(AnalysisTask task, this.dependencyCycle) : super( | 482   InfiniteTaskLoopException(AnalysisTask task, this.dependencyCycle) | 
| 480           'Infinite loop while performing task ${task.descriptor.name} for ${tas
     k.target}'); | 483       : super( | 
|  | 484             'Infinite loop while performing task ${task.descriptor.name} for ${t
     ask.target}'); | 
| 481 } | 485 } | 
| 482 | 486 | 
| 483 /** | 487 /** | 
| 484  * Object used by CycleAwareDependencyWalker to report a single strongly | 488  * Object used by CycleAwareDependencyWalker to report a single strongly | 
| 485  * connected component of nodes. | 489  * connected component of nodes. | 
| 486  */ | 490  */ | 
| 487 class StronglyConnectedComponent<Node> { | 491 class StronglyConnectedComponent<Node> { | 
| 488   /** | 492   /** | 
| 489    * The nodes contained in the strongly connected component. | 493    * The nodes contained in the strongly connected component. | 
| 490    */ | 494    */ | 
| (...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 | 562    * cycles, this is the set of all [WorkItem]s in the entire strongly | 
| 559    * connected component).  Otherwise, `null`. | 563    * connected component).  Otherwise, `null`. | 
| 560    */ | 564    */ | 
| 561   List<WorkItem> dependencyCycle; | 565   List<WorkItem> dependencyCycle; | 
| 562 | 566 | 
| 563   /** | 567   /** | 
| 564    * Initialize a newly created work item to compute the inputs for the task | 568    * Initialize a newly created work item to compute the inputs for the task | 
| 565    * described by the given descriptor. | 569    * described by the given descriptor. | 
| 566    */ | 570    */ | 
| 567   WorkItem(this.context, this.target, this.descriptor, this.spawningResult) { | 571   WorkItem(this.context, this.target, this.descriptor, this.spawningResult) { | 
| 568     AnalysisTarget actualTarget = identical( | 572     AnalysisTarget actualTarget = | 
| 569             target, AnalysisContextTarget.request) | 573         identical(target, AnalysisContextTarget.request) | 
| 570         ? new AnalysisContextTarget(context) | 574             ? new AnalysisContextTarget(context) | 
| 571         : target; | 575             : target; | 
| 572     Map<String, TaskInput> inputDescriptors = | 576     Map<String, TaskInput> inputDescriptors = | 
| 573         descriptor.createTaskInputs(actualTarget); | 577         descriptor.createTaskInputs(actualTarget); | 
| 574     builder = new TopLevelTaskInputBuilder(inputDescriptors); | 578     builder = new TopLevelTaskInputBuilder(inputDescriptors); | 
| 575     if (!builder.moveNext()) { | 579     if (!builder.moveNext()) { | 
| 576       builder = null; | 580       builder = null; | 
| 577     } | 581     } | 
| 578     inputs = new HashMap<String, dynamic>(); | 582     inputs = new HashMap<String, dynamic>(); | 
| 579   } | 583   } | 
| 580 | 584 | 
| 581   @override | 585   @override | 
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 665       } | 669       } | 
| 666     } | 670     } | 
| 667     return null; | 671     return null; | 
| 668   } | 672   } | 
| 669 | 673 | 
| 670   @override | 674   @override | 
| 671   String toString() => 'Run $descriptor on $target'; | 675   String toString() => 'Run $descriptor on $target'; | 
| 672 } | 676 } | 
| 673 | 677 | 
| 674 /** | 678 /** | 
| 675  * [AnalysisDriver] uses [WorkManager]s to select results to compute. |  | 
| 676  * |  | 
| 677  * They know specific of the targets and results they care about, |  | 
| 678  * so they can request analysis results in optimal order. |  | 
| 679  */ |  | 
| 680 abstract class WorkManager { |  | 
| 681   /** |  | 
| 682    * Notifies the managers that the given set of priority [targets] was set. |  | 
| 683    */ |  | 
| 684   void applyPriorityTargets(List<AnalysisTarget> targets); |  | 
| 685 |  | 
| 686   /** |  | 
| 687    * Return the next [TargetedResult] that this work manager wants to be |  | 
| 688    * computed, or `null` if this manager doesn't need any new results. |  | 
| 689    */ |  | 
| 690   TargetedResult getNextResult(); |  | 
| 691 |  | 
| 692   /** |  | 
| 693    * Return the priority if the next work order this work manager want to be |  | 
| 694    * computed. The [AnalysisDriver] will perform the work order with |  | 
| 695    * the highest priority. |  | 
| 696    * |  | 
| 697    * Even if the returned value is [WorkOrderPriority.NONE], it still does not |  | 
| 698    * guarantee that [getNextResult] will return not `null`. |  | 
| 699    */ |  | 
| 700   WorkOrderPriority getNextResultPriority(); |  | 
| 701 |  | 
| 702   /** |  | 
| 703    * Notifies the manager that the given [outputs] were produced for |  | 
| 704    * the given [target]. |  | 
| 705    */ |  | 
| 706   void resultsComputed( |  | 
| 707       AnalysisTarget target, Map<ResultDescriptor, dynamic> outputs); |  | 
| 708 } |  | 
| 709 |  | 
| 710 /** |  | 
| 711  * A description of the work to be done to compute a desired analysis result. | 679  * 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. | 680  * The class implements a lazy depth-first traversal of the work item's input. | 
| 713  */ | 681  */ | 
| 714 class WorkOrder implements Iterator<WorkItem> { | 682 class WorkOrder implements Iterator<WorkItem> { | 
| 715   /** | 683   /** | 
| 716    * The dependency walker which is being used to determine what work to do | 684    * The dependency walker which is being used to determine what work to do | 
| 717    * next. | 685    * next. | 
| 718    */ | 686    */ | 
| 719   final _WorkOrderDependencyWalker _dependencyWalker; | 687   final _WorkOrderDependencyWalker _dependencyWalker; | 
| 720 | 688 | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 767         } else { | 735         } else { | 
| 768           assert(currentItems.length == 1); | 736           assert(currentItems.length == 1); | 
| 769         } | 737         } | 
| 770         return true; | 738         return true; | 
| 771       } | 739       } | 
| 772     }); | 740     }); | 
| 773   } | 741   } | 
| 774 } | 742 } | 
| 775 | 743 | 
| 776 /** | 744 /** | 
| 777  * The priorities of work orders returned by [WorkManager]s. |  | 
| 778  */ |  | 
| 779 enum WorkOrderPriority { |  | 
| 780   /** |  | 
| 781    * Responding to an user's action. |  | 
| 782    */ |  | 
| 783   INTERACTIVE, |  | 
| 784 |  | 
| 785   /** |  | 
| 786    * Computing information for priority sources. |  | 
| 787    */ |  | 
| 788   PRIORITY, |  | 
| 789 |  | 
| 790   /** |  | 
| 791    * A work should be done, but without any special urgency. |  | 
| 792    */ |  | 
| 793   NORMAL, |  | 
| 794 |  | 
| 795   /** |  | 
| 796    * Nothing to do. |  | 
| 797    */ |  | 
| 798   NONE |  | 
| 799 } |  | 
| 800 |  | 
| 801 /** |  | 
| 802  * Specilaization of [CycleAwareDependencyWalker] for use by [WorkOrder]. | 745  * Specilaization of [CycleAwareDependencyWalker] for use by [WorkOrder]. | 
| 803  */ | 746  */ | 
| 804 class _WorkOrderDependencyWalker extends CycleAwareDependencyWalker<WorkItem> { | 747 class _WorkOrderDependencyWalker extends CycleAwareDependencyWalker<WorkItem> { | 
| 805   /** | 748   /** | 
| 806    * The task manager used to build work items. | 749    * The task manager used to build work items. | 
| 807    */ | 750    */ | 
| 808   final TaskManager taskManager; | 751   final TaskManager taskManager; | 
| 809 | 752 | 
| 810   _WorkOrderDependencyWalker(this.taskManager, WorkItem startingNode) | 753   _WorkOrderDependencyWalker(this.taskManager, WorkItem startingNode) | 
| 811       : super(startingNode); | 754       : super(startingNode); | 
| 812 | 755 | 
| 813   @override | 756   @override | 
| 814   WorkItem getNextInput(WorkItem node, List<WorkItem> skipInputs) { | 757   WorkItem getNextInput(WorkItem node, List<WorkItem> skipInputs) { | 
| 815     return node.gatherInputs(taskManager, skipInputs); | 758     return node.gatherInputs(taskManager, skipInputs); | 
| 816   } | 759   } | 
| 817 } | 760 } | 
| OLD | NEW | 
|---|