| Index: pkg/kernel/lib/interpreter/interpreter.dart
|
| diff --git a/pkg/kernel/lib/interpreter/interpreter.dart b/pkg/kernel/lib/interpreter/interpreter.dart
|
| index e516c13d41c445a231c237fb17fcc0ba12a37822..0bb5af1d3a6d0a4171d839e6a3edb48fded1faaf 100644
|
| --- a/pkg/kernel/lib/interpreter/interpreter.dart
|
| +++ b/pkg/kernel/lib/interpreter/interpreter.dart
|
| @@ -711,6 +711,8 @@ class InstanceFieldsA extends ApplicationContinuation {
|
| }
|
|
|
| if (constructor.initializers.length == 0) {
|
| + // This can happen when initializing fields of a constructor with an empty
|
| + // initializer list.
|
| return new ForwardConfiguration(continuation, environment);
|
| }
|
|
|
| @@ -1036,11 +1038,13 @@ class InitializationEK extends ExpressionContinuation {
|
| InitializationEK(this.constructor, this.environment, this.continuation);
|
|
|
| Configuration call(Value value) {
|
| + Location location = new Location(value);
|
| +
|
| if (constructor.initializers.isNotEmpty &&
|
| constructor.initializers.last is RedirectingInitializer) {
|
| - throw 'Support for redirecting initializers is not implemented.';
|
| + return _createRedirectingInitializerConfig(
|
| + constructor.initializers.first, location);
|
| }
|
| -
|
| // The statement body is captured by the next statement continuation and
|
| // expressions for field initialization are evaluated.
|
| var ctrEnv = environment.extendWithThis(value);
|
| @@ -1048,10 +1052,35 @@ class InitializationEK extends ExpressionContinuation {
|
| new ConstructorBodySK(constructor.function.body, ctrEnv, continuation);
|
| var initializers = _getFieldInitializers(constructor.enclosingClass);
|
| var fieldsCont =
|
| - new InstanceFieldsA(constructor, new Location(value), ctrEnv, bodyCont);
|
| + new InstanceFieldsA(constructor, location, ctrEnv, bodyCont);
|
| return new EvalListConfiguration(
|
| initializers, new Environment.empty(), fieldsCont);
|
| }
|
| +
|
| + /// Creates the next configuration to further initializer the value for
|
| + /// redirecting constructors.
|
| + Configuration _createRedirectingInitializerConfig(
|
| + Initializer initializer, Location location) {
|
| + Initializer current = constructor.initializers.first;
|
| + if (current is RedirectingInitializer) {
|
| + // Evaluate the list of arguments for invoking the target constructor in
|
| + // the current environment.
|
| + List<InterpreterExpression> exprs =
|
| + _getArgumentExpressions(current.arguments, current.target.function);
|
| + var cont =
|
| + new ConstructorInitializerA(current.target, location, continuation);
|
| + return new EvalListConfiguration(exprs, environment, cont);
|
| + }
|
| + Expression expr = (current is FieldInitializer)
|
| + ? current.value
|
| + : (current as LocalInitializer).variable.initializer;
|
| +
|
| + // The index is set to 0 since we are evaluating the expression for the
|
| + // first initializer in the initializer list.
|
| + var cont = new InitializerListEK(
|
| + constructor, 0, location, environment, continuation);
|
| + return new EvalConfiguration(expr, environment, cont);
|
| + }
|
| }
|
|
|
| class InitializerListEK extends ExpressionContinuation {
|
| @@ -1098,13 +1127,11 @@ class InitializerListEK extends ExpressionContinuation {
|
| _initializeNullFields(_currentClass, location.value);
|
| return new ForwardConfiguration(continuation, environment);
|
| }
|
| - return _createEvalListConfig(next);
|
| + return _createEvalListConfig(next.arguments, next.target, env);
|
| }
|
|
|
| if (next is RedirectingInitializer) {
|
| - // TODO(zhivkag): Produce the configuration according to
|
| - // specification.
|
| - throw 'Support for RedirectingInitializers is not implemented.';
|
| + return _createEvalListConfig(next.arguments, next.target, env);
|
| }
|
|
|
| Expression nextExpr = (next is FieldInitializer)
|
| @@ -1115,13 +1142,12 @@ class InitializerListEK extends ExpressionContinuation {
|
| return new EvalConfiguration(nextExpr, env, cont);
|
| }
|
|
|
| - Configuration _createEvalListConfig(SuperInitializer initializer) {
|
| - List<InterpreterExpression> args = _getArgumentExpressions(
|
| - initializer.arguments, initializer.target.function);
|
| - var cont =
|
| - new ConstructorInitializerA(initializer.target, location, continuation);
|
| -
|
| - return new EvalListConfiguration(args, environment, cont);
|
| + Configuration _createEvalListConfig(
|
| + Arguments args, Constructor ctr, Environment env) {
|
| + List<InterpreterExpression> exprs =
|
| + _getArgumentExpressions(args, ctr.function);
|
| + var cont = new ConstructorInitializerA(ctr, location, continuation);
|
| + return new EvalListConfiguration(exprs, env, cont);
|
| }
|
| }
|
|
|
|
|