| Index: lib/dom/scripts/systemwrapping.py
|
| diff --git a/lib/dom/scripts/systemwrapping.py b/lib/dom/scripts/systemwrapping.py
|
| index 7ec5be45685609c2f15a5e088d801a535b49a3d5..aa9089e63e5339b18410050004db58d6bd63d12c 100644
|
| --- a/lib/dom/scripts/systemwrapping.py
|
| +++ b/lib/dom/scripts/systemwrapping.py
|
| @@ -6,6 +6,7 @@
|
| """This module provides shared functionality for the systems to generate
|
| wrapping binding from the IDL database."""
|
|
|
| +import generator
|
| import os
|
| from generator import *
|
| from systembase import *
|
| @@ -372,7 +373,7 @@ class WrappingInterfaceGenerator(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');
|
|
|
| @@ -425,122 +426,3 @@ class WrappingInterfaceGenerator(object):
|
| NAME=native_name,
|
| TYPE=info.type_name,
|
| PARAMS=', '.join(['receiver'] + arg_names) )
|
| -
|
| -
|
| - 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)
|
| -
|
| - def ShouldGenerateSingleOperation():
|
| - if position == len(info.param_infos):
|
| - if len(overloads) > 1:
|
| - raise Exception('Duplicate operations ' + str(overloads))
|
| - return True
|
| -
|
| - # Check if we dispatch on RequiredCppParameter arguments. In this
|
| - # case all trailing arguments must be RequiredCppParameter and there
|
| - # is no need in dispatch.
|
| - # TODO(antonm): better diagnositics.
|
| - if position >= len(overloads[0].arguments):
|
| - def IsRequiredCppParameter(arg):
|
| - return 'RequiredCppParameter' in arg.ext_attrs
|
| - last_overload = overloads[-1]
|
| - if (len(last_overload.arguments) > position and
|
| - IsRequiredCppParameter(last_overload.arguments[position])):
|
| - for overload in overloads:
|
| - args = overload.arguments[position:]
|
| - if not all([IsRequiredCppParameter(arg) for arg in args]):
|
| - raise Exception('Invalid overload for RequiredCppParameter')
|
| - return True
|
| -
|
| - return False
|
| -
|
| - if ShouldGenerateSingleOperation():
|
| - self.GenerateSingleOperation(emitter, info, indent, overloads[-1])
|
| - 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 subtype 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
|
|
|