mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Support multiple WebIDL interfaces being generated in the same output binding file.
Each interface gets its own module named ${Interface}Binding. Structs, enums, and callbacks continue to use the root module of the binding file. If there is only one interface in the file, we generate reexports for several public APIs and types so that existing DOM implementations don't need any modifications. When multiple interfaces exist, the reexported names get the interface name prepended (eg. FooWrap instead of Wrap). As part of this work, stop glob-importing all DOM types in every generated binding and start generating more targeted lists of relevant types based on the methods, members, etc. of WebIDL types that are in use.
This commit is contained in:
parent
49d483590e
commit
221bc84693
5 changed files with 239 additions and 135 deletions
|
@ -21,6 +21,7 @@ from WebIDL import (
|
||||||
IDLType,
|
IDLType,
|
||||||
IDLInterfaceMember,
|
IDLInterfaceMember,
|
||||||
IDLUndefinedValue,
|
IDLUndefinedValue,
|
||||||
|
IDLWrapperType,
|
||||||
)
|
)
|
||||||
|
|
||||||
from Configuration import (
|
from Configuration import (
|
||||||
|
@ -942,7 +943,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
assert not type.treatNonObjectAsNull() or not type.treatNonCallableAsNull()
|
assert not type.treatNonObjectAsNull() or not type.treatNonCallableAsNull()
|
||||||
|
|
||||||
callback = type.unroll().callback
|
callback = type.unroll().callback
|
||||||
declType = CGGeneric('%s::%s' % (getModuleFromObject(callback), callback.identifier.name))
|
declType = CGGeneric(callback.identifier.name)
|
||||||
finalDeclType = CGTemplatedType("Rc", declType)
|
finalDeclType = CGTemplatedType("Rc", declType)
|
||||||
|
|
||||||
conversion = CGCallbackTempRoot(declType.define())
|
conversion = CGCallbackTempRoot(declType.define())
|
||||||
|
@ -1738,7 +1739,7 @@ class CGImports(CGWrapper):
|
||||||
"""
|
"""
|
||||||
Generates the appropriate import/use statements.
|
Generates the appropriate import/use statements.
|
||||||
"""
|
"""
|
||||||
def __init__(self, child, descriptors, callbacks, imports, config, ignored_warnings=None):
|
def __init__(self, child, descriptors, callbacks, dictionaries, enums, imports, config, ignored_warnings=None):
|
||||||
"""
|
"""
|
||||||
Adds a set of imports.
|
Adds a set of imports.
|
||||||
"""
|
"""
|
||||||
|
@ -1752,17 +1753,19 @@ class CGImports(CGWrapper):
|
||||||
]
|
]
|
||||||
|
|
||||||
def componentTypes(type):
|
def componentTypes(type):
|
||||||
if type.nullable():
|
if type.isType() and type.nullable():
|
||||||
type = type.unroll()
|
type = type.unroll()
|
||||||
if type.isUnion():
|
if type.isUnion():
|
||||||
return type.flatMemberTypes
|
return type.flatMemberTypes
|
||||||
|
if type.isDictionary():
|
||||||
|
return [type] + getTypesFromDictionary(type)
|
||||||
return [type]
|
return [type]
|
||||||
|
|
||||||
def isImportable(type):
|
def isImportable(type):
|
||||||
if not type.isType():
|
if not type.isType():
|
||||||
assert type.isInterface()
|
assert type.isInterface() or type.isDictionary() or type.isEnum()
|
||||||
return not type.isCallback()
|
return True
|
||||||
return type.isNonCallbackInterface() and not type.builtin
|
return not (type.builtin or type.isSequence() or type.isUnion())
|
||||||
|
|
||||||
def relatedTypesForSignatures(method):
|
def relatedTypesForSignatures(method):
|
||||||
types = []
|
types = []
|
||||||
|
@ -1774,13 +1777,27 @@ class CGImports(CGWrapper):
|
||||||
|
|
||||||
def getIdentifier(t):
|
def getIdentifier(t):
|
||||||
if t.isType():
|
if t.isType():
|
||||||
return t.inner.identifier
|
if t.nullable():
|
||||||
assert t.isInterface()
|
t = t.inner
|
||||||
|
if t.isCallback():
|
||||||
|
return t.callback.identifier
|
||||||
|
return t.identifier
|
||||||
|
assert t.isInterface() or t.isDictionary() or t.isEnum()
|
||||||
return t.identifier
|
return t.identifier
|
||||||
|
|
||||||
|
def removeWrapperAndNullableTypes(types):
|
||||||
|
normalized = []
|
||||||
|
for t in types:
|
||||||
|
while (t.isType() and t.nullable()) or isinstance(t, IDLWrapperType):
|
||||||
|
t = t.inner
|
||||||
|
if isImportable(t):
|
||||||
|
normalized += [t]
|
||||||
|
return normalized
|
||||||
|
|
||||||
types = []
|
types = []
|
||||||
for d in descriptors:
|
for d in descriptors:
|
||||||
types += [d.interface]
|
if not d.interface.isCallback():
|
||||||
|
types += [d.interface]
|
||||||
|
|
||||||
members = d.interface.members + d.interface.namedConstructors
|
members = d.interface.members + d.interface.namedConstructors
|
||||||
constructor = d.interface.ctor()
|
constructor = d.interface.ctor()
|
||||||
|
@ -1796,19 +1813,39 @@ class CGImports(CGWrapper):
|
||||||
elif m.isAttr():
|
elif m.isAttr():
|
||||||
types += componentTypes(m.type)
|
types += componentTypes(m.type)
|
||||||
|
|
||||||
|
# Import the type names used in the callbacks that are being defined.
|
||||||
for c in callbacks:
|
for c in callbacks:
|
||||||
types += relatedTypesForSignatures(c)
|
types += relatedTypesForSignatures(c)
|
||||||
|
|
||||||
|
# Import the type names used in the dictionaries that are being defined.
|
||||||
|
for d in dictionaries:
|
||||||
|
types += componentTypes(d)
|
||||||
|
|
||||||
|
# Normalize the types we've collected and remove any ones which can't be imported.
|
||||||
|
types = removeWrapperAndNullableTypes(types)
|
||||||
|
|
||||||
descriptorProvider = config.getDescriptorProvider()
|
descriptorProvider = config.getDescriptorProvider()
|
||||||
|
extras = []
|
||||||
for t in types:
|
for t in types:
|
||||||
if isImportable(t):
|
# Importing these types in the same module that defines them is an error.
|
||||||
|
if t in dictionaries or t in enums:
|
||||||
|
continue
|
||||||
|
if t.isInterface():
|
||||||
descriptor = descriptorProvider.getDescriptor(getIdentifier(t).name)
|
descriptor = descriptorProvider.getDescriptor(getIdentifier(t).name)
|
||||||
imports += ['%s' % descriptor.path]
|
extras += [descriptor.path]
|
||||||
|
if descriptor.interface.parent:
|
||||||
|
parentName = getIdentifier(descriptor.interface.parent).name
|
||||||
|
descriptor = descriptorProvider.getDescriptor(parentName)
|
||||||
|
extras += [descriptor.path, descriptor.bindingPath]
|
||||||
|
else:
|
||||||
|
if t.isEnum():
|
||||||
|
extras += [getModuleFromObject(t) + '::' + getIdentifier(t).name + 'Values']
|
||||||
|
extras += [getModuleFromObject(t) + '::' + getIdentifier(t).name]
|
||||||
|
|
||||||
statements = []
|
statements = []
|
||||||
if len(ignored_warnings) > 0:
|
if len(ignored_warnings) > 0:
|
||||||
statements.append('#![allow(%s)]' % ','.join(ignored_warnings))
|
statements.append('#![allow(%s)]' % ','.join(ignored_warnings))
|
||||||
statements.extend('use %s;' % i for i in sorted(set(imports)))
|
statements.extend('use %s;' % i for i in sorted(set(imports + extras)))
|
||||||
|
|
||||||
CGWrapper.__init__(self, child,
|
CGWrapper.__init__(self, child,
|
||||||
pre='\n'.join(statements) + '\n\n')
|
pre='\n'.join(statements) + '\n\n')
|
||||||
|
@ -2111,7 +2148,7 @@ def UnionTypes(descriptors, dictionaries, callbacks, config):
|
||||||
# Sort unionStructs by key, retrieve value
|
# Sort unionStructs by key, retrieve value
|
||||||
unionStructs = (i[1] for i in sorted(unionStructs.items(), key=operator.itemgetter(0)))
|
unionStructs = (i[1] for i in sorted(unionStructs.items(), key=operator.itemgetter(0)))
|
||||||
|
|
||||||
return CGImports(CGList(unionStructs, "\n\n"), [], [], imports, config, ignored_warnings=[])
|
return CGImports(CGList(unionStructs, "\n\n"), [], [], [], [], imports, config, ignored_warnings=[])
|
||||||
|
|
||||||
|
|
||||||
class Argument():
|
class Argument():
|
||||||
|
@ -2709,7 +2746,7 @@ class CGGetProtoObjectMethod(CGGetPerInterfaceObject):
|
||||||
"""
|
"""
|
||||||
def __init__(self, descriptor):
|
def __init__(self, descriptor):
|
||||||
CGGetPerInterfaceObject.__init__(self, descriptor, "GetProtoObject",
|
CGGetPerInterfaceObject.__init__(self, descriptor, "GetProtoObject",
|
||||||
"PrototypeList::ID", pub=descriptor.hasDescendants())
|
"PrototypeList::ID", pub=True)
|
||||||
|
|
||||||
def definition_body(self):
|
def definition_body(self):
|
||||||
return CGList([
|
return CGList([
|
||||||
|
@ -2727,7 +2764,7 @@ class CGGetConstructorObjectMethod(CGGetPerInterfaceObject):
|
||||||
def __init__(self, descriptor):
|
def __init__(self, descriptor):
|
||||||
CGGetPerInterfaceObject.__init__(self, descriptor, "GetConstructorObject",
|
CGGetPerInterfaceObject.__init__(self, descriptor, "GetConstructorObject",
|
||||||
"PrototypeList::Constructor",
|
"PrototypeList::Constructor",
|
||||||
pub=descriptor.hasDescendants())
|
pub=True)
|
||||||
|
|
||||||
def definition_body(self):
|
def definition_body(self):
|
||||||
return CGList([
|
return CGList([
|
||||||
|
@ -5067,6 +5104,7 @@ class CGInterfaceTrait(CGThing):
|
||||||
post="}")
|
post="}")
|
||||||
else:
|
else:
|
||||||
self.cgRoot = CGGeneric("")
|
self.cgRoot = CGGeneric("")
|
||||||
|
self.empty = not methods
|
||||||
|
|
||||||
def define(self):
|
def define(self):
|
||||||
return self.cgRoot.define()
|
return self.cgRoot.define()
|
||||||
|
@ -5082,18 +5120,135 @@ class CGWeakReferenceableTrait(CGThing):
|
||||||
return self.code
|
return self.code
|
||||||
|
|
||||||
|
|
||||||
|
def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries=None, enums=None):
|
||||||
|
if not callbacks:
|
||||||
|
callbacks = []
|
||||||
|
if not dictionaries:
|
||||||
|
dictionaries = []
|
||||||
|
if not enums:
|
||||||
|
enums = []
|
||||||
|
|
||||||
|
return CGImports(cgthings, descriptors, callbacks, dictionaries, enums, [
|
||||||
|
'js',
|
||||||
|
'js::{JS_CALLEE, JSCLASS_GLOBAL_SLOT_COUNT}',
|
||||||
|
'js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL, JSCLASS_RESERVED_SLOTS_MASK}',
|
||||||
|
'js::error::throw_type_error',
|
||||||
|
'js::jsapi::{JSJitInfo_AliasSet, JSJitInfo_ArgType, AutoIdVector, CallArgs, FreeOp}',
|
||||||
|
'js::jsapi::{JSITER_SYMBOLS, JSPROP_ENUMERATE, JSPROP_PERMANENT, JSPROP_READONLY, JSPROP_SHARED}',
|
||||||
|
'js::jsapi::{JSCLASS_RESERVED_SLOTS_SHIFT, JSITER_HIDDEN, JSITER_OWNONLY}',
|
||||||
|
'js::jsapi::{GetPropertyKeys, Handle}',
|
||||||
|
'js::jsapi::{HandleId, HandleObject, HandleValue, HandleValueArray}',
|
||||||
|
'js::jsapi::{INTERNED_STRING_TO_JSID, IsCallable, JS_CallFunctionValue}',
|
||||||
|
'js::jsapi::{JS_CopyPropertiesFrom, JS_ForwardGetPropertyTo}',
|
||||||
|
'js::jsapi::{JS_GetClass, JS_GetErrorPrototype, JS_GetFunctionPrototype}',
|
||||||
|
'js::jsapi::{JS_GetGlobalForObject, JS_GetObjectPrototype, JS_GetProperty}',
|
||||||
|
'js::jsapi::{JS_GetPropertyById, JS_GetPropertyDescriptorById, JS_GetReservedSlot}',
|
||||||
|
'js::jsapi::{JS_HasProperty, JS_HasPropertyById, JS_InitializePropertiesFromCompatibleNativeObject}',
|
||||||
|
'js::jsapi::{JS_AtomizeAndPinString, JS_NewObject, JS_NewObjectWithGivenProto}',
|
||||||
|
'js::jsapi::{JS_NewObjectWithoutMetadata, JS_SetProperty}',
|
||||||
|
'js::jsapi::{JS_SplicePrototype, JS_SetReservedSlot, JSAutoCompartment}',
|
||||||
|
'js::jsapi::{JSContext, JSClass, JSFreeOp, JSFunctionSpec}',
|
||||||
|
'js::jsapi::{JSJitGetterCallArgs, JSJitInfo, JSJitMethodCallArgs, JSJitSetterCallArgs}',
|
||||||
|
'js::jsapi::{JSNative, JSObject, JSNativeWrapper, JSPropertySpec}',
|
||||||
|
'js::jsapi::{JSString, JSTracer, JSType, JSTypedMethodJitInfo, JSValueType}',
|
||||||
|
'js::jsapi::{ObjectOpResult, JSJitInfo_OpType, MutableHandle, MutableHandleObject}',
|
||||||
|
'js::jsapi::{MutableHandleValue, PropertyDescriptor, RootedObject}',
|
||||||
|
'js::jsapi::{SymbolCode, jsid}',
|
||||||
|
'js::jsval::JSVal',
|
||||||
|
'js::jsval::{ObjectValue, ObjectOrNullValue, PrivateValue}',
|
||||||
|
'js::jsval::{NullValue, UndefinedValue}',
|
||||||
|
'js::glue::{CallJitMethodOp, CallJitGetterOp, CallJitSetterOp, CreateProxyHandler}',
|
||||||
|
'js::glue::{GetProxyPrivate, NewProxyObject, ProxyTraps}',
|
||||||
|
'js::glue::{RUST_JSID_IS_STRING, int_to_jsid}',
|
||||||
|
'js::glue::AppendToAutoIdVector',
|
||||||
|
'js::rust::{GCMethods, define_methods, define_properties}',
|
||||||
|
'dom',
|
||||||
|
'dom::bindings',
|
||||||
|
'dom::bindings::codegen::InterfaceObjectMap',
|
||||||
|
'dom::bindings::global::{GlobalRef, global_root_from_object, global_root_from_reflector}',
|
||||||
|
'dom::bindings::interface::{InterfaceConstructorBehavior, NonCallbackInterfaceObjectClass}',
|
||||||
|
'dom::bindings::interface::{create_callback_interface_object, create_interface_prototype_object}',
|
||||||
|
'dom::bindings::interface::{create_named_constructors, create_noncallback_interface_object}',
|
||||||
|
'dom::bindings::interface::{define_guarded_methods, define_guarded_properties}',
|
||||||
|
'dom::bindings::interface::{ConstantSpec, NonNullJSNative}',
|
||||||
|
'dom::bindings::interface::ConstantVal::{IntVal, UintVal}',
|
||||||
|
'dom::bindings::interface::is_exposed_in',
|
||||||
|
'dom::bindings::js::{JS, Root, RootedReference}',
|
||||||
|
'dom::bindings::js::{OptionalRootedReference}',
|
||||||
|
'dom::bindings::reflector::{Reflectable}',
|
||||||
|
'dom::bindings::utils::{DOMClass, DOMJSClass}',
|
||||||
|
'dom::bindings::utils::{DOM_PROTO_UNFORGEABLE_HOLDER_SLOT, JSCLASS_DOM_GLOBAL}',
|
||||||
|
'dom::bindings::utils::{ProtoOrIfaceArray, create_dom_global}',
|
||||||
|
'dom::bindings::utils::{enumerate_global, finalize_global, find_enum_string_index}',
|
||||||
|
'dom::bindings::utils::{generic_getter, generic_lenient_getter, generic_lenient_setter}',
|
||||||
|
'dom::bindings::utils::{generic_method, generic_setter, get_array_index_from_id}',
|
||||||
|
'dom::bindings::utils::{get_dictionary_property, get_property_on_prototype}',
|
||||||
|
'dom::bindings::utils::{get_proto_or_iface_array, has_property_on_prototype}',
|
||||||
|
'dom::bindings::utils::{is_platform_object, resolve_global, set_dictionary_property, trace_global}',
|
||||||
|
'dom::bindings::trace::{JSTraceable, RootedTraceable}',
|
||||||
|
'dom::bindings::callback::{CallbackContainer,CallbackInterface,CallbackFunction}',
|
||||||
|
'dom::bindings::callback::{CallSetup,ExceptionHandling}',
|
||||||
|
'dom::bindings::callback::wrap_call_this_object',
|
||||||
|
'dom::bindings::conversions::{ConversionBehavior, ConversionResult, DOM_OBJECT_SLOT}',
|
||||||
|
'dom::bindings::conversions::{IDLInterface, is_array_like}',
|
||||||
|
'dom::bindings::conversions::{FromJSValConvertible, StringificationBehavior}',
|
||||||
|
'dom::bindings::conversions::{ToJSValConvertible, jsid_to_str, native_from_handlevalue}',
|
||||||
|
'dom::bindings::conversions::{native_from_object, private_from_object, root_from_object}',
|
||||||
|
'dom::bindings::conversions::{root_from_handleobject, root_from_handlevalue}',
|
||||||
|
'dom::bindings::codegen::{PrototypeList, RegisterBindings, UnionTypes}',
|
||||||
|
'dom::bindings::error::{Fallible, Error, ErrorResult}',
|
||||||
|
'dom::bindings::error::Error::JSFailed',
|
||||||
|
'dom::bindings::error::throw_dom_exception',
|
||||||
|
'dom::bindings::guard::{Condition, Guard}',
|
||||||
|
'dom::bindings::proxyhandler',
|
||||||
|
'dom::bindings::proxyhandler::{ensure_expando_object, fill_property_descriptor}',
|
||||||
|
'dom::bindings::proxyhandler::{get_expando_object, get_property_descriptor}',
|
||||||
|
'dom::bindings::num::Finite',
|
||||||
|
'dom::bindings::str::{ByteString, DOMString, USVString}',
|
||||||
|
'dom::bindings::weakref::{DOM_WEAK_SLOT, WeakBox, WeakReferenceable}',
|
||||||
|
'dom::browsingcontext::BrowsingContext',
|
||||||
|
'mem::heap_size_of_raw_self_and_children',
|
||||||
|
'libc',
|
||||||
|
'util::prefs::PREFS',
|
||||||
|
'script_runtime::{store_panic_result, maybe_take_panic_result}',
|
||||||
|
'std::borrow::ToOwned',
|
||||||
|
'std::cmp',
|
||||||
|
'std::mem',
|
||||||
|
'std::num',
|
||||||
|
'std::os',
|
||||||
|
'std::panic::{self, AssertUnwindSafe}',
|
||||||
|
'std::ptr',
|
||||||
|
'std::str',
|
||||||
|
'std::rc',
|
||||||
|
'std::rc::Rc',
|
||||||
|
'std::default::Default',
|
||||||
|
'std::ffi::CString',
|
||||||
|
], config)
|
||||||
|
|
||||||
|
|
||||||
class CGDescriptor(CGThing):
|
class CGDescriptor(CGThing):
|
||||||
def __init__(self, descriptor):
|
def __init__(self, descriptor, config, soleDescriptor):
|
||||||
CGThing.__init__(self)
|
CGThing.__init__(self)
|
||||||
|
|
||||||
assert not descriptor.concrete or not descriptor.interface.isCallback()
|
assert not descriptor.concrete or not descriptor.interface.isCallback()
|
||||||
|
|
||||||
|
reexports = []
|
||||||
|
|
||||||
|
def reexportedName(name):
|
||||||
|
if name.startswith(descriptor.name):
|
||||||
|
return name
|
||||||
|
if not soleDescriptor:
|
||||||
|
return '%s as %s%s' % (name, descriptor.name, name)
|
||||||
|
return name
|
||||||
|
|
||||||
cgThings = []
|
cgThings = []
|
||||||
if not descriptor.interface.isCallback():
|
if not descriptor.interface.isCallback():
|
||||||
cgThings.append(CGGetProtoObjectMethod(descriptor))
|
cgThings.append(CGGetProtoObjectMethod(descriptor))
|
||||||
|
reexports.append('GetProtoObject')
|
||||||
if (descriptor.interface.hasInterfaceObject() and
|
if (descriptor.interface.hasInterfaceObject() and
|
||||||
descriptor.shouldHaveGetConstructorObjectMethod()):
|
descriptor.shouldHaveGetConstructorObjectMethod()):
|
||||||
cgThings.append(CGGetConstructorObjectMethod(descriptor))
|
cgThings.append(CGGetConstructorObjectMethod(descriptor))
|
||||||
|
reexports.append('GetConstructorObject')
|
||||||
|
|
||||||
unscopableNames = []
|
unscopableNames = []
|
||||||
for m in descriptor.interface.members:
|
for m in descriptor.interface.members:
|
||||||
|
@ -5155,9 +5310,11 @@ class CGDescriptor(CGThing):
|
||||||
cgThings.append(CGNamespace.build([descriptor.name + "Constants"],
|
cgThings.append(CGNamespace.build([descriptor.name + "Constants"],
|
||||||
CGConstant(constMembers),
|
CGConstant(constMembers),
|
||||||
public=True))
|
public=True))
|
||||||
|
reexports.append(descriptor.name + 'Constants')
|
||||||
|
|
||||||
if descriptor.interface.hasInterfaceObject():
|
if descriptor.interface.hasInterfaceObject():
|
||||||
cgThings.append(CGDefineDOMInterfaceMethod(descriptor))
|
cgThings.append(CGDefineDOMInterfaceMethod(descriptor))
|
||||||
|
reexports.append('DefineDOMInterface')
|
||||||
cgThings.append(CGConstructorEnabled(descriptor))
|
cgThings.append(CGConstructorEnabled(descriptor))
|
||||||
|
|
||||||
if descriptor.proxy:
|
if descriptor.proxy:
|
||||||
|
@ -5193,6 +5350,7 @@ class CGDescriptor(CGThing):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
cgThings.append(CGWrapMethod(descriptor))
|
cgThings.append(CGWrapMethod(descriptor))
|
||||||
|
reexports.append('Wrap')
|
||||||
|
|
||||||
haveUnscopables = False
|
haveUnscopables = False
|
||||||
if not descriptor.interface.isCallback():
|
if not descriptor.interface.isCallback():
|
||||||
|
@ -5205,7 +5363,12 @@ class CGDescriptor(CGThing):
|
||||||
CGGeneric("];\n")], "\n"))
|
CGGeneric("];\n")], "\n"))
|
||||||
if descriptor.concrete or descriptor.hasDescendants():
|
if descriptor.concrete or descriptor.hasDescendants():
|
||||||
cgThings.append(CGIDLInterface(descriptor))
|
cgThings.append(CGIDLInterface(descriptor))
|
||||||
cgThings.append(CGInterfaceTrait(descriptor))
|
|
||||||
|
interfaceTrait = CGInterfaceTrait(descriptor)
|
||||||
|
cgThings.append(interfaceTrait)
|
||||||
|
if not interfaceTrait.empty:
|
||||||
|
reexports.append('%sMethods' % descriptor.name)
|
||||||
|
|
||||||
if descriptor.weakReferenceable:
|
if descriptor.weakReferenceable:
|
||||||
cgThings.append(CGWeakReferenceableTrait(descriptor))
|
cgThings.append(CGWeakReferenceableTrait(descriptor))
|
||||||
|
|
||||||
|
@ -5213,11 +5376,13 @@ class CGDescriptor(CGThing):
|
||||||
cgThings.append(CGGeneric(str(properties)))
|
cgThings.append(CGGeneric(str(properties)))
|
||||||
cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties, haveUnscopables))
|
cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties, haveUnscopables))
|
||||||
|
|
||||||
cgThings = CGList(cgThings, "\n")
|
cgThings = generate_imports(config, CGList(cgThings, '\n'), [descriptor])
|
||||||
# self.cgRoot = CGWrapper(CGNamespace(toBindingNamespace(descriptor.name),
|
cgThings = CGWrapper(CGNamespace(toBindingNamespace(descriptor.name),
|
||||||
# cgThings),
|
cgThings, public=True),
|
||||||
# post='\n')
|
post='\n')
|
||||||
self.cgRoot = cgThings
|
reexports = ', '.join(map(lambda name: reexportedName(name), reexports))
|
||||||
|
self.cgRoot = CGList([CGGeneric('pub use self::%sBinding::{%s};' % (descriptor.name, reexports)),
|
||||||
|
cgThings], '\n')
|
||||||
|
|
||||||
def define(self):
|
def define(self):
|
||||||
return self.cgRoot.define()
|
return self.cgRoot.define()
|
||||||
|
@ -5467,8 +5632,8 @@ class CGRegisterProxyHandlersMethod(CGAbstractMethod):
|
||||||
|
|
||||||
def definition_body(self):
|
def definition_body(self):
|
||||||
return CGList([
|
return CGList([
|
||||||
CGGeneric("proxy_handlers[Proxies::%s as usize] = codegen::Bindings::%sBinding::DefineProxyHandler();"
|
CGGeneric("proxy_handlers[Proxies::%s as usize] = Bindings::%s::DefineProxyHandler();"
|
||||||
% (desc.name, desc.name))
|
% (desc.name, '::'.join([desc.name + 'Binding'] * 2)))
|
||||||
for desc in self.descriptors
|
for desc in self.descriptors
|
||||||
], "\n")
|
], "\n")
|
||||||
|
|
||||||
|
@ -5541,7 +5706,7 @@ class CGBindingRoot(CGThing):
|
||||||
for c in mainCallbacks)
|
for c in mainCallbacks)
|
||||||
|
|
||||||
# Do codegen for all the descriptors
|
# Do codegen for all the descriptors
|
||||||
cgthings.extend([CGDescriptor(x) for x in descriptors])
|
cgthings.extend([CGDescriptor(x, config, len(descriptors) == 1) for x in descriptors])
|
||||||
|
|
||||||
# Do codegen for all the callback interfaces.
|
# Do codegen for all the callback interfaces.
|
||||||
cgthings.extend(CGList([CGCallbackInterface(x),
|
cgthings.extend(CGList([CGCallbackInterface(x),
|
||||||
|
@ -5552,102 +5717,8 @@ class CGBindingRoot(CGThing):
|
||||||
curr = CGWrapper(CGList(cgthings, "\n\n"), post="\n\n")
|
curr = CGWrapper(CGList(cgthings, "\n\n"), post="\n\n")
|
||||||
|
|
||||||
# Add imports
|
# Add imports
|
||||||
curr = CGImports(curr, descriptors + callbackDescriptors, mainCallbacks, [
|
curr = generate_imports(config, curr, callbackDescriptors, mainCallbacks,
|
||||||
'js',
|
dictionaries, enums)
|
||||||
'js::{JS_CALLEE, JSCLASS_GLOBAL_SLOT_COUNT}',
|
|
||||||
'js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL, JSCLASS_RESERVED_SLOTS_MASK}',
|
|
||||||
'js::error::throw_type_error',
|
|
||||||
'js::jsapi::{JSJitInfo_AliasSet, JSJitInfo_ArgType, AutoIdVector, CallArgs, FreeOp}',
|
|
||||||
'js::jsapi::{JSITER_SYMBOLS, JSPROP_ENUMERATE, JSPROP_PERMANENT, JSPROP_READONLY, JSPROP_SHARED}',
|
|
||||||
'js::jsapi::{JSCLASS_RESERVED_SLOTS_SHIFT, JSITER_HIDDEN, JSITER_OWNONLY}',
|
|
||||||
'js::jsapi::{GetPropertyKeys, Handle}',
|
|
||||||
'js::jsapi::{HandleId, HandleObject, HandleValue, HandleValueArray}',
|
|
||||||
'js::jsapi::{INTERNED_STRING_TO_JSID, IsCallable, JS_CallFunctionValue}',
|
|
||||||
'js::jsapi::{JS_CopyPropertiesFrom, JS_ForwardGetPropertyTo}',
|
|
||||||
'js::jsapi::{JS_GetClass, JS_GetErrorPrototype, JS_GetFunctionPrototype}',
|
|
||||||
'js::jsapi::{JS_GetGlobalForObject, JS_GetObjectPrototype, JS_GetProperty}',
|
|
||||||
'js::jsapi::{JS_GetPropertyById, JS_GetPropertyDescriptorById, JS_GetReservedSlot}',
|
|
||||||
'js::jsapi::{JS_HasProperty, JS_HasPropertyById, JS_InitializePropertiesFromCompatibleNativeObject}',
|
|
||||||
'js::jsapi::{JS_AtomizeAndPinString, JS_NewObject, JS_NewObjectWithGivenProto}',
|
|
||||||
'js::jsapi::{JS_NewObjectWithoutMetadata, JS_SetProperty}',
|
|
||||||
'js::jsapi::{JS_SplicePrototype, JS_SetReservedSlot, JSAutoCompartment}',
|
|
||||||
'js::jsapi::{JSContext, JSClass, JSFreeOp, JSFunctionSpec}',
|
|
||||||
'js::jsapi::{JSJitGetterCallArgs, JSJitInfo, JSJitMethodCallArgs, JSJitSetterCallArgs}',
|
|
||||||
'js::jsapi::{JSNative, JSObject, JSNativeWrapper, JSPropertySpec}',
|
|
||||||
'js::jsapi::{JSString, JSTracer, JSType, JSTypedMethodJitInfo, JSValueType}',
|
|
||||||
'js::jsapi::{ObjectOpResult, JSJitInfo_OpType, MutableHandle, MutableHandleObject}',
|
|
||||||
'js::jsapi::{MutableHandleValue, PropertyDescriptor, RootedObject}',
|
|
||||||
'js::jsapi::{SymbolCode, jsid}',
|
|
||||||
'js::jsval::JSVal',
|
|
||||||
'js::jsval::{ObjectValue, ObjectOrNullValue, PrivateValue}',
|
|
||||||
'js::jsval::{NullValue, UndefinedValue}',
|
|
||||||
'js::glue::{CallJitMethodOp, CallJitGetterOp, CallJitSetterOp, CreateProxyHandler}',
|
|
||||||
'js::glue::{GetProxyPrivate, NewProxyObject, ProxyTraps}',
|
|
||||||
'js::glue::{RUST_JSID_IS_STRING, int_to_jsid}',
|
|
||||||
'js::glue::AppendToAutoIdVector',
|
|
||||||
'js::rust::{GCMethods, define_methods, define_properties}',
|
|
||||||
'dom::bindings',
|
|
||||||
'dom::bindings::codegen::InterfaceObjectMap',
|
|
||||||
'dom::bindings::global::{GlobalRef, global_root_from_object, global_root_from_reflector}',
|
|
||||||
'dom::bindings::interface::{InterfaceConstructorBehavior, NonCallbackInterfaceObjectClass}',
|
|
||||||
'dom::bindings::interface::{create_callback_interface_object, create_interface_prototype_object}',
|
|
||||||
'dom::bindings::interface::{create_named_constructors, create_noncallback_interface_object}',
|
|
||||||
'dom::bindings::interface::{define_guarded_methods, define_guarded_properties}',
|
|
||||||
'dom::bindings::interface::{ConstantSpec, NonNullJSNative}',
|
|
||||||
'dom::bindings::interface::ConstantVal::{IntVal, UintVal}',
|
|
||||||
'dom::bindings::interface::is_exposed_in',
|
|
||||||
'dom::bindings::js::{JS, Root, RootedReference}',
|
|
||||||
'dom::bindings::js::{OptionalRootedReference}',
|
|
||||||
'dom::bindings::reflector::{Reflectable}',
|
|
||||||
'dom::bindings::utils::{DOMClass, DOMJSClass}',
|
|
||||||
'dom::bindings::utils::{DOM_PROTO_UNFORGEABLE_HOLDER_SLOT, JSCLASS_DOM_GLOBAL}',
|
|
||||||
'dom::bindings::utils::{ProtoOrIfaceArray, create_dom_global}',
|
|
||||||
'dom::bindings::utils::{enumerate_global, finalize_global, find_enum_string_index}',
|
|
||||||
'dom::bindings::utils::{generic_getter, generic_lenient_getter, generic_lenient_setter}',
|
|
||||||
'dom::bindings::utils::{generic_method, generic_setter, get_array_index_from_id}',
|
|
||||||
'dom::bindings::utils::{get_dictionary_property, get_property_on_prototype}',
|
|
||||||
'dom::bindings::utils::{get_proto_or_iface_array, has_property_on_prototype}',
|
|
||||||
'dom::bindings::utils::{is_platform_object, resolve_global, set_dictionary_property, trace_global}',
|
|
||||||
'dom::bindings::trace::{JSTraceable, RootedTraceable}',
|
|
||||||
'dom::bindings::callback::{CallbackContainer,CallbackInterface,CallbackFunction}',
|
|
||||||
'dom::bindings::callback::{CallSetup,ExceptionHandling}',
|
|
||||||
'dom::bindings::callback::wrap_call_this_object',
|
|
||||||
'dom::bindings::conversions::{ConversionBehavior, ConversionResult, DOM_OBJECT_SLOT}',
|
|
||||||
'dom::bindings::conversions::{IDLInterface, is_array_like}',
|
|
||||||
'dom::bindings::conversions::{FromJSValConvertible, StringificationBehavior}',
|
|
||||||
'dom::bindings::conversions::{ToJSValConvertible, jsid_to_str, native_from_handlevalue}',
|
|
||||||
'dom::bindings::conversions::{native_from_object, private_from_object, root_from_object}',
|
|
||||||
'dom::bindings::conversions::{root_from_handleobject, root_from_handlevalue}',
|
|
||||||
'dom::bindings::codegen::{PrototypeList, RegisterBindings, UnionTypes}',
|
|
||||||
'dom::bindings::codegen::Bindings::*',
|
|
||||||
'dom::bindings::error::{Fallible, Error, ErrorResult}',
|
|
||||||
'dom::bindings::error::Error::JSFailed',
|
|
||||||
'dom::bindings::error::throw_dom_exception',
|
|
||||||
'dom::bindings::guard::{Condition, Guard}',
|
|
||||||
'dom::bindings::proxyhandler',
|
|
||||||
'dom::bindings::proxyhandler::{ensure_expando_object, fill_property_descriptor}',
|
|
||||||
'dom::bindings::proxyhandler::{get_expando_object, get_property_descriptor}',
|
|
||||||
'dom::bindings::num::Finite',
|
|
||||||
'dom::bindings::str::{ByteString, DOMString, USVString}',
|
|
||||||
'dom::bindings::weakref::{DOM_WEAK_SLOT, WeakBox, WeakReferenceable}',
|
|
||||||
'dom::browsingcontext::BrowsingContext',
|
|
||||||
'mem::heap_size_of_raw_self_and_children',
|
|
||||||
'libc',
|
|
||||||
'util::prefs::PREFS',
|
|
||||||
'script_runtime::{store_panic_result, maybe_take_panic_result}',
|
|
||||||
'std::borrow::ToOwned',
|
|
||||||
'std::cmp',
|
|
||||||
'std::mem',
|
|
||||||
'std::num',
|
|
||||||
'std::os',
|
|
||||||
'std::panic::{self, AssertUnwindSafe}',
|
|
||||||
'std::ptr',
|
|
||||||
'std::str',
|
|
||||||
'std::rc',
|
|
||||||
'std::rc::Rc',
|
|
||||||
'std::default::Default',
|
|
||||||
'std::ffi::CString',
|
|
||||||
], config)
|
|
||||||
|
|
||||||
# Add the auto-generated comment.
|
# Add the auto-generated comment.
|
||||||
curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
|
curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
|
||||||
|
@ -6285,12 +6356,12 @@ class GlobalGenRoots():
|
||||||
pairs = []
|
pairs = []
|
||||||
for d in config.getDescriptors(hasInterfaceObject=True):
|
for d in config.getDescriptors(hasInterfaceObject=True):
|
||||||
binding = toBindingNamespace(d.name)
|
binding = toBindingNamespace(d.name)
|
||||||
pairs.append((d.name, binding))
|
pairs.append((d.name, binding, binding))
|
||||||
for ctor in d.interface.namedConstructors:
|
for ctor in d.interface.namedConstructors:
|
||||||
pairs.append((ctor.identifier.name, binding))
|
pairs.append((ctor.identifier.name, binding, binding))
|
||||||
pairs.sort(key=operator.itemgetter(0))
|
pairs.sort(key=operator.itemgetter(0))
|
||||||
mappings = [
|
mappings = [
|
||||||
CGGeneric('b"%s" => codegen::Bindings::%s::DefineDOMInterface as unsafe fn(_, _),' % pair)
|
CGGeneric('b"%s" => codegen::Bindings::%s::%s::DefineDOMInterface as unsafe fn(_, _),' % pair)
|
||||||
for pair in pairs
|
for pair in pairs
|
||||||
]
|
]
|
||||||
mapType = "phf::Map<&'static [u8], unsafe fn(*mut JSContext, HandleObject)>"
|
mapType = "phf::Map<&'static [u8], unsafe fn(*mut JSContext, HandleObject)>"
|
||||||
|
@ -6339,8 +6410,8 @@ class GlobalGenRoots():
|
||||||
CGRegisterProxyHandlers(config),
|
CGRegisterProxyHandlers(config),
|
||||||
], "\n")
|
], "\n")
|
||||||
|
|
||||||
return CGImports(code, [], [], [
|
return CGImports(code, [], [], [], [], [
|
||||||
'dom::bindings::codegen',
|
'dom::bindings::codegen::Bindings',
|
||||||
'dom::bindings::codegen::PrototypeList::Proxies',
|
'dom::bindings::codegen::PrototypeList::Proxies',
|
||||||
'libc',
|
'libc',
|
||||||
], config, ignored_warnings=[])
|
], config, ignored_warnings=[])
|
||||||
|
@ -6355,9 +6426,13 @@ class GlobalGenRoots():
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def Bindings(config):
|
def Bindings(config):
|
||||||
|
|
||||||
descriptors = (set(d.name + "Binding" for d in config.getDescriptors(register=True)) |
|
def leafModule(d):
|
||||||
set(getModuleFromObject(d) for d in config.callbacks) |
|
return getModuleFromObject(d).split('::')[-1]
|
||||||
set(getModuleFromObject(d) for d in config.getDictionaries()))
|
|
||||||
|
descriptors = config.getDescriptors(register=True)
|
||||||
|
descriptors = (set(d.name + "Binding" for d in descriptors) |
|
||||||
|
set(leafModule(d) for d in config.callbacks) |
|
||||||
|
set(leafModule(d) for d in config.getDictionaries()))
|
||||||
curr = CGList([CGGeneric("pub mod %s;\n" % name) for name in sorted(descriptors)])
|
curr = CGList([CGGeneric("pub mod %s;\n" % name) for name in sorted(descriptors)])
|
||||||
curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
|
curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
|
||||||
return curr
|
return curr
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from WebIDL import IDLExternalInterface, IDLInterface, WebIDLError
|
from WebIDL import IDLExternalInterface, IDLInterface, IDLWrapperType, WebIDLError
|
||||||
|
|
||||||
|
|
||||||
class Configuration:
|
class Configuration:
|
||||||
|
@ -183,7 +183,8 @@ class Descriptor(DescriptorProvider):
|
||||||
# built-in rooting mechanisms for them.
|
# built-in rooting mechanisms for them.
|
||||||
if self.interface.isCallback():
|
if self.interface.isCallback():
|
||||||
self.needsRooting = False
|
self.needsRooting = False
|
||||||
ty = "%sBinding::%s" % (ifaceName, ifaceName)
|
ty = 'dom::bindings::codegen::Bindings::%sBinding::%s' % (ifaceName, ifaceName)
|
||||||
|
pathDefault = ty
|
||||||
self.returnType = "Rc<%s>" % ty
|
self.returnType = "Rc<%s>" % ty
|
||||||
self.argumentType = "???"
|
self.argumentType = "???"
|
||||||
self.nativeType = ty
|
self.nativeType = ty
|
||||||
|
@ -192,10 +193,12 @@ class Descriptor(DescriptorProvider):
|
||||||
self.returnType = "Root<%s>" % typeName
|
self.returnType = "Root<%s>" % typeName
|
||||||
self.argumentType = "&%s" % typeName
|
self.argumentType = "&%s" % typeName
|
||||||
self.nativeType = "*const %s" % typeName
|
self.nativeType = "*const %s" % typeName
|
||||||
|
pathDefault = 'dom::types::%s' % typeName
|
||||||
|
|
||||||
self.concreteType = typeName
|
self.concreteType = typeName
|
||||||
self.register = desc.get('register', True)
|
self.register = desc.get('register', True)
|
||||||
self.path = desc.get('path', 'dom::types::%s' % typeName)
|
self.path = desc.get('path', pathDefault)
|
||||||
|
self.bindingPath = 'dom::bindings::codegen::Bindings::%s' % ('::'.join([ifaceName + 'Binding'] * 2))
|
||||||
self.outerObjectHook = desc.get('outerObjectHook', 'None')
|
self.outerObjectHook = desc.get('outerObjectHook', 'None')
|
||||||
self.proxy = False
|
self.proxy = False
|
||||||
self.weakReferenceable = desc.get('weakReferenceable', False)
|
self.weakReferenceable = desc.get('weakReferenceable', False)
|
||||||
|
@ -377,7 +380,8 @@ class Descriptor(DescriptorProvider):
|
||||||
|
|
||||||
# Some utility methods
|
# Some utility methods
|
||||||
def getModuleFromObject(object):
|
def getModuleFromObject(object):
|
||||||
return os.path.basename(object.location.filename()).split('.webidl')[0] + 'Binding'
|
return ('dom::bindings::codegen::Bindings::' +
|
||||||
|
os.path.basename(object.location.filename()).split('.webidl')[0] + 'Binding')
|
||||||
|
|
||||||
|
|
||||||
def getTypesFromDescriptor(descriptor):
|
def getTypesFromDescriptor(descriptor):
|
||||||
|
@ -404,6 +408,8 @@ def getTypesFromDictionary(dictionary):
|
||||||
"""
|
"""
|
||||||
Get all member types for this dictionary
|
Get all member types for this dictionary
|
||||||
"""
|
"""
|
||||||
|
if isinstance(dictionary, IDLWrapperType):
|
||||||
|
dictionary = dictionary.inner
|
||||||
types = []
|
types = []
|
||||||
curDict = dictionary
|
curDict = dictionary
|
||||||
while curDict:
|
while curDict:
|
||||||
|
|
|
@ -2170,7 +2170,7 @@ class IDLUnresolvedType(IDLType):
|
||||||
return typedefType.complete(scope)
|
return typedefType.complete(scope)
|
||||||
elif obj.isCallback() and not obj.isInterface():
|
elif obj.isCallback() and not obj.isInterface():
|
||||||
assert self.name.name == obj.identifier.name
|
assert self.name.name == obj.identifier.name
|
||||||
return IDLCallbackType(self.location, obj)
|
return IDLCallbackType(obj.location, obj)
|
||||||
|
|
||||||
if self._promiseInnerType and not self._promiseInnerType.isComplete():
|
if self._promiseInnerType and not self._promiseInnerType.isComplete():
|
||||||
self._promiseInnerType = self._promiseInnerType.complete(scope)
|
self._promiseInnerType = self._promiseInnerType.complete(scope)
|
||||||
|
@ -6534,7 +6534,7 @@ class Parser(Tokenizer):
|
||||||
type = IDLTypedefType(self.getLocation(p, 1), obj.innerType,
|
type = IDLTypedefType(self.getLocation(p, 1), obj.innerType,
|
||||||
obj.identifier.name)
|
obj.identifier.name)
|
||||||
elif obj.isCallback() and not obj.isInterface():
|
elif obj.isCallback() and not obj.isInterface():
|
||||||
type = IDLCallbackType(self.getLocation(p, 1), obj)
|
type = IDLCallbackType(obj.location, obj)
|
||||||
else:
|
else:
|
||||||
type = IDLWrapperType(self.getLocation(p, 1), p[1])
|
type = IDLWrapperType(self.getLocation(p, 1), p[1])
|
||||||
p[0] = self.handleModifiers(type, p[2])
|
p[0] = self.handleModifiers(type, p[2])
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
diff --git a/components/script/dom/bindings/codegen/parser/WebIDL.py b/components/script/dom/bindings/codegen/parser/WebIDL.py
|
||||||
|
index da32340..81c52b7 100644
|
||||||
|
--- a/components/script/dom/bindings/codegen/parser/WebIDL.py
|
||||||
|
+++ b/components/script/dom/bindings/codegen/parser/WebIDL.py
|
||||||
|
@@ -2170,7 +2170,7 @@ class IDLUnresolvedType(IDLType):
|
||||||
|
return typedefType.complete(scope)
|
||||||
|
elif obj.isCallback() and not obj.isInterface():
|
||||||
|
assert self.name.name == obj.identifier.name
|
||||||
|
- return IDLCallbackType(self.location, obj)
|
||||||
|
+ return IDLCallbackType(obj.location, obj)
|
||||||
|
|
||||||
|
if self._promiseInnerType and not self._promiseInnerType.isComplete():
|
||||||
|
self._promiseInnerType = self._promiseInnerType.complete(scope)
|
||||||
|
@@ -6521,7 +6521,7 @@ class Parser(Tokenizer):
|
||||||
|
type = IDLTypedefType(self.getLocation(p, 1), obj.innerType,
|
||||||
|
obj.identifier.name)
|
||||||
|
elif obj.isCallback() and not obj.isInterface():
|
||||||
|
- type = IDLCallbackType(self.getLocation(p, 1), obj)
|
||||||
|
+ type = IDLCallbackType(obj.location, obj)
|
||||||
|
else:
|
||||||
|
type = IDLWrapperType(self.getLocation(p, 1), p[1])
|
||||||
|
p[0] = self.handleModifiers(type, p[2])
|
|
@ -2,6 +2,7 @@ wget https://hg.mozilla.org/mozilla-central/raw-file/tip/dom/bindings/parser/Web
|
||||||
patch < abstract.patch
|
patch < abstract.patch
|
||||||
patch < debug.patch
|
patch < debug.patch
|
||||||
patch < pref-main-thread.patch
|
patch < pref-main-thread.patch
|
||||||
|
patch < callback-location.patch
|
||||||
|
|
||||||
wget https://hg.mozilla.org/mozilla-central/archive/tip.tar.gz/dom/bindings/parser/tests/ -O tests.tar.gz
|
wget https://hg.mozilla.org/mozilla-central/archive/tip.tar.gz/dom/bindings/parser/tests/ -O tests.tar.gz
|
||||||
rm -r tests
|
rm -r tests
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue