| Index: client/dom/scripts/dartgenerator.py
|
| diff --git a/client/dom/scripts/dartgenerator.py b/client/dom/scripts/dartgenerator.py
|
| index e267c905996abb0c91c02932c43c029da3c663ef..338678abb5204db3585638d62f4e4489d11e2cc7 100755
|
| --- a/client/dom/scripts/dartgenerator.py
|
| +++ b/client/dom/scripts/dartgenerator.py
|
| @@ -12,133 +12,14 @@ import multiemitter
|
| import os
|
| import re
|
| import shutil
|
| +from generator import *
|
| +from systembase import *
|
| +from systemfrog import *
|
| +from systemhtml import *
|
| +from systeminterface import *
|
|
|
| _logger = logging.getLogger('dartgenerator')
|
|
|
| -# IDL->Dart primitive types conversion.
|
| -_idl_to_dart_type_conversions = {
|
| - 'any': 'Object',
|
| - 'any[]': 'List',
|
| - 'custom': 'Dynamic',
|
| - 'boolean': 'bool',
|
| - 'DOMObject': 'Object',
|
| - 'DOMString': 'String',
|
| - 'DOMStringList': 'List<String>',
|
| - 'DOMTimeStamp': 'int',
|
| - 'Date': 'Date',
|
| - # Map to num to enable callers to pass in Dart int, rational
|
| - # types. Our implementations will need to convert these to
|
| - # doubles or floats as needed.
|
| - 'double': 'num',
|
| - 'float': 'num',
|
| - 'int': 'int',
|
| - # Map to extra precision - int is a bignum in Dart.
|
| - 'long': 'int',
|
| - 'long long': 'int',
|
| - 'object': 'Object',
|
| - # Map to extra precision - int is a bignum in Dart.
|
| - 'short': 'int',
|
| - 'string': 'String',
|
| - 'void': 'void',
|
| - 'Array': 'List',
|
| - 'sequence': 'List',
|
| - # TODO(sra): Come up with some meaningful name so that where this appears in
|
| - # the documentation, the user is made aware that only a limited subset of
|
| - # serializable types are actually permitted.
|
| - 'SerializedScriptValue': 'Dynamic',
|
| - # TODO(vsm): Automatically recognize types defined in src.
|
| - 'TimeoutHandler': 'TimeoutHandler',
|
| - 'RequestAnimationFrameCallback': 'RequestAnimationFrameCallback',
|
| -
|
| - # TODO(sra): Flags is really a dictionary: {create:bool, exclusive:bool}
|
| - # http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#the-flags-interface
|
| - 'WebKitFlags': 'Object',
|
| - }
|
| -
|
| -_dart_to_idl_type_conversions = dict((v,k) for k, v in
|
| - _idl_to_dart_type_conversions.iteritems())
|
| -
|
| -
|
| -#
|
| -# Identifiers that are used in the IDL than need to be treated specially because
|
| -# *some* JavaScript processors forbid them as properties.
|
| -#
|
| -_javascript_keywords = ['delete', 'continue']
|
| -
|
| -#
|
| -# Interface version of the DOM needs to delegate typed array constructors to a
|
| -# factory provider.
|
| -#
|
| -_interface_factories = {
|
| - 'Float32Array': '_TypedArrayFactoryProvider',
|
| - 'Float64Array': '_TypedArrayFactoryProvider',
|
| - 'Int8Array': '_TypedArrayFactoryProvider',
|
| - 'Int16Array': '_TypedArrayFactoryProvider',
|
| - 'Int32Array': '_TypedArrayFactoryProvider',
|
| - 'Uint8Array': '_TypedArrayFactoryProvider',
|
| - 'Uint16Array': '_TypedArrayFactoryProvider',
|
| - 'Uint32Array': '_TypedArrayFactoryProvider',
|
| - 'Uint8ClampedArray': '_TypedArrayFactoryProvider',
|
| -}
|
| -
|
| -#
|
| -# Custom methods that must be implemented by hand.
|
| -#
|
| -_custom_methods = set([
|
| - ('DOMWindow', 'setInterval'),
|
| - ('DOMWindow', 'setTimeout'),
|
| - ('WorkerContext', 'setInterval'),
|
| - ('WorkerContext', 'setTimeout'),
|
| - ('CanvasRenderingContext2D', 'setFillStyle'),
|
| - ('CanvasRenderingContext2D', 'setStrokeStyle'),
|
| - ('CanvasRenderingContext2D', 'setFillStyle'),
|
| - ])
|
| -
|
| -#
|
| -# Custom getters that must be implemented by hand.
|
| -#
|
| -_custom_getters = set([
|
| - ('DOMWindow', 'localStorage'),
|
| - ])
|
| -
|
| -#
|
| -# Custom native specs for the Frog dom.
|
| -#
|
| -_frog_dom_custom_native_specs = {
|
| - # Decorate the singleton Console object, if present (workers do not have a
|
| - # console).
|
| - 'Console': "=(typeof console == 'undefined' ? {} : console)",
|
| -
|
| - # DOMWindow aliased with global scope.
|
| - 'DOMWindow': '@*DOMWindow',
|
| -}
|
| -
|
| -#
|
| -# Simple method substitution when one method had different names on different
|
| -# browsers, but are otherwise identical. The alternates are tried in order and
|
| -# the first one defined is used.
|
| -#
|
| -# This can be probably be removed when Chrome renames initWebKitWheelEvent to
|
| -# initWheelEvent.
|
| -#
|
| -_alternate_methods = {
|
| - ('WheelEvent', 'initWheelEvent'): ['initWebKitWheelEvent', 'initWheelEvent']
|
| -}
|
| -
|
| -
|
| -def _MatchSourceFilter(filter, thing):
|
| - if not filter:
|
| - return True
|
| - else:
|
| - return any(token in thing.annotations for token in filter)
|
| -
|
| -def _IsDartListType(type):
|
| - return type == 'List' or type.startswith('List<')
|
| -
|
| -def _IsDartCollectionType(type):
|
| - return _IsDartListType(type)
|
| -
|
| -
|
| class DartGenerator(object):
|
| """Utilities to generate Dart APIs and corresponding JavaScript."""
|
|
|
| @@ -162,12 +43,8 @@ class DartGenerator(object):
|
| def _StripModules(self, type_name):
|
| return type_name.split('::')[-1]
|
|
|
| - def _IsPrimitiveType(self, type_name):
|
| - return (self._ConvertPrimitiveType(type_name) is not None or
|
| - type_name in _dart_to_idl_type_conversions)
|
| -
|
| def _IsCompoundType(self, database, type_name):
|
| - if self._IsPrimitiveType(type_name):
|
| + if IsPrimitiveType(type_name):
|
| return True
|
|
|
| striped_type_name = self._StripModules(type_name)
|
| @@ -186,15 +63,6 @@ class DartGenerator(object):
|
| def _IsDartType(self, type_name):
|
| return '.' in type_name
|
|
|
| - def _ConvertPrimitiveType(self, type_name):
|
| - if type_name.startswith('unsigned '):
|
| - type_name = type_name[len('unsigned '):]
|
| -
|
| - if type_name in _idl_to_dart_type_conversions:
|
| - # Primitive type conversion
|
| - return _idl_to_dart_type_conversions[type_name]
|
| - return None
|
| -
|
| def LoadAuxiliary(self):
|
| def Visitor(_, dirname, names):
|
| for name in names:
|
| @@ -203,7 +71,7 @@ class DartGenerator(object):
|
| self._auxiliary_files[name] = os.path.join(dirname, name)
|
| os.path.walk(self._auxiliary_dir, Visitor, None)
|
|
|
| - def RenameTypes(self, database, conversion_table=None):
|
| + def RenameTypes(self, database, conversion_table, rename_javascript_binding_names):
|
| """Renames interfaces using the given conversion table.
|
|
|
| References through all interfaces will be renamed as well.
|
| @@ -215,18 +83,23 @@ class DartGenerator(object):
|
|
|
| if conversion_table is None:
|
| conversion_table = {}
|
| -
|
| +
|
| # Rename interfaces:
|
| for old_name, new_name in conversion_table.items():
|
| if database.HasInterface(old_name):
|
| - _logger.info('renaming interface %s to %s' %
|
| - (old_name, new_name))
|
| + _logger.info('renaming interface %s to %s' % (old_name, new_name))
|
| interface = database.GetInterface(old_name)
|
| database.DeleteInterface(old_name)
|
| if not database.HasInterface(new_name):
|
| interface.id = new_name
|
| database.AddInterface(interface)
|
| -
|
| + else:
|
| + new_interface = database.GetInterface(new_name)
|
| + new_interface.merge(interface)
|
| +
|
| + interface.javascript_binding_name = (old_name if rename_javascript_binding_names
|
| + else new_name)
|
| +
|
| # Fix references:
|
| for interface in database.GetInterfaces():
|
| for idl_type in interface.all(idlnode.IDLType):
|
| @@ -265,8 +138,8 @@ class DartGenerator(object):
|
| def ConvertType(interface, type_name):
|
| """Helper method for converting a type name to the proper
|
| Dart name"""
|
| - if self._IsPrimitiveType(type_name):
|
| - return self._ConvertPrimitiveType(type_name)
|
| + if IsPrimitiveType(type_name):
|
| + return ConvertPrimitiveType(type_name)
|
|
|
| if self._IsDartType(type_name):
|
| # This is for when dart qualified names are explicitly
|
| @@ -355,7 +228,7 @@ class DartGenerator(object):
|
| def Generate(self, database, output_dir,
|
| module_source_preference=[], source_filter=None,
|
| super_database=None, common_prefix=None, super_map={},
|
| - lib_dir=None, systems=[]):
|
| + html_map={}, lib_dir=None, systems=[]):
|
| """Generates Dart and JS files for the loaded interfaces.
|
|
|
| Args:
|
| @@ -373,7 +246,7 @@ class DartGenerator(object):
|
| lib_file_path -- filename for generated .lib file, None if not required.
|
| lib_template -- template file in this directory for generated lib file.
|
| """
|
| -
|
| +
|
| self._emitters = multiemitter.MultiEmitter()
|
| self._database = database
|
| self._output_dir = output_dir
|
| @@ -383,15 +256,16 @@ class DartGenerator(object):
|
| self._systems = []
|
|
|
| # TODO(jmesserly): only create these if needed
|
| - interface_system = InterfacesSystem(
|
| - TemplateLoader(self._template_dir, ['dom/interface', 'dom', '']),
|
| - self._database, self._emitters, self._output_dir)
|
| - self._systems.append(interface_system)
|
| -
|
| - html_interface_system = HtmlInterfacesSystem(
|
| - TemplateLoader(self._template_dir, ['html/interface', 'html', '']),
|
| - self._database, self._emitters, self._output_dir)
|
| - self._systems.append(html_interface_system)
|
| + if ('htmlfrog' in systems) or ('htmldartium' in systems):
|
| + html_interface_system = HtmlInterfacesSystem(
|
| + TemplateLoader(self._template_dir, ['html/interface', 'html', '']),
|
| + self._database, self._emitters, self._output_dir, self)
|
| + self._systems.append(html_interface_system)
|
| + else:
|
| + interface_system = InterfacesSystem(
|
| + TemplateLoader(self._template_dir, ['dom/interface', 'dom', '']),
|
| + self._database, self._emitters, self._output_dir)
|
| + self._systems.append(interface_system)
|
|
|
| if 'native' in systems:
|
| native_system = NativeImplementationSystem(
|
| @@ -432,7 +306,7 @@ class DartGenerator(object):
|
| if 'htmlfrog' in systems:
|
| html_system = HtmlFrogSystem(
|
| TemplateLoader(self._template_dir, ['html/frog', 'html', '']),
|
| - self._database, self._emitters, self._output_dir)
|
| + self._database, self._emitters, self._output_dir, self)
|
|
|
| html_system._interface_system = html_interface_system
|
| self._systems.append(html_system)
|
| @@ -440,7 +314,7 @@ class DartGenerator(object):
|
| if 'htmldartium' in systems:
|
| html_system = HtmlDartiumSystem(
|
| TemplateLoader(self._template_dir, ['html/dartium', 'html', '']),
|
| - self._database, self._emitters, self._output_dir)
|
| + self._database, self._emitters, self._output_dir, self)
|
|
|
| html_system._interface_system = html_interface_system
|
| self._systems.append(html_system)
|
| @@ -448,7 +322,7 @@ class DartGenerator(object):
|
| # Collect interfaces
|
| interfaces = []
|
| for interface in database.GetInterfaces():
|
| - if not _MatchSourceFilter(source_filter, interface):
|
| + if not MatchSourceFilter(source_filter, interface):
|
| # Skip this interface since it's not present in the required source
|
| _logger.info('Omitting interface - %s' % interface.id)
|
| continue
|
| @@ -478,7 +352,7 @@ class DartGenerator(object):
|
| interface_name, auxiliary_file))
|
| continue
|
|
|
| - info = _RecognizeCallback(interface)
|
| + info = RecognizeCallback(interface)
|
| if info:
|
| for system in self._systems:
|
| system.ProcessCallback(interface, info)
|
| @@ -506,7 +380,7 @@ class DartGenerator(object):
|
| return
|
| seen.add(interface.id)
|
| for parent in interface.parents:
|
| - if _IsDartCollectionType(parent.type.id):
|
| + if IsDartCollectionType(parent.type.id):
|
| continue
|
| if self._database.HasInterface(parent.type.id):
|
| parent_interface = self._database.GetInterface(parent.type.id)
|
| @@ -544,8 +418,9 @@ class DartGenerator(object):
|
| for generator in generators:
|
| generator.AddAttribute(getter, setter)
|
|
|
| - events = _PairUpAttributes([attr for attr in interface.attributes
|
| + events = set([attr for attr in interface.attributes
|
| if self._IsEventAttribute(interface, attr)])
|
| +
|
| if events:
|
| for generator in generators:
|
| generator.AddEventAttributes(events)
|
| @@ -556,7 +431,6 @@ class DartGenerator(object):
|
| if element_type:
|
| for generator in generators:
|
| generator.AddIndexer(element_type)
|
| -
|
| # Group overloaded operations by id
|
| operationsById = {}
|
| for operation in interface.operations:
|
| @@ -567,7 +441,7 @@ class DartGenerator(object):
|
| # Generate operations
|
| for id in sorted(operationsById.keys()):
|
| operations = operationsById[id]
|
| - info = _AnalyzeOperation(interface, operations)
|
| + info = AnalyzeOperation(interface, operations)
|
| for generator in generators:
|
| generator.AddOperation(info)
|
|
|
| @@ -577,10 +451,10 @@ class DartGenerator(object):
|
| # avoid making a duplicate definition and pray that the signatures match.
|
|
|
| for parent_interface in self._TransitiveSecondaryParents(interface):
|
| - if isinstance(parent_interface, str): # _IsDartCollectionType(parent_interface)
|
| + if isinstance(parent_interface, str): # IsDartCollectionType(parent_interface)
|
| continue
|
| attributes = [attr for attr in parent_interface.attributes
|
| - if not _FindMatchingAttribute(interface, attr)]
|
| + if not FindMatchingAttribute(interface, attr)]
|
| for (getter, setter) in _PairUpAttributes(attributes):
|
| for generator in generators:
|
| generator.AddSecondaryAttribute(parent_interface, getter, setter)
|
| @@ -596,7 +470,7 @@ class DartGenerator(object):
|
| for id in sorted(operationsById.keys()):
|
| if not any(op.id == id for op in interface.operations):
|
| operations = operationsById[id]
|
| - info = _AnalyzeOperation(interface, operations)
|
| + info = AnalyzeOperation(interface, operations)
|
| for generator in generators:
|
| generator.AddSecondaryOperation(parent_interface, info)
|
|
|
| @@ -607,10 +481,8 @@ class DartGenerator(object):
|
| def _IsEventAttribute(self, interface, attr):
|
| # Remove EventListener attributes like 'onclick' when addEventListener
|
| # is available.
|
| - if attr.type.id == 'EventListener':
|
| - if 'EventTarget' in self._AllImplementedInterfaces(interface):
|
| - return True
|
| - return False
|
| + return (attr.type.id == 'EventListener' and
|
| + 'EventTarget' in self._AllImplementedInterfaces(interface))
|
|
|
| def _TransitiveSecondaryParents(self, interface):
|
| """Returns a list of all non-primary parents.
|
| @@ -620,7 +492,7 @@ class DartGenerator(object):
|
| """
|
| def walk(parents):
|
| for parent in parents:
|
| - if _IsDartCollectionType(parent.type.id):
|
| + if IsDartCollectionType(parent.type.id):
|
| result.append(parent.type.id)
|
| continue
|
| if self._database.HasInterface(parent.type.id):
|
| @@ -683,18 +555,6 @@ class DartGenerator(object):
|
| """
|
| return self._inheritance_closure[interface.id]
|
|
|
| -
|
| -def _RecognizeCallback(interface):
|
| - """Returns the info for the callback method if the interface smells like a
|
| - callback.
|
| - """
|
| - if 'Callback' not in interface.ext_attrs: return None
|
| - handlers = [op for op in interface.operations if op.id == 'handleEvent']
|
| - if not handlers: return None
|
| - if not (handlers == interface.operations): return None
|
| - return _AnalyzeOperation(interface, handlers)
|
| -
|
| -
|
| def _PairUpAttributes(attributes):
|
| """Returns a list of (getter, setter) pairs sorted by name.
|
|
|
| @@ -710,186 +570,6 @@ def _PairUpAttributes(attributes):
|
| setters[attr.id] = attr
|
| return [(getters.get(id), setters.get(id)) for id in names]
|
|
|
| -
|
| -def _FindMatchingAttribute(interface, attr1):
|
| - matches = [attr2 for attr2 in interface.attributes
|
| - if attr1.id == attr2.id
|
| - and attr1.is_fc_getter == attr2.is_fc_getter
|
| - and attr1.is_fc_setter == attr2.is_fc_setter]
|
| - if matches:
|
| - assert len(matches) == 1
|
| - return matches[0]
|
| - return None
|
| -
|
| -
|
| -def _AnalyzeOperation(interface, operations):
|
| - """Makes operation calling convention decision for a set of overloads.
|
| -
|
| - Returns: An OperationInfo object.
|
| - """
|
| -
|
| - # Zip together arguments from each overload by position, then convert
|
| - # to a dart argument.
|
| -
|
| - # Given a list of overloaded arguments, choose a suitable name.
|
| - def OverloadedName(args):
|
| - return '_OR_'.join(sorted(set(arg.id for arg in args)))
|
| -
|
| - # Given a list of overloaded arguments, choose a suitable type.
|
| - def OverloadedType(args):
|
| - typeIds = sorted(set(arg.type.id for arg in args))
|
| - if len(typeIds) == 1:
|
| - return typeIds[0]
|
| - else:
|
| - return TypeName(typeIds, interface)
|
| -
|
| - # Given a list of overloaded arguments, render a dart argument.
|
| - def DartArg(args):
|
| - filtered = filter(None, args)
|
| - optional = any(not arg or arg.is_optional for arg in args)
|
| - type = OverloadedType(filtered)
|
| - name = OverloadedName(filtered)
|
| - if optional:
|
| - return (name, type, 'null')
|
| - else:
|
| - return (name, type, None)
|
| -
|
| - args = map(lambda *args: DartArg(args),
|
| - *(op.arguments for op in operations))
|
| -
|
| - info = OperationInfo()
|
| - info.overloads = operations
|
| - info.declared_name = operations[0].id
|
| - info.name = operations[0].ext_attrs.get('DartName', info.declared_name)
|
| - info.js_name = info.declared_name
|
| - info.type_name = operations[0].type.id # TODO: widen.
|
| - info.arg_infos = args
|
| - return info
|
| -
|
| -
|
| -class OperationInfo(object):
|
| - """Holder for various derived information from a set of overloaded operations.
|
| -
|
| - Attributes:
|
| - 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.
|
| - """
|
| -
|
| - def ParametersInterfaceDeclaration(self):
|
| - """Returns a formatted string declaring the parameters for the interface."""
|
| - return self._FormatArgs(self.arg_infos, True)
|
| -
|
| - def ParametersImplementationDeclaration(self, rename_type=None):
|
| - """Returns a formatted string declaring the parameters for the
|
| - implementation.
|
| -
|
| - Args:
|
| - rename_type: A function that allows the types to be renamed.
|
| - """
|
| - 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 _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)
|
| - else:
|
| - return '%s %s' % (type, name)
|
| -
|
| - 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))
|
| - else:
|
| - if optional:
|
| - raise Exception('Optional arguments cannot precede required ones: '
|
| - + str(args))
|
| - required.append((name, type, None))
|
| - argtexts = map(FormatArg, required)
|
| - if optional:
|
| - argtexts.append('[' + ', '.join(map(FormatArg, optional)) + ']')
|
| - return ', '.join(argtexts)
|
| -
|
| -
|
| -def MaybeListElementTypeName(type_name):
|
| - """Returns the List element type T from string of form "List<T>", or None."""
|
| - match = re.match(r'List<(\w*)>$', type_name)
|
| - if match:
|
| - return match.group(1)
|
| - return None
|
| -
|
| -def MaybeListElementType(interface):
|
| - """Returns the List element type T, or None in interface does not implement
|
| - List<T>.
|
| - """
|
| - for parent in interface.parents:
|
| - element_type = MaybeListElementTypeName(parent.type.id)
|
| - if element_type:
|
| - return element_type
|
| - return None
|
| -
|
| -def MaybeTypedArrayElementType(interface):
|
| - """Returns the typed array element type, or None in interface is not a
|
| - TypedArray.
|
| - """
|
| - # Typed arrays implement ArrayBufferView and List<T>.
|
| - for parent in interface.parents:
|
| - if parent.type.id == 'ArrayBufferView':
|
| - return MaybeListElementType(interface)
|
| - if parent.type.id == 'Uint8Array':
|
| - return 'int'
|
| - return None
|
| -
|
| -
|
| -def AttributeOutputOrder(a, b):
|
| - """Canonical output ordering for attributes."""
|
| - # Getters before setters:
|
| - if a.id < b.id: return -1
|
| - if a.id > b.id: return 1
|
| - if a.is_fc_setter < b.is_fc_setter: return -1
|
| - if a.is_fc_setter > b.is_fc_setter: return 1
|
| - return 0
|
| -
|
| -def ConstantOutputOrder(a, b):
|
| - """Canonical output ordering for constants."""
|
| - if a.id < b.id: return -1
|
| - if a.id > b.id: return 1
|
| - return 0
|
| -
|
| -
|
| -def _FormatNameList(names):
|
| - """Returns JavaScript array literal expression with one name per line."""
|
| - #names = sorted(names)
|
| - if len(names) <= 1:
|
| - expression_string = str(names) # e.g. ['length']
|
| - else:
|
| - expression_string = ',\n '.join(str(names).split(','))
|
| - expression_string = expression_string.replace('[', '[\n ')
|
| - return expression_string
|
| -
|
| -
|
| -def IndentText(text, indent):
|
| - """Format lines of text with indent."""
|
| - def FormatLine(line):
|
| - if line.strip():
|
| - return '%s%s\n' % (indent, line)
|
| - else:
|
| - return '\n'
|
| - return ''.join(FormatLine(line) for line in text.split('\n'))
|
| -
|
| # ------------------------------------------------------------------------------
|
|
|
| class TemplateLoader(object):
|
| @@ -928,190 +608,6 @@ class TemplateLoader(object):
|
| raise Exception("Could not find template '%s' on %s / %s" % (
|
| name, self._root, self._subpaths))
|
|
|
| -
|
| -# ------------------------------------------------------------------------------
|
| -
|
| -class System(object):
|
| - """Generates all the files for one implementation."""
|
| -
|
| - def __init__(self, templates, database, emitters, output_dir):
|
| - self._templates = templates
|
| - self._database = database
|
| - self._emitters = emitters
|
| - self._output_dir = output_dir
|
| - self._dart_callback_file_paths = []
|
| -
|
| - def InterfaceGenerator(self,
|
| - interface,
|
| - common_prefix,
|
| - super_interface_name,
|
| - source_filter):
|
| - """Returns an interface generator for |interface|."""
|
| - return None
|
| -
|
| - def ProcessCallback(self, interface, info):
|
| - pass
|
| -
|
| - def GenerateLibraries(self, lib_dir):
|
| - pass
|
| -
|
| - def Finish(self):
|
| - pass
|
| -
|
| -
|
| - def _ProcessCallback(self, interface, info, file_path):
|
| - """Generates a typedef for the callback interface."""
|
| - self._dart_callback_file_paths.append(file_path)
|
| - code = self._emitters.FileEmitter(file_path)
|
| -
|
| - code.Emit(self._templates.Load('callback.darttemplate'))
|
| - code.Emit('typedef $TYPE $NAME($PARAMS);\n',
|
| - NAME=interface.id,
|
| - TYPE=info.type_name,
|
| - PARAMS=info.ParametersImplementationDeclaration())
|
| -
|
| - def _GenerateLibFile(self, lib_template, lib_file_path, file_paths,
|
| - **template_args):
|
| - """Generates a lib file from a template and a list of files.
|
| -
|
| - Additional keyword arguments are passed to the template.
|
| - """
|
| - # Load template.
|
| - template = self._templates.Load(lib_template)
|
| - # Generate the .lib file.
|
| - lib_file_contents = self._emitters.FileEmitter(lib_file_path)
|
| -
|
| - # Emit the list of #source directives.
|
| - list_emitter = lib_file_contents.Emit(template, **template_args)
|
| - lib_file_dir = os.path.dirname(lib_file_path)
|
| - for path in sorted(file_paths):
|
| - relpath = os.path.relpath(path, lib_file_dir)
|
| - list_emitter.Emit("#source('$PATH');\n", PATH=relpath)
|
| -
|
| -
|
| - def _BaseDefines(self, interface):
|
| - """Returns a set of names (strings) for members defined in a base class.
|
| - """
|
| - def WalkParentChain(interface):
|
| - if interface.parents:
|
| - # Only consider primary parent, secondary parents are not on the
|
| - # implementation class inheritance chain.
|
| - parent = interface.parents[0]
|
| - if _IsDartCollectionType(parent.type.id):
|
| - return
|
| - if self._database.HasInterface(parent.type.id):
|
| - parent_interface = self._database.GetInterface(parent.type.id)
|
| - for attr in parent_interface.attributes:
|
| - result.add(attr.id)
|
| - for op in parent_interface.operations:
|
| - result.add(op.id)
|
| - WalkParentChain(parent_interface)
|
| -
|
| - result = set()
|
| - WalkParentChain(interface)
|
| - return result;
|
| -
|
| -
|
| -# ------------------------------------------------------------------------------
|
| -
|
| -class InterfacesSystem(System):
|
| -
|
| - def __init__(self, templates, database, emitters, output_dir):
|
| - super(InterfacesSystem, self).__init__(
|
| - templates, database, emitters, output_dir)
|
| - self._dart_interface_file_paths = []
|
| -
|
| -
|
| - def InterfaceGenerator(self,
|
| - interface,
|
| - common_prefix,
|
| - super_interface_name,
|
| - source_filter):
|
| - """."""
|
| - interface_name = interface.id
|
| - dart_interface_file_path = self._FilePathForDartInterface(interface_name)
|
| -
|
| - self._dart_interface_file_paths.append(dart_interface_file_path)
|
| -
|
| - dart_interface_code = self._emitters.FileEmitter(dart_interface_file_path)
|
| -
|
| - template_file = 'interface_%s.darttemplate' % interface_name
|
| - template = self._templates.TryLoad(template_file)
|
| - if not template:
|
| - template = self._templates.Load('interface.darttemplate')
|
| -
|
| - return DartInterfaceGenerator(
|
| - interface, dart_interface_code,
|
| - template,
|
| - common_prefix, super_interface_name,
|
| - source_filter)
|
| -
|
| - def ProcessCallback(self, interface, info):
|
| - """Generates a typedef for the callback interface."""
|
| - interface_name = interface.id
|
| - file_path = self._FilePathForDartInterface(interface_name)
|
| - self._ProcessCallback(interface, info, file_path)
|
| -
|
| - def GenerateLibraries(self, lib_dir):
|
| - pass
|
| -
|
| -
|
| - def _FilePathForDartInterface(self, interface_name):
|
| - """Returns the file path of the Dart interface definition."""
|
| - return os.path.join(self._output_dir, 'src', 'interface',
|
| - '%s.dart' % interface_name)
|
| -
|
| -
|
| -# ------------------------------------------------------------------------------
|
| -
|
| -class HtmlInterfacesSystem(System):
|
| -
|
| - def __init__(self, templates, database, emitters, output_dir):
|
| - super(HtmlInterfacesSystem, self).__init__(
|
| - templates, database, emitters, output_dir)
|
| - self._dart_interface_file_paths = []
|
| -
|
| - def InterfaceGenerator(self,
|
| - interface,
|
| - common_prefix,
|
| - super_interface_name,
|
| - source_filter):
|
| - """."""
|
| - interface_name = interface.id
|
| - dart_interface_file_path = self._FilePathForDartInterface(interface_name)
|
| -
|
| - self._dart_interface_file_paths.append(dart_interface_file_path)
|
| -
|
| - dart_interface_code = self._emitters.FileEmitter(dart_interface_file_path)
|
| -
|
| - template_file = 'interface_%s.darttemplate' % interface_name
|
| - template = self._templates.TryLoad(template_file)
|
| - if not template:
|
| - template = self._templates.Load('interface.darttemplate')
|
| -
|
| - return HtmlDartInterfaceGenerator(
|
| - interface, dart_interface_code,
|
| - template,
|
| - common_prefix, super_interface_name,
|
| - source_filter)
|
| -
|
| - def ProcessCallback(self, interface, info):
|
| - """Generates a typedef for the callback interface."""
|
| - interface_name = interface.id
|
| - file_path = self._FilePathForDartInterface(interface_name)
|
| - self._ProcessCallback(interface, info, file_path)
|
| -
|
| - def GenerateLibraries(self, lib_dir):
|
| - pass
|
| -
|
| -
|
| - def _FilePathForDartInterface(self, interface_name):
|
| - """Returns the file path of the Dart interface definition."""
|
| - # TODO(jmesserly): is this the right path
|
| - return os.path.join(self._output_dir, 'html', 'interface',
|
| - '%s.dart' % interface_name)
|
| -
|
| -
|
| # ------------------------------------------------------------------------------
|
|
|
| class DummyImplementationSystem(System):
|
| @@ -1204,270 +700,6 @@ class WrappingImplementationSystem(System):
|
|
|
| # ------------------------------------------------------------------------------
|
|
|
| -class FrogSystem(System):
|
| -
|
| - def __init__(self, templates, database, emitters, output_dir):
|
| - super(FrogSystem, self).__init__(
|
| - templates, database, emitters, output_dir)
|
| - self._dart_frog_file_paths = []
|
| -
|
| - def InterfaceGenerator(self,
|
| - interface,
|
| - common_prefix,
|
| - super_interface_name,
|
| - source_filter):
|
| - """."""
|
| - dart_frog_file_path = self._FilePathForFrogImpl(interface.id)
|
| - self._dart_frog_file_paths.append(dart_frog_file_path)
|
| -
|
| - template_file = 'impl_%s.darttemplate' % interface.id
|
| - template = self._templates.TryLoad(template_file)
|
| - if not template:
|
| - template = self._templates.Load('frog_impl.darttemplate')
|
| -
|
| - dart_code = self._emitters.FileEmitter(dart_frog_file_path)
|
| - return FrogInterfaceGenerator(self, interface, template,
|
| - super_interface_name, dart_code)
|
| -
|
| - def GenerateLibraries(self, lib_dir):
|
| - self._GenerateLibFile(
|
| - 'frog_dom.darttemplate',
|
| - os.path.join(lib_dir, 'dom_frog.dart'),
|
| - (self._interface_system._dart_interface_file_paths +
|
| - self._interface_system._dart_callback_file_paths +
|
| - self._dart_frog_file_paths))
|
| -
|
| - def Finish(self):
|
| - pass
|
| -
|
| - def _FilePathForFrogImpl(self, interface_name):
|
| - """Returns the file path of the Frog implementation."""
|
| - return os.path.join(self._output_dir, 'src', 'frog',
|
| - '%s.dart' % interface_name)
|
| -
|
| -
|
| -# ------------------------------------------------------------------------------
|
| -
|
| -class HtmlFrogSystem(System):
|
| -
|
| - def __init__(self, templates, database, emitters, output_dir):
|
| - super(HtmlFrogSystem, self).__init__(
|
| - templates, database, emitters, output_dir)
|
| - self._dart_frog_file_paths = []
|
| -
|
| - def InterfaceGenerator(self,
|
| - interface,
|
| - common_prefix,
|
| - super_interface_name,
|
| - source_filter):
|
| - """."""
|
| - dart_frog_file_path = self._FilePathForFrogImpl(interface.id)
|
| - self._dart_frog_file_paths.append(dart_frog_file_path)
|
| -
|
| - template_file = 'impl_%s.darttemplate' % interface.id
|
| - template = self._templates.TryLoad(template_file)
|
| - if not template:
|
| - template = self._templates.Load('frog_impl.darttemplate')
|
| -
|
| - dart_code = self._emitters.FileEmitter(dart_frog_file_path)
|
| - return HtmlFrogInterfaceGenerator(self, interface, template,
|
| - super_interface_name, dart_code)
|
| -
|
| - def GenerateLibraries(self, lib_dir):
|
| - self._GenerateLibFile(
|
| - 'html_frog.darttemplate',
|
| - os.path.join(lib_dir, 'html_frog.dart'),
|
| - (self._interface_system._dart_interface_file_paths +
|
| - self._interface_system._dart_callback_file_paths +
|
| - self._dart_frog_file_paths))
|
| -
|
| - def Finish(self):
|
| - pass
|
| -
|
| - def _FilePathForFrogImpl(self, interface_name):
|
| - """Returns the file path of the Frog implementation."""
|
| - # TODO(jmesserly): is this the right path
|
| - return os.path.join(self._output_dir, 'html', 'frog',
|
| - '%s.dart' % interface_name)
|
| -
|
| -# ------------------------------------------------------------------------------
|
| -
|
| -class DartInterfaceGenerator(object):
|
| - """Generates Dart Interface definition for one DOM IDL interface."""
|
| -
|
| - def __init__(self, interface, emitter, template,
|
| - common_prefix, super_interface, source_filter):
|
| - """Generates Dart code for the given interface.
|
| -
|
| - Args:
|
| - interface -- an IDLInterface instance. It is assumed that all types have
|
| - been converted to Dart types (e.g. int, String), unless they are in the
|
| - same package as the interface.
|
| - common_prefix -- the prefix for the common library, if any.
|
| - super_interface -- the name of the common interface that this interface
|
| - implements, if any.
|
| - source_filter -- if specified, rewrites the names of any superinterfaces
|
| - that are not from these sources to use the common prefix.
|
| - """
|
| - self._interface = interface
|
| - self._emitter = emitter
|
| - self._template = template
|
| - self._common_prefix = common_prefix
|
| - self._super_interface = super_interface
|
| - self._source_filter = source_filter
|
| -
|
| -
|
| - def StartInterface(self):
|
| - if self._super_interface:
|
| - typename = self._super_interface
|
| - else:
|
| - typename = self._interface.id
|
| -
|
| - # TODO(vsm): Add appropriate package / namespace syntax.
|
| - (extends_emitter,
|
| - self._members_emitter,
|
| - self._top_level_emitter) = self._emitter.Emit(
|
| - self._template + '$!TOP_LEVEL',
|
| - ID=typename)
|
| -
|
| - extends = []
|
| - suppressed_extends = []
|
| -
|
| - for parent in self._interface.parents:
|
| - # TODO(vsm): Remove source_filter.
|
| - if _MatchSourceFilter(self._source_filter, parent):
|
| - # Parent is a DOM type.
|
| - extends.append(parent.type.id)
|
| - elif '<' in parent.type.id:
|
| - # Parent is a Dart collection type.
|
| - # TODO(vsm): Make this check more robust.
|
| - extends.append(parent.type.id)
|
| - else:
|
| - suppressed_extends.append('%s.%s' %
|
| - (self._common_prefix, parent.type.id))
|
| -
|
| - comment = ' extends'
|
| - if extends:
|
| - extends_emitter.Emit(' extends $SUPERS', SUPERS=', '.join(extends))
|
| - comment = ','
|
| - if suppressed_extends:
|
| - extends_emitter.Emit(' /*$COMMENT $SUPERS */',
|
| - COMMENT=comment,
|
| - SUPERS=', '.join(suppressed_extends))
|
| -
|
| - if typename in _interface_factories:
|
| - extends_emitter.Emit(' default $F', F=_interface_factories[typename])
|
| -
|
| - element_type = MaybeTypedArrayElementType(self._interface)
|
| - if element_type:
|
| - self._members_emitter.Emit(
|
| - '\n'
|
| - ' $CTOR(int length);\n'
|
| - '\n'
|
| - ' $CTOR.fromList(List<$TYPE> list);\n'
|
| - '\n'
|
| - ' $CTOR.fromBuffer(ArrayBuffer buffer);\n',
|
| - CTOR=self._interface.id,
|
| - TYPE=element_type)
|
| -
|
| -
|
| - def FinishInterface(self):
|
| - # TODO(vsm): Use typedef if / when that is supported in Dart.
|
| - # Define variant as subtype.
|
| - if (self._super_interface and
|
| - self._interface.id is not self._super_interface):
|
| - consts_emitter = self._top_level_emitter.Emit(
|
| - '\n'
|
| - 'interface $NAME extends $BASE {\n'
|
| - '$!CONSTS'
|
| - '}\n',
|
| - NAME=self._interface.id,
|
| - BASE=self._super_interface)
|
| - for const in sorted(self._interface.constants, ConstantOutputOrder):
|
| - self._EmitConstant(consts_emitter, const)
|
| -
|
| - def AddConstant(self, constant):
|
| - if (not self._super_interface or
|
| - self._interface.id is self._super_interface):
|
| - self._EmitConstant(self._members_emitter, constant)
|
| -
|
| - def _EmitConstant(self, emitter, constant):
|
| - emitter.Emit('\n static final $TYPE $NAME = $VALUE;\n',
|
| - NAME=constant.id,
|
| - TYPE=constant.type.id,
|
| - VALUE=constant.value)
|
| -
|
| - def AddAttribute(self, getter, setter):
|
| - if getter and setter and getter.type.id == setter.type.id:
|
| - self._members_emitter.Emit('\n $TYPE $NAME;\n',
|
| - NAME=getter.id, TYPE=getter.type.id);
|
| - return
|
| - if getter and not setter:
|
| - self._members_emitter.Emit('\n final $TYPE $NAME;\n',
|
| - NAME=getter.id, TYPE=getter.type.id);
|
| - return
|
| - raise Exception('Unexpected getter/setter combination %s %s' %
|
| - (getter, setter))
|
| -
|
| - def AddIndexer(self, element_type):
|
| - # Interface inherits all operations from List<element_type>.
|
| - pass
|
| -
|
| - def AddOperation(self, info):
|
| - """
|
| - Arguments:
|
| - operations - contains the overloads, one or more operations with the same
|
| - name.
|
| - """
|
| - self._members_emitter.Emit('\n'
|
| - ' $TYPE $NAME($PARAMS);\n',
|
| - TYPE=info.type_name,
|
| - NAME=info.name,
|
| - PARAMS=info.ParametersInterfaceDeclaration())
|
| -
|
| - # Interfaces get secondary members directly via the superinterfaces.
|
| - def AddSecondaryAttribute(self, interface, getter, setter):
|
| - pass
|
| -
|
| - def AddSecondaryOperation(self, interface, attr):
|
| - pass
|
| -
|
| - def AddEventAttributes(self, event_attrs):
|
| - pass
|
| -
|
| -# Given a sorted sequence of type identifiers, return an appropriate type
|
| -# name
|
| -def TypeName(typeIds, interface):
|
| - # Dynamically type this field for now.
|
| - return 'var'
|
| -
|
| -# ------------------------------------------------------------------------------
|
| -
|
| -# TODO(jmesserly): inheritance is probably not the right way to factor this long
|
| -# term, but it makes merging better for now.
|
| -class HtmlDartInterfaceGenerator(DartInterfaceGenerator):
|
| - """Generates Dart Interface definition for one DOM IDL interface."""
|
| -
|
| - def __init__(self, interface, emitter, template,
|
| - common_prefix, super_interface, source_filter):
|
| - super(HtmlDartInterfaceGenerator, self).__init__(interface,
|
| - emitter, template, common_prefix, super_interface, source_filter)
|
| -
|
| - def AddEventAttributes(self, event_attrs):
|
| - events_interface = self._interface.id + 'Events'
|
| - self._members_emitter.Emit('\n $TYPE get on();\n',
|
| - TYPE=events_interface)
|
| - events_members = self._emitter.Emit(
|
| - '\ninterface $INTERFACE {\n$!MEMBERS}\n',
|
| - INTERFACE=events_interface)
|
| -
|
| - for getter, setter in event_attrs:
|
| - event = getter or setter
|
| - events_members.Emit('\n EventListenerList get $NAME();\n', NAME=event.id)
|
| -
|
| -
|
| -# ------------------------------------------------------------------------------
|
| -
|
| class DummyInterfaceGenerator(object):
|
| """Generates nothing."""
|
|
|
| @@ -1569,7 +801,7 @@ class WrappingInterfaceGenerator(object):
|
| # attributes instead. For now, this hack lets the interfaces
|
| # inherit, but not the classes.
|
| # List methods are injected in AddIndexer.
|
| - if _IsDartListType(supertype) or _IsDartCollectionType(supertype):
|
| + if IsDartListType(supertype) or IsDartCollectionType(supertype):
|
| return 'DOMWrapperBase'
|
|
|
| if supertype == 'EventTarget':
|
| @@ -1961,323 +1193,6 @@ class WrappingInterfaceGenerator(object):
|
| true_code, info, indent + ' ', position + 1, positive)
|
| return True
|
|
|
| -
|
| -# ------------------------------------------------------------------------------
|
| -
|
| -class FrogInterfaceGenerator(object):
|
| - """Generates a Frog class for a DOM IDL interface."""
|
| -
|
| - def __init__(self, system, interface, template, super_interface, dart_code):
|
| - """Generates Dart code for the given interface.
|
| -
|
| - Args:
|
| -
|
| - interface: an IDLInterface instance. It is assumed that all types have
|
| - been converted to Dart types (e.g. int, String), unless they are in
|
| - the same package as the interface.
|
| - template: A string template.
|
| - super_interface: A string or None, the name of the common interface that
|
| - this interface implements, if any.
|
| - dart_code: an Emitter for the file containing the Dart implementation
|
| - class.
|
| - """
|
| - self._system = system
|
| - self._interface = interface
|
| - self._template = template
|
| - self._super_interface = super_interface
|
| - self._dart_code = dart_code
|
| - self._current_secondary_parent = None
|
| -
|
| -
|
| - def StartInterface(self):
|
| - interface = self._interface
|
| - interface_name = interface.id
|
| -
|
| - self._class_name = self._ImplClassName(interface_name)
|
| -
|
| - base = None
|
| - if interface.parents:
|
| - supertype = interface.parents[0].type.id
|
| - if _IsDartCollectionType(supertype):
|
| - # List methods are injected in AddIndexer.
|
| - pass
|
| - else:
|
| - base = self._ImplClassName(supertype)
|
| -
|
| - if interface_name in _frog_dom_custom_native_specs:
|
| - native_spec = _frog_dom_custom_native_specs[interface_name]
|
| - else:
|
| - # Make the class 'hidden' so it is dynamically patched at runtime. This
|
| - # is useful not only for browser compat, but to allow code that links
|
| - # against dart:dom to load in a worker isolate.
|
| - native_spec = '*' + interface_name
|
| -
|
| - if base:
|
| - extends = ' extends ' + base
|
| - elif native_spec[0] == '=':
|
| - # The implementation is a singleton with no prototype.
|
| - extends = ''
|
| - else:
|
| - extends = ' extends _DOMTypeJs'
|
| -
|
| - # TODO: Include all implemented interfaces, including other Lists.
|
| - implements = [interface_name]
|
| - element_type = MaybeTypedArrayElementType(self._interface)
|
| - if element_type:
|
| - implements.append('List<' + element_type + '>')
|
| -
|
| - self._members_emitter = self._dart_code.Emit(
|
| - self._template,
|
| - #class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
|
| - #$!MEMBERS
|
| - #}
|
| - CLASSNAME=self._class_name,
|
| - EXTENDS=extends,
|
| - IMPLEMENTS=' implements ' + ', '.join(implements),
|
| - NATIVESPEC=' native "' + native_spec + '"')
|
| -
|
| - element_type = MaybeTypedArrayElementType(interface)
|
| - if element_type:
|
| - self.AddTypedArrayConstructors(element_type)
|
| -
|
| -
|
| - def FinishInterface(self):
|
| - """."""
|
| - pass
|
| -
|
| - def _ImplClassName(self, type_name):
|
| - return '_' + type_name + 'Js'
|
| -
|
| - def _NarrowToImplementationType(self, type_name):
|
| - # TODO(sra): Move into the 'system' and cache the result.
|
| - if type_name == 'EventListener':
|
| - # Callbacks are typedef functions so don't have a class.
|
| - return type_name
|
| - if self._system._database.HasInterface(type_name):
|
| - interface = self._system._database.GetInterface(type_name)
|
| - if _RecognizeCallback(interface):
|
| - # Callbacks are typedef functions so don't have a class.
|
| - return type_name
|
| - else:
|
| - return self._ImplClassName(type_name)
|
| - return type_name
|
| -
|
| - def _NarrowInputType(self, type_name):
|
| - return self._NarrowToImplementationType(type_name)
|
| -
|
| - def _NarrowOutputType(self, type_name):
|
| - return self._NarrowToImplementationType(type_name)
|
| -
|
| - def AddConstant(self, constant):
|
| - # Since we are currently generating native classes without interfaces,
|
| - # generate the constants as part of the class. This will need to go away
|
| - # if we revert back to generating interfaces.
|
| - self._members_emitter.Emit('\n static final $TYPE $NAME = $VALUE;\n',
|
| - NAME=constant.id,
|
| - TYPE=constant.type.id,
|
| - VALUE=constant.value)
|
| -
|
| - pass
|
| -
|
| - def AddAttribute(self, getter, setter):
|
| - output_type = getter and self._NarrowOutputType(getter.type.id)
|
| - input_type = setter and self._NarrowInputType(setter.type.id)
|
| -
|
| - # If the (getter, setter) pair is shadowing, we can't generate a shadowing
|
| - # field (Issue 1633).
|
| - (super_getter, super_getter_interface) = self._FindShadowedAttribute(getter)
|
| - (super_setter, super_setter_interface) = self._FindShadowedAttribute(setter)
|
| - if super_getter or super_setter:
|
| - if getter and not setter and super_getter and not super_setter:
|
| - if getter.type.id == super_getter.type.id:
|
| - # Compatible getter, use the superclass property. This works because
|
| - # JavaScript will do its own dynamic dispatch.
|
| - self._members_emitter.Emit(
|
| - '\n'
|
| - ' // Use implementation from $SUPER.\n'
|
| - ' // final $TYPE $NAME;\n',
|
| - SUPER=super_getter_interface.id,
|
| - NAME=getter.id, TYPE=output_type)
|
| - return
|
| -
|
| - self._members_emitter.Emit('\n // Shadowing definition.')
|
| - self._AddAttributeUsingProperties(getter, setter)
|
| - return
|
| -
|
| - if getter and setter and input_type == output_type:
|
| - self._members_emitter.Emit(
|
| - '\n $TYPE $NAME;\n',
|
| - NAME=getter.id, TYPE=output_type)
|
| - return
|
| - if getter and not setter:
|
| - self._members_emitter.Emit(
|
| - '\n final $TYPE $NAME;\n',
|
| - NAME=getter.id, TYPE=output_type)
|
| - return
|
| - self._AddAttributeUsingProperties(getter, setter)
|
| -
|
| - def _AddAttributeUsingProperties(self, getter, setter):
|
| - if getter:
|
| - self._AddGetter(getter)
|
| - if setter:
|
| - self._AddSetter(setter)
|
| -
|
| - def _AddGetter(self, attr):
|
| - # TODO(sra): Remove native body when Issue 829 fixed.
|
| - self._members_emitter.Emit(
|
| - '\n $TYPE get $NAME() native "return this.$NAME;";\n',
|
| - NAME=attr.id, TYPE=self._NarrowOutputType(attr.type.id))
|
| -
|
| - def _AddSetter(self, attr):
|
| - # TODO(sra): Remove native body when Issue 829 fixed.
|
| - self._members_emitter.Emit(
|
| - ' void set $NAME($TYPE value) native "this.$NAME = value;";\n',
|
| - NAME=attr.id, TYPE=self._NarrowInputType(attr.type.id))
|
| -
|
| - def _FindShadowedAttribute(self, attr):
|
| - """Returns (attribute, superinterface) or (None, None)."""
|
| - def FindInParent(interface):
|
| - """Returns matching attribute in parent, or None."""
|
| - if interface.parents:
|
| - parent = interface.parents[0]
|
| - if _IsDartCollectionType(parent.type.id):
|
| - return (None, None)
|
| - if self._system._database.HasInterface(parent.type.id):
|
| - parent_interface = self._system._database.GetInterface(parent.type.id)
|
| - attr2 = _FindMatchingAttribute(parent_interface, attr)
|
| - if attr2:
|
| - return (attr2, parent_interface)
|
| - return FindInParent(parent_interface)
|
| - return (None, None)
|
| -
|
| - return FindInParent(self._interface) if attr else (None, None)
|
| -
|
| -
|
| - def AddSecondaryAttribute(self, interface, getter, setter):
|
| - self._SecondaryContext(interface)
|
| - self.AddAttribute(getter, setter)
|
| -
|
| - def AddSecondaryOperation(self, interface, info):
|
| - self._SecondaryContext(interface)
|
| - self.AddOperation(info)
|
| -
|
| - def AddEventAttributes(self, event_attrs):
|
| - pass
|
| -
|
| - def _SecondaryContext(self, interface):
|
| - if interface is not self._current_secondary_parent:
|
| - self._current_secondary_parent = interface
|
| - self._members_emitter.Emit('\n // From $WHERE\n', WHERE=interface.id)
|
| -
|
| - def AddIndexer(self, element_type):
|
| - """Adds all the methods required to complete implementation of List."""
|
| - # We would like to simply inherit the implementation of everything except
|
| - # get length(), [], and maybe []=. It is possible to extend from a base
|
| - # array implementation class only when there is no other implementation
|
| - # inheritance. There might be no implementation inheritance other than
|
| - # DOMBaseWrapper for many classes, but there might be some where the
|
| - # array-ness is introduced by a non-root interface:
|
| - #
|
| - # interface Y extends X, List<T> ...
|
| - #
|
| - # In the non-root case we have to choose between:
|
| - #
|
| - # class YImpl extends XImpl { add List<T> methods; }
|
| - #
|
| - # and
|
| - #
|
| - # class YImpl extends ListBase<T> { copies of transitive XImpl methods; }
|
| - #
|
| - self._members_emitter.Emit(
|
| - '\n'
|
| - ' $TYPE operator[](int index) native "return this[index];";\n',
|
| - TYPE=self._NarrowOutputType(element_type))
|
| -
|
| - if 'CustomIndexedSetter' in self._interface.ext_attrs:
|
| - self._members_emitter.Emit(
|
| - '\n'
|
| - ' void operator[]=(int index, $TYPE value) native "this[index] = value";\n',
|
| - TYPE=self._NarrowInputType(element_type))
|
| - else:
|
| - self._members_emitter.Emit(
|
| - '\n'
|
| - ' void operator[]=(int index, $TYPE value) {\n'
|
| - ' throw new UnsupportedOperationException("Cannot assign element of immutable List.");\n'
|
| - ' }\n',
|
| - TYPE=self._NarrowInputType(element_type))
|
| -
|
| - # TODO(sra): Use separate mixins for mutable implementations of List<T>.
|
| - # TODO(sra): Use separate mixins for typed array implementations of List<T>.
|
| - template_file = 'immutable_list_mixin.darttemplate'
|
| - template = self._system._templates.Load(template_file)
|
| - self._members_emitter.Emit(template, E=element_type)
|
| -
|
| -
|
| - def AddTypedArrayConstructors(self, element_type):
|
| - self._members_emitter.Emit(
|
| - '\n'
|
| - ' factory $CTOR(int length) => _construct_$CTOR(length);\n'
|
| - '\n'
|
| - ' factory $CTOR.fromList(List<$TYPE> list) => _construct_$CTOR(list);\n'
|
| - '\n'
|
| - ' factory $CTOR.fromBuffer(ArrayBuffer buffer) => _construct_$CTOR(buffer);\n'
|
| - '\n'
|
| - ' static _construct_$CTOR(arg) native \'return new $CTOR(arg);\';\n',
|
| - CTOR=self._interface.id,
|
| - TYPE=element_type)
|
| -
|
| -
|
| - def AddOperation(self, info):
|
| - """
|
| - Arguments:
|
| - info: An OperationInfo object.
|
| - """
|
| - # TODO(vsm): Handle overloads.
|
| - self._members_emitter.Emit(
|
| - '\n'
|
| - ' $TYPE $NAME($PARAMS) native;\n',
|
| - TYPE=self._NarrowOutputType(info.type_name),
|
| - NAME=info.name,
|
| - PARAMS=info.ParametersImplementationDeclaration(
|
| - lambda type_name: self._NarrowInputType(type_name)))
|
| -
|
| -
|
| -# ------------------------------------------------------------------------------
|
| -
|
| -# TODO(jmesserly): inheritance is probably not the right way to factor this long
|
| -# term, but it makes merging better for now.
|
| -class HtmlFrogInterfaceGenerator(FrogInterfaceGenerator):
|
| - """Generates a Frog class for the dart:html library from a DOM IDL
|
| - interface.
|
| - """
|
| -
|
| - def __init__(self, system, interface, template, super_interface, dart_code):
|
| - super(HtmlFrogInterfaceGenerator, self).__init__(
|
| - system, interface, template, super_interface, dart_code)
|
| -
|
| - def AddEventAttributes(self, event_attrs):
|
| - events_class = self._interface.id + 'EventsImpl'
|
| - events_interface = self._interface.id + 'Events'
|
| - self._members_emitter.Emit('\n $TYPE get on() =>\n new $TYPE(this);\n',
|
| - TYPE=events_class)
|
| -
|
| - events_members = self._dart_code.Emit(
|
| - '\n'
|
| - 'class $CLASSNAME extends EventsImplementation '
|
| - 'implements $INTERFACE {\n'
|
| - ' $CLASSNAME(_ptr) : super._wrap(_ptr);\n'
|
| - '$!MEMBERS}\n',
|
| - CLASSNAME=events_class,
|
| - INTERFACE=events_interface)
|
| -
|
| - for getter, setter in event_attrs:
|
| - event = getter or setter
|
| - events_members.Emit(
|
| - "\n"
|
| - "EventListenerList get $NAME() => _get('$NAME');\n",
|
| - NAME=event.id)
|
| -
|
| -
|
| # ------------------------------------------------------------------------------
|
|
|
| class IDLTypeInfo(object):
|
|
|