Chromium Code Reviews| 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 from generator import AnalyzeOperation, ConstantOutputOrder, \ | 9 from generator import AnalyzeOperation, ConstantOutputOrder, \ |
| 10 DartDomNameOfAttribute, FindMatchingAttribute, IsDartCollectionType, \ | 10 DartDomNameOfAttribute, FindMatchingAttribute, IsDartCollectionType, \ |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 169 self.EmitOperation(info, '_item') | 169 self.EmitOperation(info, '_item') |
| 170 return | 170 return |
| 171 | 171 |
| 172 if declare_only: | 172 if declare_only: |
| 173 self.DeclareOperation(info, | 173 self.DeclareOperation(info, |
| 174 self.SecureOutputType(info.type_name), method_name) | 174 self.SecureOutputType(info.type_name), method_name) |
| 175 else: | 175 else: |
| 176 self.EmitOperation(info, method_name) | 176 self.EmitOperation(info, method_name) |
| 177 | 177 |
| 178 def _GenerateDispatcherBody(self, | 178 def _GenerateDispatcherBody(self, |
| 179 emitter, | |
| 180 operations, | 179 operations, |
| 181 parameter_names, | 180 parameter_names, |
| 181 declaration, | |
| 182 generate_call, | 182 generate_call, |
| 183 is_optional, | 183 is_optional, |
| 184 can_omit_type_check=lambda type, pos: False): | 184 can_omit_type_check=lambda type, pos: False): |
| 185 | 185 |
| 186 body_emitter = self._members_emitter.Emit( | |
| 187 '\n' | |
| 188 ' $DECLARATION {\n' | |
| 189 '$!BODY' | |
| 190 ' }\n', | |
| 191 DECLARATION=declaration) | |
| 192 | |
| 193 version = [0] | |
| 194 def GenerateCall(operation, argument_count, checks): | |
| 195 if checks: | |
| 196 (stmts_emitter, call_emitter) = body_emitter.Emit( | |
| 197 ' if ($CHECKS) {\n$!STMTS$!CALL }\n', | |
| 198 INDENT=' ', | |
| 199 CHECKS=' && '.join(checks)) | |
| 200 else: | |
| 201 (stmts_emitter, call_emitter) = body_emitter.Emit('$!A$!B', INDENT=' '); | |
|
Emily Fortuna
2013/01/22 19:16:40
80 char here and below
Anton Muhin
2013/01/23 08:16:51
Done.
| |
| 202 | |
| 203 if operation.type.id == 'void': | |
| 204 call_emitter = call_emitter.Emit('$(INDENT)$!CALL;\n$(INDENT)return;\n') | |
| 205 else: | |
| 206 call_emitter = call_emitter.Emit('$(INDENT)return $!CALL;\n') | |
| 207 | |
| 208 version[0] += 1 | |
| 209 generate_call(stmts_emitter, call_emitter, version[0], operation, argument _count) | |
| 210 | |
| 186 def GenerateChecksAndCall(operation, argument_count): | 211 def GenerateChecksAndCall(operation, argument_count): |
| 187 checks = [] | 212 checks = [] |
| 188 for i in range(0, argument_count): | 213 for i in range(0, argument_count): |
| 189 argument = operation.arguments[i] | 214 argument = operation.arguments[i] |
| 190 parameter_name = parameter_names[i] | 215 parameter_name = parameter_names[i] |
| 191 test_type = self._DartType(argument.type.id) | 216 test_type = self._DartType(argument.type.id) |
| 192 if test_type in ['dynamic', 'Object']: | 217 if test_type in ['dynamic', 'Object']: |
| 193 checks.append('?%s' % parameter_name) | 218 checks.append('?%s' % parameter_name) |
| 194 elif not can_omit_type_check(test_type, i): | 219 elif not can_omit_type_check(test_type, i): |
| 195 checks.append('(%s is %s || %s == null)' % ( | 220 checks.append('(%s is %s || %s == null)' % ( |
| 196 parameter_name, test_type, parameter_name)) | 221 parameter_name, test_type, parameter_name)) |
| 197 # There can be multiple presence checks. We need them all since a later | 222 # There can be multiple presence checks. We need them all since a later |
| 198 # optional argument could have been passed by name, leaving 'holes'. | 223 # optional argument could have been passed by name, leaving 'holes'. |
| 199 checks.extend(['!?%s' % name for name in parameter_names[argument_count:]] ) | 224 checks.extend(['!?%s' % name for name in parameter_names[argument_count:]] ) |
| 200 | 225 |
| 201 generate_call(operation, argument_count, checks) | 226 GenerateCall(operation, argument_count, checks) |
| 202 | 227 |
| 203 # TODO: Optimize the dispatch to avoid repeated checks. | 228 # TODO: Optimize the dispatch to avoid repeated checks. |
| 204 if len(operations) > 1: | 229 if len(operations) > 1: |
| 205 for operation in operations: | 230 for operation in operations: |
| 206 for position, argument in enumerate(operation.arguments): | 231 for position, argument in enumerate(operation.arguments): |
| 207 if is_optional(operation, argument): | 232 if is_optional(operation, argument): |
| 208 GenerateChecksAndCall(operation, position) | 233 GenerateChecksAndCall(operation, position) |
| 209 GenerateChecksAndCall(operation, len(operation.arguments)) | 234 GenerateChecksAndCall(operation, len(operation.arguments)) |
| 210 emitter.Emit( | 235 body_emitter.Emit( |
| 211 ' throw new ArgumentError("Incorrect number or type of arguments"); ' | 236 ' throw new ArgumentError("Incorrect number or type of arguments"); ' |
| 212 '\n'); | 237 '\n'); |
| 213 else: | 238 else: |
| 214 operation = operations[0] | 239 operation = operations[0] |
| 215 argument_count = len(operation.arguments) | 240 argument_count = len(operation.arguments) |
| 216 for position, argument in list(enumerate(operation.arguments))[::-1]: | 241 for position, argument in list(enumerate(operation.arguments))[::-1]: |
| 217 if is_optional(operation, argument): | 242 if is_optional(operation, argument): |
| 218 check = '?%s' % parameter_names[position] | 243 check = '?%s' % parameter_names[position] |
| 219 # argument_count instead of position + 1 is used here to cover one | 244 # argument_count instead of position + 1 is used here to cover one |
| 220 # complicated case with the effectively optional argument in the middl e. | 245 # complicated case with the effectively optional argument in the middl e. |
| 221 # Consider foo(x, [Optional] y, [Optional=DefaultIsNullString] z) | 246 # Consider foo(x, [Optional] y, [Optional=DefaultIsNullString] z) |
| 222 # (as of now it's modelled after HTMLMediaElement.webkitAddKey). | 247 # (as of now it's modelled after HTMLMediaElement.webkitAddKey). |
| 223 # y is optional in WebCore, while z is not. | 248 # y is optional in WebCore, while z is not. |
| 224 # In this case, if y was actually passed, we'd like to emit foo(x, y, z) invocation, | 249 # In this case, if y was actually passed, we'd like to emit foo(x, y, z) invocation, |
| 225 # not foo(x, y). | 250 # not foo(x, y). |
| 226 generate_call(operation, argument_count, [check]) | 251 GenerateCall(operation, argument_count, [check]) |
| 227 argument_count = position | 252 argument_count = position |
| 228 generate_call(operation, argument_count, []) | 253 GenerateCall(operation, argument_count, []) |
| 229 | 254 |
| 230 def AdditionalImplementedInterfaces(self): | 255 def AdditionalImplementedInterfaces(self): |
| 231 # TODO: Include all implemented interfaces, including other Lists. | 256 # TODO: Include all implemented interfaces, including other Lists. |
| 232 implements = [] | 257 implements = [] |
| 233 if self._interface_type_info.is_typed_array(): | 258 if self._interface_type_info.is_typed_array(): |
| 234 element_type = self._interface_type_info.list_item_type() | 259 element_type = self._interface_type_info.list_item_type() |
| 235 implements.append('List<%s>' % self._DartType(element_type)) | 260 implements.append('List<%s>' % self._DartType(element_type)) |
| 236 if self._interface_type_info.list_item_type(): | 261 if self._interface_type_info.list_item_type(): |
| 237 item_type_info = self._type_registry.TypeInfo( | 262 item_type_info = self._type_registry.TypeInfo( |
| 238 self._interface_type_info.list_item_type()) | 263 self._interface_type_info.list_item_type()) |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 444 walk(interface.parents) | 469 walk(interface.parents) |
| 445 else: | 470 else: |
| 446 walk(interface.parents[1:]) | 471 walk(interface.parents[1:]) |
| 447 return result | 472 return result |
| 448 | 473 |
| 449 def _DartType(self, type_name): | 474 def _DartType(self, type_name): |
| 450 return self._type_registry.DartType(type_name) | 475 return self._type_registry.DartType(type_name) |
| 451 | 476 |
| 452 def _IsPrivate(self, name): | 477 def _IsPrivate(self, name): |
| 453 return name.startswith('_') | 478 return name.startswith('_') |
| OLD | NEW |