Chromium Code Reviews| 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..f9aa86830de5e34d0e1eb90a61c9723a4783bdc3 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); |
|
Dmitry Stefantsov
2017/07/27 09:10:39
I think [InstanceFieldsA] here is something differ
zhivkag
2017/07/27 10:38:21
It should be the same thing, except for the step (
Dmitry Stefantsov
2017/07/27 10:43:31
Thanks for the explanation!
|
| + 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 |
|
Dmitry Stefantsov
2017/07/27 09:10:39
The line is too long.
zhivkag
2017/07/27 10:38:21
Done.
|
| +/// 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; |
| + } |
| + } |
| +} |