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

Side by Side Diff: pkg/kernel/lib/interpreter/interpreter.dart

Issue 2986973002: Add support for initializers in constructor invocation (Closed)
Patch Set: Fix comment 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 // The first initializer is either an initializer with expression
694 // fields in immediately enclosing class to null. 694 // (i.e., Field or Local initializer) or a Super initializer.
Dmitry Stefantsov 2017/08/02 10:27:19 On my first read I get this comment as "we can't h
zhivkag 2017/08/02 10:56:04 I removed the comment. Its intent was not to expla
695 _initializeNullFields(_currentClass, location.value); 695 if (constructor.initializers.length == 0 ||
696 return new ForwardConfiguration(continuation, environment); 696 constructor.initializers.first is SuperInitializer) {
697 _initializeNullFields(_currentClass, location.value);
698 // TODO(zhivkag): Produce the configuration for executing the super
699 // initializer.
700 return new ForwardConfiguration(continuation, environment);
701 }
702 // Otherwise, the next expression from Field or Local initializers will be
703 // evaluated.
704 Expression expr = (constructor.initializers.first is FieldInitializer)
705 ? (constructor.initializers.first as FieldInitializer).value
706 : (constructor.initializers.first as LocalInitializer)
707 .variable
708 .initializer;
709
710 var cont = new InitializerListEK(constructor, 0 /* initializerIndex*/,
711 location, environment, continuation);
712 return new EvalConfiguration(expr, environment, cont);
697 } 713 }
698 } 714 }
699 715
700 // ------------------------------------------------------------------------ 716 // ------------------------------------------------------------------------
701 // Expression Continuations 717 // Expression Continuations
702 // ------------------------------------------------------------------------ 718 // ------------------------------------------------------------------------
703 719
704 /// Represents an expression continuation. 720 /// Represents an expression continuation.
705 /// 721 ///
706 /// There are various kinds of [ExpressionContinuation]s and their names are 722 /// 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 = 1012 var bodyCont =
997 new ConstructorBodySK(constructor.function.body, ctrEnv, continuation); 1013 new ConstructorBodySK(constructor.function.body, ctrEnv, continuation);
998 var initializers = _getFieldInitializers(constructor.enclosingClass); 1014 var initializers = _getFieldInitializers(constructor.enclosingClass);
999 var fieldsCont = 1015 var fieldsCont =
1000 new InstanceFieldsA(constructor, new Location(value), ctrEnv, bodyCont); 1016 new InstanceFieldsA(constructor, new Location(value), ctrEnv, bodyCont);
1001 return new EvalListConfiguration( 1017 return new EvalListConfiguration(
1002 initializers, new Environment.empty(), fieldsCont); 1018 initializers, new Environment.empty(), fieldsCont);
1003 } 1019 }
1004 } 1020 }
1005 1021
1022 class InitializerListEK extends ExpressionContinuation {
1023 final Constructor constructor;
1024 final int initializerIndex;
1025 final Location location;
1026 final Environment environment;
1027 // TODO(zhivkag): Add componnents for exception handling.
1028 final ConstructorBodySK continuation;
1029 final Class _currentClass;
1030
1031 InitializerListEK(this.constructor, this.initializerIndex, this.location,
1032 this.environment, this.continuation)
1033 : _currentClass = new Class(constructor.enclosingClass.reference);
1034
1035 /// Creates a continuation for the evaluation of the initializer at position
1036 /// `index`.
Dmitry Stefantsov 2017/08/02 10:27:19 Here "index" is a reference to an identifier, so i
zhivkag 2017/08/02 10:56:04 Done.
1037 InitializerListEK withInitializerIndex(int index) {
1038 return new InitializerListEK(
1039 constructor, index, location, environment, continuation);
1040 }
1041
1042 Configuration call(Value value) {
1043 Initializer current = constructor.initializers[initializerIndex];
1044 if (current is FieldInitializer) {
1045 _currentClass.lookupImplicitSetter(current.field.name)(
1046 location.value, value);
1047 return _createNextConfiguration(environment);
1048 }
1049 if (current is LocalInitializer) {
1050 Environment newEnv = environment.extend(current.variable, value);
1051 return _createNextConfiguration(newEnv);
1052 }
1053 throw "Value can't be applied to initalizer of type ${current.runtimeType}";
1054 }
1055
1056 Configuration _createNextConfiguration(Environment env) {
1057 assert(initializerIndex + 1 < constructor.initializers.length);
1058 Initializer next = constructor.initializers[initializerIndex + 1];
1059 if (next is SuperInitializer) {
1060 // TODO(zhivkag): Execute `object` constructor when support for
Dmitry Stefantsov 2017/08/02 10:27:19 "object" here is not a code fragment (as I get it)
zhivkag 2017/08/02 10:56:05 Done.
1061 // native/external functions is added.
1062 if (_currentClass.superclass.superclass == null) {
1063 _initializeNullFields(_currentClass, location.value);
1064 return new ForwardConfiguration(continuation, environment);
1065 }
1066 // TODO(zhivkag): Produce the configuration according to
1067 // specification.
1068 throw 'Support for SuperInitializers in not implemented.';
Dmitry Stefantsov 2017/08/02 10:27:19 Just a curiosity question: why string literals are
zhivkag 2017/08/02 10:56:04 Sometimes I use double quotes when the string cont
1069 }
1070
1071 if (next is RedirectingInitializer) {
1072 // TODO(zhivkag): Produce the configuration according to
1073 // specification.
1074 throw 'Support for RedirectingInitializers is not implemented.';
1075 }
1076
1077 Expression nextExpr = (next is FieldInitializer)
1078 ? next.value
1079 : (next as LocalInitializer).variable.initializer;
1080
1081 var cont = withInitializerIndex(initializerIndex + 1);
1082 return new EvalConfiguration(nextExpr, env, cont);
1083 }
1084 }
1085
1006 /// Executes statements. 1086 /// Executes statements.
1007 /// 1087 ///
1008 /// Execution of a statement completes in one of the following ways: 1088 /// Execution of a statement completes in one of the following ways:
1009 /// - It completes normally, in which case the execution proceeds to applying 1089 /// - It completes normally, in which case the execution proceeds to applying
1010 /// the next continuation. 1090 /// the next continuation.
1011 /// - It breaks with a label, in which case the corresponding continuation is 1091 /// - It breaks with a label, in which case the corresponding continuation is
1012 /// returned and applied. 1092 /// returned and applied.
1013 /// - It returns with or without value, in which case the return continuation is 1093 /// - It returns with or without value, in which case the return continuation is
1014 /// returned and applied accordingly. 1094 /// returned and applied accordingly.
1015 /// - It throws, in which case the handler is returned and applied accordingly. 1095 /// - It throws, in which case the handler is returned and applied accordingly.
1016 class StatementExecuter 1096 class StatementExecuter
1017 extends StatementVisitor1<Configuration, ExecConfiguration> { 1097 extends StatementVisitor1<Configuration, ExecConfiguration> {
1018 Evaluator evaluator = new Evaluator(); 1098 Evaluator evaluator = new Evaluator();
1019 1099
1020 void trampolinedExecution(Configuration configuration) { 1100 void trampolinedExecution(Configuration configuration) {
1021 while (configuration != null) { 1101 while (configuration != null) {
1022 configuration = configuration.step(this); 1102 configuration = configuration.step(this);
1023 } 1103 }
1024 ;
1025 } 1104 }
1026 1105
1027 Configuration exec(Statement statement, ExecConfiguration conf) => 1106 Configuration exec(Statement statement, ExecConfiguration conf) =>
1028 statement.accept1(this, conf); 1107 statement.accept1(this, conf);
1029 Configuration eval(Expression expression, EvalConfiguration config) => 1108 Configuration eval(Expression expression, EvalConfiguration config) =>
1030 evaluator.eval(expression, config); 1109 evaluator.eval(expression, config);
1031 Configuration evalList( 1110 Configuration evalList(
1032 List<InterpreterExpression> es, Environment env, Continuation cont) => 1111 List<InterpreterExpression> es, Environment env, Continuation cont) =>
1033 evaluator.evalList(es, env, cont); 1112 evaluator.evalList(es, env, cont);
1034 1113
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
1419 /// Initializes all non initialized fields from the provided class to 1498 /// Initializes all non initialized fields from the provided class to
1420 /// `Value.nullInstance` in the provided value. 1499 /// `Value.nullInstance` in the provided value.
1421 void _initializeNullFields(Class class_, Value value) { 1500 void _initializeNullFields(Class class_, Value value) {
1422 int startIndex = class_.superclass?.instanceSize ?? 0; 1501 int startIndex = class_.superclass?.instanceSize ?? 0;
1423 for (int i = startIndex; i < class_.instanceSize; i++) { 1502 for (int i = startIndex; i < class_.instanceSize; i++) {
1424 if (value.fields[i].value == null) { 1503 if (value.fields[i].value == null) {
1425 value.fields[i].value = Value.nullInstance; 1504 value.fields[i].value = Value.nullInstance;
1426 } 1505 }
1427 } 1506 }
1428 } 1507 }
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