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 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 # FIXME: item should be renamed to operator[], not removed. | 186 # FIXME: item should be renamed to operator[], not removed. |
187 self.EmitOperation(info, '_item') | 187 self.EmitOperation(info, '_item') |
188 return | 188 return |
189 | 189 |
190 if declare_only: | 190 if declare_only: |
191 self.DeclareOperation(info, | 191 self.DeclareOperation(info, |
192 self.SecureOutputType(info.type_name), method_name) | 192 self.SecureOutputType(info.type_name), method_name) |
193 else: | 193 else: |
194 self.EmitOperation(info, method_name) | 194 self.EmitOperation(info, method_name) |
195 | 195 |
196 def _OverloadChecks(self, | 196 def _GenerateDispatcherBody(self, |
197 operation, | 197 emitter, |
| 198 operations, |
198 parameter_names, | 199 parameter_names, |
199 argument_count, | 200 generate_call, |
| 201 is_optional, |
200 can_omit_type_check=lambda type, pos: False): | 202 can_omit_type_check=lambda type, pos: False): |
201 checks = [] | 203 |
202 for i in range(0, argument_count): | 204 def GenerateChecksAndCall(operation, argument_count): |
203 argument = operation.arguments[i] | 205 checks = [] |
204 parameter_name = parameter_names[i] | 206 for i in range(0, argument_count): |
205 test_type = self._DartType(argument.type.id) | 207 argument = operation.arguments[i] |
206 if test_type in ['dynamic', 'Object']: | 208 parameter_name = parameter_names[i] |
207 checks.append('?%s' % parameter_name) | 209 test_type = self._DartType(argument.type.id) |
208 elif not can_omit_type_check(test_type, i): | 210 if test_type in ['dynamic', 'Object']: |
209 checks.append('(%s is %s || %s == null)' % ( | 211 checks.append('?%s' % parameter_name) |
210 parameter_name, test_type, parameter_name)) | 212 elif not can_omit_type_check(test_type, i): |
211 # There can be multiple presence checks. We need them all since a later | 213 checks.append('(%s is %s || %s == null)' % ( |
212 # optional argument could have been passed by name, leaving 'holes'. | 214 parameter_name, test_type, parameter_name)) |
213 checks.extend(['!?%s' % name for name in parameter_names[argument_count:]]) | 215 # There can be multiple presence checks. We need them all since a later |
214 return checks | 216 # optional argument could have been passed by name, leaving 'holes'. |
| 217 checks.extend(['!?%s' % name for name in parameter_names[argument_count:]]
) |
| 218 |
| 219 generate_call(operation, argument_count, checks) |
| 220 |
| 221 # TODO: Optimize the dispatch to avoid repeated checks. |
| 222 if len(operations) > 1: |
| 223 for operation in operations: |
| 224 for position, argument in enumerate(operation.arguments): |
| 225 if is_optional(operation, argument): |
| 226 GenerateChecksAndCall(operation, position) |
| 227 GenerateChecksAndCall(operation, len(operation.arguments)) |
| 228 emitter.Emit( |
| 229 ' throw new ArgumentError("Incorrect number or type of arguments");
' |
| 230 '\n'); |
| 231 else: |
| 232 operation = operations[0] |
| 233 argument_count = len(operation.arguments) |
| 234 for position, argument in list(enumerate(operation.arguments))[::-1]: |
| 235 if is_optional(operation, argument): |
| 236 check = '?%s' % parameter_names[position] |
| 237 # argument_count instead of position + 1 is used here to cover one |
| 238 # complicated case with the effectively optional argument in the middl
e. |
| 239 # Consider foo(x, [Optional] y, [Optional=DefaultIsNullString] z) |
| 240 # (as of now it's modelled after HTMLMediaElement.webkitAddKey). |
| 241 # y is optional in WebCore, while z is not. |
| 242 # In this case, if y was actually passed, we'd like to emit foo(x, y,
z) invocation, |
| 243 # not foo(x, y). |
| 244 generate_call(operation, argument_count, [check]) |
| 245 argument_count = position |
| 246 generate_call(operation, argument_count, []) |
215 | 247 |
216 def AdditionalImplementedInterfaces(self): | 248 def AdditionalImplementedInterfaces(self): |
217 # TODO: Include all implemented interfaces, including other Lists. | 249 # TODO: Include all implemented interfaces, including other Lists. |
218 implements = [] | 250 implements = [] |
219 if self._interface_type_info.is_typed_array(): | 251 if self._interface_type_info.is_typed_array(): |
220 element_type = self._interface_type_info.list_item_type() | 252 element_type = self._interface_type_info.list_item_type() |
221 implements.append('List<%s>' % self._DartType(element_type)) | 253 implements.append('List<%s>' % self._DartType(element_type)) |
222 if self._interface_type_info.list_item_type(): | 254 if self._interface_type_info.list_item_type(): |
223 item_type_info = self._type_registry.TypeInfo( | 255 item_type_info = self._type_registry.TypeInfo( |
224 self._interface_type_info.list_item_type()) | 256 self._interface_type_info.list_item_type()) |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 walk(interface.parents) | 471 walk(interface.parents) |
440 else: | 472 else: |
441 walk(interface.parents[1:]) | 473 walk(interface.parents[1:]) |
442 return result | 474 return result |
443 | 475 |
444 def _DartType(self, type_name): | 476 def _DartType(self, type_name): |
445 return self._type_registry.DartType(type_name) | 477 return self._type_registry.DartType(type_name) |
446 | 478 |
447 def _IsPrivate(self, name): | 479 def _IsPrivate(self, name): |
448 return name.startswith('_') | 480 return name.startswith('_') |
OLD | NEW |