diff options
Diffstat (limited to 'components/script/dom/bindings')
-rw-r--r-- | components/script/dom/bindings/codegen/CodegenRust.py | 152 | ||||
-rw-r--r-- | components/script/dom/bindings/codegen/run.py | 2 | ||||
-rw-r--r-- | components/script/dom/bindings/import.rs | 1 | ||||
-rw-r--r-- | components/script/dom/bindings/mod.rs | 6 |
4 files changed, 155 insertions, 6 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index f716f4a8be1..6ac9ae1d5d9 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -540,6 +540,12 @@ def union_native_type(t): return f'UnionTypes::{name}' +# Unfortunately, .capitalize() on a string will lowercase things inside the +# string, which we do not want. +def firstCap(string): + return f"{string[0].upper()}{string[1:]}" + + class JSToNativeConversionInfo(): """ An object representing information about a JS-to-native conversion. @@ -643,11 +649,6 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, assert (defaultValue is None) == (default is None) return JSToNativeConversionInfo(template, default, declType) - # Unfortunately, .capitalize() on a string will lowercase things inside the - # string, which we do not want. - def firstCap(string): - return f"{string[0].upper()}{string[1:]}" - # Helper functions for dealing with failures due to the JS value being the # wrong type of value. def onFailureNotAnObject(failureCode): @@ -2621,6 +2622,7 @@ def UnionTypes(descriptors, dictionaries, callbacks, typedefs, config): imports = [ 'crate::dom', 'crate::dom::bindings::import::base::*', + 'crate::dom::bindings::codegen::DomTypes::DomTypes', 'crate::dom::bindings::conversions::windowproxy_from_handlevalue', 'crate::dom::bindings::record::Record', 'crate::dom::types::*', @@ -2658,6 +2660,108 @@ def UnionTypes(descriptors, dictionaries, callbacks, typedefs, config): typedefs=[], imports=imports, config=config) +def DomTypes(descriptors, descriptorProvider, dictionaries, callbacks, typedefs, config): + traits = [ + "js::rust::Trace", + "malloc_size_of::MallocSizeOf", + "Sized", + ] + joinedTraits = ' + '.join(traits) + elements = [CGGeneric(f"pub trait DomTypes: {joinedTraits} where Self: 'static {{\n")] + for descriptor in descriptors: + iface_name = descriptor.interface.identifier.name + traits = [] + + chain = descriptor.prototypeChain + upcast = descriptor.hasDescendants() + + if not upcast: + # No other interface will implement DeriveFrom<Foo> for this Foo, so avoid + # implementing it for itself. + chain = chain[:-1] + + if chain: + traits += ["crate::dom::bindings::inheritance::Castable"] + + for parent in chain: + traits += [f"crate::dom::bindings::conversions::DerivedFrom<Self::{parent}>"] + + iterableDecl = descriptor.interface.maplikeOrSetlikeOrIterable + if iterableDecl: + if iterableDecl.isMaplike(): + keytype = getRetvalDeclarationForType(iterableDecl.keyType, None).define() + valuetype = getRetvalDeclarationForType(iterableDecl.valueType, None).define() + traits += [f"crate::dom::bindings::like::Maplike<Key={keytype}, Value={valuetype}>"] + if iterableDecl.isSetlike(): + keytype = getRetvalDeclarationForType(iterableDecl.keyType, None).define() + traits += [f"crate::dom::bindings::like::Setlike<Key={keytype}>"] + if iterableDecl.hasKeyType(): + traits += [ + "crate::dom::bindings::reflector::DomObjectIteratorWrap", + ] + + if descriptor.weakReferenceable: + traits += ["crate::dom::bindings::weakref::WeakReferenceable"] + + if not descriptor.interface.isNamespace(): + traits += [ + "js::conversions::ToJSValConvertible", + "crate::dom::bindings::reflector::MutDomObject", + "crate::dom::bindings::reflector::DomObject", + ] + + if descriptor.register: + if ( + (descriptor.concrete or descriptor.hasDescendants()) + and not descriptor.interface.isNamespace() + and not descriptor.interface.isIteratorInterface() + ): + traits += [ + "crate::dom::bindings::conversions::IDLInterface", + "PartialEq", + ] + + if descriptor.concrete and not descriptor.isGlobal(): + traits += ["crate::dom::bindings::reflector::DomObjectWrap"] + + if not descriptor.interface.isCallback() and not descriptor.interface.isIteratorInterface(): + nonConstMembers = [m for m in descriptor.interface.members if not m.isConst()] + ctor = descriptor.interface.ctor() + if ( + nonConstMembers + or (ctor and not ctor.isHTMLConstructor()) + or descriptor.interface.legacyFactoryFunctions + ): + namespace = f"{toBindingPath(descriptor)}" + traits += [f"crate::dom::bindings::codegen::Bindings::{namespace}::{iface_name}Methods<Self>"] + isPromise = firstCap(iface_name) == "Promise" + elements += [ + CGGeneric(" #[crown::unrooted_must_root_lint::must_root]\n"), + CGGeneric(" #[crown::unrooted_must_root_lint::allow_unrooted_in_rc]\n" if isPromise else ""), + CGGeneric(f" type {firstCap(iface_name)}: {' + '.join(traits)};\n") + ] + elements += [CGGeneric("}\n")] + return CGList([CGGeneric("use crate::dom::bindings::str::DOMString;\n")] + elements) + + +def DomTypeHolder(descriptors, descriptorProvider, dictionaries, callbacks, typedefs, config): + elements = [ + CGGeneric( + "#[derive(JSTraceable, MallocSizeOf, PartialEq)]\n" + "pub struct DomTypeHolder;\n" + "impl crate::DomTypes for DomTypeHolder {\n" + ), + ] + for descriptor in descriptors: + if descriptor.interface.isCallback() or descriptor.interface.isIteratorInterface(): + continue + iface_name = descriptor.interface.identifier.name + path = f"crate::dom::{iface_name.lower()}::{firstCap(iface_name)}" + elements.append(CGGeneric(f" type {firstCap(iface_name)} = {path};\n")) + elements.append(CGGeneric("}\n")) + return CGList(elements) + + class Argument(): """ A class for outputting the type and name of an argument @@ -3061,6 +3165,12 @@ DomRoot::from_ref(&*root)\ """) +def toBindingPath(descriptor): + module = toBindingModuleFileFromDescriptor(descriptor) + namespace = toBindingNamespace(descriptor.interface.identifier.name) + return f"{module}::{namespace}" + + class CGIDLInterface(CGThing): """ Class for codegen of an implementation of the IDLInterface trait. @@ -6495,7 +6605,7 @@ class CGInterfaceTrait(CGThing): if methods: self.cgRoot = CGWrapper(CGIndenter(CGList(methods, "")), - pre=f"pub trait {descriptor.interface.identifier.name}Methods {{\n", + pre=f"pub trait {descriptor.interface.identifier.name}Methods<D: DomTypes> {{\n", post="}") else: self.cgRoot = CGGeneric("") @@ -8151,6 +8261,36 @@ impl {base} {{ return curr @staticmethod + def DomTypes(config): + curr = DomTypes(config.getDescriptors(), + config.getDescriptorProvider(), + config.getDictionaries(), + config.getCallbacks(), + config.typedefs, + config) + + # Add the auto-generated comment. + curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT) + + # Done. + return curr + + @staticmethod + def DomTypeHolder(config): + curr = DomTypeHolder(config.getDescriptors(), + config.getDescriptorProvider(), + config.getDictionaries(), + config.getCallbacks(), + config.typedefs, + config) + + # Add the auto-generated comment. + curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT) + + # Done. + return curr + + @staticmethod def SupportedDomApis(config): descriptors = config.getDescriptors(isExposedConditionally=False) diff --git a/components/script/dom/bindings/codegen/run.py b/components/script/dom/bindings/codegen/run.py index 4bf5966e305..52840b1b1d3 100644 --- a/components/script/dom/bindings/codegen/run.py +++ b/components/script/dom/bindings/codegen/run.py @@ -48,6 +48,8 @@ def main(): ("InheritTypes", "InheritTypes.rs"), ("Bindings", "Bindings/mod.rs"), ("UnionTypes", "UnionTypes.rs"), + ("DomTypes", "DomTypes.rs"), + ("DomTypeHolder", "DomTypeHolder.rs"), ]: generate(config, name, os.path.join(out_dir, filename)) make_dir(doc_servo) diff --git a/components/script/dom/bindings/import.rs b/components/script/dom/bindings/import.rs index 1f6f0cec972..c4c7a460ca9 100644 --- a/components/script/dom/bindings/import.rs +++ b/components/script/dom/bindings/import.rs @@ -25,6 +25,7 @@ pub mod base { ChannelCountMode, ChannelCountModeValues, ChannelInterpretation, ChannelInterpretationValues, }; + pub use crate::dom::bindings::codegen::DomTypes::DomTypes; pub use crate::dom::bindings::codegen::UnionTypes; pub use crate::dom::bindings::conversions::{ root_from_handlevalue, ConversionBehavior, ConversionResult, FromJSValConvertible, diff --git a/components/script/dom/bindings/mod.rs b/components/script/dom/bindings/mod.rs index d291f8e353f..a6666b70d90 100644 --- a/components/script/dom/bindings/mod.rs +++ b/components/script/dom/bindings/mod.rs @@ -170,6 +170,12 @@ pub mod xmlname; /// Generated JS-Rust bindings. #[allow(missing_docs, non_snake_case)] pub mod codegen { + pub mod DomTypeHolder { + include!(concat!(env!("OUT_DIR"), "/DomTypeHolder.rs")); + } + pub mod DomTypes { + include!(concat!(env!("OUT_DIR"), "/DomTypes.rs")); + } #[allow(dead_code)] pub mod Bindings { include!(concat!(env!("OUT_DIR"), "/Bindings/mod.rs")); |