mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-06-18 07:21:24 +00:00
Implement WebIDL callback interfaces
This commit implements callback interfaces for WebIDL, the final WebIDL construct that we were unconditionally ignoring! Callback interfaces are implemented as dictionaries of callbacks. Single-operation callback interfaces are also expanded when flattening to accept a `Function` as well, in accordance with the WebIDL spec. New features have been added to `web-sys` for all the new callback interface types. Additionally the `EventTarget.webidl` was tweaked to not have `EventListener?` as this is required for all functional usage and there's no need to keep that sort of web browser compat here. Closes #258
This commit is contained in:
@ -42,9 +42,10 @@ use backend::util::{ident_ty, rust_ident, raw_ident, wrap_import_function};
|
||||
use proc_macro2::{Ident, Span};
|
||||
use weedle::attribute::{ExtendedAttributeList};
|
||||
use weedle::dictionary::DictionaryMember;
|
||||
use weedle::interface::InterfaceMember;
|
||||
|
||||
use first_pass::{FirstPass, FirstPassRecord, OperationId, InterfaceData};
|
||||
use first_pass::OperationData;
|
||||
use first_pass::{OperationData, CallbackInterfaceData};
|
||||
use util::{public, webidl_const_v_to_backend_const_v, TypePosition, camel_case_ident, shouty_snake_case_ident, snake_case_ident, mdn_doc};
|
||||
use idl_type::ToIdlType;
|
||||
|
||||
@ -108,6 +109,11 @@ fn parse(webidl_source: &str, allowed_types: Option<&[&str]>)
|
||||
first_pass_record.append_interface(&mut program, name, d);
|
||||
}
|
||||
}
|
||||
for (name, d) in first_pass_record.callback_interfaces.iter() {
|
||||
if filter(name) {
|
||||
first_pass_record.append_callback_interface(&mut program, d);
|
||||
}
|
||||
}
|
||||
|
||||
// Prune out `extends` annotations that aren't defined as these shouldn't
|
||||
// prevent the type from being usable entirely. They're just there for
|
||||
@ -644,4 +650,38 @@ impl<'src> FirstPassRecord<'src> {
|
||||
list,
|
||||
));
|
||||
}
|
||||
|
||||
fn append_callback_interface(
|
||||
&self,
|
||||
program: &mut backend::ast::Program,
|
||||
item: &CallbackInterfaceData<'src>,
|
||||
) {
|
||||
let mut fields = Vec::new();
|
||||
for member in item.definition.members.body.iter() {
|
||||
match member {
|
||||
InterfaceMember::Operation(op) => {
|
||||
let identifier = match op.identifier {
|
||||
Some(i) => i.0,
|
||||
None => continue,
|
||||
};
|
||||
let pos = TypePosition::Argument;
|
||||
fields.push(ast::DictionaryField {
|
||||
required: false,
|
||||
name: rust_ident(&snake_case_ident(identifier)),
|
||||
ty: idl_type::IdlType::Callback.to_syn_type(pos)
|
||||
.unwrap(),
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
warn!("skipping callback interface member on {}",
|
||||
item.definition.identifier.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
program.dictionaries.push(ast::Dictionary {
|
||||
name: rust_ident(&camel_case_ident(item.definition.identifier.0)),
|
||||
fields,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user