Index: tools/dom/scripts/htmldartgenerator.py |
diff --git a/tools/dom/scripts/htmldartgenerator.py b/tools/dom/scripts/htmldartgenerator.py |
index 46ba4ba34edb21bce4e63a4c2d33b8cea05b974f..d0fc560462708143fd438eba10a3f5e426e12cff 100644 |
--- a/tools/dom/scripts/htmldartgenerator.py |
+++ b/tools/dom/scripts/htmldartgenerator.py |
@@ -193,25 +193,57 @@ class HtmlDartGenerator(object): |
else: |
self.EmitOperation(info, method_name) |
- def _OverloadChecks(self, |
- operation, |
+ def _GenerateDispatcherBody(self, |
+ emitter, |
+ operations, |
parameter_names, |
- argument_count, |
+ generate_call, |
+ is_optional, |
can_omit_type_check=lambda type, pos: False): |
- checks = [] |
- for i in range(0, argument_count): |
- argument = operation.arguments[i] |
- parameter_name = parameter_names[i] |
- test_type = self._DartType(argument.type.id) |
- if test_type in ['dynamic', 'Object']: |
- checks.append('?%s' % parameter_name) |
- elif not can_omit_type_check(test_type, i): |
- checks.append('(%s is %s || %s == null)' % ( |
- parameter_name, test_type, parameter_name)) |
- # There can be multiple presence checks. We need them all since a later |
- # optional argument could have been passed by name, leaving 'holes'. |
- checks.extend(['!?%s' % name for name in parameter_names[argument_count:]]) |
- return checks |
+ |
+ def GenerateChecksAndCall(operation, argument_count): |
+ checks = [] |
+ for i in range(0, argument_count): |
+ argument = operation.arguments[i] |
+ parameter_name = parameter_names[i] |
+ test_type = self._DartType(argument.type.id) |
+ if test_type in ['dynamic', 'Object']: |
+ checks.append('?%s' % parameter_name) |
+ elif not can_omit_type_check(test_type, i): |
+ checks.append('(%s is %s || %s == null)' % ( |
+ parameter_name, test_type, parameter_name)) |
+ # There can be multiple presence checks. We need them all since a later |
+ # optional argument could have been passed by name, leaving 'holes'. |
+ checks.extend(['!?%s' % name for name in parameter_names[argument_count:]]) |
+ |
+ generate_call(operation, argument_count, checks) |
+ |
+ # TODO: Optimize the dispatch to avoid repeated checks. |
+ if len(operations) > 1: |
+ for operation in operations: |
+ for position, argument in enumerate(operation.arguments): |
+ if is_optional(operation, argument): |
+ GenerateChecksAndCall(operation, position) |
+ GenerateChecksAndCall(operation, len(operation.arguments)) |
+ emitter.Emit( |
+ ' throw new ArgumentError("Incorrect number or type of arguments");' |
+ '\n'); |
+ else: |
+ operation = operations[0] |
+ argument_count = len(operation.arguments) |
+ for position, argument in list(enumerate(operation.arguments))[::-1]: |
+ if is_optional(operation, argument): |
+ check = '?%s' % parameter_names[position] |
+ # argument_count instead of position + 1 is used here to cover one |
+ # complicated case with the effectively optional argument in the middle. |
+ # Consider foo(x, [Optional] y, [Optional=DefaultIsNullString] z) |
+ # (as of now it's modelled after HTMLMediaElement.webkitAddKey). |
+ # y is optional in WebCore, while z is not. |
+ # In this case, if y was actually passed, we'd like to emit foo(x, y, z) invocation, |
+ # not foo(x, y). |
+ generate_call(operation, argument_count, [check]) |
+ argument_count = position |
+ generate_call(operation, argument_count, []) |
def AdditionalImplementedInterfaces(self): |
# TODO: Include all implemented interfaces, including other Lists. |