| Index: lib/dom/scripts/generator.py
|
| diff --git a/lib/dom/scripts/generator.py b/lib/dom/scripts/generator.py
|
| index 96f90af208bf2276f1df9a74c2053b1345e610b5..96d9fb0ac58e5fd56d7f007e6978ca92183bc847 100644
|
| --- a/lib/dom/scripts/generator.py
|
| +++ b/lib/dom/scripts/generator.py
|
| @@ -131,9 +131,27 @@ def MatchSourceFilter(filter, thing):
|
| else:
|
| return any(token in thing.annotations for token in filter)
|
|
|
| +
|
| def DartType(idl_type_name):
|
| return GetIDLTypeInfo(idl_type_name).dart_type()
|
|
|
| +
|
| +class ParamInfo(object):
|
| + """Holder for various information about a parameter of a Dart operation.
|
| +
|
| + Attributes:
|
| + name: Name of parameter.
|
| + type_id: Original type id. None for merged types.
|
| + dart_type: DartType of parameter.
|
| + default_value: String holding the expression. None for mandatory parameter.
|
| + """
|
| + def __init__(self, name, type_id, dart_type, default_value):
|
| + self.name = name
|
| + self.type_id = type_id
|
| + self.dart_type = dart_type
|
| + self.default_value = default_value
|
| +
|
| +
|
| # Given a list of overloaded arguments, render a dart argument.
|
| def _DartArg(args, interface):
|
| # Given a list of overloaded arguments, choose a suitable name.
|
| @@ -142,20 +160,24 @@ def _DartArg(args, interface):
|
|
|
| # Given a list of overloaded arguments, choose a suitable type.
|
| def OverloadedType(args):
|
| - typeIds = sorted(set(DartType(arg.type.id) for arg in args))
|
| - if len(typeIds) == 1:
|
| - return typeIds[0]
|
| + type_ids = sorted(set(arg.type.id for arg in args))
|
| + dart_types = sorted(set(DartType(arg.type.id) for arg in args))
|
| + if len(dart_types) == 1:
|
| + if len(type_ids) == 1:
|
| + return (type_ids[0], dart_types[0])
|
| + else:
|
| + return (None, dart_types[0])
|
| else:
|
| - return TypeName(typeIds, interface)
|
| + return (None, TypeName(type_ids, interface))
|
|
|
| filtered = filter(None, args)
|
| optional = any(not arg or arg.is_optional for arg in args)
|
| - type = OverloadedType(filtered)
|
| + (type_id, dart_type) = OverloadedType(filtered)
|
| name = OverloadedName(filtered)
|
| if optional:
|
| - return (name, type, 'null')
|
| + return ParamInfo(name, type_id, dart_type, 'null')
|
| else:
|
| - return (name, type, None)
|
| + return ParamInfo(name, type_id, dart_type, None)
|
|
|
|
|
| def AnalyzeOperation(interface, operations):
|
| @@ -175,7 +197,7 @@ def AnalyzeOperation(interface, operations):
|
| info.name = operations[0].ext_attrs.get('DartName', info.declared_name)
|
| info.js_name = info.declared_name
|
| info.type_name = DartType(operations[0].type.id) # TODO: widen.
|
| - info.arg_infos = args
|
| + info.param_infos = args
|
| return info
|
|
|
|
|
| @@ -213,7 +235,7 @@ def AnalyzeConstructor(interface):
|
| info.name = name
|
| info.js_name = name
|
| info.type_name = interface.id
|
| - info.arg_infos = args
|
| + info.param_infos = args
|
| return info
|
|
|
|
|
| @@ -257,6 +279,33 @@ def DartDomNameOfAttribute(attr):
|
| name = attr.ext_attrs.get('DartName', None) or name
|
| return name
|
|
|
| +
|
| +def TypeOrNothing(dart_type, comment=None):
|
| + """Returns string for declaring something with |dart_type| in a context
|
| + where a type may be omitted.
|
| + The string is empty or has a trailing space.
|
| + """
|
| + if dart_type == 'Dynamic':
|
| + if comment:
|
| + return '/*%s*/ ' % comment # Just a comment foo(/*T*/ x)
|
| + else:
|
| + return '' # foo(x) looks nicer than foo(Dynamic x)
|
| + else:
|
| + return dart_type + ' '
|
| +
|
| +
|
| +def TypeOrVar(dart_type, comment=None):
|
| + """Returns string for declaring something with |dart_type| in a context
|
| + where if a type is omitted, 'var' must be used instead."""
|
| + if dart_type == 'Dynamic':
|
| + if comment:
|
| + return 'var /*%s*/' % comment # e.g. var /*T*/ x;
|
| + else:
|
| + return 'var' # e.g. var x;
|
| + else:
|
| + return dart_type
|
| +
|
| +
|
| class OperationInfo(object):
|
| """Holder for various derived information from a set of overloaded operations.
|
|
|
| @@ -264,13 +313,14 @@ class OperationInfo(object):
|
| overloads: A list of IDL operation overloads with the same name.
|
| name: A string, the simple name of the operation.
|
| type_name: A string, the name of the return type of the operation.
|
| - arg_infos: A list of (name, type, default_value) tuples.
|
| - default_value is None for mandatory arguments.
|
| + param_infos: A list of ParamInfo.
|
| """
|
|
|
| def ParametersInterfaceDeclaration(self):
|
| """Returns a formatted string declaring the parameters for the interface."""
|
| - return self._FormatArgs(self.arg_infos, True)
|
| + return self._FormatParams(
|
| + self.param_infos, True,
|
| + lambda param: TypeOrNothing(param.dart_type, param.type_id))
|
|
|
| def ParametersImplementationDeclaration(self, rename_type=None):
|
| """Returns a formatted string declaring the parameters for the
|
| @@ -278,44 +328,54 @@ class OperationInfo(object):
|
|
|
| Args:
|
| rename_type: A function that allows the types to be renamed.
|
| + The function is applied to the parameter's dart_type.
|
| """
|
| - args = self.arg_infos
|
| if rename_type:
|
| - args = [(name, rename_type(type), default)
|
| - for (name, type, default) in args]
|
| - return self._FormatArgs(args, False)
|
| + def renamer(param_info):
|
| + return TypeOrNothing(rename_type(param_info.dart_type))
|
| + return self._FormatParams(self.param_infos, False, renamer)
|
| + else:
|
| + def type_fn(param_info):
|
| + if param_info.dart_type == 'Dynamic':
|
| + if param_info.type_id:
|
| + # It is more informative to use a comment IDL type.
|
| + return '/*%s*/' % param_info.type_id
|
| + else:
|
| + return 'var'
|
| + else:
|
| + return param_info.dart_type
|
| + return self._FormatParams(
|
| + self.param_infos, False,
|
| + lambda param: TypeOrNothing(param.dart_type, param.type_id))
|
|
|
| def ParametersAsArgumentList(self):
|
| - """Returns a formatted string declaring the parameters names as an argument
|
| - list.
|
| + """Returns a string of the parameter names suitable for passing the
|
| + parameters as arguments.
|
| """
|
| - return ', '.join(map(lambda arg_info: arg_info[0], self.arg_infos))
|
| -
|
| - def _FormatArgs(self, args, is_interface):
|
| - def FormatArg(arg_info):
|
| - """Returns an argument declaration fragment for an argument info tuple."""
|
| - (name, type, default) = arg_info
|
| - if default:
|
| - return '%s %s = %s' % (type, name, default)
|
| + return ', '.join(map(lambda param_info: param_info.name, self.param_infos))
|
| +
|
| + def _FormatParams(self, params, is_interface, type_fn):
|
| + def FormatParam(param):
|
| + """Returns a parameter declaration fragment for an ParamInfo."""
|
| + type = type_fn(param)
|
| + if is_interface or param.default_value is None:
|
| + return '%s%s' % (type, param.name)
|
| else:
|
| - return '%s %s' % (type, name)
|
| + return '%s%s = %s' % (type, param.name, param.default_value)
|
|
|
| required = []
|
| optional = []
|
| - for (name, type, default) in args:
|
| - if default:
|
| - if is_interface:
|
| - optional.append((name, type, None)) # Default values illegal.
|
| - else:
|
| - optional.append((name, type, default))
|
| + for param_info in params:
|
| + if param_info.default_value:
|
| + optional.append(param_info)
|
| else:
|
| if optional:
|
| - raise Exception('Optional arguments cannot precede required ones: '
|
| + raise Exception('Optional parameters cannot precede required ones: '
|
| + str(args))
|
| - required.append((name, type, None))
|
| - argtexts = map(FormatArg, required)
|
| + required.append(param_info)
|
| + argtexts = map(FormatParam, required)
|
| if optional:
|
| - argtexts.append('[' + ', '.join(map(FormatArg, optional)) + ']')
|
| + argtexts.append('[' + ', '.join(map(FormatParam, optional)) + ']')
|
| return ', '.join(argtexts)
|
|
|
|
|
| @@ -357,14 +417,15 @@ def IndentText(text, indent):
|
|
|
| # Given a sorted sequence of type identifiers, return an appropriate type
|
| # name
|
| -def TypeName(typeIds, interface):
|
| +def TypeName(type_ids, interface):
|
| # Dynamically type this field for now.
|
| - return 'var'
|
| + return 'Dynamic'
|
|
|
| # ------------------------------------------------------------------------------
|
|
|
| class IDLTypeInfo(object):
|
| - def __init__(self, idl_type, dart_type=None, native_type=None, ref_counted=True,
|
| + def __init__(self, idl_type, dart_type=None,
|
| + native_type=None, ref_counted=True,
|
| has_dart_wrapper=True, conversion_template=None,
|
| custom_to_dart=False, conversion_includes=[]):
|
| self._idl_type = idl_type
|
| @@ -441,12 +502,15 @@ class IDLTypeInfo(object):
|
|
|
| def conversion_includes(self):
|
| def NeededDartTypes(type_name):
|
| + if re.match(r'Dynamic(\/.*)?$', type_name): return []
|
| match = re.match(r'List<(\w*)>$', type_name)
|
| if match:
|
| return NeededDartTypes(match.group(1))
|
| return [type_name]
|
|
|
| - return ['"Dart%s.h"' % include for include in NeededDartTypes(self.dart_type()) + self._conversion_includes]
|
| + return ['"Dart%s.h"' % include
|
| + for include in
|
| + NeededDartTypes(self.dart_type()) + self._conversion_includes]
|
|
|
| def conversion_cast(self, expression):
|
| if self._conversion_template:
|
| @@ -568,7 +632,14 @@ _idl_type_registry = {
|
| 'EventListener': IDLTypeInfo('EventListener', has_dart_wrapper=False),
|
| 'EventTarget': IDLTypeInfo('EventTarget', has_dart_wrapper=False),
|
| 'HTMLElement': IDLTypeInfo('HTMLElement', custom_to_dart=True),
|
| - 'IDBKey': IDLTypeInfo('IDBKey', has_dart_wrapper=False),
|
| + 'IDBAny': IDLTypeInfo('IDBAny', dart_type='Dynamic',
|
| + native_type='IDBAny',
|
| + has_dart_wrapper=False,
|
| + conversion_includes=['IDBAny']),
|
| + 'IDBKey': IDLTypeInfo('IDBKey', dart_type='Dynamic',
|
| + native_type='IDBKey',
|
| + has_dart_wrapper=False,
|
| + conversion_includes=['IDBKey']),
|
| 'MediaQueryListListener': IDLTypeInfo('MediaQueryListListener', has_dart_wrapper=False),
|
| 'OptionsObject': IDLTypeInfo('OptionsObject', has_dart_wrapper=False),
|
| 'StyleSheet': IDLTypeInfo('StyleSheet', conversion_includes=['CSSStyleSheet']),
|
|
|