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

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

Issue 1320923003: Implement a task to compute the dependencies between static variables (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Address comments Created 5 years, 3 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.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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/plugin/engine_plugin.dart ('k') | pkg/analyzer/lib/src/task/strong_mode.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698