| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |