Skip to content

Commit

Permalink
Improve the handling of inference for instance fields in the task model
Browse files Browse the repository at this point in the history
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 .
  • Loading branch information
leafpetersen committed Sep 28, 2015
1 parent 66bc931 commit 9be2107
Show file tree
Hide file tree
Showing 3 changed files with 692 additions and 39 deletions.
21 changes: 11 additions & 10 deletions pkg/analyzer/lib/src/generated/resolver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9613,12 +9613,13 @@ class PartialResolverVisitor extends ResolverVisitor {
final bool strongMode;

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

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

@override
Object visitFieldDeclaration(FieldDeclaration node) {
if (strongMode && node.isStatic) {
_addStaticVariables(node.fields.variables);
if (strongMode) {
_addVariables(node.fields.variables);
bool wasDiscarding = discardErrorsInInitializer;
discardErrorsInInitializer = true;
try {
Expand All @@ -9699,7 +9700,7 @@ class PartialResolverVisitor extends ResolverVisitor {
@override
Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
if (strongMode) {
_addStaticVariables(node.variables.variables);
_addVariables(node.variables.variables);
bool wasDiscarding = discardErrorsInInitializer;
discardErrorsInInitializer = true;
try {
Expand All @@ -9718,10 +9719,10 @@ class PartialResolverVisitor extends ResolverVisitor {
* potentially need to be re-resolved after inference because they might
* refer to a field whose type was inferred.
*/
void _addStaticVariables(NodeList<VariableDeclaration> variables) {
void _addVariables(NodeList<VariableDeclaration> variables) {
for (VariableDeclaration variable in variables) {
if (variable.initializer != null) {
staticVariables.add(variable.element);
variablesAndFields.add(variable.element);
}
}
}
Expand Down
51 changes: 24 additions & 27 deletions pkg/analyzer/lib/src/task/dart.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2667,35 +2667,32 @@ class InferStaticVariableTypeTask extends InferStaticVariableTask {
// have types inferred before inferring the type of this variable.
//
VariableElementImpl variable = target;

CompilationUnit unit = getRequiredInput(UNIT_INPUT);
TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
RecordingErrorListener errorListener = new RecordingErrorListener();
if (dependencyCycle == null) {
//
// Re-resolve the variable's initializer so that the inferred types of other
// variables will be propagated.
//
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");
}
Expression initializer = declaration.initializer;
ResolutionEraser.erase(initializer, eraseDeclarations: false);
ResolutionContext resolutionContext =
ResolutionContextBuilder.contextFor(initializer, errorListener);
ResolverVisitor visitor = new ResolverVisitor(
variable.library, variable.source, typeProvider, errorListener,
nameScope: resolutionContext.scope);
if (resolutionContext.enclosingClassDeclaration != null) {
visitor.prepareToResolveMembersInClass(
resolutionContext.enclosingClassDeclaration);
}
visitor.initForIncrementalResolution();
initializer.accept(visitor);
VariableDeclaration declaration = getDeclaration(unit);
//
// Re-resolve the variable's initializer so that the inferred types of other
// variables will be propagated.
//
Expression initializer = declaration.initializer;
ResolutionEraser.erase(initializer, eraseDeclarations: false);
ResolutionContext resolutionContext =
ResolutionContextBuilder.contextFor(initializer, errorListener);
ResolverVisitor visitor = new ResolverVisitor(
variable.library, variable.source, typeProvider, errorListener,
nameScope: resolutionContext.scope);
if (resolutionContext.enclosingClassDeclaration != null) {
visitor.prepareToResolveMembersInClass(
resolutionContext.enclosingClassDeclaration);
}
visitor.initForIncrementalResolution();
initializer.accept(visitor);

// If we're not in a dependency cycle, and we have no type annotation,
// do inference.
if (dependencyCycle == null && variable.hasImplicitType) {
//
// Record the type of the variable.
//
Expand Down Expand Up @@ -3159,7 +3156,7 @@ class PartiallyResolveUnitReferencesTask extends SourceBasedAnalysisTask {
//
// Record outputs.
//
outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = visitor.staticVariables;
outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = visitor.variablesAndFields;
outputs[PARTIALLY_RESOLVE_REFERENCES_ERRORS] =
removeDuplicateErrors(errorListener.errors);
outputs[RESOLVED_UNIT5] = unit;
Expand Down
Loading

0 comments on commit 9be2107

Please sign in to comment.