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), |
}; |
} |