Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(710)

Unified Diff: pkg/kernel/lib/interpreter/interpreter.dart

Issue 2986973002: Add support for initializers in constructor invocation (Closed)
Patch Set: Apply review comments Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/kernel/testcases/interpreter/object_field_initializers_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/kernel/lib/interpreter/interpreter.dart
diff --git a/pkg/kernel/lib/interpreter/interpreter.dart b/pkg/kernel/lib/interpreter/interpreter.dart
index 87cf0ef9f8cfd4f9b504d22c24e2c77cb36458fb..ba6cd1b992035abab57964599cc95679e77f1ecc 100644
--- a/pkg/kernel/lib/interpreter/interpreter.dart
+++ b/pkg/kernel/lib/interpreter/interpreter.dart
@@ -690,10 +690,24 @@ class InstanceFieldsA extends ApplicationContinuation {
_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);
+ if (constructor.initializers.length == 0 ||
+ constructor.initializers.first is SuperInitializer) {
+ _initializeNullFields(_currentClass, location.value);
+ // TODO(zhivkag): Produce the configuration for executing the super
+ // initializer.
+ return new ForwardConfiguration(continuation, environment);
+ }
+ // 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 new EvalConfiguration(expr, environment, cont);
}
}
@@ -1003,6 +1017,70 @@ class InitializationEK extends ExpressionContinuation {
}
}
+class InitializerListEK extends ExpressionContinuation {
+ final Constructor constructor;
+ final int initializerIndex;
+ final Location location;
+ final Environment environment;
+ // TODO(zhivkag): Add componnents for exception handling.
+ final ConstructorBodySK continuation;
+ final Class _currentClass;
+
+ InitializerListEK(this.constructor, this.initializerIndex, this.location,
+ this.environment, this.continuation)
+ : _currentClass = new Class(constructor.enclosingClass.reference);
+
+ /// Creates a continuation for the evaluation of the initializer at position
+ /// [index].
+ InitializerListEK withInitializerIndex(int index) {
+ return new InitializerListEK(
+ constructor, index, location, environment, continuation);
+ }
+
+ Configuration call(Value value) {
+ Initializer current = constructor.initializers[initializerIndex];
+ if (current is FieldInitializer) {
+ _currentClass.lookupImplicitSetter(current.field.name)(
+ location.value, value);
+ return _createNextConfiguration(environment);
+ }
+ if (current is LocalInitializer) {
+ Environment newEnv = environment.extend(current.variable, value);
+ return _createNextConfiguration(newEnv);
+ }
+ throw "Value can't be applied to initalizer of type ${current.runtimeType}";
+ }
+
+ Configuration _createNextConfiguration(Environment env) {
+ assert(initializerIndex + 1 < constructor.initializers.length);
+ Initializer next = constructor.initializers[initializerIndex + 1];
+ if (next is SuperInitializer) {
+ // TODO(zhivkag): Execute constructor of "object" class when support for
+ // native/external functions is added.
+ if (_currentClass.superclass.superclass == null) {
+ _initializeNullFields(_currentClass, location.value);
+ return new ForwardConfiguration(continuation, environment);
+ }
+ // TODO(zhivkag): Produce the configuration according to
+ // specification.
+ throw 'Support for SuperInitializers in not implemented.';
+ }
+
+ if (next is RedirectingInitializer) {
+ // TODO(zhivkag): Produce the configuration according to
+ // specification.
+ throw 'Support for RedirectingInitializers is not implemented.';
+ }
+
+ Expression nextExpr = (next is FieldInitializer)
+ ? next.value
+ : (next as LocalInitializer).variable.initializer;
+
+ var cont = withInitializerIndex(initializerIndex + 1);
+ return new EvalConfiguration(nextExpr, env, cont);
+ }
+}
+
/// Executes statements.
///
/// Execution of a statement completes in one of the following ways:
@@ -1021,7 +1099,6 @@ class StatementExecuter
while (configuration != null) {
configuration = configuration.step(this);
}
- ;
}
Configuration exec(Statement statement, ExecConfiguration conf) =>
« no previous file with comments | « no previous file | pkg/kernel/testcases/interpreter/object_field_initializers_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698