diff options
author | Samson <16504129+sagudev@users.noreply.github.com> | 2023-09-06 15:08:45 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-06 13:08:45 +0000 |
commit | e0a6281e7375468f367aadf398d5a836512d9df6 (patch) | |
tree | d29cc82409d68f4b053de615d66c17ac779addd5 /components/script/dom/bindings/codegen | |
parent | 3df284cf54d9d99daf32794a030efa6358f5cf39 (diff) | |
download | servo-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.py | 77 | ||||
-rw-r--r-- | components/script/dom/bindings/codegen/Configuration.py | 10 |
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 |