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

Side by Side Diff: lib/compiler/implementation/compile_time_constants.dart

Issue 9930005: Use default values of named arguments when invoking the default super constructor. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 4
5 class Constant implements Hashable { 5 class Constant implements Hashable {
6 const Constant(); 6 const Constant();
7 7
8 bool isNull() => false; 8 bool isNull() => false;
9 bool isBool() => false; 9 bool isBool() => false;
10 bool isTrue() => false; 10 bool isTrue() => false;
(...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 visitSendSet(SendSet node) { 945 visitSendSet(SendSet node) {
946 error(node); 946 error(node);
947 } 947 }
948 948
949 /** Returns the list of constants that are passed to the static function. */ 949 /** Returns the list of constants that are passed to the static function. */
950 List<Constant> evaluateArgumentsToConstructor(Send send, 950 List<Constant> evaluateArgumentsToConstructor(Send send,
951 FunctionElement target) { 951 FunctionElement target) {
952 FunctionParameters parameters = target.computeParameters(compiler); 952 FunctionParameters parameters = target.computeParameters(compiler);
953 List<Constant> arguments = <Constant>[]; 953 List<Constant> arguments = <Constant>[];
954 Selector selector = elements.getSelector(send); 954 Selector selector = elements.getSelector(send);
955 // For an implicit super call we construct a synthetic send which is not
956 // in the elements.
957 if (selector == null) {
958 assert(send.argumentsNode.isEmpty());
959 selector = Selector.INVOCATION_0;
960 }
955 961
956 Function compileArgument = evaluate; 962 Function compileArgument = evaluate;
957 Function compileConstant = compiler.compileVariable; 963 Function compileConstant = compiler.compileVariable;
958 bool succeeded = selector.addSendArgumentsToList( 964 bool succeeded = selector.addSendArgumentsToList(
959 send, arguments, parameters, compileArgument, compileConstant); 965 send, arguments, parameters, compileArgument, compileConstant);
960 if (!succeeded) error(send); 966 if (!succeeded) error(send);
961 return arguments; 967 return arguments;
962 } 968 }
963 969
964 Constant visitNewExpression(NewExpression node) { 970 Constant visitNewExpression(NewExpression node) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 parameters.forEachParameter((Element parameter) { 1041 parameters.forEachParameter((Element parameter) {
1036 Constant argument = arguments[index++]; 1042 Constant argument = arguments[index++];
1037 definitions[parameter] = argument; 1043 definitions[parameter] = argument;
1038 if (parameter.kind == ElementKind.FIELD_PARAMETER) { 1044 if (parameter.kind == ElementKind.FIELD_PARAMETER) {
1039 FieldParameterElement fieldParameterElement = parameter; 1045 FieldParameterElement fieldParameterElement = parameter;
1040 fieldValues[fieldParameterElement.fieldElement] = argument; 1046 fieldValues[fieldParameterElement.fieldElement] = argument;
1041 } 1047 }
1042 }); 1048 });
1043 } 1049 }
1044 1050
1045 void evaluateSuperOrRedirectSend(FunctionElement targetConstructor, 1051 void evaluateSuperOrRedirectSend(Send send,
1046 List<Constant> targetArguments) { 1052 FunctionElement targetConstructor) {
1053 List<Constant> arguments =
1054 evaluateArgumentsToConstructor(send, targetConstructor);
1047 ConstructorEvaluator evaluator = 1055 ConstructorEvaluator evaluator =
1048 new ConstructorEvaluator(targetConstructor, compiler); 1056 new ConstructorEvaluator(targetConstructor, compiler);
1049 evaluator.evaluateConstructorFieldValues(targetArguments); 1057 evaluator.evaluateConstructorFieldValues(arguments);
1050 // Copy over the fieldValues from the super/redirect-constructor. 1058 // Copy over the fieldValues from the super/redirect-constructor.
1051 evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value); 1059 evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value);
1052 } 1060 }
1053 1061
1054 /** 1062 /**
1055 * Runs through the initializers of the given [constructor] and updates 1063 * Runs through the initializers of the given [constructor] and updates
1056 * the [fieldValues] map. 1064 * the [fieldValues] map.
1057 */ 1065 */
1058 void evaluateConstructorInitializers() { 1066 void evaluateConstructorInitializers() {
1059 FunctionExpression functionNode = constructor.parseNode(compiler); 1067 FunctionExpression functionNode = constructor.parseNode(compiler);
1060 NodeList initializerList = functionNode.initializers; 1068 NodeList initializerList = functionNode.initializers;
1061 1069
1062 bool foundSuperOrRedirect = false; 1070 bool foundSuperOrRedirect = false;
1063 1071
1064 if (initializerList !== null) { 1072 if (initializerList !== null) {
1065 for (Link<Node> link = initializerList.nodes; 1073 for (Link<Node> link = initializerList.nodes;
1066 !link.isEmpty(); 1074 !link.isEmpty();
1067 link = link.tail) { 1075 link = link.tail) {
1068 assert(link.head is Send); 1076 assert(link.head is Send);
1069 if (link.head is !SendSet) { 1077 if (link.head is !SendSet) {
1070 // A super initializer or constructor redirection. 1078 // A super initializer or constructor redirection.
1071 Send call = link.head; 1079 Send call = link.head;
1072 FunctionElement targetConstructor = elements[call]; 1080 FunctionElement targetConstructor = elements[call];
1073 List<Constant> targetArguments = 1081 evaluateSuperOrRedirectSend(call, targetConstructor);
1074 evaluateArgumentsToConstructor(call, targetConstructor);
1075 evaluateSuperOrRedirectSend(targetConstructor, targetArguments);
1076 foundSuperOrRedirect = true; 1082 foundSuperOrRedirect = true;
1077 } else { 1083 } else {
1078 // A field initializer. 1084 // A field initializer.
1079 SendSet init = link.head; 1085 SendSet init = link.head;
1080 Link<Node> initArguments = init.arguments; 1086 Link<Node> initArguments = init.arguments;
1081 assert(!initArguments.isEmpty() && initArguments.tail.isEmpty()); 1087 assert(!initArguments.isEmpty() && initArguments.tail.isEmpty());
1082 Constant fieldValue = evaluate(initArguments.head); 1088 Constant fieldValue = evaluate(initArguments.head);
1083 fieldValues[elements[init]] = fieldValue; 1089 fieldValues[elements[init]] = fieldValue;
1084 } 1090 }
1085 } 1091 }
1086 } 1092 }
1087 1093
1088 if (!foundSuperOrRedirect) { 1094 if (!foundSuperOrRedirect) {
1089 // No super initializer found. Try to find the default constructor if 1095 // No super initializer found. Try to find the default constructor if
1090 // the class is not Object. 1096 // the class is not Object.
1091 ClassElement enclosingClass = constructor.enclosingElement; 1097 ClassElement enclosingClass = constructor.enclosingElement;
1092 ClassElement superClass = enclosingClass.superclass; 1098 ClassElement superClass = enclosingClass.superclass;
1093 if (enclosingClass != compiler.objectClass) { 1099 if (enclosingClass != compiler.objectClass) {
1094 assert(superClass !== null); 1100 assert(superClass !== null);
1095 assert(superClass.isResolved); 1101 assert(superClass.isResolved);
1096 FunctionElement targetConstructor = 1102 FunctionElement targetConstructor =
1097 superClass.lookupConstructor(superClass.name); 1103 superClass.lookupConstructor(superClass.name);
1098 if (targetConstructor === null) { 1104 if (targetConstructor === null) {
1099 compiler.internalError("no default constructor available"); 1105 compiler.internalError("no default constructor available");
1100 } 1106 }
1101 evaluateSuperOrRedirectSend(targetConstructor, const <Constant>[]); 1107 NodeList emptyNodeList = new NodeList(nodes: const EmptyLink());
1108 Send syntheticSend = new Send(null, null, emptyNodeList);
1109 evaluateSuperOrRedirectSend(syntheticSend, targetConstructor);
1102 } 1110 }
1103 } 1111 }
1104 } 1112 }
1105 1113
1106 /** 1114 /**
1107 * Simulates the execution of the [constructor] with the given 1115 * Simulates the execution of the [constructor] with the given
1108 * [arguments] to obtain the field values that need to be passed to the 1116 * [arguments] to obtain the field values that need to be passed to the
1109 * native JavaScript constructor. 1117 * native JavaScript constructor.
1110 */ 1118 */
1111 void evaluateConstructorFieldValues(List<Constant> arguments) { 1119 void evaluateConstructorFieldValues(List<Constant> arguments) {
(...skipping 12 matching lines...) Expand all
1124 Constant fieldValue = fieldValues[field]; 1132 Constant fieldValue = fieldValues[field];
1125 if (fieldValue === null) { 1133 if (fieldValue === null) {
1126 // Use the default value. 1134 // Use the default value.
1127 fieldValue = compiler.compileVariable(field); 1135 fieldValue = compiler.compileVariable(field);
1128 } 1136 }
1129 jsNewArguments.add(fieldValue); 1137 jsNewArguments.add(fieldValue);
1130 }); 1138 });
1131 return jsNewArguments; 1139 return jsNewArguments;
1132 } 1140 }
1133 } 1141 }
OLDNEW
« no previous file with comments | « no previous file | lib/compiler/implementation/ssa/builder.dart » ('j') | lib/compiler/implementation/ssa/builder.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698