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

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

Issue 2881053002: Add support for super constructor invocation (Closed)
Patch Set: Created 3 years, 7 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_super_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 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);
+ }
+ }
+}
« no previous file with comments | « no previous file | pkg/kernel/testcases/interpreter/object_super_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698