Skip to content

Commit 9be2107

Browse files
committed
Improve the handling of inference for instance fields in the task model
strong mode inference. This CL adds instance fields to the set of variables for which dependencies are computed, and re-resolves each instance field initializer using type information inferred for the static variables upon which it depends. This CL also stops static variables with existing type information from having their types overwritten. This CL ports over a number of the DDC inference tests, more remain to be ported. There is still at least one outstanding issue with instance variable inference, see #354 (and the two tests marked fail added in this CL). BUG= [email protected] Review URL: https://codereview.chromium.org//1370793002 .
1 parent 66bc931 commit 9be2107

File tree

3 files changed

+692
-39
lines changed

3 files changed

+692
-39
lines changed

pkg/analyzer/lib/src/generated/resolver.dart

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9613,12 +9613,13 @@ class PartialResolverVisitor extends ResolverVisitor {
96139613
final bool strongMode;
96149614

96159615
/**
9616-
* The static variables that have an initializer. These are the variables that
9617-
* need to be re-resolved after static variables have their types inferred. A
9618-
* subset of these variables are those whose types should be inferred. The
9619-
* list will be empty unless the resolver is being run in strong mode.
9616+
* The static variables and fields that have an initializer. These are the
9617+
* variables that need to be re-resolved after static variables have their
9618+
* types inferred. A subset of these variables are those whose types should
9619+
* be inferred. The list will be empty unless the resolver is being run in
9620+
* strong mode.
96209621
*/
9621-
final List<VariableElement> staticVariables = <VariableElement>[];
9622+
final List<VariableElement> variablesAndFields = <VariableElement>[];
96229623

96239624
/**
96249625
* A flag indicating whether we should discard errors while resolving the
@@ -9671,8 +9672,8 @@ class PartialResolverVisitor extends ResolverVisitor {
96719672

96729673
@override
96739674
Object visitFieldDeclaration(FieldDeclaration node) {
9674-
if (strongMode && node.isStatic) {
9675-
_addStaticVariables(node.fields.variables);
9675+
if (strongMode) {
9676+
_addVariables(node.fields.variables);
96769677
bool wasDiscarding = discardErrorsInInitializer;
96779678
discardErrorsInInitializer = true;
96789679
try {
@@ -9699,7 +9700,7 @@ class PartialResolverVisitor extends ResolverVisitor {
96999700
@override
97009701
Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
97019702
if (strongMode) {
9702-
_addStaticVariables(node.variables.variables);
9703+
_addVariables(node.variables.variables);
97039704
bool wasDiscarding = discardErrorsInInitializer;
97049705
discardErrorsInInitializer = true;
97059706
try {
@@ -9718,10 +9719,10 @@ class PartialResolverVisitor extends ResolverVisitor {
97189719
* potentially need to be re-resolved after inference because they might
97199720
* refer to a field whose type was inferred.
97209721
*/
9721-
void _addStaticVariables(NodeList<VariableDeclaration> variables) {
9722+
void _addVariables(NodeList<VariableDeclaration> variables) {
97229723
for (VariableDeclaration variable in variables) {
97239724
if (variable.initializer != null) {
9724-
staticVariables.add(variable.element);
9725+
variablesAndFields.add(variable.element);
97259726
}
97269727
}
97279728
}

pkg/analyzer/lib/src/task/dart.dart

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2667,35 +2667,32 @@ class InferStaticVariableTypeTask extends InferStaticVariableTask {
26672667
// have types inferred before inferring the type of this variable.
26682668
//
26692669
VariableElementImpl variable = target;
2670+
26702671
CompilationUnit unit = getRequiredInput(UNIT_INPUT);
26712672
TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
26722673
RecordingErrorListener errorListener = new RecordingErrorListener();
2673-
if (dependencyCycle == null) {
2674-
//
2675-
// Re-resolve the variable's initializer so that the inferred types of other
2676-
// variables will be propagated.
2677-
//
2678-
NodeLocator locator = new NodeLocator(variable.nameOffset);
2679-
AstNode node = locator.searchWithin(unit);
2680-
VariableDeclaration declaration = node
2681-
.getAncestor((AstNode ancestor) => ancestor is VariableDeclaration);
2682-
if (declaration == null || declaration.name != node) {
2683-
throw new AnalysisException(
2684-
"NodeLocator failed to find a variable's declaration");
2685-
}
2686-
Expression initializer = declaration.initializer;
2687-
ResolutionEraser.erase(initializer, eraseDeclarations: false);
2688-
ResolutionContext resolutionContext =
2689-
ResolutionContextBuilder.contextFor(initializer, errorListener);
2690-
ResolverVisitor visitor = new ResolverVisitor(
2691-
variable.library, variable.source, typeProvider, errorListener,
2692-
nameScope: resolutionContext.scope);
2693-
if (resolutionContext.enclosingClassDeclaration != null) {
2694-
visitor.prepareToResolveMembersInClass(
2695-
resolutionContext.enclosingClassDeclaration);
2696-
}
2697-
visitor.initForIncrementalResolution();
2698-
initializer.accept(visitor);
2674+
VariableDeclaration declaration = getDeclaration(unit);
2675+
//
2676+
// Re-resolve the variable's initializer so that the inferred types of other
2677+
// variables will be propagated.
2678+
//
2679+
Expression initializer = declaration.initializer;
2680+
ResolutionEraser.erase(initializer, eraseDeclarations: false);
2681+
ResolutionContext resolutionContext =
2682+
ResolutionContextBuilder.contextFor(initializer, errorListener);
2683+
ResolverVisitor visitor = new ResolverVisitor(
2684+
variable.library, variable.source, typeProvider, errorListener,
2685+
nameScope: resolutionContext.scope);
2686+
if (resolutionContext.enclosingClassDeclaration != null) {
2687+
visitor.prepareToResolveMembersInClass(
2688+
resolutionContext.enclosingClassDeclaration);
2689+
}
2690+
visitor.initForIncrementalResolution();
2691+
initializer.accept(visitor);
2692+
2693+
// If we're not in a dependency cycle, and we have no type annotation,
2694+
// do inference.
2695+
if (dependencyCycle == null && variable.hasImplicitType) {
26992696
//
27002697
// Record the type of the variable.
27012698
//
@@ -3159,7 +3156,7 @@ class PartiallyResolveUnitReferencesTask extends SourceBasedAnalysisTask {
31593156
//
31603157
// Record outputs.
31613158
//
3162-
outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = visitor.staticVariables;
3159+
outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = visitor.variablesAndFields;
31633160
outputs[PARTIALLY_RESOLVE_REFERENCES_ERRORS] =
31643161
removeDuplicateErrors(errorListener.errors);
31653162
outputs[RESOLVED_UNIT5] = unit;

0 commit comments

Comments
 (0)