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

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