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

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

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