| Index: pkg/kernel/lib/interpreter/interpreter.dart
|
| diff --git a/pkg/kernel/lib/interpreter/interpreter.dart b/pkg/kernel/lib/interpreter/interpreter.dart
|
| index bb40ab71fa65be0db3766d279d7d50c9a8f96e80..b5c996fd299d47b94101b9812ec5eaee04f3ddd0 100644
|
| --- a/pkg/kernel/lib/interpreter/interpreter.dart
|
| +++ b/pkg/kernel/lib/interpreter/interpreter.dart
|
| @@ -179,6 +179,7 @@ class Evaluator
|
| var class_ = new Class(node.target.enclosingClass.reference);
|
| var newObject =
|
| new ObjectValue(class_, new List<Value>(class_.instanceSize));
|
| +
|
| ApplicationContinuation cont = new ConstructorInvocationApplication(
|
| newObject, node.target, config.continuation);
|
|
|
| @@ -603,12 +604,22 @@ class InstanceFieldsApplication extends ApplicationContinuation {
|
| _currentClass.setProperty(newObject, current.field, current.value);
|
| }
|
|
|
| - if (constructor.initializers.isEmpty ||
|
| - constructor.initializers.first is SuperInitializer) {
|
| - // todo: eval super args or constructor body configuration.
|
| + if (constructor.initializers.isEmpty) {
|
| return new ContinuationConfiguration(expressionContinuation, newObject);
|
| }
|
|
|
| + if (constructor.initializers.first is SuperInitializer) {
|
| + // SuperInitializer appears last in the initializer list.
|
| + assert(constructor.initializers.length == 1);
|
| + SuperInitializer current = constructor.initializers.first;
|
| + var args = _createArgumentExpressionList(
|
| + current.arguments, current.target.function);
|
| + var superApp = new ConstructorInvocationApplication(
|
| + newObject, current.target, expressionContinuation);
|
| + _initializeNullFields(_currentClass, newObject);
|
| + return new ExpressionListConfiguration(args, environment, superApp);
|
| + }
|
| +
|
| Class class_ = new Class(constructor.enclosingClass.reference);
|
| Environment initEnv = new Environment(environment);
|
|
|
| @@ -649,6 +660,8 @@ class InitializerContinuation extends ExpressionContinuation {
|
| Initializer next = initializers[1];
|
|
|
| if (next is RedirectingInitializer) {
|
| + // RedirectingInitializer appears last in the initializer list.
|
| + assert(initializers.length == 2);
|
| var cont = new ConstructorInvocationApplication(
|
| newObject, next.target, continuation);
|
| var args =
|
| @@ -658,11 +671,15 @@ class InitializerContinuation extends ExpressionContinuation {
|
| }
|
|
|
| if (next is SuperInitializer) {
|
| - // todo: eval args for super.
|
| - if (currentClass.superclass.superclass != null) {
|
| - throw 'Super initializer invocation is not supported.';
|
| - }
|
| - return new ContinuationConfiguration(continuation, newObject);
|
| + // SuperInitializer appears last in the initializer list.
|
| + assert(initializers.length == 2);
|
| + var args =
|
| + _createArgumentExpressionList(next.arguments, next.target.function);
|
| + var superApp = new ConstructorInvocationApplication(
|
| + newObject, next.target, continuation);
|
| + _initializeNullFields(currentClass, newObject);
|
| + return new ExpressionListConfiguration(
|
| + args, initializerEnvironment, superApp);
|
| }
|
|
|
| var cont = new InitializerContinuation(newObject, currentClass,
|
| @@ -1384,3 +1401,16 @@ Expression _getExpression(Initializer initializer) {
|
|
|
| throw '${initializer.runtimeType} has no epxression.';
|
| }
|
| +
|
| +/// Initializes all non initialized fields in given class with
|
| +/// [Value.nullInstance].
|
| +void _initializeNullFields(Class class_, ObjectValue newObject) {
|
| + int superClassSize = class_.superclass?.instanceSize ?? 0;
|
| + for (int i = superClassSize; i < class_.instanceSize; i++) {
|
| + Field field = class_.instanceFields[i];
|
| + if (class_.getProperty(newObject, field) == null) {
|
| + assert(field.initializer == null);
|
| + class_.setProperty(newObject, field, Value.nullInstance);
|
| + }
|
| + }
|
| +}
|
|
|