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

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

Issue 1131383008: Generate the proper error when a constant refers to itself. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 7 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';
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 * [skipInputs], and return it. If [node] has no further inputs, return 341 * [skipInputs], and return it. If [node] has no further inputs, return
342 * `null`. 342 * `null`.
343 */ 343 */
344 Node getNextInput(Node node, List<Node> skipInputs); 344 Node getNextInput(Node node, List<Node> skipInputs);
345 345
346 /** 346 /**
347 * Determine the next strongly connected component in the graph, and return 347 * Determine the next strongly connected component in the graph, and return
348 * it. The client is expected to evaluate this component before calling 348 * it. The client is expected to evaluate this component before calling
349 * [getNextStronglyConnectedComponent] again. 349 * [getNextStronglyConnectedComponent] again.
350 */ 350 */
351 List<Node> getNextStronglyConnectedComponent() { 351 StronglyConnectedComponent<Node> getNextStronglyConnectedComponent() {
352 while (_currentIndices.isNotEmpty) { 352 while (_currentIndices.isNotEmpty) {
353 Node nextUnevaluatedInput = getNextInput(_path[_currentIndices.last], 353 Node nextUnevaluatedInput = getNextInput(_path[_currentIndices.last],
354 _provisionalDependencies[_currentIndices.last]); 354 _provisionalDependencies[_currentIndices.last]);
355 assert(!_provisionalDependencies[_currentIndices.last] 355 assert(!_provisionalDependencies[_currentIndices.last]
356 .contains(nextUnevaluatedInput)); 356 .contains(nextUnevaluatedInput));
357 if (nextUnevaluatedInput != null) { 357 if (nextUnevaluatedInput != null) {
358 // TODO(paulberry): the call to _path.indexOf makes the algorithm 358 // TODO(paulberry): the call to _path.indexOf makes the algorithm
359 // O(n^2) in the depth of the dependency graph. If this becomes a 359 // O(n^2) in the depth of the dependency graph. If this becomes a
360 // problem, consider maintaining a map from node to index. 360 // problem, consider maintaining a map from node to index.
361 int previousIndex = _path.indexOf(nextUnevaluatedInput); 361 int previousIndex = _path.indexOf(nextUnevaluatedInput);
(...skipping 25 matching lines...) Expand all
387 } else { 387 } else {
388 // The node has no more inputs. Figure out if there are any more nodes 388 // The node has no more inputs. Figure out if there are any more nodes
389 // in the current strongly connected component that need to have their 389 // in the current strongly connected component that need to have their
390 // indices examined. 390 // indices examined.
391 _currentIndices.removeLast(); 391 _currentIndices.removeLast();
392 if (_currentIndices.isEmpty || 392 if (_currentIndices.isEmpty ||
393 _currentIndices.last < _contractedPath.last) { 393 _currentIndices.last < _contractedPath.last) {
394 // No more nodes in the current strongly connected component need to 394 // No more nodes in the current strongly connected component need to
395 // have their indices examined. We can now yield this component to 395 // have their indices examined. We can now yield this component to
396 // the caller. 396 // the caller.
397 List<Node> component = _path.sublist(_contractedPath.last); 397 List<Node> nodes = _path.sublist(_contractedPath.last);
398 bool containsCycle = nodes.length > 1;
399 if (!containsCycle) {
400 if (_provisionalDependencies.last.isNotEmpty) {
401 containsCycle = true;
402 }
403 }
398 _path.length = _contractedPath.last; 404 _path.length = _contractedPath.last;
399 _provisionalDependencies.length = _contractedPath.last; 405 _provisionalDependencies.length = _contractedPath.last;
400 _contractedPath.removeLast(); 406 _contractedPath.removeLast();
401 return component; 407 return new StronglyConnectedComponent<Node>(nodes, containsCycle);
402 } else { 408 } else {
403 // At least one node in the current strongly connected component 409 // At least one node in the current strongly connected component
404 // still needs to have its inputs examined. So loop and allow the 410 // still needs to have its inputs examined. So loop and allow the
405 // inputs to be examined. 411 // inputs to be examined.
406 continue; 412 continue;
407 } 413 }
408 } 414 }
409 } 415 }
410 // No further strongly connected components found. 416 // No further strongly connected components found.
411 return null; 417 return null;
(...skipping 27 matching lines...) Expand all
439 445
440 /** 446 /**
441 * Initialize a newly created exception to represent a failed attempt to 447 * Initialize a newly created exception to represent a failed attempt to
442 * perform the given [task] due to the given [dependencyCycle]. 448 * perform the given [task] due to the given [dependencyCycle].
443 */ 449 */
444 InfiniteTaskLoopException(AnalysisTask task, this.dependencyCycle) : super( 450 InfiniteTaskLoopException(AnalysisTask task, this.dependencyCycle) : super(
445 'Infinite loop while performing task ${task.descriptor.name} for ${tas k.target}'); 451 'Infinite loop while performing task ${task.descriptor.name} for ${tas k.target}');
446 } 452 }
447 453
448 /** 454 /**
455 * Object used by CycleAwareDependencyWalker to report a single strongly
456 * connected component of nodes.
457 */
458 class StronglyConnectedComponent<Node> {
459 /**
460 * The nodes contained in the strongly connected component.
461 */
462 final List<Node> nodes;
463
464 /**
465 * Indicates whether the strongly component contains any cycles. Note that
466 * if [nodes] has multiple elements, this will always be `true`. However, if
467 * [nodes] has exactly one element, this may be either `true` or `false`
468 * depending on whether the node has a dependency on itself.
469 */
470 final bool containsCycle;
471
472 StronglyConnectedComponent(this.nodes, this.containsCycle);
473 }
474
475 /**
449 * A description of a single anaysis task that can be performed to advance 476 * A description of a single anaysis task that can be performed to advance
450 * analysis. 477 * analysis.
451 */ 478 */
452 class WorkItem { 479 class WorkItem {
453 /** 480 /**
454 * The context in which the task will be performed. 481 * The context in which the task will be performed.
455 */ 482 */
456 final InternalAnalysisContext context; 483 final InternalAnalysisContext context;
457 484
458 /** 485 /**
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
688 } 715 }
689 716
690 @override 717 @override
691 bool moveNext() { 718 bool moveNext() {
692 if (currentItems != null && currentItems.length > 1) { 719 if (currentItems != null && currentItems.length > 1) {
693 // Yield more items. 720 // Yield more items.
694 currentItems.removeLast(); 721 currentItems.removeLast();
695 return true; 722 return true;
696 } else { 723 } else {
697 // Get a new strongly connected component. 724 // Get a new strongly connected component.
698 currentItems = _dependencyWalker.getNextStronglyConnectedComponent(); 725 StronglyConnectedComponent<WorkItem> nextStronglyConnectedComponent =
699 if (currentItems == null) { 726 _dependencyWalker.getNextStronglyConnectedComponent();
727 if (nextStronglyConnectedComponent == null) {
728 currentItems = null;
700 return false; 729 return false;
701 } 730 }
702 if (currentItems.length > 1) { 731 currentItems = nextStronglyConnectedComponent.nodes;
732 if (nextStronglyConnectedComponent.containsCycle) {
703 // A cycle has been found. 733 // A cycle has been found.
704 for (WorkItem item in currentItems) { 734 for (WorkItem item in currentItems) {
705 item.dependencyCycle = currentItems.toList(); 735 item.dependencyCycle = currentItems.toList();
706 } 736 }
707 } else { 737 } else {
708 assert(currentItems.length == 1); 738 assert(currentItems.length == 1);
709 } 739 }
710 return true; 740 return true;
711 } 741 }
712 } 742 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 final TaskManager taskManager; 777 final TaskManager taskManager;
748 778
749 _WorkOrderDependencyWalker(this.taskManager, WorkItem startingNode) 779 _WorkOrderDependencyWalker(this.taskManager, WorkItem startingNode)
750 : super(startingNode); 780 : super(startingNode);
751 781
752 @override 782 @override
753 WorkItem getNextInput(WorkItem node, List<WorkItem> skipInputs) { 783 WorkItem getNextInput(WorkItem node, List<WorkItem> skipInputs) {
754 return node.gatherInputs(taskManager, skipInputs); 784 return node.gatherInputs(taskManager, skipInputs);
755 } 785 }
756 } 786 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/generated/constant.dart ('k') | pkg/analyzer/test/generated/compile_time_error_code_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698