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 |