| 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'; |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 bool moveNext() { | 406 bool moveNext() { |
| 407 if (pendingItems.isEmpty) { | 407 if (pendingItems.isEmpty) { |
| 408 currentItem = null; | 408 currentItem = null; |
| 409 return false; | 409 return false; |
| 410 } | 410 } |
| 411 currentItem = pendingItems.removeLast(); | 411 currentItem = pendingItems.removeLast(); |
| 412 WorkItem childItem = currentItem.gatherInputs(taskManager); | 412 WorkItem childItem = currentItem.gatherInputs(taskManager); |
| 413 while (childItem != null) { | 413 while (childItem != null) { |
| 414 pendingItems.add(currentItem); | 414 pendingItems.add(currentItem); |
| 415 currentItem = childItem; | 415 currentItem = childItem; |
| 416 if (_hasInfiniteTaskLoop()) { |
| 417 currentItem = pendingItems.removeLast(); |
| 418 try { |
| 419 throw new InfiniteTaskLoopException(childItem); |
| 420 } on InfiniteTaskLoopException catch (exception, stackTrace) { |
| 421 currentItem.exception = new CaughtException(exception, stackTrace); |
| 422 } |
| 423 return true; |
| 424 } |
| 416 childItem = currentItem.gatherInputs(taskManager); | 425 childItem = currentItem.gatherInputs(taskManager); |
| 417 } | 426 } |
| 418 return true; | 427 return true; |
| 419 } | 428 } |
| 429 |
| 430 /** |
| 431 * Check to see whether the current work item is attempting to perform the |
| 432 * same task on the same target as any of the pending work items. If it is, |
| 433 * then throw an [InfiniteTaskLoopException]. |
| 434 */ |
| 435 bool _hasInfiniteTaskLoop() { |
| 436 TaskDescriptor descriptor = currentItem.descriptor; |
| 437 AnalysisTarget target = currentItem.target; |
| 438 for (WorkItem item in pendingItems) { |
| 439 if (item.descriptor == descriptor && item.target == target) { |
| 440 return true; |
| 441 } |
| 442 } |
| 443 return false; |
| 444 } |
| 420 } | 445 } |
| 446 |
| 447 /** |
| 448 * An exception indicating that an attempt was made to perform a task on a |
| 449 * target while gathering the inputs to perform the same task for the same |
| 450 * target. |
| 451 */ |
| 452 class InfiniteTaskLoopException extends AnalysisException { |
| 453 /** |
| 454 * Initialize a newly created exception to represent an attempt to perform |
| 455 * the task for the target represented by the given [item]. |
| 456 */ |
| 457 InfiniteTaskLoopException(WorkItem item) : super('Infinite loop while performi
ng task ${item.descriptor.name} for ${item.target}'); |
| 458 } |
| OLD | NEW |