mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-06-17 06:51:24 +00:00
Merge branch 'master' into feat/basic-enum-support
This commit is contained in:
@ -78,7 +78,7 @@ fn compile_ast(mut ast: backend::ast::Program) -> String {
|
||||
let mut defined = BTreeSet::from_iter(
|
||||
vec![
|
||||
"str", "char", "bool", "JsValue", "u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64",
|
||||
"usize", "isize", "f32", "f64",
|
||||
"usize", "isize", "f32", "f64", "Result",
|
||||
].into_iter()
|
||||
.map(|id| proc_macro2::Ident::new(id, proc_macro2::Span::call_site())),
|
||||
);
|
||||
@ -211,11 +211,29 @@ impl<'a> WebidlParse<&'a webidl::ast::NonPartialInterface> for webidl::ast::Exte
|
||||
) -> Result<()> {
|
||||
let mut add_constructor = |arguments: &[webidl::ast::Argument], class: &str| {
|
||||
let self_ty = ident_ty(rust_ident(&interface.name));
|
||||
|
||||
let kind = backend::ast::ImportFunctionKind::Method {
|
||||
class: class.to_string(),
|
||||
ty: self_ty.clone(),
|
||||
kind: backend::ast::MethodKind::Constructor,
|
||||
};
|
||||
|
||||
let structural = false;
|
||||
|
||||
// Constructors aren't annotated with `[Throws]` extended attributes
|
||||
// (how could they be, since they themselves are extended
|
||||
// attributes?) so we must conservatively assume that they can
|
||||
// always throw.
|
||||
//
|
||||
// From https://heycam.github.io/webidl/#Constructor (emphasis
|
||||
// mine):
|
||||
//
|
||||
// > The prose definition of a constructor must either return an IDL
|
||||
// > value of a type corresponding to the interface the
|
||||
// > `[Constructor]` extended attribute appears on, **or throw an
|
||||
// > exception**.
|
||||
let throws = true;
|
||||
|
||||
create_function(
|
||||
"new",
|
||||
arguments
|
||||
@ -223,7 +241,8 @@ impl<'a> WebidlParse<&'a webidl::ast::NonPartialInterface> for webidl::ast::Exte
|
||||
.map(|arg| (&*arg.name, &*arg.type_, arg.variadic)),
|
||||
Some(self_ty),
|
||||
kind,
|
||||
false,
|
||||
structural,
|
||||
throws,
|
||||
).map(|function| {
|
||||
program.imports.push(backend::ast::Import {
|
||||
module: None,
|
||||
@ -325,14 +344,27 @@ impl<'a> WebidlParse<&'a str> for webidl::ast::RegularAttribute {
|
||||
}
|
||||
|
||||
let is_structural = util::is_structural(&self.extended_attributes);
|
||||
let throws = util::throws(&self.extended_attributes);
|
||||
|
||||
create_getter(&self.name, &self.type_, self_name, false, is_structural)
|
||||
.map(wrap_import_function)
|
||||
create_getter(
|
||||
&self.name,
|
||||
&self.type_,
|
||||
self_name,
|
||||
false,
|
||||
is_structural,
|
||||
throws,
|
||||
).map(wrap_import_function)
|
||||
.map(|import| program.imports.push(import));
|
||||
|
||||
if !self.read_only {
|
||||
create_setter(&self.name, &self.type_, self_name, false, is_structural)
|
||||
.map(wrap_import_function)
|
||||
create_setter(
|
||||
&self.name,
|
||||
&self.type_,
|
||||
self_name,
|
||||
false,
|
||||
is_structural,
|
||||
throws,
|
||||
).map(wrap_import_function)
|
||||
.map(|import| program.imports.push(import));
|
||||
}
|
||||
|
||||
@ -347,14 +379,27 @@ impl<'a> WebidlParse<&'a str> for webidl::ast::StaticAttribute {
|
||||
}
|
||||
|
||||
let is_structural = util::is_structural(&self.extended_attributes);
|
||||
let throws = util::throws(&self.extended_attributes);
|
||||
|
||||
create_getter(&self.name, &self.type_, self_name, true, is_structural)
|
||||
.map(wrap_import_function)
|
||||
create_getter(
|
||||
&self.name,
|
||||
&self.type_,
|
||||
self_name,
|
||||
true,
|
||||
is_structural,
|
||||
throws,
|
||||
).map(wrap_import_function)
|
||||
.map(|import| program.imports.push(import));
|
||||
|
||||
if !self.read_only {
|
||||
create_setter(&self.name, &self.type_, self_name, true, is_structural)
|
||||
.map(wrap_import_function)
|
||||
create_setter(
|
||||
&self.name,
|
||||
&self.type_,
|
||||
self_name,
|
||||
true,
|
||||
is_structural,
|
||||
throws,
|
||||
).map(wrap_import_function)
|
||||
.map(|import| program.imports.push(import));
|
||||
}
|
||||
|
||||
@ -368,12 +413,15 @@ impl<'a> WebidlParse<&'a str> for webidl::ast::RegularOperation {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let throws = util::throws(&self.extended_attributes);
|
||||
|
||||
create_basic_method(
|
||||
&self.arguments,
|
||||
self.name.as_ref(),
|
||||
&self.return_type,
|
||||
self_name,
|
||||
false,
|
||||
throws,
|
||||
).map(wrap_import_function)
|
||||
.map(|import| program.imports.push(import));
|
||||
|
||||
@ -387,12 +435,15 @@ impl<'a> WebidlParse<&'a str> for webidl::ast::StaticOperation {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let throws = util::throws(&self.extended_attributes);
|
||||
|
||||
create_basic_method(
|
||||
&self.arguments,
|
||||
self.name.as_ref(),
|
||||
&self.return_type,
|
||||
self_name,
|
||||
true,
|
||||
throws,
|
||||
).map(wrap_import_function)
|
||||
.map(|import| program.imports.push(import));
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::iter;
|
||||
use std::iter::{self, FromIterator};
|
||||
|
||||
use backend;
|
||||
use backend::util::{ident_ty, raw_ident, rust_ident, simple_path_ty};
|
||||
use backend::util::{ident_ty, leading_colon_path_ty, raw_ident, rust_ident, simple_path_ty};
|
||||
use heck::SnakeCase;
|
||||
use proc_macro2::Ident;
|
||||
use syn;
|
||||
@ -146,12 +146,40 @@ where
|
||||
Some(res)
|
||||
}
|
||||
|
||||
fn unit_ty() -> syn::Type {
|
||||
syn::Type::Tuple(syn::TypeTuple {
|
||||
paren_token: Default::default(),
|
||||
elems: syn::punctuated::Punctuated::new(),
|
||||
})
|
||||
}
|
||||
|
||||
fn result_ty(t: syn::Type) -> syn::Type {
|
||||
let js_value = leading_colon_path_ty(vec![rust_ident("wasm_bindgen"), rust_ident("JsValue")]);
|
||||
|
||||
let arguments = syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments {
|
||||
colon2_token: None,
|
||||
lt_token: Default::default(),
|
||||
args: FromIterator::from_iter(vec![
|
||||
syn::GenericArgument::Type(t),
|
||||
syn::GenericArgument::Type(js_value),
|
||||
]),
|
||||
gt_token: Default::default(),
|
||||
});
|
||||
|
||||
let ident = raw_ident("Result");
|
||||
let seg = syn::PathSegment { ident, arguments };
|
||||
let path: syn::Path = seg.into();
|
||||
let ty = syn::TypePath { qself: None, path };
|
||||
ty.into()
|
||||
}
|
||||
|
||||
pub fn create_function<'a, I>(
|
||||
name: &str,
|
||||
arguments: I,
|
||||
ret: Option<syn::Type>,
|
||||
mut ret: Option<syn::Type>,
|
||||
kind: backend::ast::ImportFunctionKind,
|
||||
structural: bool,
|
||||
catch: bool,
|
||||
) -> Option<backend::ast::ImportFunction>
|
||||
where
|
||||
I: Iterator<Item = (&'a str, &'a webidl::ast::Type, bool)>,
|
||||
@ -163,6 +191,10 @@ where
|
||||
|
||||
let js_ret = ret.clone();
|
||||
|
||||
if catch {
|
||||
ret = Some(ret.map_or_else(|| result_ty(unit_ty()), |ret| result_ty(ret)))
|
||||
}
|
||||
|
||||
let shim = {
|
||||
let ns = match kind {
|
||||
backend::ast::ImportFunctionKind::Normal => "",
|
||||
@ -184,7 +216,7 @@ where
|
||||
},
|
||||
rust_name,
|
||||
js_ret,
|
||||
catch: false,
|
||||
catch,
|
||||
structural,
|
||||
kind,
|
||||
shim,
|
||||
@ -197,6 +229,7 @@ pub fn create_basic_method(
|
||||
return_type: &webidl::ast::ReturnType,
|
||||
self_name: &str,
|
||||
is_static: bool,
|
||||
catch: bool,
|
||||
) -> Option<backend::ast::ImportFunction> {
|
||||
let name = match name {
|
||||
None => {
|
||||
@ -235,6 +268,7 @@ pub fn create_basic_method(
|
||||
ret,
|
||||
kind,
|
||||
false,
|
||||
catch,
|
||||
)
|
||||
}
|
||||
|
||||
@ -244,6 +278,7 @@ pub fn create_getter(
|
||||
self_name: &str,
|
||||
is_static: bool,
|
||||
is_structural: bool,
|
||||
catch: bool,
|
||||
) -> Option<backend::ast::ImportFunction> {
|
||||
let ret = match webidl_ty_to_syn_ty(ty, TypePosition::Return) {
|
||||
None => {
|
||||
@ -262,7 +297,7 @@ pub fn create_getter(
|
||||
}),
|
||||
};
|
||||
|
||||
create_function(name, iter::empty(), ret, kind, is_structural)
|
||||
create_function(name, iter::empty(), ret, kind, is_structural, catch)
|
||||
}
|
||||
|
||||
pub fn create_setter(
|
||||
@ -271,6 +306,7 @@ pub fn create_setter(
|
||||
self_name: &str,
|
||||
is_static: bool,
|
||||
is_structural: bool,
|
||||
catch: bool,
|
||||
) -> Option<backend::ast::ImportFunction> {
|
||||
let kind = backend::ast::ImportFunctionKind::Method {
|
||||
class: self_name.to_string(),
|
||||
@ -287,6 +323,7 @@ pub fn create_setter(
|
||||
None,
|
||||
kind,
|
||||
is_structural,
|
||||
catch,
|
||||
)
|
||||
}
|
||||
|
||||
@ -315,3 +352,13 @@ pub fn is_structural(attrs: &[Box<ExtendedAttribute>]) -> bool {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn throws(attrs: &[Box<ExtendedAttribute>]) -> bool {
|
||||
attrs.iter().any(|attr| {
|
||||
if let ExtendedAttribute::NoArguments(webidl::ast::Other::Identifier(ref name)) = **attr {
|
||||
name == "Throws"
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user