| 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/context/context.dart' show ResultComputedEvent; |
| 11 import 'package:analyzer/src/generated/engine.dart' | 12 import 'package:analyzer/src/generated/engine.dart' |
| 12 hide AnalysisTask, AnalysisContextImpl; | 13 hide AnalysisTask, AnalysisContextImpl; |
| 13 import 'package:analyzer/src/generated/java_engine.dart'; | 14 import 'package:analyzer/src/generated/java_engine.dart'; |
| 14 import 'package:analyzer/src/generated/resolver.dart'; | 15 import 'package:analyzer/src/generated/resolver.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'; |
| 19 | 20 |
| 20 final PerformanceTag workOrderMoveNextPerfTag = | 21 final PerformanceTag workOrderMoveNextPerfTag = |
| (...skipping 14 matching lines...) Expand all Loading... |
| 35 * compute. | 36 * compute. |
| 36 */ | 37 */ |
| 37 final List<WorkManager> workManagers; | 38 final List<WorkManager> workManagers; |
| 38 | 39 |
| 39 /** | 40 /** |
| 40 * The context in which analysis is to be performed. | 41 * The context in which analysis is to be performed. |
| 41 */ | 42 */ |
| 42 final InternalAnalysisContext context; | 43 final InternalAnalysisContext context; |
| 43 | 44 |
| 44 /** | 45 /** |
| 46 * The map of [ResultComputedEvent] controllers. |
| 47 */ |
| 48 final Map<ResultDescriptor, StreamController<ResultComputedEvent>> resultCompu
tedControllers = |
| 49 <ResultDescriptor, StreamController<ResultComputedEvent>>{}; |
| 50 |
| 51 /** |
| 45 * 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 |
| 46 * completed. | 53 * completed. |
| 47 */ | 54 */ |
| 48 WorkOrder currentWorkOrder; | 55 WorkOrder currentWorkOrder; |
| 49 | 56 |
| 50 /** | 57 /** |
| 51 * Indicates whether any tasks are currently being performed (or building | 58 * Indicates whether any tasks are currently being performed (or building |
| 52 * their inputs). In debug builds, we use this to ensure that tasks don't | 59 * their inputs). In debug builds, we use this to ensure that tasks don't |
| 53 * try to make use of the task manager in reentrant fashion. | 60 * try to make use of the task manager in reentrant fashion. |
| 54 */ | 61 */ |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 WorkOrder workOrder = createWorkOrderForResult(target, result); | 187 WorkOrder workOrder = createWorkOrderForResult(target, result); |
| 181 if (workOrder != null) { | 188 if (workOrder != null) { |
| 182 return workOrder; | 189 return workOrder; |
| 183 } | 190 } |
| 184 } | 191 } |
| 185 } | 192 } |
| 186 return null; | 193 return null; |
| 187 } | 194 } |
| 188 | 195 |
| 189 /** | 196 /** |
| 197 * Return the stream that is notified when a new value for the given |
| 198 * [descriptor] is computed. |
| 199 */ |
| 200 Stream<ResultComputedEvent> onResultComputed(ResultDescriptor descriptor) { |
| 201 return resultComputedControllers.putIfAbsent(descriptor, () => |
| 202 new StreamController<ResultComputedEvent>.broadcast(sync: true)).stream; |
| 203 } |
| 204 |
| 205 /** |
| 190 * Perform the next analysis task, and return `true` if there is more work to | 206 * Perform the next analysis task, and return `true` if there is more work to |
| 191 * be done in order to compute all of the required analysis information. | 207 * be done in order to compute all of the required analysis information. |
| 192 */ | 208 */ |
| 193 bool performAnalysisTask() { | 209 bool performAnalysisTask() { |
| 194 // | 210 // |
| 195 // TODO(brianwilkerson) This implementaiton does not allow us to prioritize | 211 // TODO(brianwilkerson) This implementaiton does not allow us to prioritize |
| 196 // work across contexts. What we need is a way for an external client to ask | 212 // work across contexts. What we need is a way for an external client to ask |
| 197 // to have all priority files analyzed for each context, then ask for normal | 213 // to have all priority files analyzed for each context, then ask for normal |
| 198 // files to be analyzed. There are a couple of ways to do this. | 214 // files to be analyzed. There are a couple of ways to do this. |
| 199 // | 215 // |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 // Mark all of the results that the task would have computed as being in | 252 // Mark all of the results that the task would have computed as being in |
| 237 // ERROR with the exception recorded on the work item. | 253 // ERROR with the exception recorded on the work item. |
| 238 CacheEntry targetEntry = context.getCacheEntry(item.target); | 254 CacheEntry targetEntry = context.getCacheEntry(item.target); |
| 239 targetEntry.setErrorState(item.exception, item.descriptor.results); | 255 targetEntry.setErrorState(item.exception, item.descriptor.results); |
| 240 return null; | 256 return null; |
| 241 } | 257 } |
| 242 // Otherwise, perform the task. | 258 // Otherwise, perform the task. |
| 243 AnalysisTask task = item.buildTask(); | 259 AnalysisTask task = item.buildTask(); |
| 244 _onTaskStartedController.add(task); | 260 _onTaskStartedController.add(task); |
| 245 task.perform(); | 261 task.perform(); |
| 246 CacheEntry entry = context.getCacheEntry(task.target); | 262 AnalysisTarget target = task.target; |
| 263 CacheEntry entry = context.getCacheEntry(target); |
| 247 if (task.caughtException == null) { | 264 if (task.caughtException == null) { |
| 248 List<TargetedResult> dependedOn = item.inputTargetedResults.toList(); | 265 List<TargetedResult> dependedOn = item.inputTargetedResults.toList(); |
| 249 Map<ResultDescriptor, dynamic> outputs = task.outputs; | 266 Map<ResultDescriptor, dynamic> outputs = task.outputs; |
| 250 for (ResultDescriptor result in task.descriptor.results) { | 267 for (ResultDescriptor result in task.descriptor.results) { |
| 251 // TODO(brianwilkerson) We could check here that a value was produced | 268 // TODO(brianwilkerson) We could check here that a value was produced |
| 252 // and throw an exception if not (unless we want to allow null values). | 269 // and throw an exception if not (unless we want to allow null values). |
| 253 entry.setValue(result, outputs[result], dependedOn); | 270 entry.setValue(result, outputs[result], dependedOn); |
| 254 } | 271 } |
| 272 outputs.forEach((ResultDescriptor descriptor, value) { |
| 273 StreamController<ResultComputedEvent> controller = |
| 274 resultComputedControllers[descriptor]; |
| 275 if (controller != null) { |
| 276 ResultComputedEvent event = |
| 277 new ResultComputedEvent(context, descriptor, target, value); |
| 278 controller.add(event); |
| 279 } |
| 280 }); |
| 255 for (WorkManager manager in workManagers) { | 281 for (WorkManager manager in workManagers) { |
| 256 manager.resultsComputed(task.target, outputs); | 282 manager.resultsComputed(target, outputs); |
| 257 } | 283 } |
| 258 } else { | 284 } else { |
| 259 entry.setErrorState(task.caughtException, item.descriptor.results); | 285 entry.setErrorState(task.caughtException, item.descriptor.results); |
| 260 } | 286 } |
| 261 _onTaskCompletedController.add(task); | 287 _onTaskCompletedController.add(task); |
| 262 return task; | 288 return task; |
| 263 } | 289 } |
| 264 | 290 |
| 265 /** | 291 /** |
| 266 * Reset the state of the driver in response to a change in the state of one | 292 * Reset the state of the driver in response to a change in the state of one |
| (...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 final TaskManager taskManager; | 809 final TaskManager taskManager; |
| 784 | 810 |
| 785 _WorkOrderDependencyWalker(this.taskManager, WorkItem startingNode) | 811 _WorkOrderDependencyWalker(this.taskManager, WorkItem startingNode) |
| 786 : super(startingNode); | 812 : super(startingNode); |
| 787 | 813 |
| 788 @override | 814 @override |
| 789 WorkItem getNextInput(WorkItem node, List<WorkItem> skipInputs) { | 815 WorkItem getNextInput(WorkItem node, List<WorkItem> skipInputs) { |
| 790 return node.gatherInputs(taskManager, skipInputs); | 816 return node.gatherInputs(taskManager, skipInputs); |
| 791 } | 817 } |
| 792 } | 818 } |
| OLD | NEW |