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

Side by Side 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 library kernel.interpreter; 4 library kernel.interpreter;
5 5
6 import '../ast.dart'; 6 import '../ast.dart';
7 import '../ast.dart' as ast show Class; 7 import '../ast.dart' as ast show Class;
8 8
9 import '../log.dart'; 9 import '../log.dart';
10 export '../log.dart'; 10 export '../log.dart';
(...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 InstanceFieldsA( 683 InstanceFieldsA(
684 this.constructor, this.location, this.environment, this.continuation) 684 this.constructor, this.location, this.environment, this.continuation)
685 : _currentClass = new Class(constructor.enclosingClass.reference); 685 : _currentClass = new Class(constructor.enclosingClass.reference);
686 686
687 Configuration call(List<InterpreterValue> fieldValues) { 687 Configuration call(List<InterpreterValue> fieldValues) {
688 for (FieldInitializerValue f in fieldValues) { 688 for (FieldInitializerValue f in fieldValues) {
689 // Directly set the field with the corresponding implicit setter. 689 // Directly set the field with the corresponding implicit setter.
690 _currentClass.implicitSetters[f.field.name](location.value, f.value); 690 _currentClass.implicitSetters[f.field.name](location.value, f.value);
691 } 691 }
692 692
693 // TODO(zhivkag): Execute constructor initializer list before initializing 693 if (constructor.initializers.length == 0 ||
694 // fields in immediately enclosing class to null. 694 constructor.initializers.first is SuperInitializer) {
695 _initializeNullFields(_currentClass, location.value); 695 _initializeNullFields(_currentClass, location.value);
696 return new ForwardConfiguration(continuation, environment); 696 // TODO(zhivkag): Produce the configuration for executing the super
697 // initializer.
698 return new ForwardConfiguration(continuation, environment);
699 }
700 // Otherwise, the next expression from Field or Local initializers will be
701 // evaluated.
702 Expression expr = (constructor.initializers.first is FieldInitializer)
703 ? (constructor.initializers.first as FieldInitializer).value
704 : (constructor.initializers.first as LocalInitializer)
705 .variable
706 .initializer;
707
708 var cont = new InitializerListEK(constructor, 0 /* initializerIndex*/,
709 location, environment, continuation);
710 return new EvalConfiguration(expr, environment, cont);
697 } 711 }
698 } 712 }
699 713
700 // ------------------------------------------------------------------------ 714 // ------------------------------------------------------------------------
701 // Expression Continuations 715 // Expression Continuations
702 // ------------------------------------------------------------------------ 716 // ------------------------------------------------------------------------
703 717
704 /// Represents an expression continuation. 718 /// Represents an expression continuation.
705 /// 719 ///
706 /// There are various kinds of [ExpressionContinuation]s and their names are 720 /// There are various kinds of [ExpressionContinuation]s and their names are
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
996 var bodyCont = 1010 var bodyCont =
997 new ConstructorBodySK(constructor.function.body, ctrEnv, continuation); 1011 new ConstructorBodySK(constructor.function.body, ctrEnv, continuation);
998 var initializers = _getFieldInitializers(constructor.enclosingClass); 1012 var initializers = _getFieldInitializers(constructor.enclosingClass);
999 var fieldsCont = 1013 var fieldsCont =
1000 new InstanceFieldsA(constructor, new Location(value), ctrEnv, bodyCont); 1014 new InstanceFieldsA(constructor, new Location(value), ctrEnv, bodyCont);
1001 return new EvalListConfiguration( 1015 return new EvalListConfiguration(
1002 initializers, new Environment.empty(), fieldsCont); 1016 initializers, new Environment.empty(), fieldsCont);
1003 } 1017 }
1004 } 1018 }
1005 1019
1020 class InitializerListEK extends ExpressionContinuation {
1021 final Constructor constructor;
1022 final int initializerIndex;
1023 final Location location;
1024 final Environment environment;
1025 // TODO(zhivkag): Add componnents for exception handling.
1026 final ConstructorBodySK continuation;
1027 final Class _currentClass;
1028
1029 InitializerListEK(this.constructor, this.initializerIndex, this.location,
1030 this.environment, this.continuation)
1031 : _currentClass = new Class(constructor.enclosingClass.reference);
1032
1033 /// Creates a continuation for the evaluation of the initializer at position
1034 /// [index].
1035 InitializerListEK withInitializerIndex(int index) {
1036 return new InitializerListEK(
1037 constructor, index, location, environment, continuation);
1038 }
1039
1040 Configuration call(Value value) {
1041 Initializer current = constructor.initializers[initializerIndex];
1042 if (current is FieldInitializer) {
1043 _currentClass.lookupImplicitSetter(current.field.name)(
1044 location.value, value);
1045 return _createNextConfiguration(environment);
1046 }
1047 if (current is LocalInitializer) {
1048 Environment newEnv = environment.extend(current.variable, value);
1049 return _createNextConfiguration(newEnv);
1050 }
1051 throw "Value can't be applied to initalizer of type ${current.runtimeType}";
1052 }
1053
1054 Configuration _createNextConfiguration(Environment env) {
1055 assert(initializerIndex + 1 < constructor.initializers.length);
1056 Initializer next = constructor.initializers[initializerIndex + 1];
1057 if (next is SuperInitializer) {
1058 // TODO(zhivkag): Execute constructor of "object" class when support for
1059 // native/external functions is added.
1060 if (_currentClass.superclass.superclass == null) {
1061 _initializeNullFields(_currentClass, location.value);
1062 return new ForwardConfiguration(continuation, environment);
1063 }
1064 // TODO(zhivkag): Produce the configuration according to
1065 // specification.
1066 throw 'Support for SuperInitializers in not implemented.';
1067 }
1068
1069 if (next is RedirectingInitializer) {
1070 // TODO(zhivkag): Produce the configuration according to
1071 // specification.
1072 throw 'Support for RedirectingInitializers is not implemented.';
1073 }
1074
1075 Expression nextExpr = (next is FieldInitializer)
1076 ? next.value
1077 : (next as LocalInitializer).variable.initializer;
1078
1079 var cont = withInitializerIndex(initializerIndex + 1);
1080 return new EvalConfiguration(nextExpr, env, cont);
1081 }
1082 }
1083
1006 /// Executes statements. 1084 /// Executes statements.
1007 /// 1085 ///
1008 /// Execution of a statement completes in one of the following ways: 1086 /// Execution of a statement completes in one of the following ways:
1009 /// - It completes normally, in which case the execution proceeds to applying 1087 /// - It completes normally, in which case the execution proceeds to applying
1010 /// the next continuation. 1088 /// the next continuation.
1011 /// - It breaks with a label, in which case the corresponding continuation is 1089 /// - It breaks with a label, in which case the corresponding continuation is
1012 /// returned and applied. 1090 /// returned and applied.
1013 /// - It returns with or without value, in which case the return continuation is 1091 /// - It returns with or without value, in which case the return continuation is
1014 /// returned and applied accordingly. 1092 /// returned and applied accordingly.
1015 /// - It throws, in which case the handler is returned and applied accordingly. 1093 /// - It throws, in which case the handler is returned and applied accordingly.
1016 class StatementExecuter 1094 class StatementExecuter
1017 extends StatementVisitor1<Configuration, ExecConfiguration> { 1095 extends StatementVisitor1<Configuration, ExecConfiguration> {
1018 Evaluator evaluator = new Evaluator(); 1096 Evaluator evaluator = new Evaluator();
1019 1097
1020 void trampolinedExecution(Configuration configuration) { 1098 void trampolinedExecution(Configuration configuration) {
1021 while (configuration != null) { 1099 while (configuration != null) {
1022 configuration = configuration.step(this); 1100 configuration = configuration.step(this);
1023 } 1101 }
1024 ;
1025 } 1102 }
1026 1103
1027 Configuration exec(Statement statement, ExecConfiguration conf) => 1104 Configuration exec(Statement statement, ExecConfiguration conf) =>
1028 statement.accept1(this, conf); 1105 statement.accept1(this, conf);
1029 Configuration eval(Expression expression, EvalConfiguration config) => 1106 Configuration eval(Expression expression, EvalConfiguration config) =>
1030 evaluator.eval(expression, config); 1107 evaluator.eval(expression, config);
1031 Configuration evalList( 1108 Configuration evalList(
1032 List<InterpreterExpression> es, Environment env, Continuation cont) => 1109 List<InterpreterExpression> es, Environment env, Continuation cont) =>
1033 evaluator.evalList(es, env, cont); 1110 evaluator.evalList(es, env, cont);
1034 1111
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
1419 /// Initializes all non initialized fields from the provided class to 1496 /// Initializes all non initialized fields from the provided class to
1420 /// `Value.nullInstance` in the provided value. 1497 /// `Value.nullInstance` in the provided value.
1421 void _initializeNullFields(Class class_, Value value) { 1498 void _initializeNullFields(Class class_, Value value) {
1422 int startIndex = class_.superclass?.instanceSize ?? 0; 1499 int startIndex = class_.superclass?.instanceSize ?? 0;
1423 for (int i = startIndex; i < class_.instanceSize; i++) { 1500 for (int i = startIndex; i < class_.instanceSize; i++) {
1424 if (value.fields[i].value == null) { 1501 if (value.fields[i].value == null) {
1425 value.fields[i].value = Value.nullInstance; 1502 value.fields[i].value = Value.nullInstance;
1426 } 1503 }
1427 } 1504 }
1428 } 1505 }
OLDNEW
« 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