Skip to content

Commit b34ac03

Browse files
authored
Add attributes to overwrite return and parameter types, descriptions and names (#4394)
1 parent 949b6c6 commit b34ac03

34 files changed

+1528
-154
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55

66
### Added
77

8+
* Add attributes to overwrite return (``unchecked_return_type`) and parameter types (`unchecked_param_type`), descriptions (`return_description` and `param_description`) as well as parameter names (`js_name`) for exported functions and methods. See the guide for more details.
9+
[#4394](https://github.com/rustwasm/wasm-bindgen/pull/4394)
10+
811
* Add a `copy_to_uninit()` method to all `TypedArray`s. It takes `&mut [MaybeUninit<T>]` and returns `&mut [T]`.
912
[#4340](https://github.com/rustwasm/wasm-bindgen/pull/4340)
1013

crates/backend/src/ast.rs

+29-3
Original file line numberDiff line numberDiff line change
@@ -375,9 +375,9 @@ pub struct Function {
375375
/// Whether the function has a js_name attribute
376376
pub renamed_via_js_name: bool,
377377
/// The arguments to the function
378-
pub arguments: Vec<syn::PatType>,
379-
/// The return type of the function, if provided
380-
pub ret: Option<syn::Type>,
378+
pub arguments: Vec<FunctionArgumentData>,
379+
/// The data of return type of the function
380+
pub ret: Option<FunctionReturnData>,
381381
/// Any custom attributes being applied to the function
382382
pub rust_attrs: Vec<syn::Attribute>,
383383
/// The visibility of this function in Rust
@@ -394,6 +394,32 @@ pub struct Function {
394394
pub variadic: bool,
395395
}
396396

397+
/// Information about a function's return
398+
#[cfg_attr(feature = "extra-traits", derive(Debug))]
399+
#[derive(Clone)]
400+
pub struct FunctionReturnData {
401+
/// Specifies the type of the function's return
402+
pub r#type: syn::Type,
403+
/// Specifies the JS return type override
404+
pub js_type: Option<String>,
405+
/// Specifies the return description
406+
pub desc: Option<String>,
407+
}
408+
409+
/// Information about a function's argument
410+
#[cfg_attr(feature = "extra-traits", derive(Debug))]
411+
#[derive(Clone)]
412+
pub struct FunctionArgumentData {
413+
/// Specifies the type of the function's argument
414+
pub pat_type: syn::PatType,
415+
/// Specifies the JS argument name override
416+
pub js_name: Option<String>,
417+
/// Specifies the JS function argument type override
418+
pub js_type: Option<String>,
419+
/// Specifies the argument description
420+
pub desc: Option<String>,
421+
}
422+
397423
/// Information about a Struct being exported
398424
#[cfg_attr(feature = "extra-traits", derive(Debug))]
399425
#[derive(Clone)]

crates/backend/src/codegen.rs

+13-8
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ impl TryToTokens for ast::Export {
637637

638638
let mut argtys = Vec::new();
639639
for (i, arg) in self.function.arguments.iter().enumerate() {
640-
argtys.push(&*arg.ty);
640+
argtys.push(&*arg.pat_type.ty);
641641
let i = i + offset;
642642
let ident = Ident::new(&format!("arg{}", i), Span::call_site());
643643
fn unwrap_nested_types(ty: &syn::Type) -> &syn::Type {
@@ -647,7 +647,7 @@ impl TryToTokens for ast::Export {
647647
_ => ty,
648648
}
649649
}
650-
let ty = unwrap_nested_types(&arg.ty);
650+
let ty = unwrap_nested_types(&arg.pat_type.ty);
651651

652652
match &ty {
653653
syn::Type::Reference(syn::TypeReference {
@@ -720,7 +720,12 @@ impl TryToTokens for ast::Export {
720720
elems: Default::default(),
721721
paren_token: Default::default(),
722722
});
723-
let syn_ret = self.function.ret.as_ref().unwrap_or(&syn_unit);
723+
let syn_ret = self
724+
.function
725+
.ret
726+
.as_ref()
727+
.map(|ret| &ret.r#type)
728+
.unwrap_or(&syn_unit);
724729
if let syn::Type::Reference(_) = syn_ret {
725730
bail_span!(syn_ret, "cannot return a borrowed ref with #[wasm_bindgen]",)
726731
}
@@ -1323,7 +1328,7 @@ impl TryToTokens for ast::ImportFunction {
13231328
ast::ImportFunctionKind::Normal => {}
13241329
}
13251330
let vis = &self.function.rust_vis;
1326-
let ret = match &self.function.ret {
1331+
let ret = match self.function.ret.as_ref().map(|ret| &ret.r#type) {
13271332
Some(ty) => quote! { -> #ty },
13281333
None => quote!(),
13291334
};
@@ -1337,8 +1342,8 @@ impl TryToTokens for ast::ImportFunction {
13371342
let wasm_bindgen_futures = &self.wasm_bindgen_futures;
13381343

13391344
for (i, arg) in self.function.arguments.iter().enumerate() {
1340-
let ty = &arg.ty;
1341-
let name = match &*arg.pat {
1345+
let ty = &arg.pat_type.ty;
1346+
let name = match &*arg.pat_type.pat {
13421347
syn::Pat::Ident(syn::PatIdent {
13431348
by_ref: None,
13441349
ident,
@@ -1347,7 +1352,7 @@ impl TryToTokens for ast::ImportFunction {
13471352
}) => ident.clone(),
13481353
syn::Pat::Wild(_) => syn::Ident::new(&format!("__genarg_{}", i), Span::call_site()),
13491354
_ => bail_span!(
1350-
arg.pat,
1355+
arg.pat_type.pat,
13511356
"unsupported pattern in #[wasm_bindgen] imported function",
13521357
),
13531358
};
@@ -1542,7 +1547,7 @@ impl ToTokens for DescribeImport<'_> {
15421547
ast::ImportKind::Type(_) => return,
15431548
ast::ImportKind::Enum(_) => return,
15441549
};
1545-
let argtys = f.function.arguments.iter().map(|arg| &arg.ty);
1550+
let argtys = f.function.arguments.iter().map(|arg| &arg.pat_type.ty);
15461551
let nargs = f.function.arguments.len() as u32;
15471552
let inform_ret = match &f.js_ret {
15481553
Some(ref t) => quote! { <#t as WasmDescribe>::describe(); },

crates/backend/src/encode.rs

+22-12
Original file line numberDiff line numberDiff line change
@@ -215,24 +215,34 @@ fn shared_export<'a>(
215215
}
216216

217217
fn shared_function<'a>(func: &'a ast::Function, _intern: &'a Interner) -> Function<'a> {
218-
let arg_names = func
219-
.arguments
220-
.iter()
221-
.enumerate()
222-
.map(|(idx, arg)| {
223-
if let syn::Pat::Ident(x) = &*arg.pat {
224-
return x.ident.unraw().to_string();
225-
}
226-
format!("arg{}", idx)
227-
})
228-
.collect::<Vec<_>>();
218+
let args =
219+
func.arguments
220+
.iter()
221+
.enumerate()
222+
.map(|(idx, arg)| FunctionArgumentData {
223+
// use argument's "js_name" if it was provided via attributes
224+
// if not use the original Rust argument ident
225+
name: arg.js_name.clone().unwrap_or(
226+
if let syn::Pat::Ident(x) = &*arg.pat_type.pat {
227+
x.ident.unraw().to_string()
228+
} else {
229+
format!("arg{}", idx)
230+
},
231+
),
232+
ty_override: arg.js_type.as_deref(),
233+
desc: arg.desc.as_deref(),
234+
})
235+
.collect::<Vec<_>>();
236+
229237
Function {
230-
arg_names,
238+
args,
231239
asyncness: func.r#async,
232240
name: &func.name,
233241
generate_typescript: func.generate_typescript,
234242
generate_jsdoc: func.generate_jsdoc,
235243
variadic: func.variadic,
244+
ret_ty_override: func.ret.as_ref().and_then(|v| v.js_type.as_deref()),
245+
ret_desc: func.ret.as_ref().and_then(|v| v.desc.as_deref()),
236246
}
237247
}
238248

crates/cli-support/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ rustc-demangle = "0.1.13"
2121
serde = { version = "1.0", features = ["derive"] }
2222
serde_json = "1.0"
2323
tempfile = "3.0"
24-
unicode-ident = "1.0.5"
2524
walrus = { version = "0.23", features = ['parallel'] }
2625
wasm-bindgen-externref-xform = { path = '../externref-xform', version = '=0.2.99' }
2726
wasm-bindgen-multi-value-xform = { path = '../multi-value-xform', version = '=0.2.99' }

crates/cli-support/src/descriptor.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::char;
22

3-
use crate::js::identifier::is_valid_ident;
3+
use wasm_bindgen_shared::identifier::is_valid_ident;
44

55
macro_rules! tys {
66
($($a:ident)*) => (tys! { @ ($($a)*) 0 });

0 commit comments

Comments
 (0)