Index: pkg/kernel/lib/interpreter/interpreter.dart |
diff --git a/pkg/kernel/lib/interpreter/interpreter.dart b/pkg/kernel/lib/interpreter/interpreter.dart |
index 4f327b9b5f445996c5929ba57dcafaa4cbd03351..87cf0ef9f8cfd4f9b504d22c24e2c77cb36458fb 100644 |
--- a/pkg/kernel/lib/interpreter/interpreter.dart |
+++ b/pkg/kernel/lib/interpreter/interpreter.dart |
@@ -670,6 +670,33 @@ class ConstructorInvocationA extends ApplicationContinuation { |
} |
} |
+/// Represents the application continuation applied on the list of evaluated |
+/// field initializer expressions. |
+class InstanceFieldsA extends ApplicationContinuation { |
+ final Constructor constructor; |
+ final Location location; |
+ final Environment environment; |
+ final ConstructorBodySK continuation; |
+ |
+ final Class _currentClass; |
+ |
+ InstanceFieldsA( |
+ this.constructor, this.location, this.environment, this.continuation) |
+ : _currentClass = new Class(constructor.enclosingClass.reference); |
+ |
+ Configuration call(List<InterpreterValue> fieldValues) { |
+ for (FieldInitializerValue f in fieldValues) { |
+ // Directly set the field with the corresponding implicit setter. |
+ _currentClass.implicitSetters[f.field.name](location.value, f.value); |
+ } |
+ |
+ // TODO(zhivkag): Execute constructor initializer list before initializing |
+ // fields in immediately enclosing class to null. |
+ _initializeNullFields(_currentClass, location.value); |
+ return new ForwardConfiguration(continuation, environment); |
+ } |
+} |
+ |
// ------------------------------------------------------------------------ |
// Expression Continuations |
// ------------------------------------------------------------------------ |
@@ -960,7 +987,7 @@ class InitializationEK extends ExpressionContinuation { |
if (constructor.initializers.isNotEmpty && |
!(constructor.initializers.last is SuperInitializer)) { |
- throw 'Support for initializer is not implemented.'; |
+ throw 'Support for initializers is not implemented.'; |
} |
// The statement body is captured by the next statement continuation and |
@@ -968,8 +995,11 @@ class InitializationEK extends ExpressionContinuation { |
var ctrEnv = environment.extendWithThis(value); |
var bodyCont = |
new ConstructorBodySK(constructor.function.body, ctrEnv, continuation); |
- // TODO(zhivkag): Add support for initialization of fields with initializers. |
- return new ForwardConfiguration(bodyCont, ctrEnv); |
+ var initializers = _getFieldInitializers(constructor.enclosingClass); |
+ var fieldsCont = |
+ new InstanceFieldsA(constructor, new Location(value), ctrEnv, bodyCont); |
+ return new EvalListConfiguration( |
+ initializers, new Environment.empty(), fieldsCont); |
} |
} |
@@ -1369,3 +1399,30 @@ List<InterpreterExpression> _getArgumentExpressions( |
return args; |
} |
+ |
+/// Creates a list of all field expressions to be evaluated. |
+/// |
+/// A field expression is an initializer expression for a given field defined |
+/// when the field was created. |
+List<InterpreterExpression> _getFieldInitializers(ast.Class class_) { |
+ var fieldInitializers = new List<InterpreterExpression>(); |
+ |
+ for (Field f in class_.fields) { |
+ if (f.initializer != null) { |
+ fieldInitializers.add(new FieldInitializerExpression(f, f.initializer)); |
+ } |
+ } |
+ |
+ return fieldInitializers; |
+} |
+ |
+/// Initializes all non initialized fields from the provided class to |
+/// `Value.nullInstance` in the provided value. |
+void _initializeNullFields(Class class_, Value value) { |
+ int startIndex = class_.superclass?.instanceSize ?? 0; |
+ for (int i = startIndex; i < class_.instanceSize; i++) { |
+ if (value.fields[i].value == null) { |
+ value.fields[i].value = Value.nullInstance; |
+ } |
+ } |
+} |