Index: pkg/kernel/lib/interpreter/interpreter.dart |
diff --git a/pkg/kernel/lib/interpreter/interpreter.dart b/pkg/kernel/lib/interpreter/interpreter.dart |
index ba6cd1b992035abab57964599cc95679e77f1ecc..e516c13d41c445a231c237fb17fcc0ba12a37822 100644 |
--- a/pkg/kernel/lib/interpreter/interpreter.dart |
+++ b/pkg/kernel/lib/interpreter/interpreter.dart |
@@ -661,8 +661,8 @@ class ConstructorInvocationA extends ApplicationContinuation { |
Configuration call(List<InterpreterValue> argValues) { |
Environment ctrEnv = ApplicationContinuation.createEnvironment( |
constructor.function, argValues); |
- |
- var newObject = new ObjectValue(constructor.enclosingClass); |
+ var class_ = new Class(constructor.enclosingClass.reference); |
+ var newObject = new ObjectValue(class_); |
var cont = new InitializationEK( |
constructor, ctrEnv, new NewSK(continuation, new Location(newObject))); |
@@ -670,6 +670,26 @@ class ConstructorInvocationA extends ApplicationContinuation { |
} |
} |
+/// Represents the application continuation for constructor invocation applied |
+/// on the list of evaluated arguments when a constructor is invoked in a |
+/// constructor initializer list with a [RedirectingInitializer] or |
+/// [SuperInitializer]. |
+class ConstructorInitializerA extends ApplicationContinuation { |
+ final Constructor constructor; |
+ final Location location; |
+ final ConstructorBodySK continuation; |
+ |
+ ConstructorInitializerA(this.constructor, this.location, this.continuation); |
+ |
+ Configuration call(List<InterpreterValue> vs) { |
+ Environment ctrEnv = |
+ ApplicationContinuation.createEnvironment(constructor.function, vs); |
+ var cont = new InitializationEK(constructor, ctrEnv, continuation); |
+ |
+ return new ValuePassingConfiguration(cont, location.value); |
+ } |
+} |
+ |
/// Represents the application continuation applied on the list of evaluated |
/// field initializer expressions. |
class InstanceFieldsA extends ApplicationContinuation { |
@@ -690,27 +710,48 @@ class InstanceFieldsA extends ApplicationContinuation { |
_currentClass.implicitSetters[f.field.name](location.value, f.value); |
} |
- if (constructor.initializers.length == 0 || |
- constructor.initializers.first is SuperInitializer) { |
- _initializeNullFields(_currentClass, location.value); |
- // TODO(zhivkag): Produce the configuration for executing the super |
- // initializer. |
+ if (constructor.initializers.length == 0) { |
return new ForwardConfiguration(continuation, environment); |
} |
+ |
+ if (constructor.initializers.first is SuperInitializer) { |
+ // Target constructor is from the superclass `object`. |
+ if (_currentClass.superclass.superclass == null) { |
+ // TODO(zhivkag): Execute the constructor when support for |
+ // native/external functions is added. |
+ _initializeNullFields(_currentClass, location.value); |
+ return new ForwardConfiguration(continuation, environment); |
+ } |
+ |
+ return _createEvalListConfig(constructor.initializers.first); |
+ } |
+ |
// Otherwise, the next expression from Field or Local initializers will be |
// evaluated. |
- Expression expr = (constructor.initializers.first is FieldInitializer) |
- ? (constructor.initializers.first as FieldInitializer).value |
- : (constructor.initializers.first as LocalInitializer) |
- .variable |
- .initializer; |
- |
- var cont = new InitializerListEK(constructor, 0 /* initializerIndex*/, |
- location, environment, continuation); |
+ return _createEvalConfig(constructor.initializers.first); |
+ } |
+ |
+ 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); |
+ } |
+ |
+ EvalConfiguration _createEvalConfig(Initializer initializer) { |
+ Expression expr = (initializer is FieldInitializer) |
+ ? initializer.value |
+ : (initializer as LocalInitializer).variable.initializer; |
+ |
+ // We start with index = 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); |
} |
} |
- |
// ------------------------------------------------------------------------ |
// Expression Continuations |
// ------------------------------------------------------------------------ |
@@ -995,13 +1036,9 @@ class InitializationEK extends ExpressionContinuation { |
InitializationEK(this.constructor, this.environment, this.continuation); |
Configuration call(Value value) { |
- if (constructor.enclosingClass.superclass.superclass != null) { |
- throw 'Support for super constructors in not implemented.'; |
- } |
- |
if (constructor.initializers.isNotEmpty && |
- !(constructor.initializers.last is SuperInitializer)) { |
- throw 'Support for initializers is not implemented.'; |
+ constructor.initializers.last is RedirectingInitializer) { |
+ throw 'Support for redirecting initializers is not implemented.'; |
} |
// The statement body is captured by the next statement continuation and |
@@ -1061,9 +1098,7 @@ class InitializerListEK extends ExpressionContinuation { |
_initializeNullFields(_currentClass, location.value); |
return new ForwardConfiguration(continuation, environment); |
} |
- // TODO(zhivkag): Produce the configuration according to |
- // specification. |
- throw 'Support for SuperInitializers in not implemented.'; |
+ return _createEvalListConfig(next); |
} |
if (next is RedirectingInitializer) { |
@@ -1079,6 +1114,15 @@ class InitializerListEK extends ExpressionContinuation { |
var cont = withInitializerIndex(initializerIndex + 1); |
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); |
+ } |
} |
/// Executes statements. |
@@ -1327,9 +1371,7 @@ class ObjectValue extends Value { |
final List<Location> fields; |
Object get value => this; |
- ObjectValue(ast.Class classDeclaration) |
- : class_ = new Class(classDeclaration.reference), |
- fields = new List<Location>(classDeclaration.fields.length) { |
+ ObjectValue(this.class_) : fields = new List<Location>(class_.instanceSize) { |
for (int i = 0; i < fields.length; i++) { |
// Create fresh locations for each field. |
fields[i] = new Location.empty(); |