aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/codegen
diff options
context:
space:
mode:
authorSamson <16504129+sagudev@users.noreply.github.com>2023-09-06 15:08:45 +0200
committerGitHub <noreply@github.com>2023-09-06 13:08:45 +0000
commite0a6281e7375468f367aadf398d5a836512d9df6 (patch)
treed29cc82409d68f4b053de615d66c17ac779addd5 /components/script/dom/bindings/codegen
parent3df284cf54d9d99daf32794a030efa6358f5cf39 (diff)
downloadservo-e0a6281e7375468f367aadf398d5a836512d9df6.tar.gz
servo-e0a6281e7375468f367aadf398d5a836512d9df6.zip
Impl Setlike and Maplike (#30237)
* MallocSizeOf for Index{Set, Map} * like as iterable in WebIDL * Codegen magic for like interfaces * TestBinding for like * Test for Setlike and Maplike test bindings * Some fixes * Switch to any.js * nit * Keep order
Diffstat (limited to 'components/script/dom/bindings/codegen')
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py77
-rw-r--r--components/script/dom/bindings/codegen/Configuration.py10
2 files changed, 83 insertions, 4 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index bc7f2ceb9a8..f7280ffba22 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -3805,7 +3805,9 @@ class CGPerSignatureCall(CGThing):
if idlNode.isMethod() and idlNode.isMaplikeOrSetlikeOrIterableMethod():
if idlNode.maplikeOrSetlikeOrIterable.isMaplike() or \
idlNode.maplikeOrSetlikeOrIterable.isSetlike():
- raise TypeError('Maplike/Setlike methods are not supported yet')
+ cgThings.append(CGMaplikeOrSetlikeMethodGenerator(descriptor,
+ idlNode.maplikeOrSetlikeOrIterable,
+ idlNode.identifier.name))
else:
cgThings.append(CGIterableMethodGenerator(descriptor,
idlNode.maplikeOrSetlikeOrIterable,
@@ -6490,6 +6492,8 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries
'crate::dom::bindings::htmlconstructor::push_new_element_queue',
'crate::dom::bindings::iterable::Iterable',
'crate::dom::bindings::iterable::IteratorType',
+ 'crate::dom::bindings::like::Setlike',
+ 'crate::dom::bindings::like::Maplike',
'crate::dom::bindings::namespace::NamespaceObjectClass',
'crate::dom::bindings::namespace::create_namespace_object',
'crate::dom::bindings::reflector::MutDomObject',
@@ -7862,6 +7866,77 @@ class CallbackOperation(CallbackOperationBase):
descriptor, descriptor.interface.isSingleOperationInterface())
+class CGMaplikeOrSetlikeMethodGenerator(CGGeneric):
+ """
+ Creates methods for *like interfaces. Unwrapping/wrapping
+ will be taken care of by the usual method generation machinery in
+ CGMethodCall/CGPerSignatureCall. Functionality is filled in here instead of
+ using CGCallGenerator.
+ """
+ def __init__(self, descriptor, likeable, methodName):
+ trait: str
+ if likeable.isSetlike():
+ trait = "Setlike"
+ elif likeable.isMaplike():
+ trait = "Maplike"
+ else:
+ raise TypeError("CGMaplikeOrSetlikeMethodGenerator is only for Setlike/Maplike")
+ """
+ setlike:
+ fn size(&self) -> usize;
+ fn add(&self, key: Self::Key);
+ fn has(&self, key: &Self::Key) -> bool;
+ fn clear(&self);
+ fn delete(&self, key: &Self::Key) -> bool;
+ maplike:
+ fn get(&self, key: Self::Key) -> Self::Value;
+ fn size(&self) -> usize;
+ fn set(&self, key: Self::Key, value: Self::Value);
+ fn has(&self, key: &Self::Key) -> bool;
+ fn clear(&self);
+ fn delete(&self, key: &Self::Key) -> bool;
+ like iterable:
+ keys/values/entries/forEach
+ """
+ # like iterables are implemented seperatly as we are actually implementing them
+ if methodName in ["keys", "values", "entries", "forEach"]:
+ CGIterableMethodGenerator.__init__(self, descriptor, likeable, methodName)
+ elif methodName in ["size", "clear"]: # zero arguments
+ CGGeneric.__init__(self, fill(
+ """
+ let result = ${trt}::${method}(&*this);
+ """,
+ trt=trait,
+ method=methodName.lower()))
+ elif methodName == "add": # special case one argumet
+ CGGeneric.__init__(self, fill(
+ """
+ ${trt}::${method}(&*this, arg0);
+ // Returns itself per https://webidl.spec.whatwg.org/#es-set-add
+ let result = this;
+ """,
+ trt=trait,
+ method=methodName))
+ elif methodName in ["has", "delete", "get"]: # one argument
+ CGGeneric.__init__(self, fill(
+ """
+ let result = ${trt}::${method}(&*this, arg0);
+ """,
+ trt=trait,
+ method=methodName))
+ elif methodName == "set": # two arguments
+ CGGeneric.__init__(self, fill(
+ """
+ ${trt}::${method}(&*this, arg0, arg1);
+ // Returns itself per https://webidl.spec.whatwg.org/#es-map-set
+ let result = this;
+ """,
+ trt=trait,
+ method=methodName))
+ else:
+ raise TypeError(f"Do not know how to impl *like method: {methodName}")
+
+
class CGIterableMethodGenerator(CGGeneric):
"""
Creates methods for iterable interfaces. Unwrapping/wrapping
diff --git a/components/script/dom/bindings/codegen/Configuration.py b/components/script/dom/bindings/codegen/Configuration.py
index bd455f5288e..aa32093772f 100644
--- a/components/script/dom/bindings/codegen/Configuration.py
+++ b/components/script/dom/bindings/codegen/Configuration.py
@@ -516,7 +516,11 @@ def getUnwrappedType(type):
def iteratorNativeType(descriptor, infer=False):
- assert descriptor.interface.isIterable()
iterableDecl = descriptor.interface.maplikeOrSetlikeOrIterable
- assert iterableDecl.isPairIterator()
- return "IterableIterator%s" % ("" if infer else '<%s>' % descriptor.interface.identifier.name)
+ assert (iterableDecl.isIterable() and iterableDecl.isPairIterator()) \
+ or iterableDecl.isSetlike() or iterableDecl.isMaplike()
+ res = "IterableIterator%s" % ("" if infer else '<%s>' % descriptor.interface.identifier.name)
+ # todo: this hack is telling us that something is still wrong in codegen
+ if iterableDecl.isSetlike() or iterableDecl.isMaplike():
+ res = f"crate::dom::bindings::iterable::{res}"
+ return res