| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 2 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 3 # for details. All rights reserved. Use of this source code is governed by a | 3 # for details. All rights reserved. Use of this source code is governed by a |
| 4 # BSD-style license that can be found in the LICENSE file. | 4 # BSD-style license that can be found in the LICENSE file. |
| 5 | 5 |
| 6 """This module provides shared functionality for the system to generate | 6 """This module provides shared functionality for the system to generate |
| 7 Dart:html APIs from the IDL database.""" | 7 Dart:html APIs from the IDL database.""" |
| 8 | 8 |
| 9 import emitter | 9 import emitter |
| 10 | 10 |
| (...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1063 | 1063 |
| 1064 body = self._members_emitter.Emit( | 1064 body = self._members_emitter.Emit( |
| 1065 '\n' | 1065 '\n' |
| 1066 ' $TYPE $(HTML_NAME)($PARAMS) {\n' | 1066 ' $TYPE $(HTML_NAME)($PARAMS) {\n' |
| 1067 '$!BODY' | 1067 '$!BODY' |
| 1068 ' }\n', | 1068 ' }\n', |
| 1069 TYPE=return_type, | 1069 TYPE=return_type, |
| 1070 HTML_NAME=html_name, | 1070 HTML_NAME=html_name, |
| 1071 PARAMS=info.ParametersImplementationDeclaration(InputType, '_default')) | 1071 PARAMS=info.ParametersImplementationDeclaration(InputType, '_default')) |
| 1072 | 1072 |
| 1073 argument_names = [param_info.name for param_info in info.param_infos] | 1073 parameter_names = [param_info.name for param_info in info.param_infos] |
| 1074 argument_types = [InputType(param_info.dart_type) | 1074 parameter_types = [InputType(param_info.dart_type) |
| 1075 for param_info in info.param_infos] | 1075 for param_info in info.param_infos] |
| 1076 operations = info.operations | 1076 operations = info.operations |
| 1077 | 1077 |
| 1078 method_version = [0] | 1078 method_version = [0] |
| 1079 temp_version = [0] | 1079 temp_version = [0] |
| 1080 | 1080 |
| 1081 def GenerateCall(operation, argument_count, checks): | 1081 def GenerateCall(operation, argument_count, checks): |
| 1082 checks = filter(lambda e: e != 'true', checks) |
| 1082 if checks: | 1083 if checks: |
| 1083 (stmts_emitter, call_emitter) = body.Emit( | 1084 (stmts_emitter, call_emitter) = body.Emit( |
| 1084 ' if ($CHECKS) {\n$!STMTS$!CALL }\n', | 1085 ' if ($CHECKS) {\n$!STMTS$!CALL }\n', |
| 1085 INDENT=' ', | 1086 INDENT=' ', |
| 1086 CHECKS=' &&\n '.join(checks)) | 1087 CHECKS=' &&\n '.join(checks)) |
| 1087 else: | 1088 else: |
| 1088 (stmts_emitter, call_emitter) = body.Emit('$!A$!B', INDENT=' '); | 1089 (stmts_emitter, call_emitter) = body.Emit('$!A$!B', INDENT=' '); |
| 1089 | 1090 |
| 1090 method_version[0] += 1 | 1091 method_version[0] += 1 |
| 1091 target = '_%s_%d' % (html_name, method_version[0]) | 1092 target = '_%s_%d' % (html_name, method_version[0]) |
| 1092 arguments = [] | 1093 arguments = [] |
| 1093 target_parameters = [] | 1094 target_parameters = [] |
| 1094 for position, arg in enumerate(operation.arguments[:argument_count]): | 1095 for position, arg in enumerate(operation.arguments[:argument_count]): |
| 1095 conversion = self._InputConversion(arg.type.id, operation.id) | 1096 conversion = self._InputConversion(arg.type.id, operation.id) |
| 1096 param_name = operation.arguments[position].id | 1097 param_name = operation.arguments[position].id |
| 1097 if conversion: | 1098 if conversion: |
| 1098 temp_version[0] += 1 | 1099 temp_version[0] += 1 |
| 1099 temp_name = '%s_%s' % (param_name, temp_version[0]) | 1100 temp_name = '%s_%s' % (param_name, temp_version[0]) |
| 1100 temp_type = conversion.output_type | 1101 temp_type = conversion.output_type |
| 1101 stmts_emitter.Emit( | 1102 stmts_emitter.Emit( |
| 1102 '$(INDENT)$TYPE $NAME = $CONVERT($ARG);\n', | 1103 '$(INDENT)$TYPE $NAME = $CONVERT($ARG);\n', |
| 1103 TYPE=TypeOrVar(temp_type), | 1104 TYPE=TypeOrVar(temp_type), |
| 1104 NAME=temp_name, | 1105 NAME=temp_name, |
| 1105 CONVERT=conversion.function_name, | 1106 CONVERT=conversion.function_name, |
| 1106 ARG=argument_names[position]) | 1107 ARG=parameter_names[position]) |
| 1107 arguments.append(temp_name) | 1108 arguments.append(temp_name) |
| 1108 param_type = temp_type | 1109 param_type = temp_type |
| 1109 verified_type = temp_type # verified by assignment in checked mode. | 1110 verified_type = temp_type # verified by assignment in checked mode. |
| 1110 else: | 1111 else: |
| 1111 arguments.append(argument_names[position]) | 1112 arguments.append(parameter_names[position]) |
| 1112 param_type = self._NarrowInputType(DartType(arg.type.id)) | 1113 param_type = self._NarrowInputType(DartType(arg.type.id)) |
| 1113 # Verified by argument checking on entry to the dispatcher. | 1114 # Verified by argument checking on entry to the dispatcher. |
| 1114 verified_type = InputType(info.param_infos[position].dart_type) | 1115 verified_type = InputType(info.param_infos[position].dart_type) |
| 1115 | 1116 |
| 1116 # The native method does not need an argument type if we know the type. | 1117 # The native method does not need an argument type if we know the type. |
| 1117 # But we do need the native methods to have correct function types, so | 1118 # But we do need the native methods to have correct function types, so |
| 1118 # be conservative. | 1119 # be conservative. |
| 1119 if param_type == verified_type: | 1120 if param_type == verified_type: |
| 1120 if param_type in ['String', 'num', 'int', 'double', 'bool', 'Object']: | 1121 if param_type in ['String', 'num', 'int', 'double', 'bool', 'Object']: |
| 1121 param_type = 'Dynamic' | 1122 param_type = 'Dynamic' |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1137 call_emitter.Emit('$(INDENT)return $CALL;\n', CALL=call) | 1138 call_emitter.Emit('$(INDENT)return $CALL;\n', CALL=call) |
| 1138 | 1139 |
| 1139 self._members_emitter.Emit( | 1140 self._members_emitter.Emit( |
| 1140 ' $TYPE$TARGET($PARAMS) native "$NATIVE";\n', | 1141 ' $TYPE$TARGET($PARAMS) native "$NATIVE";\n', |
| 1141 TYPE=TypeOrNothing(native_return_type), | 1142 TYPE=TypeOrNothing(native_return_type), |
| 1142 TARGET=target, | 1143 TARGET=target, |
| 1143 PARAMS=', '.join(target_parameters), | 1144 PARAMS=', '.join(target_parameters), |
| 1144 NATIVE=info.declared_name) | 1145 NATIVE=info.declared_name) |
| 1145 | 1146 |
| 1146 def GenerateChecksAndCall(operation, argument_count): | 1147 def GenerateChecksAndCall(operation, argument_count): |
| 1147 checks = ['_default == %s' % name for name in argument_names] | 1148 checks = ['_default == %s' % name for name in parameter_names] |
| 1148 for i in range(0, argument_count): | 1149 for i in range(0, argument_count): |
| 1149 argument = operation.arguments[i] | 1150 argument = operation.arguments[i] |
| 1150 argument_name = argument_names[i] | 1151 parameter_name = parameter_names[i] |
| 1151 test_type = self._DartType(argument.type.id) | 1152 test_type = self._DartType(argument.type.id) |
| 1152 if test_type in ['Dynamic', 'Object']: | 1153 if test_type in ['Dynamic', 'Object']: |
| 1153 checks[i] = '_default != %s' % argument_name | 1154 checks[i] = '_default != %s' % parameter_name |
| 1155 elif test_type == parameter_types[i]: |
| 1156 checks[i] = 'true' |
| 1154 else: | 1157 else: |
| 1155 checks[i] = '(%s is %s || %s == null)' % ( | 1158 checks[i] = '(%s is %s || %s == null)' % ( |
| 1156 argument_name, self._DartType(argument.type.id), argument_name) | 1159 parameter_name, test_type, parameter_name) |
| 1160 # Only need first _default check since we don't have any other default |
| 1161 # values in the dispatch method's signature. |
| 1162 checks = checks[:argument_count + 1] |
| 1157 GenerateCall(operation, argument_count, checks) | 1163 GenerateCall(operation, argument_count, checks) |
| 1158 | 1164 |
| 1159 # TODO: Optimize the dispatch to avoid repeated checks. | 1165 # TODO: Optimize the dispatch to avoid repeated checks. |
| 1160 if len(operations) > 1: | 1166 if len(operations) > 1: |
| 1161 for operation in operations: | 1167 for operation in operations: |
| 1162 for position, argument in enumerate(operation.arguments): | 1168 for position, argument in enumerate(operation.arguments): |
| 1163 if self._IsOptional(operation, argument): | 1169 if self._IsOptional(operation, argument): |
| 1164 GenerateChecksAndCall(operation, position) | 1170 GenerateChecksAndCall(operation, position) |
| 1165 GenerateChecksAndCall(operation, len(operation.arguments)) | 1171 GenerateChecksAndCall(operation, len(operation.arguments)) |
| 1166 body.Emit(' throw "Incorrect number or type of arguments";\n'); | 1172 body.Emit(' throw "Incorrect number or type of arguments";\n'); |
| 1167 else: | 1173 else: |
| 1168 operation = operations[0] | 1174 operation = operations[0] |
| 1169 argument_count = len(operation.arguments) | 1175 argument_count = len(operation.arguments) |
| 1170 for position, argument in list(enumerate(operation.arguments))[::-1]: | 1176 for position, argument in list(enumerate(operation.arguments))[::-1]: |
| 1171 if self._IsOptional(operation, argument): | 1177 if self._IsOptional(operation, argument): |
| 1172 check = '_default != %s' % argument_names[position] | 1178 check = '_default != %s' % parameter_names[position] |
| 1173 GenerateCall(operation, position + 1, [check]) | 1179 GenerateCall(operation, position + 1, [check]) |
| 1174 argument_count = position | 1180 argument_count = position |
| 1175 GenerateCall(operation, argument_count, []) | 1181 GenerateCall(operation, argument_count, []) |
| 1176 | 1182 |
| 1177 | 1183 |
| 1178 def _IsOptional(self, operation, argument): | 1184 def _IsOptional(self, operation, argument): |
| 1179 return IsOptional(argument) | 1185 return IsOptional(argument) |
| 1180 | 1186 |
| 1181 | 1187 |
| 1182 def _OperationRequiresConversions(self, operation): | 1188 def _OperationRequiresConversions(self, operation): |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1218 return HtmlDart2JSClassGenerator(self, interface) | 1224 return HtmlDart2JSClassGenerator(self, interface) |
| 1219 | 1225 |
| 1220 def GenerateLibraries(self, dart_files): | 1226 def GenerateLibraries(self, dart_files): |
| 1221 self._GenerateLibFile( | 1227 self._GenerateLibFile( |
| 1222 'html_dart2js.darttemplate', | 1228 'html_dart2js.darttemplate', |
| 1223 os.path.join(self._output_dir, 'html_dart2js.dart'), | 1229 os.path.join(self._output_dir, 'html_dart2js.dart'), |
| 1224 dart_files) | 1230 dart_files) |
| 1225 | 1231 |
| 1226 def Finish(self): | 1232 def Finish(self): |
| 1227 pass | 1233 pass |
| OLD | NEW |