script: Refer to DOM interfaces with generic types in generated bindings. (#35457)

Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
Josh Matthews 2025-02-21 06:10:00 -05:00 committed by GitHub
parent 14db055d46
commit 1192ae32b0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 627 additions and 167 deletions

View file

@ -7,6 +7,7 @@
//! Implementation of `iterable<...>` and `iterable<..., ...>` WebIDL declarations.
use std::cell::Cell;
use std::marker::PhantomData;
use std::ptr;
use std::ptr::NonNull;
@ -15,18 +16,20 @@ use js::conversions::ToJSValConvertible;
use js::jsapi::{Heap, JSObject};
use js::jsval::UndefinedValue;
use js::rust::{HandleObject, HandleValue, MutableHandleObject};
use script_bindings::conversions::IDLInterface;
use script_bindings::utils::DOMClass;
use crate::dom::bindings::codegen::Bindings::IterableIteratorBinding::{
IterableKeyAndValueResult, IterableKeyOrValueResult,
};
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::{
reflect_dom_object, DomGlobal, DomObjectIteratorWrap, DomObjectWrap, Reflector,
reflect_dom_object, DomGlobalGeneric, DomObjectIteratorWrap, DomObjectWrap, Reflector,
};
use crate::dom::bindings::root::{Dom, DomRoot, Root};
use crate::dom::bindings::trace::{JSTraceable, RootedTraceableBox};
use crate::dom::globalscope::GlobalScope;
use crate::dom::bindings::trace::{JSTraceable, NoTrace, RootedTraceableBox};
use crate::script_runtime::{CanGc, JSContext};
use crate::DomTypes;
/// The values that an iterator will iterate over.
#[derive(JSTraceable, MallocSizeOf)]
@ -55,14 +58,41 @@ pub(crate) trait Iterable {
/// An iterator over the iterable entries of a given DOM interface.
#[dom_struct]
pub(crate) struct IterableIterator<T: DomObjectIteratorWrap + JSTraceable + Iterable> {
pub(crate) struct IterableIterator<
D: DomTypes,
T: DomObjectIteratorWrap<D> + JSTraceable + Iterable + DomGlobalGeneric<D>,
> {
reflector: Reflector,
iterable: Dom<T>,
type_: IteratorType,
index: Cell<u32>,
_marker: NoTrace<PhantomData<D>>,
}
impl<T: DomObjectIteratorWrap + JSTraceable + Iterable> IterableIterator<T> {
impl<D: DomTypes, T: DomObjectIteratorWrap<D> + JSTraceable + Iterable> IterableIterator<D, T> {
pub fn global(&self) -> DomRoot<D::GlobalScope> {
<Self as DomGlobalGeneric<D>>::global(self)
}
}
impl<
D: DomTypes,
T: DomObjectIteratorWrap<D>
+ JSTraceable
+ Iterable
+ DomGlobalGeneric<D>
+ IDLInterface
+ IteratorDerives,
> IDLInterface for IterableIterator<D, T>
{
fn derives(class: &'static DOMClass) -> bool {
<T as IteratorDerives>::derives(class)
}
}
impl<D: DomTypes, T: DomObjectIteratorWrap<D> + JSTraceable + Iterable + DomGlobalGeneric<D>>
IterableIterator<D, T>
{
/// Create a new iterator instance for the provided iterable DOM interface.
pub(crate) fn new(iterable: &T, type_: IteratorType) -> DomRoot<Self> {
let iterator = Box::new(IterableIterator {
@ -70,6 +100,7 @@ impl<T: DomObjectIteratorWrap + JSTraceable + Iterable> IterableIterator<T> {
type_,
iterable: Dom::from_ref(iterable),
index: Cell::new(0),
_marker: NoTrace(PhantomData),
});
reflect_dom_object(iterator, &*iterable.global(), CanGc::note())
}
@ -119,16 +150,26 @@ impl<T: DomObjectIteratorWrap + JSTraceable + Iterable> IterableIterator<T> {
}
}
impl<T: DomObjectIteratorWrap + JSTraceable + Iterable> DomObjectWrap for IterableIterator<T> {
impl<D: DomTypes, T: DomObjectIteratorWrap<D> + JSTraceable + Iterable + DomGlobalGeneric<D>>
DomObjectWrap<D> for IterableIterator<D, T>
{
const WRAP: unsafe fn(
JSContext,
&GlobalScope,
&D::GlobalScope,
Option<HandleObject>,
Box<Self>,
CanGc,
) -> Root<Dom<Self>> = T::ITER_WRAP;
}
/// A version of the [IDLInterface] trait that is specific to types that have
/// iterators defined for them. This allows the `script` crate to define the
/// derives check for the concrete interface type, while the [IteratableIterator]
/// type defined in this module can be parameterized over an unknown generic.
pub trait IteratorDerives {
fn derives(class: &'static DOMClass) -> bool;
}
fn dict_return(
cx: JSContext,
mut result: MutableHandleObject,