Index: lib/dom/scripts/systemhtml.py |
diff --git a/lib/dom/scripts/systemhtml.py b/lib/dom/scripts/systemhtml.py |
index 7d10be8d379322692ce1408bf5ff3fe8055121be..8f3d11aa6d1b9065e1b43cb9adb9632d33d21c8b 100644 |
--- a/lib/dom/scripts/systemhtml.py |
+++ b/lib/dom/scripts/systemhtml.py |
@@ -6,6 +6,7 @@ |
"""This module provides shared functionality for the system to generate |
Dart:html APIs from the IDL database.""" |
+import generator |
from systemfrog import * |
from systeminterface import * |
@@ -1573,7 +1574,7 @@ class HtmlDartiumInterfaceGenerator(object): |
overloads = sorted(info.overloads, |
key=lambda overload: len(overload.arguments)) |
self._native_version = 0 |
- fallthrough = self.GenerateDispatch(body, info, ' ', 0, overloads) |
+ fallthrough = generator.GenerateDispatch(self, body, info, ' ', 0, overloads) |
if fallthrough: |
body.Emit(' throw "Incorrect number or type of arguments";\n'); |
@@ -1609,101 +1610,3 @@ class HtmlDartiumInterfaceGenerator(object): |
THIS=self.DomObjectName(), |
NAME=info.name, |
ARGS=argument_expressions) |
- |
- def GenerateDispatch(self, emitter, info, indent, position, overloads): |
- """Generates a dispatch to one of the overloads. |
- |
- Arguments: |
- emitter: an Emitter for the body of a block of code. |
- info: the compound information about the operation and its overloads. |
- indent: an indentation string for generated code. |
- position: the index of the parameter to dispatch on. |
- overloads: a list of the remaining IDLOperations to dispatch. |
- |
- Returns True if the dispatch can fall through on failure, False if the code |
- always dispatches. |
- """ |
- |
- def NullCheck(name): |
- return '%s === null' % name |
- |
- def TypeCheck(name, type): |
- return '%s is %s' % (name, type) |
- |
- if position == len(info.param_infos): |
- if len(overloads) > 1: |
- raise Exception('Duplicate operations ' + str(overloads)) |
- operation = overloads[0] |
- self.GenerateSingleOperation(emitter, info, indent, operation) |
- return False |
- |
- # FIXME: Consider a simpler dispatch that iterates over the |
- # overloads and generates an overload specific check. Revisit |
- # when we move to named optional arguments. |
- |
- # Partition the overloads to divide and conquer on the dispatch. |
- positive = [] |
- negative = [] |
- first_overload = overloads[0] |
- param = info.param_infos[position] |
- |
- if position < len(first_overload.arguments): |
- # FIXME: This will not work if the second overload has a more |
- # precise type than the first. E.g., |
- # void foo(Node x); |
- # void foo(Element x); |
- type = DartType(first_overload.arguments[position].type.id) |
- test = TypeCheck(param.name, type) |
- pred = lambda op: (len(op.arguments) > position and |
- DartType(op.arguments[position].type.id) == type) |
- else: |
- type = None |
- test = NullCheck(param.name) |
- pred = lambda op: position >= len(op.arguments) |
- |
- for overload in overloads: |
- if pred(overload): |
- positive.append(overload) |
- else: |
- negative.append(overload) |
- |
- if positive and negative: |
- (true_code, false_code) = emitter.Emit( |
- '$(INDENT)if ($COND) {\n' |
- '$!TRUE' |
- '$(INDENT)} else {\n' |
- '$!FALSE' |
- '$(INDENT)}\n', |
- COND=test, INDENT=indent) |
- fallthrough1 = self.GenerateDispatch( |
- true_code, info, indent + ' ', position + 1, positive) |
- fallthrough2 = self.GenerateDispatch( |
- false_code, info, indent + ' ', position, negative) |
- return fallthrough1 or fallthrough2 |
- |
- if negative: |
- raise Exception('Internal error, must be all positive') |
- |
- # All overloads require the same test. Do we bother? |
- |
- # If the test is the same as the method's formal parameter then checked mode |
- # will have done the test already. (It could be null too but we ignore that |
- # case since all the overload behave the same and we don't know which types |
- # in the IDL are not nullable.) |
- if type == param.dart_type: |
- return self.GenerateDispatch( |
- emitter, info, indent, position + 1, positive) |
- |
- # Otherwise the overloads have the same type but the type is a substype of |
- # the method's synthesized formal parameter. e.g we have overloads f(X) and |
- # f(Y), implemented by the synthesized method f(Z) where X<Z and Y<Z. The |
- # dispatch has removed f(X), leaving only f(Y), but there is no guarantee |
- # that Y = Z-X, so we need to check for Y. |
- true_code = emitter.Emit( |
- '$(INDENT)if ($COND) {\n' |
- '$!TRUE' |
- '$(INDENT)}\n', |
- COND=test, INDENT=indent) |
- self.GenerateDispatch( |
- true_code, info, indent + ' ', position + 1, positive) |
- return True |