| 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.dart; | 5 library analyzer.src.task.dart; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/src/context/cache.dart'; | 9 import 'package:analyzer/src/context/cache.dart'; |
| 10 import 'package:analyzer/src/generated/ast.dart'; | 10 import 'package:analyzer/src/generated/ast.dart'; |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 /** | 154 /** |
| 155 * The sources representing the combined import/export closure of a library. | 155 * The sources representing the combined import/export closure of a library. |
| 156 * The [Source]s include only library sources, not their units. | 156 * The [Source]s include only library sources, not their units. |
| 157 * | 157 * |
| 158 * The result is only available for [Source]s representing a library. | 158 * The result is only available for [Source]s representing a library. |
| 159 */ | 159 */ |
| 160 final ListResultDescriptor<Source> IMPORT_EXPORT_SOURCE_CLOSURE = | 160 final ListResultDescriptor<Source> IMPORT_EXPORT_SOURCE_CLOSURE = |
| 161 new ListResultDescriptor<Source>('IMPORT_EXPORT_SOURCE_CLOSURE', null); | 161 new ListResultDescriptor<Source>('IMPORT_EXPORT_SOURCE_CLOSURE', null); |
| 162 | 162 |
| 163 /** | 163 /** |
| 164 * A list of the [VariableElement]s whose type should be inferred that another |
| 165 * inferable static variable (the target) depends on. |
| 166 * |
| 167 * The result is only available for [VariableElement]s, and only when strong |
| 168 * mode is enabled. |
| 169 */ |
| 170 final ListResultDescriptor< |
| 171 VariableElement> INFERABLE_STATIC_VARIABLE_DEPENDENCIES = |
| 172 new ListResultDescriptor<VariableElement>( |
| 173 'INFERABLE_STATIC_VARIABLE_DEPENDENCIES', null); |
| 174 |
| 175 /** |
| 164 * A list of the [VariableElement]s defined in a unit whose type should be | 176 * A list of the [VariableElement]s defined in a unit whose type should be |
| 165 * inferred. This includes variables defined at the library level as well as | 177 * inferred. This includes variables defined at the library level as well as |
| 166 * static members inside classes. | 178 * static members inside classes. |
| 167 * | 179 * |
| 168 * The result is only available for [LibrarySpecificUnit]s, and only when strong | 180 * The result is only available for [LibrarySpecificUnit]s, and only when strong |
| 169 * mode is enabled. | 181 * mode is enabled. |
| 170 */ | 182 */ |
| 171 final ListResultDescriptor<VariableElement> INFERABLE_STATIC_VARIABLES_IN_UNIT = | 183 final ListResultDescriptor<VariableElement> INFERABLE_STATIC_VARIABLES_IN_UNIT = |
| 172 new ListResultDescriptor<VariableElement>( | 184 new ListResultDescriptor<VariableElement>( |
| 173 'INFERABLE_STATIC_VARIABLES_IN_UNIT', null); | 185 'INFERABLE_STATIC_VARIABLES_IN_UNIT', null); |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 */ | 475 */ |
| 464 static const String PARSED_UNIT_INPUT_NAME = 'PARSED_UNIT_INPUT_NAME'; | 476 static const String PARSED_UNIT_INPUT_NAME = 'PARSED_UNIT_INPUT_NAME'; |
| 465 | 477 |
| 466 /** | 478 /** |
| 467 * The task descriptor describing this kind of task. | 479 * The task descriptor describing this kind of task. |
| 468 */ | 480 */ |
| 469 static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( | 481 static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
| 470 'BuildCompilationUnitElementTask', | 482 'BuildCompilationUnitElementTask', |
| 471 createTask, | 483 createTask, |
| 472 buildInputs, <ResultDescriptor>[ | 484 buildInputs, <ResultDescriptor>[ |
| 473 CLASSES_IN_UNIT, | |
| 474 COMPILATION_UNIT_CONSTANTS, | 485 COMPILATION_UNIT_CONSTANTS, |
| 475 COMPILATION_UNIT_ELEMENT, | 486 COMPILATION_UNIT_ELEMENT, |
| 476 INFERABLE_STATIC_VARIABLES_IN_UNIT, | |
| 477 RESOLVED_UNIT1 | 487 RESOLVED_UNIT1 |
| 478 ]); | 488 ]); |
| 479 | 489 |
| 480 /** | 490 /** |
| 481 * Initialize a newly created task to build a compilation unit element for | 491 * Initialize a newly created task to build a compilation unit element for |
| 482 * the given [target] in the given [context]. | 492 * the given [target] in the given [context]. |
| 483 */ | 493 */ |
| 484 BuildCompilationUnitElementTask( | 494 BuildCompilationUnitElementTask( |
| 485 InternalAnalysisContext context, AnalysisTarget target) | 495 InternalAnalysisContext context, AnalysisTarget target) |
| 486 : super(context, target); | 496 : super(context, target); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 513 } | 523 } |
| 514 // | 524 // |
| 515 // Prepare constants. | 525 // Prepare constants. |
| 516 // | 526 // |
| 517 ConstantFinder constantFinder = | 527 ConstantFinder constantFinder = |
| 518 new ConstantFinder(context, source, librarySpecificUnit.library); | 528 new ConstantFinder(context, source, librarySpecificUnit.library); |
| 519 unit.accept(constantFinder); | 529 unit.accept(constantFinder); |
| 520 List<ConstantEvaluationTarget> constants = new List< | 530 List<ConstantEvaluationTarget> constants = new List< |
| 521 ConstantEvaluationTarget>.from(constantFinder.constantsToCompute); | 531 ConstantEvaluationTarget>.from(constantFinder.constantsToCompute); |
| 522 // | 532 // |
| 523 // Prepare targets for inference. | |
| 524 // | |
| 525 List<VariableElement> staticVariables = <VariableElement>[]; | |
| 526 List<ClassElement> classes = <ClassElement>[]; | |
| 527 if (context.analysisOptions.strongMode) { | |
| 528 InferrenceFinder inferrenceFinder = new InferrenceFinder(); | |
| 529 unit.accept(inferrenceFinder); | |
| 530 staticVariables = inferrenceFinder.staticVariables; | |
| 531 classes = inferrenceFinder.classes; | |
| 532 } | |
| 533 // | |
| 534 // Record outputs. | 533 // Record outputs. |
| 535 // | 534 // |
| 536 outputs[CLASSES_IN_UNIT] = classes; | |
| 537 outputs[COMPILATION_UNIT_CONSTANTS] = constants; | 535 outputs[COMPILATION_UNIT_CONSTANTS] = constants; |
| 538 outputs[COMPILATION_UNIT_ELEMENT] = element; | 536 outputs[COMPILATION_UNIT_ELEMENT] = element; |
| 539 outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = staticVariables; | |
| 540 outputs[RESOLVED_UNIT1] = unit; | 537 outputs[RESOLVED_UNIT1] = unit; |
| 541 } | 538 } |
| 542 | 539 |
| 543 /** | 540 /** |
| 544 * Return a map from the names of the inputs of this kind of task to the task | 541 * Return a map from the names of the inputs of this kind of task to the task |
| 545 * input descriptors describing those inputs for a task with the given | 542 * input descriptors describing those inputs for a task with the given |
| 546 * [target]. | 543 * [target]. |
| 547 */ | 544 */ |
| 548 static Map<String, TaskInput> buildInputs(AnalysisTarget target) { | 545 static Map<String, TaskInput> buildInputs(AnalysisTarget target) { |
| 549 LibrarySpecificUnit unit = target; | 546 LibrarySpecificUnit unit = target; |
| (...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1482 @override | 1479 @override |
| 1483 void internalPerform() { | 1480 void internalPerform() { |
| 1484 // | 1481 // |
| 1485 // Prepare inputs. | 1482 // Prepare inputs. |
| 1486 // | 1483 // |
| 1487 // Note: UNIT_INPUT is not needed. It is merely a bookkeeping dependency | 1484 // Note: UNIT_INPUT is not needed. It is merely a bookkeeping dependency |
| 1488 // to ensure that resolution has occurred before we attempt to determine | 1485 // to ensure that resolution has occurred before we attempt to determine |
| 1489 // constant dependencies. | 1486 // constant dependencies. |
| 1490 // | 1487 // |
| 1491 ConstantEvaluationTarget constant = target; | 1488 ConstantEvaluationTarget constant = target; |
| 1492 AnalysisContext context = constant.context; | |
| 1493 TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT); | 1489 TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT); |
| 1494 // | 1490 // |
| 1495 // Compute dependencies. | 1491 // Compute dependencies. |
| 1496 // | 1492 // |
| 1497 List<ConstantEvaluationTarget> dependencies = <ConstantEvaluationTarget>[]; | 1493 List<ConstantEvaluationTarget> dependencies = <ConstantEvaluationTarget>[]; |
| 1498 new ConstantEvaluationEngine(typeProvider, context.declaredVariables) | 1494 new ConstantEvaluationEngine(typeProvider, context.declaredVariables) |
| 1499 .computeDependencies(constant, dependencies.add); | 1495 .computeDependencies(constant, dependencies.add); |
| 1500 // | 1496 // |
| 1501 // Record outputs. | 1497 // Record outputs. |
| 1502 // | 1498 // |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1522 UNIT_INPUT: RESOLVED_UNIT8 | 1518 UNIT_INPUT: RESOLVED_UNIT8 |
| 1523 .of(new LibrarySpecificUnit(target.librarySource, target.source)), | 1519 .of(new LibrarySpecificUnit(target.librarySource, target.source)), |
| 1524 TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request) | 1520 TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request) |
| 1525 }; | 1521 }; |
| 1526 } | 1522 } |
| 1527 throw new AnalysisException( | 1523 throw new AnalysisException( |
| 1528 'Cannot build inputs for a ${target.runtimeType}'); | 1524 'Cannot build inputs for a ${target.runtimeType}'); |
| 1529 } | 1525 } |
| 1530 | 1526 |
| 1531 /** | 1527 /** |
| 1532 * Create a [ResolveUnitReferencesTask] based on the given [target] in | 1528 * Create a [ComputeConstantDependenciesTask] based on the given [target] in |
| 1533 * the given [context]. | 1529 * the given [context]. |
| 1534 */ | 1530 */ |
| 1535 static ComputeConstantDependenciesTask createTask( | 1531 static ComputeConstantDependenciesTask createTask( |
| 1536 AnalysisContext context, AnalysisTarget target) { | 1532 AnalysisContext context, AnalysisTarget target) { |
| 1537 return new ComputeConstantDependenciesTask(context, target); | 1533 return new ComputeConstantDependenciesTask(context, target); |
| 1538 } | 1534 } |
| 1539 } | 1535 } |
| 1540 | 1536 |
| 1541 /** | 1537 /** |
| 1542 * A task that computes the value of a constant ([CONSTANT_VALUE]) and | 1538 * A task that computes the value of a constant ([CONSTANT_VALUE]) and |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1624 * Create a [ComputeConstantValueTask] based on the given [target] in the | 1620 * Create a [ComputeConstantValueTask] based on the given [target] in the |
| 1625 * given [context]. | 1621 * given [context]. |
| 1626 */ | 1622 */ |
| 1627 static ComputeConstantValueTask createTask( | 1623 static ComputeConstantValueTask createTask( |
| 1628 AnalysisContext context, AnalysisTarget target) { | 1624 AnalysisContext context, AnalysisTarget target) { |
| 1629 return new ComputeConstantValueTask(context, target); | 1625 return new ComputeConstantValueTask(context, target); |
| 1630 } | 1626 } |
| 1631 } | 1627 } |
| 1632 | 1628 |
| 1633 /** | 1629 /** |
| 1630 * A task that computes the [INFERABLE_STATIC_VARIABLE_DEPENDENCIES] for a |
| 1631 * static variable whose type should be inferred. |
| 1632 */ |
| 1633 class ComputeInferableStaticVariableDependenciesTask |
| 1634 extends ConstantEvaluationAnalysisTask { |
| 1635 /** |
| 1636 * The name of the [RESOLVED_UNIT5] input. |
| 1637 */ |
| 1638 static const String UNIT_INPUT = 'UNIT_INPUT'; |
| 1639 |
| 1640 static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
| 1641 'ComputeInferableStaticVariableDependenciesTask', |
| 1642 createTask, |
| 1643 buildInputs, |
| 1644 <ResultDescriptor>[INFERABLE_STATIC_VARIABLE_DEPENDENCIES]); |
| 1645 |
| 1646 ComputeInferableStaticVariableDependenciesTask( |
| 1647 InternalAnalysisContext context, VariableElement variable) |
| 1648 : super(context, variable); |
| 1649 |
| 1650 @override |
| 1651 TaskDescriptor get descriptor => DESCRIPTOR; |
| 1652 |
| 1653 @override |
| 1654 void internalPerform() { |
| 1655 // |
| 1656 // Prepare inputs. |
| 1657 // |
| 1658 VariableElement variable = target; |
| 1659 CompilationUnit unit = getRequiredInput(UNIT_INPUT); |
| 1660 // |
| 1661 // Compute dependencies. |
| 1662 // |
| 1663 NodeLocator locator = new NodeLocator(variable.nameOffset); |
| 1664 AstNode node = locator.searchWithin(unit); |
| 1665 VariableDeclaration declaration = |
| 1666 node.getAncestor((AstNode ancestor) => ancestor is VariableDeclaration); |
| 1667 if (declaration == null || declaration.name != node) { |
| 1668 throw new AnalysisException( |
| 1669 "NodeLocator failed to find a variable's declaration"); |
| 1670 } |
| 1671 VariableGatherer gatherer = new VariableGatherer(_isInferableStatic); |
| 1672 declaration.initializer.accept(gatherer); |
| 1673 // |
| 1674 // Record outputs. |
| 1675 // |
| 1676 outputs[INFERABLE_STATIC_VARIABLE_DEPENDENCIES] = gatherer.results; |
| 1677 } |
| 1678 |
| 1679 /** |
| 1680 * Return `true` if the given [variable] is a static variable whose type |
| 1681 * should be inferred. |
| 1682 */ |
| 1683 bool _isInferableStatic(VariableElement variable) => variable.isStatic && |
| 1684 variable.hasImplicitType && |
| 1685 variable.initializer != null; |
| 1686 |
| 1687 /** |
| 1688 * Return a map from the names of the inputs of this kind of task to the task |
| 1689 * input descriptors describing those inputs for a task with the |
| 1690 * given [target]. |
| 1691 */ |
| 1692 static Map<String, TaskInput> buildInputs(AnalysisTarget target) { |
| 1693 if (target is VariableElement) { |
| 1694 CompilationUnitElementImpl unit = target |
| 1695 .getAncestor((Element element) => element is CompilationUnitElement); |
| 1696 return <String, TaskInput>{ |
| 1697 UNIT_INPUT: RESOLVED_UNIT5 |
| 1698 .of(new LibrarySpecificUnit(unit.librarySource, unit.source)) |
| 1699 }; |
| 1700 } |
| 1701 throw new AnalysisException( |
| 1702 'Cannot build inputs for a ${target.runtimeType}'); |
| 1703 } |
| 1704 |
| 1705 /** |
| 1706 * Create a [ComputeInferableStaticVariableDependenciesTask] based on the |
| 1707 * given [target] in the given [context]. |
| 1708 */ |
| 1709 static ComputeInferableStaticVariableDependenciesTask createTask( |
| 1710 AnalysisContext context, AnalysisTarget target) { |
| 1711 return new ComputeInferableStaticVariableDependenciesTask(context, target); |
| 1712 } |
| 1713 } |
| 1714 |
| 1715 /** |
| 1634 * A base class for analysis tasks whose target is expected to be a | 1716 * A base class for analysis tasks whose target is expected to be a |
| 1635 * [ConstantEvaluationTarget]. | 1717 * [ConstantEvaluationTarget]. |
| 1636 */ | 1718 */ |
| 1637 abstract class ConstantEvaluationAnalysisTask extends AnalysisTask { | 1719 abstract class ConstantEvaluationAnalysisTask extends AnalysisTask { |
| 1638 /** | 1720 /** |
| 1639 * Initialize a newly created task to perform analysis within the given | 1721 * Initialize a newly created task to perform analysis within the given |
| 1640 * [context] in order to produce results for the given [constant]. | 1722 * [context] in order to produce results for the given [constant]. |
| 1641 */ | 1723 */ |
| 1642 ConstantEvaluationAnalysisTask( | 1724 ConstantEvaluationAnalysisTask( |
| 1643 AnalysisContext context, ConstantEvaluationTarget constant) | 1725 AnalysisContext context, ConstantEvaluationTarget constant) |
| (...skipping 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2662 * The name of the [TYPE_PROVIDER] input. | 2744 * The name of the [TYPE_PROVIDER] input. |
| 2663 */ | 2745 */ |
| 2664 static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT'; | 2746 static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT'; |
| 2665 | 2747 |
| 2666 /** | 2748 /** |
| 2667 * The task descriptor describing this kind of task. | 2749 * The task descriptor describing this kind of task. |
| 2668 */ | 2750 */ |
| 2669 static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( | 2751 static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
| 2670 'PartiallyResolveUnitReferencesTask', | 2752 'PartiallyResolveUnitReferencesTask', |
| 2671 createTask, | 2753 createTask, |
| 2672 buildInputs, | 2754 buildInputs, <ResultDescriptor>[ |
| 2673 <ResultDescriptor>[PARTIALLY_RESOLVE_REFERENCES_ERRORS, RESOLVED_UNIT5]); | 2755 CLASSES_IN_UNIT, |
| 2756 INFERABLE_STATIC_VARIABLES_IN_UNIT, |
| 2757 PARTIALLY_RESOLVE_REFERENCES_ERRORS, |
| 2758 RESOLVED_UNIT5 |
| 2759 ]); |
| 2674 | 2760 |
| 2675 PartiallyResolveUnitReferencesTask( | 2761 PartiallyResolveUnitReferencesTask( |
| 2676 InternalAnalysisContext context, AnalysisTarget target) | 2762 InternalAnalysisContext context, AnalysisTarget target) |
| 2677 : super(context, target); | 2763 : super(context, target); |
| 2678 | 2764 |
| 2679 @override | 2765 @override |
| 2680 TaskDescriptor get descriptor => DESCRIPTOR; | 2766 TaskDescriptor get descriptor => DESCRIPTOR; |
| 2681 | 2767 |
| 2682 @override | 2768 @override |
| 2683 void internalPerform() { | 2769 void internalPerform() { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2695 InheritanceManager inheritanceManager = | 2781 InheritanceManager inheritanceManager = |
| 2696 new InheritanceManager(libraryElement); | 2782 new InheritanceManager(libraryElement); |
| 2697 // TODO(brianwilkerson) Improve performance by not resolving anything inside | 2783 // TODO(brianwilkerson) Improve performance by not resolving anything inside |
| 2698 // function bodies. Function bodies will be resolved later so this is wasted | 2784 // function bodies. Function bodies will be resolved later so this is wasted |
| 2699 // effort. | 2785 // effort. |
| 2700 AstVisitor visitor = new ResolverVisitor( | 2786 AstVisitor visitor = new ResolverVisitor( |
| 2701 libraryElement, unitElement.source, typeProvider, errorListener, | 2787 libraryElement, unitElement.source, typeProvider, errorListener, |
| 2702 inheritanceManager: inheritanceManager); | 2788 inheritanceManager: inheritanceManager); |
| 2703 unit.accept(visitor); | 2789 unit.accept(visitor); |
| 2704 // | 2790 // |
| 2791 // Prepare targets for inference. |
| 2792 // |
| 2793 List<VariableElement> staticVariables = <VariableElement>[]; |
| 2794 List<ClassElement> classes = <ClassElement>[]; |
| 2795 if (context.analysisOptions.strongMode) { |
| 2796 InferrenceFinder inferrenceFinder = new InferrenceFinder(); |
| 2797 unit.accept(inferrenceFinder); |
| 2798 staticVariables = inferrenceFinder.staticVariables; |
| 2799 classes = inferrenceFinder.classes; |
| 2800 } |
| 2801 // |
| 2705 // Record outputs. | 2802 // Record outputs. |
| 2706 // | 2803 // |
| 2804 outputs[CLASSES_IN_UNIT] = classes; |
| 2805 outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = staticVariables; |
| 2707 outputs[PARTIALLY_RESOLVE_REFERENCES_ERRORS] = | 2806 outputs[PARTIALLY_RESOLVE_REFERENCES_ERRORS] = |
| 2708 removeDuplicateErrors(errorListener.errors); | 2807 removeDuplicateErrors(errorListener.errors); |
| 2709 outputs[RESOLVED_UNIT5] = unit; | 2808 outputs[RESOLVED_UNIT5] = unit; |
| 2710 } | 2809 } |
| 2711 | 2810 |
| 2712 /** | 2811 /** |
| 2713 * Return a map from the names of the inputs of this kind of task to the task | 2812 * Return a map from the names of the inputs of this kind of task to the task |
| 2714 * input descriptors describing those inputs for a task with the | 2813 * input descriptors describing those inputs for a task with the |
| 2715 * given [target]. | 2814 * given [target]. |
| 2716 */ | 2815 */ |
| (...skipping 904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3621 | 3720 |
| 3622 @override | 3721 @override |
| 3623 bool moveNext() { | 3722 bool moveNext() { |
| 3624 if (_newSources.isEmpty) { | 3723 if (_newSources.isEmpty) { |
| 3625 return false; | 3724 return false; |
| 3626 } | 3725 } |
| 3627 currentTarget = _newSources.removeLast(); | 3726 currentTarget = _newSources.removeLast(); |
| 3628 return true; | 3727 return true; |
| 3629 } | 3728 } |
| 3630 } | 3729 } |
| OLD | NEW |