| Index: client/dom/scripts/dartgenerator.py
|
| diff --git a/client/dom/scripts/dartgenerator.py b/client/dom/scripts/dartgenerator.py
|
| index 673310faa71a45aad596c3465bf31e16e6f6c4f0..f46f7029184b9bf28f8eec4c7cc71c32d95f634e 100755
|
| --- a/client/dom/scripts/dartgenerator.py
|
| +++ b/client/dom/scripts/dartgenerator.py
|
| @@ -17,6 +17,8 @@ from systembase import *
|
| from systemfrog import *
|
| from systemhtml import *
|
| from systeminterface import *
|
| +from systemnative import *
|
| +from systemwrapping import *
|
|
|
| _logger = logging.getLogger('dartgenerator')
|
|
|
| @@ -172,7 +174,7 @@ class DartGenerator(object):
|
| # generator. We should migrate other generators to idl registry and
|
| # remove this hack.
|
| if original_type_name != idl_type.id:
|
| - _original_idl_types[idl_type] = original_type_name
|
| + original_idl_types[idl_type] = original_type_name
|
|
|
| def FilterInterfaces(self, database,
|
| and_annotations=[],
|
| @@ -652,62 +654,6 @@ class DummyImplementationSystem(System):
|
|
|
| # ------------------------------------------------------------------------------
|
|
|
| -class WrappingImplementationSystem(System):
|
| -
|
| - def __init__(self, templates, database, emitters, output_dir):
|
| - """Prepared for generating wrapping implementation.
|
| -
|
| - - Creates emitter for JS code.
|
| - - Creates emitter for Dart code.
|
| - """
|
| - super(WrappingImplementationSystem, self).__init__(
|
| - templates, database, emitters, output_dir)
|
| - self._dart_wrapping_file_paths = []
|
| -
|
| -
|
| - def InterfaceGenerator(self,
|
| - interface,
|
| - common_prefix,
|
| - super_interface_name,
|
| - source_filter):
|
| - """."""
|
| - interface_name = interface.id
|
| - dart_wrapping_file_path = self._FilePathForDartWrappingImpl(interface_name)
|
| -
|
| - self._dart_wrapping_file_paths.append(dart_wrapping_file_path)
|
| -
|
| - dart_code = self._emitters.FileEmitter(dart_wrapping_file_path)
|
| - dart_code.Emit(self._templates.Load('wrapping_impl.darttemplate'))
|
| - return WrappingInterfaceGenerator(interface, super_interface_name,
|
| - dart_code,
|
| - self._BaseDefines(interface))
|
| -
|
| - def ProcessCallback(self, interface, info):
|
| - pass
|
| -
|
| - def GenerateLibraries(self, lib_dir):
|
| - # Library generated for implementation.
|
| - self._GenerateLibFile(
|
| - 'wrapping_dom.darttemplate',
|
| - os.path.join(lib_dir, 'wrapping_dom.dart'),
|
| - (self._interface_system._dart_interface_file_paths +
|
| - self._interface_system._dart_callback_file_paths +
|
| - # FIXME: Move the implementation to a separate library.
|
| - self._dart_wrapping_file_paths
|
| - ))
|
| -
|
| -
|
| - def Finish(self):
|
| - pass
|
| -
|
| -
|
| - def _FilePathForDartWrappingImpl(self, interface_name):
|
| - """Returns the file path of the Dart wrapping implementation."""
|
| - return os.path.join(self._output_dir, 'src', 'wrapping',
|
| - '_%sWrappingImplementation.dart' % interface_name)
|
| -
|
| -# ------------------------------------------------------------------------------
|
| -
|
| class DummyInterfaceGenerator(object):
|
| """Generates nothing."""
|
|
|
| @@ -743,1356 +689,3 @@ class DummyInterfaceGenerator(object):
|
|
|
| def AddEventAttributes(self, event_attrs):
|
| pass
|
| -
|
| -# ------------------------------------------------------------------------------
|
| -
|
| -class WrappingInterfaceGenerator(object):
|
| - """Generates Dart and JS implementation for one DOM IDL interface."""
|
| -
|
| - def __init__(self, interface, super_interface, dart_code, base_members):
|
| - """Generates Dart and JS 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.
|
| - 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.
|
| - base_members: a set of names of members defined in a base class. This is
|
| - used to avoid static member 'overriding' in the generated Dart code.
|
| - """
|
| - self._interface = interface
|
| - self._super_interface = super_interface
|
| - self._dart_code = dart_code
|
| - self._base_members = base_members
|
| - self._current_secondary_parent = None
|
| -
|
| -
|
| - def StartInterface(self):
|
| - interface = self._interface
|
| - interface_name = interface.id
|
| -
|
| - self._class_name = self._ImplClassName(interface_name)
|
| -
|
| - base = self._BaseClassName(interface)
|
| -
|
| - (self._members_emitter,
|
| - self._top_level_emitter) = self._dart_code.Emit(
|
| - '\n'
|
| - 'class $CLASS extends $BASE implements $INTERFACE {\n'
|
| - ' $CLASS() : super() {}\n'
|
| - '\n'
|
| - ' static create_$CLASS() native {\n'
|
| - ' return new $CLASS();\n'
|
| - ' }\n'
|
| - '$!MEMBERS'
|
| - '\n'
|
| - ' String get typeName() { return "$INTERFACE"; }\n'
|
| - '}\n'
|
| - '$!TOP_LEVEL',
|
| - CLASS=self._class_name, BASE=base, INTERFACE=interface_name)
|
| -
|
| - def _ImplClassName(self, type_name):
|
| - return '_' + type_name + 'WrappingImplementation'
|
| -
|
| - def _BaseClassName(self, interface):
|
| - if not interface.parents:
|
| - return 'DOMWrapperBase'
|
| -
|
| - supertype = interface.parents[0].type.id
|
| -
|
| - # FIXME: We're currently injecting List<..> and EventTarget as
|
| - # supertypes in dart.idl. We should annotate/preserve as
|
| - # 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):
|
| - return 'DOMWrapperBase'
|
| -
|
| - if supertype == 'EventTarget':
|
| - # Most implementors of EventTarget specify the EventListener operations
|
| - # again. If the operations are not specified, try to inherit from the
|
| - # EventTarget implementation.
|
| - #
|
| - # Applies to MessagePort.
|
| - if not [op for op in interface.operations if op.id == 'addEventListener']:
|
| - return self._ImplClassName(supertype)
|
| - return 'DOMWrapperBase'
|
| -
|
| - return self._ImplClassName(supertype)
|
| -
|
| - def FinishInterface(self):
|
| - """."""
|
| - pass
|
| -
|
| - def AddConstant(self, constant):
|
| - # Constants are already defined on the interface.
|
| - pass
|
| -
|
| - def _MethodName(self, prefix, name):
|
| - method_name = prefix + name
|
| - if name in self._base_members: # Avoid illegal Dart 'static override'.
|
| - method_name = method_name + '_' + self._interface.id
|
| - return method_name
|
| -
|
| - def AddAttribute(self, getter, setter):
|
| - if getter:
|
| - self._AddGetter(getter)
|
| - if setter:
|
| - self._AddSetter(setter)
|
| -
|
| - def _AddGetter(self, attr):
|
| - # FIXME: Instead of injecting the interface name into the method when it is
|
| - # also implemented in the base class, suppress the method altogether if it
|
| - # has the same signature. I.e., let the JS do the virtual dispatch instead.
|
| - method_name = self._MethodName('_get_', attr.id)
|
| - self._members_emitter.Emit(
|
| - '\n'
|
| - ' $TYPE get $NAME() { return $METHOD(this); }\n'
|
| - ' static $TYPE $METHOD(var _this) native;\n',
|
| - NAME=attr.id, TYPE=attr.type.id, METHOD=method_name)
|
| -
|
| - def _AddSetter(self, attr):
|
| - # FIXME: See comment on getter.
|
| - method_name = self._MethodName('_set_', attr.id)
|
| - self._members_emitter.Emit(
|
| - '\n'
|
| - ' void set $NAME($TYPE value) { $METHOD(this, value); }\n'
|
| - ' static void $METHOD(var _this, $TYPE value) native;\n',
|
| - NAME=attr.id, TYPE=attr.type.id, METHOD=method_name)
|
| -
|
| - 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; }
|
| - #
|
| - if self._HasNativeIndexGetter(self._interface):
|
| - self._EmitNativeIndexGetter(self._interface, element_type)
|
| - else:
|
| - self._members_emitter.Emit(
|
| - '\n'
|
| - ' $TYPE operator[](int index) {\n'
|
| - ' return item(index);\n'
|
| - ' }\n',
|
| - TYPE=element_type)
|
| -
|
| - if self._HasNativeIndexSetter(self._interface):
|
| - self._EmitNativeIndexSetter(self._interface, 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=element_type)
|
| -
|
| - self._members_emitter.Emit(
|
| - '\n'
|
| - ' void add($TYPE value) {\n'
|
| - ' throw new UnsupportedOperationException("Cannot add to immutable List.");\n'
|
| - ' }\n'
|
| - '\n'
|
| - ' void addLast($TYPE value) {\n'
|
| - ' throw new UnsupportedOperationException("Cannot add to immutable List.");\n'
|
| - ' }\n'
|
| - '\n'
|
| - ' void addAll(Collection<$TYPE> collection) {\n'
|
| - ' throw new UnsupportedOperationException("Cannot add to immutable List.");\n'
|
| - ' }\n'
|
| - '\n'
|
| - ' void sort(int compare($TYPE a, $TYPE b)) {\n'
|
| - ' throw new UnsupportedOperationException("Cannot sort immutable List.");\n'
|
| - ' }\n'
|
| - '\n'
|
| - ' void copyFrom(List<Object> src, int srcStart, '
|
| - 'int dstStart, int count) {\n'
|
| - ' throw new UnsupportedOperationException("This object is immutable.");\n'
|
| - ' }\n'
|
| - '\n'
|
| - ' int indexOf($TYPE element, [int start = 0]) {\n'
|
| - ' return _Lists.indexOf(this, element, start, this.length);\n'
|
| - ' }\n'
|
| - '\n'
|
| - ' int lastIndexOf($TYPE element, [int start = null]) {\n'
|
| - ' if (start === null) start = length - 1;\n'
|
| - ' return _Lists.lastIndexOf(this, element, start);\n'
|
| - ' }\n'
|
| - '\n'
|
| - ' int clear() {\n'
|
| - ' throw new UnsupportedOperationException("Cannot clear immutable List.");\n'
|
| - ' }\n'
|
| - '\n'
|
| - ' $TYPE removeLast() {\n'
|
| - ' throw new UnsupportedOperationException("Cannot removeLast on immutable List.");\n'
|
| - ' }\n'
|
| - '\n'
|
| - ' $TYPE last() {\n'
|
| - ' return this[length - 1];\n'
|
| - ' }\n'
|
| - '\n'
|
| - ' void forEach(void f($TYPE element)) {\n'
|
| - ' _Collections.forEach(this, f);\n'
|
| - ' }\n'
|
| - '\n'
|
| - ' Collection map(f($TYPE element)) {\n'
|
| - ' return _Collections.map(this, [], f);\n'
|
| - ' }\n'
|
| - '\n'
|
| - ' Collection<$TYPE> filter(bool f($TYPE element)) {\n'
|
| - ' return _Collections.filter(this, new List<$TYPE>(), f);\n'
|
| - ' }\n'
|
| - '\n'
|
| - ' bool every(bool f($TYPE element)) {\n'
|
| - ' return _Collections.every(this, f);\n'
|
| - ' }\n'
|
| - '\n'
|
| - ' bool some(bool f($TYPE element)) {\n'
|
| - ' return _Collections.some(this, f);\n'
|
| - ' }\n'
|
| - '\n'
|
| - ' void setRange(int start, int length, List<$TYPE> from, [int startFrom]) {\n'
|
| - ' throw new UnsupportedOperationException("Cannot setRange on immutable List.");\n'
|
| - ' }\n'
|
| - '\n'
|
| - ' void removeRange(int start, int length) {\n'
|
| - ' throw new UnsupportedOperationException("Cannot removeRange on immutable List.");\n'
|
| - ' }\n'
|
| - '\n'
|
| - ' void insertRange(int start, int length, [$TYPE initialValue]) {\n'
|
| - ' throw new UnsupportedOperationException("Cannot insertRange on immutable List.");\n'
|
| - ' }\n'
|
| - '\n'
|
| - ' List<$TYPE> getRange(int start, int length) {\n'
|
| - ' throw new NotImplementedException();\n'
|
| - ' }\n'
|
| - '\n'
|
| - ' bool isEmpty() {\n'
|
| - ' return length == 0;\n'
|
| - ' }\n'
|
| - '\n'
|
| - ' Iterator<$TYPE> iterator() {\n'
|
| - ' return new _FixedSizeListIterator<$TYPE>(this);\n'
|
| - ' }\n',
|
| - TYPE=element_type)
|
| -
|
| - def _HasNativeIndexGetter(self, interface):
|
| - return ('IndexedGetter' in interface.ext_attrs or
|
| - 'NumericIndexedGetter' in interface.ext_attrs)
|
| -
|
| - def _EmitNativeIndexGetter(self, interface, element_type):
|
| - method_name = '_index'
|
| - self._members_emitter.Emit(
|
| - '\n'
|
| - ' $TYPE operator[](int index) { return $METHOD(this, index); }\n'
|
| - ' static $TYPE $METHOD(var _this, int index) native;\n',
|
| - TYPE=element_type, METHOD=method_name)
|
| -
|
| - def _HasNativeIndexSetter(self, interface):
|
| - return 'CustomIndexedSetter' in interface.ext_attrs
|
| -
|
| - def _EmitNativeIndexSetter(self, interface, element_type):
|
| - method_name = '_set_index'
|
| - self._members_emitter.Emit(
|
| - '\n'
|
| - ' void operator[]=(int index, $TYPE value) {\n'
|
| - ' return $METHOD(this, index, value);\n'
|
| - ' }\n'
|
| - ' static $METHOD(_this, index, value) native;\n',
|
| - TYPE=element_type, METHOD=method_name)
|
| -
|
| - def AddOperation(self, info):
|
| - """
|
| - Arguments:
|
| - info: An OperationInfo object.
|
| - """
|
| - body = self._members_emitter.Emit(
|
| - '\n'
|
| - ' $TYPE $NAME($PARAMS) {\n'
|
| - '$!BODY'
|
| - ' }\n',
|
| - TYPE=info.type_name,
|
| - NAME=info.name,
|
| - PARAMS=info.ParametersImplementationDeclaration())
|
| -
|
| - # Process in order of ascending number of arguments to ensure missing
|
| - # optional arguments are processed early.
|
| - overloads = sorted(info.overloads,
|
| - key=lambda overload: len(overload.arguments))
|
| - self._native_version = 0
|
| - fallthrough = self.GenerateDispatch(body, info, ' ', 0, overloads)
|
| - if fallthrough:
|
| - body.Emit(' throw "Incorrect number or type of arguments";\n');
|
| -
|
| - def GenerateSingleOperation(self, emitter, info, indent, operation):
|
| - """Generates a call to a single operation.
|
| -
|
| - 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.
|
| - operation: the IDLOperation to call.
|
| - """
|
| - # TODO(sra): Do we need to distinguish calling with missing optional
|
| - # arguments from passing 'null' which is represented as 'undefined'?
|
| - def UnwrapArgExpression(name, type):
|
| - # TODO: Type specific unwrapping.
|
| - return '__dom_unwrap(%s)' % (name)
|
| -
|
| - def ArgNameAndUnwrapper(arg_info, overload_arg):
|
| - (name, type, value) = arg_info
|
| - return (name, UnwrapArgExpression(name, type))
|
| -
|
| - names_and_unwrappers = [ArgNameAndUnwrapper(info.arg_infos[i], arg)
|
| - for (i, arg) in enumerate(operation.arguments)]
|
| - unwrap_args = [unwrap_arg for (_, unwrap_arg) in names_and_unwrappers]
|
| - arg_names = [name for (name, _) in names_and_unwrappers]
|
| -
|
| - self._native_version += 1
|
| - native_name = self._MethodName('_', info.name)
|
| - if self._native_version > 1:
|
| - native_name = '%s_%s' % (native_name, self._native_version)
|
| -
|
| - argument_expressions = ', '.join(['this'] + arg_names)
|
| - if info.type_name != 'void':
|
| - emitter.Emit('$(INDENT)return $NATIVENAME($ARGS);\n',
|
| - INDENT=indent,
|
| - NATIVENAME=native_name,
|
| - ARGS=argument_expressions)
|
| - else:
|
| - emitter.Emit('$(INDENT)$NATIVENAME($ARGS);\n'
|
| - '$(INDENT)return;\n',
|
| - INDENT=indent,
|
| - NATIVENAME=native_name,
|
| - ARGS=argument_expressions)
|
| -
|
| - self._members_emitter.Emit(' static $TYPE $NAME($PARAMS) native;\n',
|
| - 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)
|
| -
|
| - if position == len(info.arg_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_name, param_type, param_default) = info.arg_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 = first_overload.arguments[position].type.id
|
| - test = TypeCheck(param_name, type)
|
| - pred = lambda op: len(op.arguments) > position and 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_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
|
| -
|
| -# ------------------------------------------------------------------------------
|
| -
|
| -class IDLTypeInfo(object):
|
| - def __init__(self, idl_type, native_type=None, ref_counted=True,
|
| - has_dart_wrapper=True, conversion_template=None,
|
| - custom_to_dart=False):
|
| - self._idl_type = idl_type
|
| - self._native_type = native_type
|
| - self._ref_counted = ref_counted
|
| - self._has_dart_wrapper = has_dart_wrapper
|
| - self._conversion_template = conversion_template
|
| - self._custom_to_dart = custom_to_dart
|
| -
|
| - def idl_type(self):
|
| - return self._idl_type
|
| -
|
| - def native_type(self):
|
| - if self._native_type:
|
| - return self._native_type
|
| - return self._idl_type
|
| -
|
| - def parameter_adapter_info(self):
|
| - native_type = self.native_type()
|
| - if self._ref_counted:
|
| - native_type = 'RefPtr< %s >' % native_type
|
| - if self._has_dart_wrapper:
|
| - wrapper_type = 'Dart%s' % self.idl_type()
|
| - adapter_type = 'ParameterAdapter<%s, %s>' % (native_type, wrapper_type)
|
| - return (adapter_type, wrapper_type)
|
| - return ('ParameterAdapter< %s >' % native_type, self._idl_type)
|
| -
|
| - def parameter_type(self):
|
| - return '%s*' % self.native_type()
|
| -
|
| - def webcore_include(self):
|
| - if self._idl_type == 'SVGNumber' or self._idl_type == 'SVGPoint':
|
| - return None
|
| - if self._idl_type.startswith('SVGPathSeg'):
|
| - return self._idl_type.replace('Abs', '').replace('Rel', '')
|
| - return self._idl_type
|
| -
|
| - def receiver(self):
|
| - return 'receiver->'
|
| -
|
| - def conversion_include(self):
|
| - return 'Dart%s' % self._idl_type
|
| -
|
| - def conversion_cast(self, expression):
|
| - if self._conversion_template:
|
| - return self._conversion_template % expression
|
| - return expression
|
| -
|
| - def custom_to_dart(self):
|
| - return self._custom_to_dart
|
| -
|
| -class PrimitiveIDLTypeInfo(IDLTypeInfo):
|
| - def __init__(self, idl_type, native_type=None, ref_counted=False,
|
| - conversion_template=None,
|
| - webcore_getter_name='getAttribute',
|
| - webcore_setter_name='setAttribute'):
|
| - super(PrimitiveIDLTypeInfo, self).__init__(idl_type,
|
| - native_type=native_type, ref_counted=ref_counted,
|
| - conversion_template=conversion_template)
|
| - self._webcore_getter_name = webcore_getter_name
|
| - self._webcore_setter_name = webcore_setter_name
|
| -
|
| - def parameter_adapter_info(self):
|
| - native_type = self.native_type()
|
| - if self._ref_counted:
|
| - native_type = 'RefPtr< %s >' % native_type
|
| - return ('ParameterAdapter< %s >' % native_type, None)
|
| -
|
| - def parameter_type(self):
|
| - if self.native_type() == 'String':
|
| - return 'const String&'
|
| - return self.native_type()
|
| -
|
| - def conversion_include(self):
|
| - return None
|
| -
|
| - def webcore_getter_name(self):
|
| - return self._webcore_getter_name
|
| -
|
| - def webcore_setter_name(self):
|
| - return self._webcore_setter_name
|
| -
|
| -class SVGTearOffIDLTypeInfo(IDLTypeInfo):
|
| - def __init__(self, idl_type, native_type='', ref_counted=True):
|
| - super(SVGTearOffIDLTypeInfo, self).__init__(idl_type,
|
| - native_type=native_type,
|
| - ref_counted=ref_counted)
|
| -
|
| - def native_type(self):
|
| - if self._native_type:
|
| - return self._native_type
|
| - tear_off_type = 'SVGPropertyTearOff'
|
| - if self._idl_type.endswith('List'):
|
| - tear_off_type = 'SVGListPropertyTearOff'
|
| - return '%s<%s>' % (tear_off_type, self._idl_type)
|
| -
|
| - def receiver(self):
|
| - if self._idl_type.endswith('List'):
|
| - return 'receiver->'
|
| - return 'receiver->propertyReference().'
|
| -
|
| -
|
| -_idl_type_registry = {
|
| - # There is GC3Dboolean which is not a bool, but unsigned char for OpenGL compatibility.
|
| - 'boolean': PrimitiveIDLTypeInfo('boolean', native_type='bool',
|
| - conversion_template='static_cast<bool>(%s)',
|
| - webcore_getter_name='hasAttribute',
|
| - webcore_setter_name='setBooleanAttribute'),
|
| - # Some IDL's unsigned shorts/shorts are mapped to WebCore C++ enums, so we
|
| - # use a static_cast<int> here not to provide overloads for all enums.
|
| - 'short': PrimitiveIDLTypeInfo('short', native_type='int', conversion_template='static_cast<int>(%s)'),
|
| - 'unsigned short': PrimitiveIDLTypeInfo('unsigned short', native_type='int', conversion_template='static_cast<int>(%s)'),
|
| - 'int': PrimitiveIDLTypeInfo('int'),
|
| - 'unsigned int': PrimitiveIDLTypeInfo('unsigned int', native_type='unsigned'),
|
| - 'long': PrimitiveIDLTypeInfo('long', native_type='int',
|
| - webcore_getter_name='getIntegralAttribute',
|
| - webcore_setter_name='setIntegralAttribute'),
|
| - 'unsigned long': PrimitiveIDLTypeInfo('unsigned long', native_type='unsigned',
|
| - webcore_getter_name='getUnsignedIntegralAttribute',
|
| - webcore_setter_name='setUnsignedIntegralAttribute'),
|
| - 'long long': PrimitiveIDLTypeInfo('long long'),
|
| - 'unsigned long long': PrimitiveIDLTypeInfo('unsigned long long'),
|
| - 'double': PrimitiveIDLTypeInfo('double'),
|
| -
|
| - 'Date': PrimitiveIDLTypeInfo('Date', native_type='double'),
|
| - 'DOMString': PrimitiveIDLTypeInfo('DOMString', native_type='String'),
|
| - 'DOMTimeStamp': PrimitiveIDLTypeInfo('DOMTimeStamp'),
|
| - 'object': PrimitiveIDLTypeInfo('object', native_type='ScriptValue'),
|
| - 'SerializedScriptValue': PrimitiveIDLTypeInfo('SerializedScriptValue', ref_counted=True),
|
| -
|
| - 'DOMException': IDLTypeInfo('DOMCoreException'),
|
| - 'DOMWindow': IDLTypeInfo('DOMWindow', custom_to_dart=True),
|
| - 'Element': IDLTypeInfo('Element', custom_to_dart=True),
|
| - 'EventListener': IDLTypeInfo('EventListener', has_dart_wrapper=False),
|
| - 'EventTarget': IDLTypeInfo('EventTarget', has_dart_wrapper=False),
|
| - 'HTMLElement': IDLTypeInfo('HTMLElement', custom_to_dart=True),
|
| - 'MediaQueryListListener': IDLTypeInfo('MediaQueryListListener', has_dart_wrapper=False),
|
| - 'OptionsObject': IDLTypeInfo('OptionsObject', has_dart_wrapper=False),
|
| - 'SVGElement': IDLTypeInfo('SVGElement', custom_to_dart=True),
|
| -
|
| - 'SVGAngle': SVGTearOffIDLTypeInfo('SVGAngle'),
|
| - 'SVGLength': SVGTearOffIDLTypeInfo('SVGLength'),
|
| - 'SVGLengthList': SVGTearOffIDLTypeInfo('SVGLengthList', ref_counted=False),
|
| - 'SVGMatrix': SVGTearOffIDLTypeInfo('SVGMatrix'),
|
| - 'SVGNumber': SVGTearOffIDLTypeInfo('SVGNumber', native_type='SVGPropertyTearOff<float>'),
|
| - 'SVGNumberList': SVGTearOffIDLTypeInfo('SVGNumberList', ref_counted=False),
|
| - 'SVGPathSegList': SVGTearOffIDLTypeInfo('SVGPathSegList', native_type='SVGPathSegListPropertyTearOff', ref_counted=False),
|
| - 'SVGPoint': SVGTearOffIDLTypeInfo('SVGPoint', native_type='SVGPropertyTearOff<FloatPoint>'),
|
| - 'SVGPointList': SVGTearOffIDLTypeInfo('SVGPointList', ref_counted=False),
|
| - 'SVGPreserveAspectRatio': SVGTearOffIDLTypeInfo('SVGPreserveAspectRatio'),
|
| - 'SVGRect': SVGTearOffIDLTypeInfo('SVGRect', native_type='SVGPropertyTearOff<FloatRect>'),
|
| - 'SVGStringList': SVGTearOffIDLTypeInfo('SVGStringList', native_type='SVGStaticListPropertyTearOff<SVGStringList>', ref_counted=False),
|
| - 'SVGTransform': SVGTearOffIDLTypeInfo('SVGTransform'),
|
| - 'SVGTransformList': SVGTearOffIDLTypeInfo('SVGTransformList', native_type='SVGTransformListPropertyTearOff', ref_counted=False)
|
| -}
|
| -
|
| -_original_idl_types = {
|
| -}
|
| -
|
| -def GetIDLTypeInfo(idl_type):
|
| - idl_type_name = _original_idl_types.get(idl_type, idl_type.id)
|
| - return GetIDLTypeInfoByName(idl_type_name)
|
| -
|
| -def GetIDLTypeInfoByName(idl_type_name):
|
| - return _idl_type_registry.get(idl_type_name, IDLTypeInfo(idl_type_name))
|
| -
|
| -class NativeImplementationSystem(System):
|
| -
|
| - def __init__(self, templates, database, emitters, auxiliary_dir, output_dir):
|
| - super(NativeImplementationSystem, self).__init__(
|
| - templates, database, emitters, output_dir)
|
| -
|
| - self._auxiliary_dir = auxiliary_dir
|
| - self._dom_public_files = []
|
| - self._dom_impl_files = []
|
| - self._cpp_header_files = []
|
| - self._cpp_impl_files = []
|
| -
|
| - def InterfaceGenerator(self,
|
| - interface,
|
| - common_prefix,
|
| - super_interface_name,
|
| - source_filter):
|
| - interface_name = interface.id
|
| -
|
| - dart_interface_path = self._FilePathForDartInterface(interface_name)
|
| - self._dom_public_files.append(dart_interface_path)
|
| -
|
| - pure_interfaces = set([
|
| - 'ElementTimeControl',
|
| - 'ElementTraversal',
|
| - 'MediaQueryListListener',
|
| - 'NodeSelector',
|
| - 'SVGExternalResourcesRequired',
|
| - 'SVGFilterPrimitiveStandardAttributes',
|
| - 'SVGFitToViewBox',
|
| - 'SVGLangSpace',
|
| - 'SVGLocatable',
|
| - 'SVGStylable',
|
| - 'SVGTests',
|
| - 'SVGTransformable',
|
| - 'SVGURIReference',
|
| - 'SVGViewSpec',
|
| - 'SVGZoomAndPan'])
|
| - if interface_name in pure_interfaces:
|
| - return None
|
| -
|
| - dart_impl_path = self._FilePathForDartImplementation(interface_name)
|
| - self._dom_impl_files.append(dart_impl_path)
|
| -
|
| - cpp_header_path = self._FilePathForCppHeader(interface_name)
|
| - self._cpp_header_files.append(cpp_header_path)
|
| -
|
| - cpp_impl_path = self._FilePathForCppImplementation(interface_name)
|
| - self._cpp_impl_files.append(cpp_impl_path)
|
| -
|
| - return NativeImplementationGenerator(interface, super_interface_name,
|
| - self._emitters.FileEmitter(dart_impl_path),
|
| - self._emitters.FileEmitter(cpp_header_path),
|
| - self._emitters.FileEmitter(cpp_impl_path),
|
| - self._BaseDefines(interface),
|
| - self._templates)
|
| -
|
| - def ProcessCallback(self, interface, info):
|
| - self._interface = interface
|
| -
|
| - dart_interface_path = self._FilePathForDartInterface(self._interface.id)
|
| - self._dom_public_files.append(dart_interface_path)
|
| -
|
| - cpp_header_handlers_emitter = emitter.Emitter()
|
| - cpp_impl_handlers_emitter = emitter.Emitter()
|
| - class_name = 'Dart%s' % self._interface.id
|
| - for operation in interface.operations:
|
| - if operation.type.id == 'void':
|
| - return_type = 'void'
|
| - return_prefix = ''
|
| - else:
|
| - return_type = 'bool'
|
| - return_prefix = 'return '
|
| -
|
| - parameters = []
|
| - arguments = []
|
| - for argument in operation.arguments:
|
| - argument_type_info = GetIDLTypeInfo(argument.type)
|
| - parameters.append('%s %s' % (argument_type_info.parameter_type(),
|
| - argument.id))
|
| - arguments.append(argument.id)
|
| -
|
| - cpp_header_handlers_emitter.Emit(
|
| - '\n'
|
| - ' virtual $TYPE handleEvent($PARAMETERS);\n',
|
| - TYPE=return_type, PARAMETERS=', '.join(parameters))
|
| -
|
| - cpp_impl_handlers_emitter.Emit(
|
| - '\n'
|
| - '$TYPE $CLASS_NAME::handleEvent($PARAMETERS)\n'
|
| - '{\n'
|
| - ' $(RETURN_PREFIX)m_callback.handleEvent($ARGUMENTS);\n'
|
| - '}\n',
|
| - TYPE=return_type,
|
| - CLASS_NAME=class_name,
|
| - PARAMETERS=', '.join(parameters),
|
| - RETURN_PREFIX=return_prefix,
|
| - ARGUMENTS=', '.join(arguments))
|
| -
|
| - cpp_header_path = self._FilePathForCppHeader(self._interface.id)
|
| - cpp_header_emitter = self._emitters.FileEmitter(cpp_header_path)
|
| - cpp_header_emitter.Emit(
|
| - self._templates.Load('cpp_callback_header.template'),
|
| - INTERFACE=self._interface.id,
|
| - HANDLERS=cpp_header_handlers_emitter.Fragments())
|
| -
|
| - cpp_impl_path = self._FilePathForCppImplementation(self._interface.id)
|
| - self._cpp_impl_files.append(cpp_impl_path)
|
| - cpp_impl_emitter = self._emitters.FileEmitter(cpp_impl_path)
|
| - cpp_impl_emitter.Emit(
|
| - self._templates.Load('cpp_callback_implementation.template'),
|
| - INTERFACE=self._interface.id,
|
| - HANDLERS=cpp_impl_handlers_emitter.Fragments())
|
| -
|
| - def GenerateLibraries(self, lib_dir):
|
| - auxiliary_dir = os.path.relpath(self._auxiliary_dir, self._output_dir)
|
| -
|
| - # Generate dom_public.dart.
|
| - self._GenerateLibFile(
|
| - 'dom_public.darttemplate',
|
| - os.path.join(self._output_dir, 'dom_public.dart'),
|
| - self._dom_public_files,
|
| - AUXILIARY_DIR=auxiliary_dir);
|
| -
|
| - # Generate dom_impl.dart.
|
| - self._GenerateLibFile(
|
| - 'dom_impl.darttemplate',
|
| - os.path.join(self._output_dir, 'dom_impl.dart'),
|
| - self._dom_impl_files,
|
| - AUXILIARY_DIR=auxiliary_dir);
|
| -
|
| - # Generate DartDerivedSourcesAll.cpp.
|
| - cpp_all_in_one_path = os.path.join(self._output_dir,
|
| - 'DartDerivedSourcesAll.cpp')
|
| -
|
| - includes_emitter = emitter.Emitter()
|
| - for f in self._cpp_impl_files:
|
| - path = os.path.relpath(f, os.path.dirname(cpp_all_in_one_path))
|
| - includes_emitter.Emit('#include "$PATH"\n', PATH=path)
|
| -
|
| - cpp_all_in_one_emitter = self._emitters.FileEmitter(cpp_all_in_one_path)
|
| - cpp_all_in_one_emitter.Emit(
|
| - self._templates.Load('cpp_all_in_one.template'),
|
| - INCLUDES=includes_emitter.Fragments())
|
| -
|
| - # Generate DartResolver.cpp.
|
| - cpp_resolver_path = os.path.join(self._output_dir, 'DartResolver.cpp')
|
| -
|
| - includes_emitter = emitter.Emitter()
|
| - resolver_body_emitter = emitter.Emitter()
|
| - for f in self._cpp_header_files:
|
| - path = os.path.relpath(f, os.path.dirname(cpp_resolver_path))
|
| - includes_emitter.Emit('#include "$PATH"\n', PATH=path)
|
| - resolver_body_emitter.Emit(
|
| - ' if (Dart_NativeFunction func = $CLASS_NAME::resolver(name, argumentCount))\n'
|
| - ' return func;\n',
|
| - CLASS_NAME=os.path.splitext(os.path.basename(path))[0])
|
| -
|
| - cpp_resolver_emitter = self._emitters.FileEmitter(cpp_resolver_path)
|
| - cpp_resolver_emitter.Emit(
|
| - self._templates.Load('cpp_resolver.template'),
|
| - INCLUDES=includes_emitter.Fragments(),
|
| - RESOLVER_BODY=resolver_body_emitter.Fragments())
|
| -
|
| - # Generate DartDerivedSourcesAll.cpp
|
| - cpp_all_in_one_path = os.path.join(self._output_dir,
|
| - 'DartDerivedSourcesAll.cpp')
|
| -
|
| - includes_emitter = emitter.Emitter()
|
| - for file in self._cpp_impl_files:
|
| - path = os.path.relpath(file, os.path.dirname(cpp_all_in_one_path))
|
| - includes_emitter.Emit('#include "$PATH"\n', PATH=path)
|
| -
|
| - cpp_all_in_one_emitter = self._emitters.FileEmitter(cpp_all_in_one_path)
|
| - cpp_all_in_one_emitter.Emit(
|
| - self._templates.Load('cpp_all_in_one.template'),
|
| - INCLUDES=includes_emitter.Fragments())
|
| -
|
| - # Generate DartResolver.cpp
|
| - cpp_resolver_path = os.path.join(self._output_dir, 'DartResolver.cpp')
|
| -
|
| - includes_emitter = emitter.Emitter()
|
| - resolver_body_emitter = emitter.Emitter()
|
| - for file in self._cpp_header_files:
|
| - path = os.path.relpath(file, os.path.dirname(cpp_resolver_path))
|
| - includes_emitter.Emit('#include "$PATH"\n', PATH=path)
|
| - resolver_body_emitter.Emit(
|
| - ' if (Dart_NativeFunction func = $CLASS_NAME::resolver(name, argumentCount))\n'
|
| - ' return func;\n',
|
| - CLASS_NAME=os.path.splitext(os.path.basename(path))[0])
|
| -
|
| - cpp_resolver_emitter = self._emitters.FileEmitter(cpp_resolver_path)
|
| - cpp_resolver_emitter.Emit(
|
| - self._templates.Load('cpp_resolver.template'),
|
| - INCLUDES=includes_emitter.Fragments(),
|
| - RESOLVER_BODY=resolver_body_emitter.Fragments())
|
| -
|
| - def Finish(self):
|
| - pass
|
| -
|
| - def _FilePathForDartInterface(self, interface_name):
|
| - return os.path.join(self._output_dir, 'src', 'interface',
|
| - '%s.dart' % interface_name)
|
| -
|
| - def _FilePathForDartImplementation(self, interface_name):
|
| - return os.path.join(self._output_dir, 'dart',
|
| - '%sImplementation.dart' % interface_name)
|
| -
|
| - def _FilePathForCppHeader(self, interface_name):
|
| - return os.path.join(self._output_dir, 'cpp', 'Dart%s.h' % interface_name)
|
| -
|
| - def _FilePathForCppImplementation(self, interface_name):
|
| - return os.path.join(self._output_dir, 'cpp', 'Dart%s.cpp' % interface_name)
|
| -
|
| -
|
| -class NativeImplementationGenerator(WrappingInterfaceGenerator):
|
| - """Generates Dart implementation for one DOM IDL interface."""
|
| -
|
| - def __init__(self, interface, super_interface,
|
| - dart_impl_emitter, cpp_header_emitter, cpp_impl_emitter,
|
| - base_members, templates):
|
| - """Generates Dart and C++ 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.
|
| - super_interface: A string or None, the name of the common interface that
|
| - this interface implements, if any.
|
| - dart_impl_emitter: an Emitter for the file containing the Dart
|
| - implementation class.
|
| - cpp_header_emitter: an Emitter for the file containing the C++ header.
|
| - cpp_impl_emitter: an Emitter for the file containing the C++
|
| - implementation.
|
| - base_members: a set of names of members defined in a base class. This is
|
| - used to avoid static member 'overriding' in the generated Dart code.
|
| - """
|
| - self._interface = interface
|
| - self._super_interface = super_interface
|
| - self._dart_impl_emitter = dart_impl_emitter
|
| - self._cpp_header_emitter = cpp_header_emitter
|
| - self._cpp_impl_emitter = cpp_impl_emitter
|
| - self._base_members = base_members
|
| - self._templates = templates
|
| - self._current_secondary_parent = None
|
| -
|
| - def StartInterface(self):
|
| - self._class_name = self._ImplClassName(self._interface.id)
|
| - self._interface_type_info = GetIDLTypeInfoByName(self._interface.id)
|
| - self._members_emitter = emitter.Emitter()
|
| - self._cpp_declarations_emitter = emitter.Emitter()
|
| - self._cpp_impl_includes = {}
|
| - self._cpp_definitions_emitter = emitter.Emitter()
|
| - self._cpp_resolver_emitter = emitter.Emitter()
|
| -
|
| - # Generate constructor.
|
| - # FIXME: add proper support for non-custom constructors.
|
| - if ('CustomConstructor' in self._interface.ext_attrs or
|
| - 'V8CustomConstructor' in self._interface.ext_attrs or
|
| - self._interface.id in ['FileReader', 'WebKitCSSMatrix', 'XSLTProcessor']):
|
| - self._cpp_resolver_emitter.Emit(
|
| - ' if (name == "$(INTERFACE_NAME)_constructor_Callback")\n'
|
| - ' return Dart$(INTERFACE_NAME)Internal::constructorCallback;\n',
|
| - INTERFACE_NAME=self._interface.id)
|
| - self._cpp_declarations_emitter.Emit(
|
| - '\n'
|
| - 'void constructorCallback(Dart_NativeArguments);\n')
|
| -
|
| - def _ImplClassName(self, interface_name):
|
| - return interface_name + 'Implementation'
|
| -
|
| - def FinishInterface(self):
|
| - base = self._BaseClassName(self._interface)
|
| - self._dart_impl_emitter.Emit(
|
| - self._templates.Load('dart_implementation.darttemplate'),
|
| - CLASS=self._class_name, BASE=base, INTERFACE=self._interface.id,
|
| - MEMBERS=self._members_emitter.Fragments())
|
| -
|
| - self._GenerateCppHeader()
|
| -
|
| - self._cpp_impl_emitter.Emit(
|
| - self._templates.Load('cpp_implementation.template'),
|
| - INTERFACE=self._interface.id,
|
| - INCLUDES=''.join(['#include "%s.h"\n' %
|
| - k for k in self._cpp_impl_includes.keys()]),
|
| - CALLBACKS=self._cpp_definitions_emitter.Fragments(),
|
| - RESOLVER=self._cpp_resolver_emitter.Fragments())
|
| -
|
| - def _GenerateCppHeader(self):
|
| - webcore_include = self._interface_type_info.webcore_include()
|
| - if webcore_include:
|
| - webcore_include = '#include "%s.h"\n' % webcore_include
|
| - else:
|
| - webcore_include = ''
|
| -
|
| - if ('CustomToJS' in self._interface.ext_attrs or
|
| - 'CustomToJSObject' in self._interface.ext_attrs or
|
| - 'PureInterface' in self._interface.ext_attrs or
|
| - 'CPPPureInterface' in self._interface.ext_attrs or
|
| - self._interface_type_info.custom_to_dart()):
|
| - to_dart_value_template = (
|
| - 'Dart_Handle toDartValue($(WEBCORE_CLASS_NAME)* value);\n')
|
| - else:
|
| - to_dart_value_template = (
|
| - 'inline Dart_Handle toDartValue($(WEBCORE_CLASS_NAME)* value)\n'
|
| - '{\n'
|
| - ' return DartDOMWrapper::toDart<Dart$(INTERFACE)>(value);\n'
|
| - '}\n')
|
| - to_dart_value_emitter = emitter.Emitter()
|
| - to_dart_value_emitter.Emit(
|
| - to_dart_value_template,
|
| - INTERFACE=self._interface.id,
|
| - WEBCORE_CLASS_NAME=self._interface_type_info.native_type())
|
| -
|
| - self._cpp_header_emitter.Emit(
|
| - self._templates.Load('cpp_header.template'),
|
| - INTERFACE=self._interface.id,
|
| - WEBCORE_INCLUDE=webcore_include,
|
| - ADDITIONAL_INCLUDES='',
|
| - WEBCORE_CLASS_NAME=self._interface_type_info.native_type(),
|
| - TO_DART_VALUE=to_dart_value_emitter.Fragments(),
|
| - DECLARATIONS=self._cpp_declarations_emitter.Fragments())
|
| -
|
| - def AddAttribute(self, getter, setter):
|
| - # FIXME: Dartium does not support attribute event listeners. However, JS
|
| - # implementation falls back to them when addEventListener is not available.
|
| - # Make sure addEventListener is available in all EventTargets and remove
|
| - # this check.
|
| - if (getter or setter).type.id == 'EventListener':
|
| - return
|
| -
|
| - # FIXME: support 'ImplementedBy'.
|
| - if 'ImplementedBy' in (getter or setter).ext_attrs:
|
| - return
|
| -
|
| - # FIXME: these should go away.
|
| - classes_with_unsupported_custom_getters = [
|
| - 'Clipboard', 'Console', 'Coordinates', 'DeviceMotionEvent',
|
| - 'DeviceOrientationEvent', 'FileReader', 'JavaScriptCallFrame',
|
| - 'HTMLInputElement', 'HTMLOptionsCollection', 'HTMLOutputElement',
|
| - 'ScriptProfileNode', 'WebKitAnimation']
|
| - if (self._interface.id in classes_with_unsupported_custom_getters and
|
| - getter and set(['Custom', 'CustomGetter']) & set(getter.ext_attrs)):
|
| - return
|
| -
|
| - if getter:
|
| - self._AddGetter(getter)
|
| - if setter:
|
| - self._AddSetter(setter)
|
| -
|
| - def _AddGetter(self, attr):
|
| - dart_declaration = '%s get %s()' % (attr.type.id, attr.id)
|
| - is_custom = 'Custom' in attr.ext_attrs or 'CustomGetter' in attr.ext_attrs
|
| - cpp_callback_name = self._GenerateNativeBinding(attr.id, 1,
|
| - dart_declaration, 'Getter', is_custom)
|
| - if is_custom:
|
| - return
|
| -
|
| - arguments = []
|
| - if 'Reflect' in attr.ext_attrs:
|
| - webcore_function_name = GetIDLTypeInfo(attr.type).webcore_getter_name()
|
| - if 'URL' in attr.ext_attrs:
|
| - if 'NonEmpty' in attr.ext_attrs:
|
| - webcore_function_name = 'getNonEmptyURLAttribute'
|
| - else:
|
| - webcore_function_name = 'getURLAttribute'
|
| - arguments.append(self._GenerateWebCoreReflectionAttributeName(attr))
|
| - else:
|
| - if attr.id == 'operator':
|
| - webcore_function_name = '_operator'
|
| - elif attr.id == 'target' and attr.type.id == 'SVGAnimatedString':
|
| - webcore_function_name = 'svgTarget'
|
| - else:
|
| - webcore_function_name = re.sub(r'^(HTML|URL|JS|XML|XSLT|\w)',
|
| - lambda s: s.group(1).lower(),
|
| - attr.id)
|
| - webcore_function_name = re.sub(r'^(create|exclusive)',
|
| - lambda s: 'is' + s.group(1).capitalize(),
|
| - webcore_function_name)
|
| - if attr.type.id.startswith('SVGAnimated'):
|
| - webcore_function_name += 'Animated'
|
| -
|
| - self._GenerateNativeCallback(cpp_callback_name, attr, '',
|
| - webcore_function_name, arguments, idl_return_type=attr.type,
|
| - raises_dart_exceptions=attr.get_raises,
|
| - raises_dom_exceptions=attr.get_raises)
|
| -
|
| - def _AddSetter(self, attr):
|
| - dart_declaration = 'void set %s(%s)' % (attr.id, attr.type.id)
|
| - is_custom = set(['Custom', 'CustomSetter', 'V8CustomSetter']) & set(attr.ext_attrs)
|
| - cpp_callback_name = self._GenerateNativeBinding(attr.id, 2,
|
| - dart_declaration, 'Setter', is_custom)
|
| - if is_custom:
|
| - return
|
| -
|
| - arguments = []
|
| - if 'Reflect' in attr.ext_attrs:
|
| - webcore_function_name = GetIDLTypeInfo(attr.type).webcore_setter_name()
|
| - arguments.append(self._GenerateWebCoreReflectionAttributeName(attr))
|
| - else:
|
| - webcore_function_name = re.sub(r'^(xml(?=[A-Z])|\w)',
|
| - lambda s: s.group(1).upper(),
|
| - attr.id)
|
| - webcore_function_name = 'set%s' % webcore_function_name
|
| - if attr.type.id.startswith('SVGAnimated'):
|
| - webcore_function_name += 'Animated'
|
| -
|
| - arguments.append(attr.id)
|
| - parameter_definitions_emitter = emitter.Emitter()
|
| - self._GenerateParameterAdapter(parameter_definitions_emitter, attr, 0)
|
| - parameter_definitions = parameter_definitions_emitter.Fragments()
|
| - self._GenerateNativeCallback(cpp_callback_name, attr, parameter_definitions,
|
| - webcore_function_name, arguments, idl_return_type=None,
|
| - raises_dart_exceptions=True,
|
| - raises_dom_exceptions=attr.set_raises)
|
| -
|
| - def _HasNativeIndexGetter(self, interface):
|
| - return ('CustomIndexedGetter' in interface.ext_attrs or
|
| - 'NumericIndexedGetter' in interface.ext_attrs)
|
| -
|
| - def _EmitNativeIndexGetter(self, interface, element_type):
|
| - dart_declaration = '%s operator[](int index)' % element_type
|
| - self._GenerateNativeBinding('numericIndexGetter', 2, dart_declaration,
|
| - 'Callback', True)
|
| -
|
| - def _EmitNativeIndexSetter(self, interface, element_type):
|
| - dart_declaration = 'void operator[]=(int index, %s value)' % element_type
|
| - self._GenerateNativeBinding('numericIndexSetter', 3, dart_declaration,
|
| - 'Callback', True)
|
| -
|
| - def AddOperation(self, info):
|
| - """
|
| - Arguments:
|
| - info: An OperationInfo object.
|
| - """
|
| -
|
| - if 'Custom' in info.overloads[0].ext_attrs:
|
| - parameters = info.ParametersImplementationDeclaration()
|
| - dart_declaration = '%s %s(%s)' % (info.type_name, info.name, parameters)
|
| - argument_count = 1 + len(info.arg_infos)
|
| - self._GenerateNativeBinding(info.name, argument_count, dart_declaration,
|
| - 'Callback', True)
|
| - return
|
| -
|
| - body = self._members_emitter.Emit(
|
| - '\n'
|
| - ' $TYPE $NAME($PARAMETERS) {\n'
|
| - '$!BODY'
|
| - ' }\n',
|
| - TYPE=info.type_name,
|
| - NAME=info.name,
|
| - PARAMETERS=info.ParametersImplementationDeclaration())
|
| -
|
| - # Process in order of ascending number of arguments to ensure missing
|
| - # optional arguments are processed early.
|
| - overloads = sorted(info.overloads,
|
| - key=lambda overload: len(overload.arguments))
|
| - self._native_version = 0
|
| - fallthrough = self.GenerateDispatch(body, info, ' ', 0, overloads)
|
| - if fallthrough:
|
| - body.Emit(' throw "Incorrect number or type of arguments";\n');
|
| -
|
| - def GenerateSingleOperation(self, dispatch_emitter, info, indent, operation):
|
| - """Generates a call to a single operation.
|
| -
|
| - Arguments:
|
| - dispatch_emitter: an dispatch_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.
|
| - operation: the IDLOperation to call.
|
| - """
|
| -
|
| - # FIXME: support ImplementedBy callbacks.
|
| - if 'ImplementedBy' in operation.ext_attrs:
|
| - return
|
| -
|
| - for op in self._interface.operations:
|
| - if op.id != operation.id or len(op.arguments) <= len(operation.arguments):
|
| - continue
|
| - next_argument = op.arguments[len(operation.arguments)]
|
| - if next_argument.is_optional and 'Callback' in next_argument.ext_attrs:
|
| - # FIXME: '[Optional, Callback]' arguments could be non-optional in
|
| - # webcore. We need to fix overloads handling to generate native
|
| - # callbacks properly.
|
| - return
|
| -
|
| - self._native_version += 1
|
| - native_name = info.name
|
| - if self._native_version > 1:
|
| - native_name = '%s_%s' % (native_name, self._native_version)
|
| - argument_list = ', '.join([info.arg_infos[i][0]
|
| - for (i, arg) in enumerate(operation.arguments)])
|
| -
|
| - # Generate dispatcher.
|
| - if info.type_name != 'void':
|
| - dispatch_emitter.Emit('$(INDENT)return _$NATIVENAME($ARGS);\n',
|
| - INDENT=indent,
|
| - NATIVENAME=native_name,
|
| - ARGS=argument_list)
|
| - else:
|
| - dispatch_emitter.Emit('$(INDENT)_$NATIVENAME($ARGS);\n'
|
| - '$(INDENT)return;\n',
|
| - INDENT=indent,
|
| - NATIVENAME=native_name,
|
| - ARGS=argument_list)
|
| - # Generate binding.
|
| - dart_declaration = '%s _%s(%s)' % (info.type_name, native_name,
|
| - argument_list)
|
| - is_custom = 'Custom' in operation.ext_attrs
|
| - cpp_callback_name = self._GenerateNativeBinding(
|
| - native_name, 1 + len(operation.arguments), dart_declaration, 'Callback',
|
| - is_custom)
|
| - if is_custom:
|
| - return
|
| -
|
| - # Generate callback.
|
| - webcore_function_name = operation.id
|
| - if 'ImplementedAs' in operation.ext_attrs:
|
| - webcore_function_name = operation.ext_attrs['ImplementedAs']
|
| -
|
| - parameter_definitions_emitter = emitter.Emitter()
|
| - raises_dart_exceptions = len(operation.arguments) > 0 or operation.raises
|
| - arguments = []
|
| -
|
| - # Process 'CallWith' argument.
|
| - if 'CallWith' in operation.ext_attrs:
|
| - call_with = operation.ext_attrs['CallWith']
|
| - if call_with == 'ScriptExecutionContext':
|
| - parameter_definitions_emitter.Emit(
|
| - ' ScriptExecutionContext* context = DartUtilities::scriptExecutionContext();\n'
|
| - ' if (!context)\n'
|
| - ' return;\n')
|
| - arguments.append('context')
|
| - elif call_with == 'ScriptArguments|CallStack':
|
| - raises_dart_exceptions = True
|
| - self._cpp_impl_includes['ScriptArguments'] = 1
|
| - self._cpp_impl_includes['ScriptCallStack'] = 1
|
| - self._cpp_impl_includes['V8Proxy'] = 1
|
| - self._cpp_impl_includes['v8'] = 1
|
| - parameter_definitions_emitter.Emit(
|
| - ' v8::HandleScope handleScope;\n'
|
| - ' v8::Context::Scope scope(V8Proxy::mainWorldContext(DartUtilities::domWindowForCurrentIsolate()->frame()));\n'
|
| - ' Dart_Handle customArgument = Dart_GetNativeArgument(args, $INDEX);\n'
|
| - ' RefPtr<ScriptArguments> scriptArguments(DartUtilities::createScriptArguments(customArgument, exception));\n'
|
| - ' if (!scriptArguments)\n'
|
| - ' goto fail;\n'
|
| - ' RefPtr<ScriptCallStack> scriptCallStack(DartUtilities::createScriptCallStack());\n'
|
| - ' if (!scriptCallStack->size())\n'
|
| - ' return;\n',
|
| - INDEX=len(operation.arguments))
|
| - arguments.extend(['scriptArguments', 'scriptCallStack'])
|
| -
|
| - # Process Dart arguments.
|
| - for (i, argument) in enumerate(operation.arguments):
|
| - if i == len(operation.arguments) - 1 and self._interface.id == 'Console' and argument.id == 'arg':
|
| - # FIXME: we are skipping last argument here because it was added in
|
| - # supplemental dart.idl. Cleanup dart.idl and remove this check.
|
| - break
|
| - self._GenerateParameterAdapter(parameter_definitions_emitter, argument, i)
|
| - arguments.append(argument.id)
|
| -
|
| - if operation.id in ['addEventListener', 'removeEventListener']:
|
| - # addEventListener's and removeEventListener's last argument is marked
|
| - # as optional in idl, but is not optional in webcore implementation.
|
| - if len(operation.arguments) == 2:
|
| - arguments.append('false')
|
| -
|
| - if self._interface.id == 'CSSStyleDeclaration' and operation.id == 'setProperty':
|
| - # CSSStyleDeclaration.setProperty priority parameter is optional in Dart
|
| - # idl, but is not optional in webcore implementation.
|
| - if len(operation.arguments) == 2:
|
| - arguments.append('String()')
|
| -
|
| - if 'NeedsUserGestureCheck' in operation.ext_attrs:
|
| - arguments.extend('DartUtilities::processingUserGesture')
|
| -
|
| - parameter_definitions = parameter_definitions_emitter.Fragments()
|
| - self._GenerateNativeCallback(cpp_callback_name, operation,
|
| - parameter_definitions, webcore_function_name, arguments,
|
| - idl_return_type=operation.type,
|
| - raises_dart_exceptions=raises_dart_exceptions,
|
| - raises_dom_exceptions=operation.raises)
|
| -
|
| - def _GenerateNativeCallback(self, callback_name, idl_node,
|
| - parameter_definitions, function_name, arguments, idl_return_type,
|
| - raises_dart_exceptions, raises_dom_exceptions):
|
| - receiver = self._interface_type_info.receiver()
|
| - if raises_dom_exceptions:
|
| - arguments.append('ec')
|
| - callback = '%s%s(%s)' % (receiver, function_name, ', '.join(arguments))
|
| -
|
| - nested_templates = []
|
| - if idl_return_type and idl_return_type.id != 'void':
|
| - return_type_info = GetIDLTypeInfo(idl_return_type)
|
| - conversion_cast = return_type_info.conversion_cast('$BODY')
|
| - if isinstance(return_type_info, SVGTearOffIDLTypeInfo):
|
| - svg_primitive_types = ['SVGAngle', 'SVGLength', 'SVGMatrix',
|
| - 'SVGNumber', 'SVGPoint', 'SVGRect', 'SVGTransform']
|
| - conversion_cast = '%s::create($BODY)'
|
| - if self._interface.id.startswith('SVGAnimated'):
|
| - conversion_cast = 'static_cast<%s*>($BODY)'
|
| - elif return_type_info.idl_type() == 'SVGStringList':
|
| - conversion_cast = '%s::create(receiver, $BODY)'
|
| - elif self._interface.id.endswith('List'):
|
| - conversion_cast = 'static_cast<%s*>($BODY.get())'
|
| - elif return_type_info.idl_type() in svg_primitive_types:
|
| - conversion_cast = '%s::create($BODY)'
|
| - else:
|
| - conversion_cast = 'static_cast<%s*>($BODY)'
|
| - conversion_cast = conversion_cast % return_type_info.native_type()
|
| - nested_templates.append(conversion_cast)
|
| -
|
| - if return_type_info.conversion_include():
|
| - self._cpp_impl_includes[return_type_info.conversion_include()] = 1
|
| - if (return_type_info.idl_type() in ['DOMString', 'AtomicString'] and
|
| - 'TreatReturnedNullStringAs' in idl_node.ext_attrs):
|
| - nested_templates.append('$BODY, ConvertDefaultToNull')
|
| - nested_templates.append(
|
| - ' Dart_Handle returnValue = toDartValue($BODY);\n'
|
| - ' if (returnValue)\n'
|
| - ' Dart_SetReturnValue(args, returnValue);\n')
|
| - else:
|
| - nested_templates.append(' $BODY;\n')
|
| -
|
| - if raises_dom_exceptions:
|
| - nested_templates.append(
|
| - ' ExceptionCode ec = 0;\n'
|
| - '$BODY'
|
| - ' if (UNLIKELY(ec)) {\n'
|
| - ' exception = DartDOMWrapper::exceptionCodeToDartException(ec);\n'
|
| - ' goto fail;\n'
|
| - ' }\n')
|
| -
|
| - nested_templates.append(
|
| - ' {\n'
|
| - ' $WEBCORE_CLASS_NAME* receiver = DartDOMWrapper::receiver< $WEBCORE_CLASS_NAME >(args);\n'
|
| - '$PARAMETER_DEFINITIONS'
|
| - '\n'
|
| - '$BODY'
|
| - ' return;\n'
|
| - ' }\n')
|
| -
|
| - if raises_dart_exceptions:
|
| - nested_templates.append(
|
| - ' Dart_Handle exception;\n'
|
| - '$BODY'
|
| - '\n'
|
| - 'fail:\n'
|
| - ' Dart_ThrowException(exception);\n'
|
| - ' ASSERT_NOT_REACHED();\n')
|
| -
|
| - nested_templates.append(
|
| - '\n'
|
| - 'static void $CALLBACK_NAME(Dart_NativeArguments args)\n'
|
| - '{\n'
|
| - ' DartApiScope dartApiScope;\n'
|
| - '$BODY'
|
| - '}\n')
|
| -
|
| - template_parameters = {
|
| - 'CALLBACK_NAME': callback_name,
|
| - 'WEBCORE_CLASS_NAME': self._interface_type_info.native_type(),
|
| - 'PARAMETER_DEFINITIONS': parameter_definitions,
|
| - }
|
| - for template in nested_templates:
|
| - template_parameters['BODY'] = callback
|
| - callback_emitter = emitter.Emitter()
|
| - callback_emitter.Emit(template, **template_parameters)
|
| - callback = ''.join(callback_emitter.Fragments())
|
| -
|
| - self._cpp_definitions_emitter.Emit(callback)
|
| -
|
| - def _GenerateParameterAdapter(self, emitter, idl_argument, index):
|
| - type_info = GetIDLTypeInfo(idl_argument.type)
|
| - (adapter_type, include_name) = type_info.parameter_adapter_info()
|
| - if include_name:
|
| - self._cpp_impl_includes[include_name] = 1
|
| - emitter.Emit(
|
| - '\n'
|
| - ' const $ADAPTER_TYPE $NAME(Dart_GetNativeArgument(args, $INDEX));\n'
|
| - ' if (!$NAME.conversionSuccessful()) {\n'
|
| - ' exception = $NAME.exception();\n'
|
| - ' goto fail;\n'
|
| - ' }\n',
|
| - ADAPTER_TYPE=adapter_type,
|
| - NAME=idl_argument.id,
|
| - INDEX=index + 1)
|
| -
|
| - def _GenerateNativeBinding(self, idl_name, argument_count, dart_declaration,
|
| - native_suffix, is_custom):
|
| - native_binding = '%s_%s_%s' % (self._interface.id, idl_name, native_suffix)
|
| - self._members_emitter.Emit(
|
| - '\n'
|
| - ' $DART_DECLARATION native "$NATIVE_BINDING";\n',
|
| - DART_DECLARATION=dart_declaration, NATIVE_BINDING=native_binding)
|
| -
|
| - cpp_callback_name = '%s%s' % (idl_name, native_suffix)
|
| - self._cpp_resolver_emitter.Emit(
|
| - ' if (argumentCount == $ARGC && name == "$NATIVE_BINDING")\n'
|
| - ' return Dart$(INTERFACE_NAME)Internal::$CPP_CALLBACK_NAME;\n',
|
| - ARGC=argument_count,
|
| - NATIVE_BINDING=native_binding,
|
| - INTERFACE_NAME=self._interface.id,
|
| - CPP_CALLBACK_NAME=cpp_callback_name)
|
| -
|
| - if is_custom:
|
| - self._cpp_declarations_emitter.Emit(
|
| - '\n'
|
| - 'void $CPP_CALLBACK_NAME(Dart_NativeArguments);\n',
|
| - CPP_CALLBACK_NAME=cpp_callback_name)
|
| -
|
| - return cpp_callback_name
|
| -
|
| - def _GenerateWebCoreReflectionAttributeName(self, attr):
|
| - namespace = 'HTMLNames'
|
| - svg_exceptions = ['class', 'id', 'onabort', 'onclick', 'onerror', 'onload',
|
| - 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover',
|
| - 'onmouseup', 'onresize', 'onscroll', 'onunload']
|
| - if self._interface.id.startswith('SVG') and not attr.id in svg_exceptions:
|
| - namespace = 'SVGNames'
|
| - self._cpp_impl_includes[namespace] = 1
|
| -
|
| - attribute_name = attr.ext_attrs['Reflect'] or attr.id.lower()
|
| - return 'WebCore::%s::%sAttr' % (namespace, attribute_name)
|
|
|