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

Unified Diff: pkg/analyzer/lib/src/task/dart.dart

Issue 1460213005: Propagate types of final/const top-level variables and fields. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: tweaks Created 5 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/analyzer/lib/src/plugin/engine_plugin.dart ('k') | pkg/analyzer/test/src/task/dart_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/task/dart.dart
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 2aae1a1f3dcb828444726b8985bd423ea4a1dbc9..c21435b6affee9f3a14507a32eb55ee69b5b33d8 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -338,6 +338,36 @@ final ListResultDescriptor<AnalysisError> PARSE_ERRORS =
'PARSE_ERRORS', AnalysisError.NO_ERRORS);
/**
+ * A list of the [VariableElement]s whose type should be known to propagate
+ * the type of another variable (the target).
+ *
+ * The result is only available for [VariableElement]s.
+ */
+final ListResultDescriptor<VariableElement> PROPAGABLE_VARIABLE_DEPENDENCIES =
+ new ListResultDescriptor<VariableElement>(
+ 'PROPAGABLE_VARIABLE_DEPENDENCIES', null);
+
+/**
+ * A list of the [VariableElement]s defined in a unit whose type might be
+ * propagated. This includes variables defined at the library level as well as
+ * static and instance members inside classes.
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ListResultDescriptor<VariableElement> PROPAGABLE_VARIABLES_IN_UNIT =
+ new ListResultDescriptor<VariableElement>(
+ 'PROPAGABLE_VARIABLES_IN_UNIT', null);
+
+/**
+ * An propagable variable ([VariableElement]) whose type has been propagated.
+ *
+ * The result is only available for [VariableElement]s.
+ */
+final ResultDescriptor<VariableElement> PROPAGATED_VARIABLE =
+ new ResultDescriptor<VariableElement>('PROPAGATED_VARIABLE', null,
+ cachingPolicy: ELEMENT_CACHING_POLICY);
+
+/**
* The flag specifying that [LIBRARY_ELEMENT2] is ready for a library and its
* import/export closure.
*
@@ -374,13 +404,13 @@ final ResultDescriptor<bool> READY_RESOLVED_UNIT10 =
new ResultDescriptor<bool>('READY_RESOLVED_UNIT10', false);
/**
- * The flag specifying that [RESOLVED_UNIT9] is ready for all of the units of a
+ * The flag specifying that [RESOLVED_UNIT11] is ready for all of the units of a
* library and its import/export closure.
*
* The result is only available for [Source]s representing a library.
*/
-final ResultDescriptor<bool> READY_RESOLVED_UNIT9 =
- new ResultDescriptor<bool>('READY_RESOLVED_UNIT9', false);
+final ResultDescriptor<bool> READY_RESOLVED_UNIT11 =
+ new ResultDescriptor<bool>('READY_RESOLVED_UNIT11', false);
/**
* The names (resolved and not) referenced by a unit.
@@ -427,7 +457,7 @@ final ResultDescriptor<CompilationUnit> RESOLVED_UNIT1 =
/**
* The resolved [CompilationUnit] associated with a compilation unit, with
- * constants resolved.
+ * constants not yet resolved.
*
* The result is only available for [LibrarySpecificUnit]s.
*/
@@ -436,6 +466,16 @@ final ResultDescriptor<CompilationUnit> RESOLVED_UNIT10 =
cachingPolicy: AST_CACHING_POLICY);
/**
+ * The resolved [CompilationUnit] associated with a compilation unit, with
+ * constants resolved.
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ResultDescriptor<CompilationUnit> RESOLVED_UNIT11 =
+ new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT11', null,
+ cachingPolicy: AST_CACHING_POLICY);
+
+/**
* The partially resolved [CompilationUnit] associated with a compilation unit.
*
* Tasks that use this value as an input can assume that the [SimpleIdentifier]s
@@ -493,7 +533,8 @@ final ResultDescriptor<CompilationUnit> RESOLVED_UNIT5 =
* The partially resolved [CompilationUnit] associated with a compilation unit.
*
* In addition to what is true of a [RESOLVED_UNIT5], tasks that use this value
- * as an input can assume that the types of static variables have been inferred.
+ * as an input can assume that the types of final variables have been
+ * propagated.
*
* The result is only available for [LibrarySpecificUnit]s.
*/
@@ -505,8 +546,7 @@ final ResultDescriptor<CompilationUnit> RESOLVED_UNIT6 =
* The partially resolved [CompilationUnit] associated with a compilation unit.
*
* In addition to what is true of a [RESOLVED_UNIT6], tasks that use this value
- * as an input can assume that the initializers of instance variables have been
- * re-resolved.
+ * as an input can assume that the types of static variables have been inferred.
*
* The result is only available for [LibrarySpecificUnit]s.
*/
@@ -515,9 +555,11 @@ final ResultDescriptor<CompilationUnit> RESOLVED_UNIT7 =
cachingPolicy: AST_CACHING_POLICY);
/**
- * The resolved [CompilationUnit] associated with a compilation unit in which
- * the types of class members have been inferred in addition to everything that
- * is true of a [RESOLVED_UNIT7].
+ * The partially resolved [CompilationUnit] associated with a compilation unit.
+ *
+ * In addition to what is true of a [RESOLVED_UNIT7], tasks that use this value
+ * as an input can assume that the initializers of instance variables have been
+ * re-resolved.
*
* The result is only available for [LibrarySpecificUnit]s.
*/
@@ -526,8 +568,9 @@ final ResultDescriptor<CompilationUnit> RESOLVED_UNIT8 =
cachingPolicy: AST_CACHING_POLICY);
/**
- * The resolved [CompilationUnit] associated with a compilation unit, with
- * constants not yet resolved.
+ * The resolved [CompilationUnit] associated with a compilation unit in which
+ * the types of class members have been inferred in addition to everything that
+ * is true of a [RESOLVED_UNIT8].
*
* The result is only available for [LibrarySpecificUnit]s.
*/
@@ -1638,7 +1681,7 @@ class ComputeConstantDependenciesTask extends ConstantEvaluationAnalysisTask {
'Cannot build inputs for a ${target.runtimeType}');
}
return <String, TaskInput>{
- 'resolvedUnit': RESOLVED_UNIT9
+ 'resolvedUnit': RESOLVED_UNIT10
.of(new LibrarySpecificUnit(librarySource, target.source)),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request)
};
@@ -1940,6 +1983,92 @@ class ComputeLibraryCycleTask extends SourceBasedAnalysisTask {
}
/**
+ * A task that computes the [PROPAGABLE_VARIABLE_DEPENDENCIES] for a variable.
+ */
+class ComputePropagableVariableDependenciesTask
+ extends ConstantEvaluationAnalysisTask {
+ /**
+ * The name of the [RESOLVED_UNIT5] input.
+ */
+ static const String UNIT_INPUT = 'UNIT_INPUT';
+
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+ 'ComputePropagableVariableDependenciesTask',
+ createTask,
+ buildInputs,
+ <ResultDescriptor>[PROPAGABLE_VARIABLE_DEPENDENCIES]);
+
+ ComputePropagableVariableDependenciesTask(
+ InternalAnalysisContext context, VariableElement variable)
+ : super(context, variable);
+
+ @override
+ TaskDescriptor get descriptor => DESCRIPTOR;
+
+ @override
+ void internalPerform() {
+ //
+ // Prepare inputs.
+ //
+ VariableElement variable = target;
+ CompilationUnit unit = getRequiredInput(UNIT_INPUT);
+ //
+ // Compute dependencies.
+ //
+ NodeLocator locator = new NodeLocator(variable.nameOffset);
+ AstNode node = locator.searchWithin(unit);
+ VariableDeclaration declaration =
+ node.getAncestor((AstNode ancestor) => ancestor is VariableDeclaration);
+ if (declaration == null || declaration.name != node) {
+ throw new AnalysisException(
+ "NodeLocator failed to find a variable's declaration");
+ }
+ VariableGatherer gatherer = new VariableGatherer(_isPropagable);
+ declaration.initializer.accept(gatherer);
+ //
+ // Record outputs.
+ //
+ outputs[PROPAGABLE_VARIABLE_DEPENDENCIES] = gatherer.results.toList();
+ }
+
+ /**
+ * Return `true` if the given [variable] is a variable whose type can be
+ * propagated.
+ */
+ bool _isPropagable(VariableElement variable) =>
+ (variable.isConst || variable.isFinal) &&
+ variable.hasImplicitType &&
+ variable.initializer != null;
+
+ /**
+ * Return a map from the names of the inputs of this kind of task to the task
+ * input descriptors describing those inputs for a task with the
+ * given [target].
+ */
+ static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+ if (target is VariableElement) {
+ CompilationUnitElementImpl unit = target
+ .getAncestor((Element element) => element is CompilationUnitElement);
+ return <String, TaskInput>{
+ UNIT_INPUT: RESOLVED_UNIT5
+ .of(new LibrarySpecificUnit(unit.librarySource, unit.source))
+ };
+ }
+ throw new AnalysisException(
+ 'Cannot build inputs for a ${target.runtimeType}');
+ }
+
+ /**
+ * Create a [ComputePropagableVariableDependenciesTask] based on the
+ * given [target] in the given [context].
+ */
+ static ComputePropagableVariableDependenciesTask createTask(
+ AnalysisContext context, AnalysisTarget target) {
+ return new ComputePropagableVariableDependenciesTask(context, target);
+ }
+}
+
+/**
* A base class for analysis tasks whose target is expected to be a
* [ConstantEvaluationTarget].
*/
@@ -2202,11 +2331,11 @@ class DartErrorsTask extends SourceBasedAnalysisTask {
}
/**
- * A task that builds [RESOLVED_UNIT10] for a unit.
+ * A task that builds [RESOLVED_UNIT11] for a unit.
*/
class EvaluateUnitConstantsTask extends SourceBasedAnalysisTask {
/**
- * The name of the [RESOLVED_UNIT9] input.
+ * The name of the [RESOLVED_UNIT10] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -2222,7 +2351,7 @@ class EvaluateUnitConstantsTask extends SourceBasedAnalysisTask {
'EvaluateUnitConstantsTask',
createTask,
buildInputs,
- <ResultDescriptor>[RESOLVED_UNIT10]);
+ <ResultDescriptor>[RESOLVED_UNIT11]);
EvaluateUnitConstantsTask(AnalysisContext context, LibrarySpecificUnit target)
: super(context, target);
@@ -2235,7 +2364,7 @@ class EvaluateUnitConstantsTask extends SourceBasedAnalysisTask {
// No actual work needs to be performed; the task manager will ensure that
// all constants are evaluated before this method is called.
CompilationUnit unit = getRequiredInput(UNIT_INPUT);
- outputs[RESOLVED_UNIT10] = unit;
+ outputs[RESOLVED_UNIT11] = unit;
}
/**
@@ -2247,7 +2376,7 @@ class EvaluateUnitConstantsTask extends SourceBasedAnalysisTask {
LibrarySpecificUnit unit = target;
return <String, TaskInput>{
'libraryElement': LIBRARY_ELEMENT.of(unit.library),
- UNIT_INPUT: RESOLVED_UNIT9.of(unit),
+ UNIT_INPUT: RESOLVED_UNIT10.of(unit),
CONSTANT_VALUES:
COMPILATION_UNIT_CONSTANTS.of(unit).toListOf(CONSTANT_VALUE)
};
@@ -2371,7 +2500,7 @@ class ExportNamespaceBuilder {
*/
class GatherUsedImportedElementsTask extends SourceBasedAnalysisTask {
/**
- * The name of the [RESOLVED_UNIT9] input.
+ * The name of the [RESOLVED_UNIT10] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -2415,7 +2544,7 @@ class GatherUsedImportedElementsTask extends SourceBasedAnalysisTask {
*/
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
LibrarySpecificUnit unit = target;
- return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT9.of(unit)};
+ return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT10.of(unit)};
}
/**
@@ -2433,7 +2562,7 @@ class GatherUsedImportedElementsTask extends SourceBasedAnalysisTask {
*/
class GatherUsedLocalElementsTask extends SourceBasedAnalysisTask {
/**
- * The name of the [RESOLVED_UNIT9] input.
+ * The name of the [RESOLVED_UNIT10] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -2477,7 +2606,7 @@ class GatherUsedLocalElementsTask extends SourceBasedAnalysisTask {
*/
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
LibrarySpecificUnit unit = target;
- return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT9.of(unit)};
+ return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT10.of(unit)};
}
/**
@@ -2495,7 +2624,7 @@ class GatherUsedLocalElementsTask extends SourceBasedAnalysisTask {
*/
class GenerateHintsTask extends SourceBasedAnalysisTask {
/**
- * The name of the [RESOLVED_UNIT9] input.
+ * The name of the [RESOLVED_UNIT10] input.
*/
static const String RESOLVED_UNIT_INPUT = 'RESOLVED_UNIT';
@@ -2701,7 +2830,7 @@ class InferInstanceMembersInUnitTask extends SourceBasedAnalysisTask {
static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
/**
- * The name of the input whose value is the [RESOLVED_UNIT6] for the
+ * The name of the input whose value is the [RESOLVED_UNIT7] for the
* compilation unit.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -2713,7 +2842,7 @@ class InferInstanceMembersInUnitTask extends SourceBasedAnalysisTask {
'InferInstanceMembersInUnitTask',
createTask,
buildInputs,
- <ResultDescriptor>[RESOLVED_UNIT8]);
+ <ResultDescriptor>[RESOLVED_UNIT9]);
/**
* Initialize a newly created task to build a library element for the given
@@ -2744,7 +2873,7 @@ class InferInstanceMembersInUnitTask extends SourceBasedAnalysisTask {
//
// Record outputs.
//
- outputs[RESOLVED_UNIT8] = unit;
+ outputs[RESOLVED_UNIT9] = unit;
}
/**
@@ -2755,7 +2884,7 @@ class InferInstanceMembersInUnitTask extends SourceBasedAnalysisTask {
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
LibrarySpecificUnit unit = target;
return <String, TaskInput>{
- UNIT_INPUT: RESOLVED_UNIT7.of(unit),
+ UNIT_INPUT: RESOLVED_UNIT8.of(unit),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
// In strong mode, add additional dependencies to enforce inference
// ordering.
@@ -2763,12 +2892,12 @@ class InferInstanceMembersInUnitTask extends SourceBasedAnalysisTask {
// Require that field re-resolution be complete for all units in the
// current library cycle.
'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit).toList(
- (CompilationUnitElementImpl unit) => RESOLVED_UNIT7
+ (CompilationUnitElementImpl unit) => RESOLVED_UNIT8
.of(new LibrarySpecificUnit(unit.librarySource, unit.source))),
// Require that full inference be complete for all dependencies of the
// current library cycle.
'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList(
- (CompilationUnitElementImpl unit) => RESOLVED_UNIT8
+ (CompilationUnitElementImpl unit) => RESOLVED_UNIT9
.of(new LibrarySpecificUnit(unit.librarySource, unit.source)))
};
}
@@ -2816,7 +2945,7 @@ abstract class InferStaticVariableTask extends ConstantEvaluationAnalysisTask {
*/
class InferStaticVariableTypesInUnitTask extends SourceBasedAnalysisTask {
/**
- * The name of the input whose value is the [RESOLVED_UNIT5] for the
+ * The name of the input whose value is the [RESOLVED_UNIT6] for the
* compilation unit.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -2834,7 +2963,7 @@ class InferStaticVariableTypesInUnitTask extends SourceBasedAnalysisTask {
'InferStaticVariableTypesInUnitTask',
createTask,
buildInputs,
- <ResultDescriptor>[RESOLVED_UNIT6]);
+ <ResultDescriptor>[RESOLVED_UNIT7]);
/**
* Initialize a newly created task to build a library element for the given
@@ -2858,7 +2987,7 @@ class InferStaticVariableTypesInUnitTask extends SourceBasedAnalysisTask {
// because the work has implicitly been done by virtue of the task model
// preparing all of the inputs.
//
- outputs[RESOLVED_UNIT6] = unit;
+ outputs[RESOLVED_UNIT7] = unit;
}
/**
@@ -2872,7 +3001,7 @@ class InferStaticVariableTypesInUnitTask extends SourceBasedAnalysisTask {
INFERRED_VARIABLES_INPUT: INFERABLE_STATIC_VARIABLES_IN_UNIT
.of(unit)
.toListOf(INFERRED_STATIC_VARIABLE),
- UNIT_INPUT: RESOLVED_UNIT5.of(unit)
+ UNIT_INPUT: RESOLVED_UNIT6.of(unit)
};
}
@@ -2903,7 +3032,7 @@ class InferStaticVariableTypeTask extends InferStaticVariableTask {
static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
/**
- * The name of the [RESOLVED_UNIT5] input.
+ * The name of the [RESOLVED_UNIT6] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -3001,14 +3130,14 @@ class InferStaticVariableTypeTask extends InferStaticVariableTask {
.of(variable)
.toListOf(INFERRED_STATIC_VARIABLE),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
- UNIT_INPUT: RESOLVED_UNIT5.of(unit),
+ UNIT_INPUT: RESOLVED_UNIT6.of(unit),
// In strong mode, add additional dependencies to enforce inference
// ordering.
// Require that full inference be complete for all dependencies of the
// current library cycle.
'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList(
- (CompilationUnitElementImpl unit) => RESOLVED_UNIT8
+ (CompilationUnitElementImpl unit) => RESOLVED_UNIT9
.of(new LibrarySpecificUnit(unit.librarySource, unit.source)))
};
}
@@ -3418,8 +3547,11 @@ class PartiallyResolveUnitReferencesTask extends SourceBasedAnalysisTask {
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
'PartiallyResolveUnitReferencesTask',
createTask,
- buildInputs,
- <ResultDescriptor>[INFERABLE_STATIC_VARIABLES_IN_UNIT, RESOLVED_UNIT5]);
+ buildInputs, <ResultDescriptor>[
+ INFERABLE_STATIC_VARIABLES_IN_UNIT,
+ PROPAGABLE_VARIABLES_IN_UNIT,
+ RESOLVED_UNIT5
+ ]);
PartiallyResolveUnitReferencesTask(
InternalAnalysisContext context, AnalysisTarget target)
@@ -3440,21 +3572,21 @@ class PartiallyResolveUnitReferencesTask extends SourceBasedAnalysisTask {
//
// Resolve references and record outputs.
//
+ InheritanceManager inheritanceManager =
+ new InheritanceManager(libraryElement);
+ PartialResolverVisitor visitor = new PartialResolverVisitor(libraryElement,
+ unitElement.source, typeProvider, AnalysisErrorListener.NULL_LISTENER,
+ inheritanceManager: inheritanceManager);
+ unit.accept(visitor);
+ //
+ // Record outputs.
+ //
if (context.analysisOptions.strongMode) {
- InheritanceManager inheritanceManager =
- new InheritanceManager(libraryElement);
- PartialResolverVisitor visitor = new PartialResolverVisitor(
- libraryElement,
- unitElement.source,
- typeProvider,
- AnalysisErrorListener.NULL_LISTENER,
- inheritanceManager: inheritanceManager);
- unit.accept(visitor);
-
- outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = visitor.variablesAndFields;
+ outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = visitor.staticVariables;
} else {
- outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = [];
+ outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = VariableElement.EMPTY_LIST;
}
+ outputs[PROPAGABLE_VARIABLES_IN_UNIT] = visitor.propagableVariables;
outputs[RESOLVED_UNIT5] = unit;
}
@@ -3476,7 +3608,7 @@ class PartiallyResolveUnitReferencesTask extends SourceBasedAnalysisTask {
// Require that full inference be complete for all dependencies of the
// current library cycle.
'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList(
- (CompilationUnitElementImpl unit) => RESOLVED_UNIT8
+ (CompilationUnitElementImpl unit) => RESOLVED_UNIT9
.of(new LibrarySpecificUnit(unit.librarySource, unit.source)))
};
}
@@ -3492,6 +3624,173 @@ class PartiallyResolveUnitReferencesTask extends SourceBasedAnalysisTask {
}
/**
+ * A task that ensures that all of the propagable variables in a compilation
+ * unit have had their type propagated.
+ */
+class PropagateVariableTypesInUnitTask extends SourceBasedAnalysisTask {
+ /**
+ * The name of the input whose value is the [RESOLVED_UNIT5] for the
+ * compilation unit.
+ */
+ static const String UNIT_INPUT = 'UNIT_INPUT';
+
+ /**
+ * The task descriptor describing this kind of task.
+ */
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+ 'PropagateVariableTypesInUnitTask',
+ createTask,
+ buildInputs,
+ <ResultDescriptor>[RESOLVED_UNIT6]);
+
+ PropagateVariableTypesInUnitTask(
+ InternalAnalysisContext context, LibrarySpecificUnit unit)
+ : super(context, unit);
+
+ @override
+ TaskDescriptor get descriptor => DESCRIPTOR;
+
+ @override
+ void internalPerform() {
+ //
+ // Prepare inputs.
+ //
+ CompilationUnit unit = getRequiredInput(UNIT_INPUT);
+ //
+ // Record outputs. There is no additional work to be done at this time
+ // because the work has implicitly been done by virtue of the task model
+ // preparing all of the inputs.
+ //
+ outputs[RESOLVED_UNIT6] = unit;
+ }
+
+ /**
+ * Return a map from the names of the inputs of this kind of task to the task
+ * input descriptors describing those inputs for a task with the given
+ * [target].
+ */
+ static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+ LibrarySpecificUnit unit = target;
+ return <String, TaskInput>{
+ 'variables':
+ PROPAGABLE_VARIABLES_IN_UNIT.of(unit).toListOf(PROPAGATED_VARIABLE),
+ UNIT_INPUT: RESOLVED_UNIT5.of(unit)
+ };
+ }
+
+ /**
+ * Create a [PropagateVariableTypesInUnitTask] based on the given [target]
+ * in the given [context].
+ */
+ static PropagateVariableTypesInUnitTask createTask(
+ AnalysisContext context, AnalysisTarget target) {
+ return new PropagateVariableTypesInUnitTask(context, target);
+ }
+}
+
+/**
+ * A task that computes the propagated type of an propagable variable and
+ * stores it in the element model.
+ */
+class PropagateVariableTypeTask extends InferStaticVariableTask {
+ /**
+ * The name of the [TYPE_PROVIDER] input.
+ */
+ static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
+
+ /**
+ * The name of the [RESOLVED_UNIT5] input.
+ */
+ static const String UNIT_INPUT = 'UNIT_INPUT';
+
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+ 'PropagateVariableTypeTask',
+ createTask,
+ buildInputs,
+ <ResultDescriptor>[PROPAGATED_VARIABLE]);
+
+ PropagateVariableTypeTask(
+ InternalAnalysisContext context, VariableElement variable)
+ : super(context, variable);
+
+ @override
+ TaskDescriptor get descriptor => DESCRIPTOR;
+
+ @override
+ bool get handlesDependencyCycles => true;
+
+ @override
+ void internalPerform() {
+ //
+ // Prepare inputs.
+ //
+ PropertyInducingElementImpl variable = target;
+ TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
+ CompilationUnit unit = getRequiredInput(UNIT_INPUT);
+
+ // If we're not in a dependency cycle, and we have no type annotation,
+ // re-resolve the right hand side and do propagation.
+ if (dependencyCycle == null && variable.hasImplicitType) {
+ VariableDeclaration declaration = getDeclaration(unit);
+ //
+ // Re-resolve the variable's initializer with the propagated types of
+ // other variables.
+ //
+ Expression initializer = declaration.initializer;
+ ResolutionContext resolutionContext = ResolutionContextBuilder.contextFor(
+ initializer, AnalysisErrorListener.NULL_LISTENER);
+ ResolverVisitor visitor = new ResolverVisitor(variable.library,
+ variable.source, typeProvider, AnalysisErrorListener.NULL_LISTENER,
+ nameScope: resolutionContext.scope);
+ if (resolutionContext.enclosingClassDeclaration != null) {
+ visitor.prepareToResolveMembersInClass(
+ resolutionContext.enclosingClassDeclaration);
+ }
+ visitor.initForIncrementalResolution();
+ initializer.accept(visitor);
+ //
+ // Record the type of the variable.
+ //
+ DartType newType = initializer.bestType;
+ if (newType != null && !newType.isBottom && !newType.isDynamic) {
+ variable.propagatedType = newType;
+ }
+ }
+ //
+ // Record outputs.
+ //
+ outputs[PROPAGATED_VARIABLE] = variable;
+ }
+
+ /**
+ * Return a map from the names of the inputs of this kind of task to the task
+ * input descriptors describing those inputs for a task with the given
+ * [target].
+ */
+ static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+ VariableElement variable = target;
+ LibrarySpecificUnit unit =
+ new LibrarySpecificUnit(variable.library.source, variable.source);
+ return <String, TaskInput>{
+ 'dependencies': PROPAGABLE_VARIABLE_DEPENDENCIES
+ .of(variable)
+ .toListOf(PROPAGATED_VARIABLE),
+ TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
+ UNIT_INPUT: RESOLVED_UNIT5.of(unit),
+ };
+ }
+
+ /**
+ * Create a [PropagateVariableTypeTask] based on the given [target] in the
+ * given [context].
+ */
+ static PropagateVariableTypeTask createTask(
+ AnalysisContext context, AnalysisTarget target) {
+ return new PropagateVariableTypeTask(context, target);
+ }
+}
+
+/**
* The helper for building the public [Namespace] of a [LibraryElement].
*/
class PublicNamespaceBuilder {
@@ -3661,17 +3960,18 @@ class ReadyResolvedUnit10Task extends SourceBasedAnalysisTask {
}
/**
- * A task that ensures that [RESOLVED_UNIT9] is ready for every unit of the
+ * A task that ensures that [RESOLVED_UNIT11] is ready for every unit of the
* target library source and its import/export closure.
*/
-class ReadyResolvedUnit9Task extends SourceBasedAnalysisTask {
+class ReadyResolvedUnit11Task extends SourceBasedAnalysisTask {
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
- 'ReadyResolvedUnit9Task',
+ 'ReadyResolvedUnit11Task',
createTask,
buildInputs,
- <ResultDescriptor>[READY_RESOLVED_UNIT9]);
+ <ResultDescriptor>[READY_RESOLVED_UNIT11]);
- ReadyResolvedUnit9Task(InternalAnalysisContext context, AnalysisTarget target)
+ ReadyResolvedUnit11Task(
+ InternalAnalysisContext context, AnalysisTarget target)
: super(context, target);
@override
@@ -3682,24 +3982,24 @@ class ReadyResolvedUnit9Task extends SourceBasedAnalysisTask {
@override
void internalPerform() {
- outputs[READY_RESOLVED_UNIT9] = true;
+ outputs[READY_RESOLVED_UNIT11] = true;
}
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
Source source = target;
return <String, TaskInput>{
'thisLibraryUnitsReady':
- LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT9),
+ LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT11),
'directlyImportedLibrariesReady':
- IMPORTED_LIBRARIES.of(source).toListOf(READY_RESOLVED_UNIT9),
+ IMPORTED_LIBRARIES.of(source).toListOf(READY_RESOLVED_UNIT11),
'directlyExportedLibrariesReady':
- EXPORTED_LIBRARIES.of(source).toListOf(READY_RESOLVED_UNIT9),
+ EXPORTED_LIBRARIES.of(source).toListOf(READY_RESOLVED_UNIT11),
};
}
- static ReadyResolvedUnit9Task createTask(
+ static ReadyResolvedUnit11Task createTask(
AnalysisContext context, AnalysisTarget target) {
- return new ReadyResolvedUnit9Task(context, target);
+ return new ReadyResolvedUnit11Task(context, target);
}
}
@@ -3860,7 +4160,7 @@ class ResolveInstanceFieldsInUnitTask extends SourceBasedAnalysisTask {
static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
/**
- * The name of the input whose value is the [RESOLVED_UNIT6] for the
+ * The name of the input whose value is the [RESOLVED_UNIT7] for the
* compilation unit.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -3872,7 +4172,7 @@ class ResolveInstanceFieldsInUnitTask extends SourceBasedAnalysisTask {
'ResolveInstanceFieldsInUnitTask',
createTask,
buildInputs,
- <ResultDescriptor>[RESOLVED_UNIT7]);
+ <ResultDescriptor>[RESOLVED_UNIT8]);
/**
* Initialize a newly created task to build a library element for the given
@@ -3920,7 +4220,7 @@ class ResolveInstanceFieldsInUnitTask extends SourceBasedAnalysisTask {
//
// Record outputs.
//
- outputs[RESOLVED_UNIT7] = unit;
+ outputs[RESOLVED_UNIT8] = unit;
}
/**
@@ -3931,7 +4231,7 @@ class ResolveInstanceFieldsInUnitTask extends SourceBasedAnalysisTask {
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
LibrarySpecificUnit unit = target;
return <String, TaskInput>{
- UNIT_INPUT: RESOLVED_UNIT6.of(unit),
+ UNIT_INPUT: RESOLVED_UNIT7.of(unit),
LIBRARY_INPUT: LIBRARY_ELEMENT5.of(unit.library),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
// In strong mode, add additional dependencies to enforce inference
@@ -3940,12 +4240,12 @@ class ResolveInstanceFieldsInUnitTask extends SourceBasedAnalysisTask {
// Require that static variable inference be complete for all units in
// the current library cycle.
'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit).toList(
- (CompilationUnitElementImpl unit) => RESOLVED_UNIT6
+ (CompilationUnitElementImpl unit) => RESOLVED_UNIT7
.of(new LibrarySpecificUnit(unit.librarySource, unit.source))),
// Require that full inference be complete for all dependencies of the
// current library cycle.
'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList(
- (CompilationUnitElementImpl unit) => RESOLVED_UNIT8
+ (CompilationUnitElementImpl unit) => RESOLVED_UNIT9
.of(new LibrarySpecificUnit(unit.librarySource, unit.source)))
};
}
@@ -3961,7 +4261,7 @@ class ResolveInstanceFieldsInUnitTask extends SourceBasedAnalysisTask {
}
/**
- * A task that finishes resolution by requesting [RESOLVED_UNIT9] for every
+ * A task that finishes resolution by requesting [RESOLVED_UNIT10] for every
* unit in the libraries closure and produces [LIBRARY_ELEMENT].
*/
class ResolveLibraryReferencesTask extends SourceBasedAnalysisTask {
@@ -3971,7 +4271,7 @@ class ResolveLibraryReferencesTask extends SourceBasedAnalysisTask {
static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
/**
- * The name of the list of [RESOLVED_UNIT9] input.
+ * The name of the list of [RESOLVED_UNIT10] input.
*/
static const String UNITS_INPUT = 'UNITS_INPUT';
@@ -4019,8 +4319,8 @@ class ResolveLibraryReferencesTask extends SourceBasedAnalysisTask {
Source source = target;
return <String, TaskInput>{
LIBRARY_INPUT: LIBRARY_ELEMENT5.of(source),
- UNITS_INPUT: LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT9),
- 'thisLibraryClosureIsReady': READY_RESOLVED_UNIT9.of(source),
+ UNITS_INPUT: LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT10),
+ 'thisLibraryClosureIsReady': READY_RESOLVED_UNIT10.of(source),
};
}
@@ -4123,7 +4423,7 @@ class ResolveUnitTask extends SourceBasedAnalysisTask {
static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
/**
- * The name of the [RESOLVED_UNIT8] input.
+ * The name of the [RESOLVED_UNIT9] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -4131,7 +4431,7 @@ class ResolveUnitTask extends SourceBasedAnalysisTask {
'ResolveUnitTask',
createTask,
buildInputs,
- <ResultDescriptor>[RESOLVE_UNIT_ERRORS, RESOLVED_UNIT9]);
+ <ResultDescriptor>[RESOLVE_UNIT_ERRORS, RESOLVED_UNIT10]);
ResolveUnitTask(
InternalAnalysisContext context, LibrarySpecificUnit compilationUnit)
@@ -4164,7 +4464,7 @@ class ResolveUnitTask extends SourceBasedAnalysisTask {
// updated version of the element model.
//
outputs[RESOLVE_UNIT_ERRORS] = errorListener.errors;
- outputs[RESOLVED_UNIT9] = unit;
+ outputs[RESOLVED_UNIT10] = unit;
}
/**
@@ -4177,14 +4477,14 @@ class ResolveUnitTask extends SourceBasedAnalysisTask {
return <String, TaskInput>{
LIBRARY_INPUT: LIBRARY_ELEMENT5.of(unit.library),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
- UNIT_INPUT: RESOLVED_UNIT8.of(unit),
+ UNIT_INPUT: RESOLVED_UNIT9.of(unit),
// In strong mode, add additional dependencies to enforce inference
// ordering.
// Require that inference be complete for all units in the
// current library cycle.
'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit).toList(
- (CompilationUnitElementImpl unit) => RESOLVED_UNIT8
+ (CompilationUnitElementImpl unit) => RESOLVED_UNIT9
.of(new LibrarySpecificUnit(unit.librarySource, unit.source)))
};
}
@@ -4493,7 +4793,7 @@ class ScanDartTask extends SourceBasedAnalysisTask {
*/
class StrongModeVerifyUnitTask extends SourceBasedAnalysisTask {
/**
- * The name of the [RESOLVED_UNIT10] input.
+ * The name of the [RESOLVED_UNIT11] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -4545,9 +4845,9 @@ class StrongModeVerifyUnitTask extends SourceBasedAnalysisTask {
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
LibrarySpecificUnit unit = target;
return <String, TaskInput>{
- UNIT_INPUT: RESOLVED_UNIT10.of(unit),
+ UNIT_INPUT: RESOLVED_UNIT11.of(unit),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
- 'thisLibraryClosureIsReady': READY_RESOLVED_UNIT10.of(unit.library),
+ 'thisLibraryClosureIsReady': READY_RESOLVED_UNIT11.of(unit.library),
};
}
« no previous file with comments | « pkg/analyzer/lib/src/plugin/engine_plugin.dart ('k') | pkg/analyzer/test/src/task/dart_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698