From 9f4ed536df07f6435ed5267c33e12ce0a1f9f951 Mon Sep 17 00:00:00 2001 From: Anton Danilkin Date: Tue, 11 Sep 2018 00:37:59 +0300 Subject: [PATCH] Use js_sys::Array, generate _n methods for ergonomics --- crates/webidl-tests/simple.rs | 14 ++++++- crates/webidl/src/lib.rs | 4 +- crates/webidl/src/util.rs | 71 +++++++++++++++++++---------------- 3 files changed, 53 insertions(+), 36 deletions(-) diff --git a/crates/webidl-tests/simple.rs b/crates/webidl-tests/simple.rs index c6c29fdc..2c8a23b4 100644 --- a/crates/webidl-tests/simple.rs +++ b/crates/webidl-tests/simple.rs @@ -95,7 +95,19 @@ fn optional_and_union_arguments() { #[wasm_bindgen_test] fn variadic() { let f = Variadic::new().unwrap(); - assert_eq!(f.sum(Box::new([1, 2, 3, 4, 5])), 15); + assert_eq!(f.sum_5(1, 2, 3, 4, 5), 15); + assert_eq!( + f.sum( + &::js_sys::Array::of5( + &JsValue::from_f64(1f64), + &JsValue::from_f64(2f64), + &JsValue::from_f64(3f64), + &JsValue::from_f64(4f64), + &JsValue::from_f64(5f64), + ) + ), + 15 + ); } #[wasm_bindgen_test] diff --git a/crates/webidl/src/lib.rs b/crates/webidl/src/lib.rs index 65fa655c..aefe9c8c 100644 --- a/crates/webidl/src/lib.rs +++ b/crates/webidl/src/lib.rs @@ -137,8 +137,8 @@ fn builtin_idents() -> BTreeSet { BTreeSet::from_iter( vec![ "str", "char", "bool", "JsValue", "u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", - "usize", "isize", "f32", "f64", "Result", "String", "Box", "Vec", "Option", - "ArrayBuffer", "Object", "Promise", "Function", + "usize", "isize", "f32", "f64", "Result", "String", "Vec", "Option", + "Array", "ArrayBuffer", "Object", "Promise", "Function", ].into_iter() .map(|id| proc_macro2::Ident::new(id, proc_macro2::Span::call_site())), ) diff --git a/crates/webidl/src/util.rs b/crates/webidl/src/util.rs index aebe2cb2..616eb658 100644 --- a/crates/webidl/src/util.rs +++ b/crates/webidl/src/util.rs @@ -172,24 +172,6 @@ pub(crate) fn slice_ty(t: syn::Type) -> syn::Type { }.into() } -/// From `T` create `Box`. -pub(crate) fn box_ty(t: syn::Type) -> syn::Type { - let arguments = syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments { - colon2_token: None, - lt_token: Default::default(), - args: FromIterator::from_iter(vec![ - syn::GenericArgument::Type(t), - ]), - gt_token: Default::default(), - }); - - let ident = raw_ident("Box"); - let seg = syn::PathSegment { ident, arguments }; - let path: syn::Path = seg.into(); - let ty = syn::TypePath { qself: None, path }; - ty.into() -} - /// From `T` create `Vec`. pub(crate) fn vec_ty(t: syn::Type) -> syn::Type { let arguments = syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments { @@ -279,16 +261,8 @@ impl<'src> FirstPassRecord<'src> { } }; let syn_type = if variadic && i == arguments_count - 1 { - // Blacklist unsupported slice types - match idl_type { - | IdlType::DomString - | IdlType::ByteString - | IdlType::UsvString => return None, - - IdlType::Interface(..) => return None, - - _ => box_ty(slice_ty(syn_type)) - } + let path = vec![rust_ident("js_sys"), rust_ident("Array")]; + shared_ref(leading_colon_path_ty(path), false) } else { syn_type }; @@ -603,18 +577,49 @@ impl<'src> FirstPassRecord<'src> { rust_name.push_str(&snake_case_ident(arg_name)); } } + let structural = force_structural || is_structural(signature.orig.attrs.as_ref(), container_attrs); + let catch = force_throws || throws(&signature.orig.attrs); + let variadic = signature.args.len() == signature.orig.args.len() + && signature.orig.args.last().map(|arg| arg.variadic).unwrap_or(false); + if variadic { + for i in 0..=7 { + ret.extend(self.create_one_function( + name, + &format!("{}_{}", rust_name, i), + signature.args[..signature.args.len() - 1].iter() + .zip(&signature.orig.args) + .map(|(idl_type, orig_arg)| (orig_arg.name.to_string(), idl_type)) + .chain( + (1..=i) + .map(|j| { + let idl_type = &signature.args[signature.args.len() - 1]; + let name = signature.orig.args[signature.args.len() - 1].name; + (format!("{}_{}", name, j), idl_type) + }) + ) + .collect::>() + .iter() + .map(|(name, idl_type)| (&name[..], idl_type.clone())), + &ret_ty, + kind.clone(), + structural, + catch, + false, + None, + )); + } + } ret.extend(self.create_one_function( name, &rust_name, signature.args.iter() .zip(&signature.orig.args) - .map(|(ty, orig_arg)| (orig_arg.name, ty)), + .map(|(idl_type, orig_arg)| (orig_arg.name, idl_type)), &ret_ty, kind.clone(), - force_structural || is_structural(signature.orig.attrs.as_ref(), container_attrs), - force_throws || throws(&signature.orig.attrs), - signature.args.len() == signature.orig.args.len() - && signature.orig.args.last().map(|arg| arg.variadic).unwrap_or(false), + structural, + catch, + variadic, None, )); }