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

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: rebase 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
« no previous file with comments | « no previous file | lib/compiler/implementation/ssa/builder.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) 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 930 matching lines...) Expand 10 before | Expand all | Expand 10 after
941 if (folded === null) error(send); 941 if (folded === null) error(send);
942 return folded; 942 return folded;
943 } 943 }
944 return super.visitSend(send); 944 return super.visitSend(send);
945 } 945 }
946 946
947 visitSendSet(SendSet node) { 947 visitSendSet(SendSet node) {
948 error(node); 948 error(node);
949 } 949 }
950 950
951 /** Returns the list of constants that are passed to the static function. */ 951 /**
952 List<Constant> evaluateArgumentsToConstructor(Send send, 952 * Returns the list of constants that are passed to the static function.
953 */
954 List<Constant> evaluateArgumentsToConstructor(Selector selector,
955 Link<Node> arguments,
953 FunctionElement target) { 956 FunctionElement target) {
954 FunctionParameters parameters = target.computeParameters(compiler); 957 FunctionParameters parameters = target.computeParameters(compiler);
955 List<Constant> arguments = <Constant>[]; 958 List<Constant> compiledArguments = <Constant>[];
956 Selector selector = elements.getSelector(send);
957 959
958 Function compileArgument = evaluate; 960 Function compileArgument = evaluate;
959 Function compileConstant = compiler.compileVariable; 961 Function compileConstant = compiler.compileVariable;
960 bool succeeded = selector.addSendArgumentsToList( 962 bool succeeded = selector.addArgumentsToList(arguments, compiledArguments,
961 send, arguments, parameters, compileArgument, compileConstant); 963 parameters, compileArgument,
962 if (!succeeded) error(send); 964 compileConstant);
963 return arguments; 965 assert(succeeded);
966 return compiledArguments;
964 } 967 }
965 968
966 Constant visitNewExpression(NewExpression node) { 969 Constant visitNewExpression(NewExpression node) {
967 if (!node.isConst()) error(node); 970 if (!node.isConst()) error(node);
968 971
969 FunctionElement constructor = elements[node.send]; 972 Send send = node.send;
973 FunctionElement constructor = elements[send];
970 ClassElement classElement = constructor.enclosingElement; 974 ClassElement classElement = constructor.enclosingElement;
971 if (classElement.isInterface()) { 975 if (classElement.isInterface()) {
972 compiler.resolver.resolveMethodElement(constructor); 976 compiler.resolver.resolveMethodElement(constructor);
973 constructor = constructor.defaultImplementation; 977 constructor = constructor.defaultImplementation;
974 classElement = constructor.enclosingElement; 978 classElement = constructor.enclosingElement;
975 } 979 }
976 980
981 Selector selector = elements.getSelector(send);
977 List<Constant> arguments = 982 List<Constant> arguments =
978 evaluateArgumentsToConstructor(node.send, constructor); 983 evaluateArgumentsToConstructor(selector, send.arguments, constructor);
979 ConstructorEvaluator evaluator = 984 ConstructorEvaluator evaluator =
980 new ConstructorEvaluator(constructor, compiler); 985 new ConstructorEvaluator(constructor, compiler);
981 evaluator.evaluateConstructorFieldValues(arguments); 986 evaluator.evaluateConstructorFieldValues(arguments);
982 List<Constant>jsNewArguments = evaluator.buildJsNewArguments(classElement); 987 List<Constant>jsNewArguments = evaluator.buildJsNewArguments(classElement);
983 988
984 compiler.registerInstantiatedClass(classElement); 989 compiler.registerInstantiatedClass(classElement);
985 // TODO(floitsch): take generic types into account. 990 // TODO(floitsch): take generic types into account.
986 Type type = classElement.computeType(compiler); 991 Type type = classElement.computeType(compiler);
987 Constant constant = new ConstructedConstant(type, jsNewArguments); 992 Constant constant = new ConstructedConstant(type, jsNewArguments);
988 compiler.constantHandler.registerCompileTimeConstant(constant); 993 compiler.constantHandler.registerCompileTimeConstant(constant);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1037 parameters.forEachParameter((Element parameter) { 1042 parameters.forEachParameter((Element parameter) {
1038 Constant argument = arguments[index++]; 1043 Constant argument = arguments[index++];
1039 definitions[parameter] = argument; 1044 definitions[parameter] = argument;
1040 if (parameter.kind == ElementKind.FIELD_PARAMETER) { 1045 if (parameter.kind == ElementKind.FIELD_PARAMETER) {
1041 FieldParameterElement fieldParameterElement = parameter; 1046 FieldParameterElement fieldParameterElement = parameter;
1042 fieldValues[fieldParameterElement.fieldElement] = argument; 1047 fieldValues[fieldParameterElement.fieldElement] = argument;
1043 } 1048 }
1044 }); 1049 });
1045 } 1050 }
1046 1051
1047 void evaluateSuperOrRedirectSend(FunctionElement targetConstructor, 1052 void evaluateSuperOrRedirectSend(Selector selector,
1048 List<Constant> targetArguments) { 1053 Link<Node> arguments,
1054 FunctionElement targetConstructor) {
1055 List<Constant> compiledArguments =
1056 evaluateArgumentsToConstructor(selector, arguments, targetConstructor);
1057
1049 ConstructorEvaluator evaluator = 1058 ConstructorEvaluator evaluator =
1050 new ConstructorEvaluator(targetConstructor, compiler); 1059 new ConstructorEvaluator(targetConstructor, compiler);
1051 evaluator.evaluateConstructorFieldValues(targetArguments); 1060 evaluator.evaluateConstructorFieldValues(compiledArguments);
1052 // Copy over the fieldValues from the super/redirect-constructor. 1061 // Copy over the fieldValues from the super/redirect-constructor.
1053 evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value); 1062 evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value);
1063 return true;
1054 } 1064 }
1055 1065
1056 /** 1066 /**
1057 * Runs through the initializers of the given [constructor] and updates 1067 * Runs through the initializers of the given [constructor] and updates
1058 * the [fieldValues] map. 1068 * the [fieldValues] map.
1059 */ 1069 */
1060 void evaluateConstructorInitializers() { 1070 void evaluateConstructorInitializers() {
1061 FunctionExpression functionNode = constructor.parseNode(compiler); 1071 FunctionExpression functionNode = constructor.parseNode(compiler);
1062 NodeList initializerList = functionNode.initializers; 1072 NodeList initializerList = functionNode.initializers;
1063 1073
1064 bool foundSuperOrRedirect = false; 1074 bool foundSuperOrRedirect = false;
1065 1075
1066 if (initializerList !== null) { 1076 if (initializerList !== null) {
1067 for (Link<Node> link = initializerList.nodes; 1077 for (Link<Node> link = initializerList.nodes;
1068 !link.isEmpty(); 1078 !link.isEmpty();
1069 link = link.tail) { 1079 link = link.tail) {
1070 assert(link.head is Send); 1080 assert(link.head is Send);
1071 if (link.head is !SendSet) { 1081 if (link.head is !SendSet) {
1072 // A super initializer or constructor redirection. 1082 // A super initializer or constructor redirection.
1073 Send call = link.head; 1083 Send call = link.head;
1074 FunctionElement targetConstructor = elements[call]; 1084 FunctionElement targetConstructor = elements[call];
1075 List<Constant> targetArguments = 1085 Selector selector = elements.getSelector(call);
1076 evaluateArgumentsToConstructor(call, targetConstructor); 1086 Link<Node> arguments = call.arguments;
1077 evaluateSuperOrRedirectSend(targetConstructor, targetArguments); 1087 evaluateSuperOrRedirectSend(selector, arguments, targetConstructor);
1078 foundSuperOrRedirect = true; 1088 foundSuperOrRedirect = true;
1079 } else { 1089 } else {
1080 // A field initializer. 1090 // A field initializer.
1081 SendSet init = link.head; 1091 SendSet init = link.head;
1082 Link<Node> initArguments = init.arguments; 1092 Link<Node> initArguments = init.arguments;
1083 assert(!initArguments.isEmpty() && initArguments.tail.isEmpty()); 1093 assert(!initArguments.isEmpty() && initArguments.tail.isEmpty());
1084 Constant fieldValue = evaluate(initArguments.head); 1094 Constant fieldValue = evaluate(initArguments.head);
1085 fieldValues[elements[init]] = fieldValue; 1095 fieldValues[elements[init]] = fieldValue;
1086 } 1096 }
1087 } 1097 }
1088 } 1098 }
1089 1099
1090 if (!foundSuperOrRedirect) { 1100 if (!foundSuperOrRedirect) {
1091 // No super initializer found. Try to find the default constructor if 1101 // No super initializer found. Try to find the default constructor if
1092 // the class is not Object. 1102 // the class is not Object.
1093 ClassElement enclosingClass = constructor.enclosingElement; 1103 ClassElement enclosingClass = constructor.enclosingElement;
1094 ClassElement superClass = enclosingClass.superclass; 1104 ClassElement superClass = enclosingClass.superclass;
1095 if (enclosingClass != compiler.objectClass) { 1105 if (enclosingClass != compiler.objectClass) {
1096 assert(superClass !== null); 1106 assert(superClass !== null);
1097 assert(superClass.isResolved); 1107 assert(superClass.isResolved);
1098 FunctionElement targetConstructor = 1108 FunctionElement targetConstructor =
1099 superClass.lookupConstructor(superClass.name); 1109 superClass.lookupConstructor(superClass.name);
1100 if (targetConstructor === null) { 1110 if (targetConstructor === null) {
1101 compiler.internalError("no default constructor available"); 1111 compiler.internalError("no default constructor available",
1112 node: functionNode);
1102 } 1113 }
1103 evaluateSuperOrRedirectSend(targetConstructor, const <Constant>[]); 1114
1115 evaluateSuperOrRedirectSend(Selector.INVOCATION_0,
1116 const EmptyLink<Node>(),
1117 targetConstructor);
1104 } 1118 }
1105 } 1119 }
1106 } 1120 }
1107 1121
1108 /** 1122 /**
1109 * Simulates the execution of the [constructor] with the given 1123 * Simulates the execution of the [constructor] with the given
1110 * [arguments] to obtain the field values that need to be passed to the 1124 * [arguments] to obtain the field values that need to be passed to the
1111 * native JavaScript constructor. 1125 * native JavaScript constructor.
1112 */ 1126 */
1113 void evaluateConstructorFieldValues(List<Constant> arguments) { 1127 void evaluateConstructorFieldValues(List<Constant> arguments) {
(...skipping 12 matching lines...) Expand all
1126 Constant fieldValue = fieldValues[field]; 1140 Constant fieldValue = fieldValues[field];
1127 if (fieldValue === null) { 1141 if (fieldValue === null) {
1128 // Use the default value. 1142 // Use the default value.
1129 fieldValue = compiler.compileVariable(field); 1143 fieldValue = compiler.compileVariable(field);
1130 } 1144 }
1131 jsNewArguments.add(fieldValue); 1145 jsNewArguments.add(fieldValue);
1132 }); 1146 });
1133 return jsNewArguments; 1147 return jsNewArguments;
1134 } 1148 }
1135 } 1149 }
OLDNEW
« no previous file with comments | « no previous file | lib/compiler/implementation/ssa/builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698