aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/bindings')
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py152
-rw-r--r--components/script/dom/bindings/codegen/run.py2
-rw-r--r--components/script/dom/bindings/import.rs1
-rw-r--r--components/script/dom/bindings/mod.rs6
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"));