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

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

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 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, 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
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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 * [target]. Return the last [AnalysisTask] that was performed. 95 * [target]. Return the last [AnalysisTask] that was performed.
95 */ 96 */
96 AnalysisTask computeResult(AnalysisTarget target, ResultDescriptor result) { 97 AnalysisTask computeResult(AnalysisTarget target, ResultDescriptor result) {
97 assert(!isTaskRunning); 98 assert(!isTaskRunning);
98 try { 99 try {
99 isTaskRunning = true; 100 isTaskRunning = true;
100 AnalysisTask task; 101 AnalysisTask task;
101 WorkOrder workOrder = createWorkOrderForResult(target, result); 102 WorkOrder workOrder = createWorkOrderForResult(target, result);
102 if (workOrder != null) { 103 if (workOrder != null) {
103 while (workOrder.moveNext()) { 104 while (workOrder.moveNext()) {
105 // AnalysisTask previousTask = task;
106 // String message = workOrder.current.toString();
104 task = performWorkItem(workOrder.current); 107 task = performWorkItem(workOrder.current);
108 // if (task == null) {
109 // throw new AnalysisException(message, previousTask.caughtException) ;
110 // }
105 } 111 }
106 } 112 }
107 return task; 113 return task;
108 } finally { 114 } finally {
109 isTaskRunning = false; 115 isTaskRunning = false;
110 } 116 }
111 } 117 }
112 118
113 /** 119 /**
114 * Return the work order describing the work that should be getting worked on, 120 * Return the work order describing the work that should be getting worked on,
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 } 196 }
191 } 197 }
192 return null; 198 return null;
193 } 199 }
194 200
195 /** 201 /**
196 * Return the stream that is notified when a new value for the given 202 * Return the stream that is notified when a new value for the given
197 * [descriptor] is computed. 203 * [descriptor] is computed.
198 */ 204 */
199 Stream<ComputedResult> onResultComputed(ResultDescriptor descriptor) { 205 Stream<ComputedResult> onResultComputed(ResultDescriptor descriptor) {
200 return resultComputedControllers.putIfAbsent(descriptor, () => 206 return resultComputedControllers
201 new StreamController<ComputedResult>.broadcast(sync: true)).stream; 207 .putIfAbsent(descriptor,
208 () => new StreamController<ComputedResult>.broadcast(sync: true))
209 .stream;
202 } 210 }
203 211
204 /** 212 /**
205 * Perform the next analysis task, and return `true` if there is more work to 213 * 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. 214 * be done in order to compute all of the required analysis information.
207 */ 215 */
208 bool performAnalysisTask() { 216 bool performAnalysisTask() {
209 // 217 //
210 // TODO(brianwilkerson) This implementaiton does not allow us to prioritize 218 // 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 219 // 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 477 * 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 478 * cycles, this is the set of all [WorkItem]s in the entire strongly
471 * connected component). Otherwise, `null`. 479 * connected component). Otherwise, `null`.
472 */ 480 */
473 final List<WorkItem> dependencyCycle; 481 final List<WorkItem> dependencyCycle;
474 482
475 /** 483 /**
476 * Initialize a newly created exception to represent a failed attempt to 484 * Initialize a newly created exception to represent a failed attempt to
477 * perform the given [task] due to the given [dependencyCycle]. 485 * perform the given [task] due to the given [dependencyCycle].
478 */ 486 */
479 InfiniteTaskLoopException(AnalysisTask task, this.dependencyCycle) : super( 487 InfiniteTaskLoopException(AnalysisTask task, this.dependencyCycle)
480 'Infinite loop while performing task ${task.descriptor.name} for ${tas k.target}'); 488 : super(
489 'Infinite loop while performing task ${task.descriptor.name} for ${t ask.target}');
481 } 490 }
482 491
483 /** 492 /**
484 * Object used by CycleAwareDependencyWalker to report a single strongly 493 * Object used by CycleAwareDependencyWalker to report a single strongly
485 * connected component of nodes. 494 * connected component of nodes.
486 */ 495 */
487 class StronglyConnectedComponent<Node> { 496 class StronglyConnectedComponent<Node> {
488 /** 497 /**
489 * The nodes contained in the strongly connected component. 498 * The nodes contained in the strongly connected component.
490 */ 499 */
(...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 567 * cycles, this is the set of all [WorkItem]s in the entire strongly
559 * connected component). Otherwise, `null`. 568 * connected component). Otherwise, `null`.
560 */ 569 */
561 List<WorkItem> dependencyCycle; 570 List<WorkItem> dependencyCycle;
562 571
563 /** 572 /**
564 * Initialize a newly created work item to compute the inputs for the task 573 * Initialize a newly created work item to compute the inputs for the task
565 * described by the given descriptor. 574 * described by the given descriptor.
566 */ 575 */
567 WorkItem(this.context, this.target, this.descriptor, this.spawningResult) { 576 WorkItem(this.context, this.target, this.descriptor, this.spawningResult) {
568 AnalysisTarget actualTarget = identical( 577 AnalysisTarget actualTarget =
569 target, AnalysisContextTarget.request) 578 identical(target, AnalysisContextTarget.request)
570 ? new AnalysisContextTarget(context) 579 ? new AnalysisContextTarget(context)
571 : target; 580 : target;
572 Map<String, TaskInput> inputDescriptors = 581 Map<String, TaskInput> inputDescriptors =
573 descriptor.createTaskInputs(actualTarget); 582 descriptor.createTaskInputs(actualTarget);
574 builder = new TopLevelTaskInputBuilder(inputDescriptors); 583 builder = new TopLevelTaskInputBuilder(inputDescriptors);
575 if (!builder.moveNext()) { 584 if (!builder.moveNext()) {
576 builder = null; 585 builder = null;
577 } 586 }
578 inputs = new HashMap<String, dynamic>(); 587 inputs = new HashMap<String, dynamic>();
579 } 588 }
580 589
581 @override 590 @override
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 try { 660 try {
652 TaskDescriptor descriptor = 661 TaskDescriptor descriptor =
653 taskManager.findTask(inputTarget, inputResult); 662 taskManager.findTask(inputTarget, inputResult);
654 return new WorkItem(context, inputTarget, descriptor, inputResult); 663 return new WorkItem(context, inputTarget, descriptor, inputResult);
655 } on AnalysisException catch (exception, stackTrace) { 664 } on AnalysisException catch (exception, stackTrace) {
656 this.exception = new CaughtException(exception, stackTrace); 665 this.exception = new CaughtException(exception, stackTrace);
657 return null; 666 return null;
658 } 667 }
659 } else { 668 } else {
660 builder.currentValue = inputEntry.getValue(inputResult); 669 builder.currentValue = inputEntry.getValue(inputResult);
670 if (builder.flushOnAccess) {
671 inputEntry.setState(inputResult, CacheState.FLUSHED);
672 }
661 } 673 }
662 if (!builder.moveNext()) { 674 if (!builder.moveNext()) {
663 inputs = builder.inputValue; 675 inputs = builder.inputValue;
664 builder = null; 676 builder = null;
665 } 677 }
666 } 678 }
667 return null; 679 return null;
668 } 680 }
669 681
670 @override 682 @override
671 String toString() => 'Run $descriptor on $target'; 683 String toString() => 'Run $descriptor on $target';
672 } 684 }
673 685
674 /** 686 /**
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. 687 * 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. 688 * The class implements a lazy depth-first traversal of the work item's input.
713 */ 689 */
714 class WorkOrder implements Iterator<WorkItem> { 690 class WorkOrder implements Iterator<WorkItem> {
715 /** 691 /**
716 * The dependency walker which is being used to determine what work to do 692 * The dependency walker which is being used to determine what work to do
717 * next. 693 * next.
718 */ 694 */
719 final _WorkOrderDependencyWalker _dependencyWalker; 695 final _WorkOrderDependencyWalker _dependencyWalker;
720 696
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 } else { 743 } else {
768 assert(currentItems.length == 1); 744 assert(currentItems.length == 1);
769 } 745 }
770 return true; 746 return true;
771 } 747 }
772 }); 748 });
773 } 749 }
774 } 750 }
775 751
776 /** 752 /**
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]. 753 * Specilaization of [CycleAwareDependencyWalker] for use by [WorkOrder].
803 */ 754 */
804 class _WorkOrderDependencyWalker extends CycleAwareDependencyWalker<WorkItem> { 755 class _WorkOrderDependencyWalker extends CycleAwareDependencyWalker<WorkItem> {
805 /** 756 /**
806 * The task manager used to build work items. 757 * The task manager used to build work items.
807 */ 758 */
808 final TaskManager taskManager; 759 final TaskManager taskManager;
809 760
810 _WorkOrderDependencyWalker(this.taskManager, WorkItem startingNode) 761 _WorkOrderDependencyWalker(this.taskManager, WorkItem startingNode)
811 : super(startingNode); 762 : super(startingNode);
812 763
813 @override 764 @override
814 WorkItem getNextInput(WorkItem node, List<WorkItem> skipInputs) { 765 WorkItem getNextInput(WorkItem node, List<WorkItem> skipInputs) {
815 return node.gatherInputs(taskManager, skipInputs); 766 return node.gatherInputs(taskManager, skipInputs);
816 } 767 }
817 } 768 }
OLDNEW
« no previous file with comments | « packages/analyzer/lib/src/task/dart_work_manager.dart ('k') | packages/analyzer/lib/src/task/general.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698