Skip to content

Commit

Permalink
Add attributes to overwrite return and parameter types, descriptions …
Browse files Browse the repository at this point in the history
…and names (#4394)
  • Loading branch information
rouzwelt authored Jan 12, 2025
1 parent 949b6c6 commit b34ac03
Show file tree
Hide file tree
Showing 34 changed files with 1,528 additions and 154 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

### Added

* 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.
[#4394](https://github.com/rustwasm/wasm-bindgen/pull/4394)

* Add a `copy_to_uninit()` method to all `TypedArray`s. It takes `&mut [MaybeUninit<T>]` and returns `&mut [T]`.
[#4340](https://github.com/rustwasm/wasm-bindgen/pull/4340)

Expand Down
32 changes: 29 additions & 3 deletions crates/backend/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,9 +375,9 @@ pub struct Function {
/// Whether the function has a js_name attribute
pub renamed_via_js_name: bool,
/// The arguments to the function
pub arguments: Vec<syn::PatType>,
/// The return type of the function, if provided
pub ret: Option<syn::Type>,
pub arguments: Vec<FunctionArgumentData>,
/// The data of return type of the function
pub ret: Option<FunctionReturnData>,
/// Any custom attributes being applied to the function
pub rust_attrs: Vec<syn::Attribute>,
/// The visibility of this function in Rust
Expand All @@ -394,6 +394,32 @@ pub struct Function {
pub variadic: bool,
}

/// Information about a function's return
#[cfg_attr(feature = "extra-traits", derive(Debug))]
#[derive(Clone)]
pub struct FunctionReturnData {
/// Specifies the type of the function's return
pub r#type: syn::Type,
/// Specifies the JS return type override
pub js_type: Option<String>,
/// Specifies the return description
pub desc: Option<String>,
}

/// Information about a function's argument
#[cfg_attr(feature = "extra-traits", derive(Debug))]
#[derive(Clone)]
pub struct FunctionArgumentData {
/// Specifies the type of the function's argument
pub pat_type: syn::PatType,
/// Specifies the JS argument name override
pub js_name: Option<String>,
/// Specifies the JS function argument type override
pub js_type: Option<String>,
/// Specifies the argument description
pub desc: Option<String>,
}

/// Information about a Struct being exported
#[cfg_attr(feature = "extra-traits", derive(Debug))]
#[derive(Clone)]
Expand Down
21 changes: 13 additions & 8 deletions crates/backend/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ impl TryToTokens for ast::Export {

let mut argtys = Vec::new();
for (i, arg) in self.function.arguments.iter().enumerate() {
argtys.push(&*arg.ty);
argtys.push(&*arg.pat_type.ty);
let i = i + offset;
let ident = Ident::new(&format!("arg{}", i), Span::call_site());
fn unwrap_nested_types(ty: &syn::Type) -> &syn::Type {
Expand All @@ -647,7 +647,7 @@ impl TryToTokens for ast::Export {
_ => ty,
}
}
let ty = unwrap_nested_types(&arg.ty);
let ty = unwrap_nested_types(&arg.pat_type.ty);

match &ty {
syn::Type::Reference(syn::TypeReference {
Expand Down Expand Up @@ -720,7 +720,12 @@ impl TryToTokens for ast::Export {
elems: Default::default(),
paren_token: Default::default(),
});
let syn_ret = self.function.ret.as_ref().unwrap_or(&syn_unit);
let syn_ret = self
.function
.ret
.as_ref()
.map(|ret| &ret.r#type)
.unwrap_or(&syn_unit);
if let syn::Type::Reference(_) = syn_ret {
bail_span!(syn_ret, "cannot return a borrowed ref with #[wasm_bindgen]",)
}
Expand Down Expand Up @@ -1323,7 +1328,7 @@ impl TryToTokens for ast::ImportFunction {
ast::ImportFunctionKind::Normal => {}
}
let vis = &self.function.rust_vis;
let ret = match &self.function.ret {
let ret = match self.function.ret.as_ref().map(|ret| &ret.r#type) {
Some(ty) => quote! { -> #ty },
None => quote!(),
};
Expand All @@ -1337,8 +1342,8 @@ impl TryToTokens for ast::ImportFunction {
let wasm_bindgen_futures = &self.wasm_bindgen_futures;

for (i, arg) in self.function.arguments.iter().enumerate() {
let ty = &arg.ty;
let name = match &*arg.pat {
let ty = &arg.pat_type.ty;
let name = match &*arg.pat_type.pat {
syn::Pat::Ident(syn::PatIdent {
by_ref: None,
ident,
Expand All @@ -1347,7 +1352,7 @@ impl TryToTokens for ast::ImportFunction {
}) => ident.clone(),
syn::Pat::Wild(_) => syn::Ident::new(&format!("__genarg_{}", i), Span::call_site()),
_ => bail_span!(
arg.pat,
arg.pat_type.pat,
"unsupported pattern in #[wasm_bindgen] imported function",
),
};
Expand Down Expand Up @@ -1542,7 +1547,7 @@ impl ToTokens for DescribeImport<'_> {
ast::ImportKind::Type(_) => return,
ast::ImportKind::Enum(_) => return,
};
let argtys = f.function.arguments.iter().map(|arg| &arg.ty);
let argtys = f.function.arguments.iter().map(|arg| &arg.pat_type.ty);
let nargs = f.function.arguments.len() as u32;
let inform_ret = match &f.js_ret {
Some(ref t) => quote! { <#t as WasmDescribe>::describe(); },
Expand Down
34 changes: 22 additions & 12 deletions crates/backend/src/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,24 +215,34 @@ fn shared_export<'a>(
}

fn shared_function<'a>(func: &'a ast::Function, _intern: &'a Interner) -> Function<'a> {
let arg_names = func
.arguments
.iter()
.enumerate()
.map(|(idx, arg)| {
if let syn::Pat::Ident(x) = &*arg.pat {
return x.ident.unraw().to_string();
}
format!("arg{}", idx)
})
.collect::<Vec<_>>();
let args =
func.arguments
.iter()
.enumerate()
.map(|(idx, arg)| FunctionArgumentData {
// use argument's "js_name" if it was provided via attributes
// if not use the original Rust argument ident
name: arg.js_name.clone().unwrap_or(
if let syn::Pat::Ident(x) = &*arg.pat_type.pat {
x.ident.unraw().to_string()
} else {
format!("arg{}", idx)
},
),
ty_override: arg.js_type.as_deref(),
desc: arg.desc.as_deref(),
})
.collect::<Vec<_>>();

Function {
arg_names,
args,
asyncness: func.r#async,
name: &func.name,
generate_typescript: func.generate_typescript,
generate_jsdoc: func.generate_jsdoc,
variadic: func.variadic,
ret_ty_override: func.ret.as_ref().and_then(|v| v.js_type.as_deref()),
ret_desc: func.ret.as_ref().and_then(|v| v.desc.as_deref()),
}
}

Expand Down
1 change: 0 additions & 1 deletion crates/cli-support/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ rustc-demangle = "0.1.13"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tempfile = "3.0"
unicode-ident = "1.0.5"
walrus = { version = "0.23", features = ['parallel'] }
wasm-bindgen-externref-xform = { path = '../externref-xform', version = '=0.2.99' }
wasm-bindgen-multi-value-xform = { path = '../multi-value-xform', version = '=0.2.99' }
Expand Down
2 changes: 1 addition & 1 deletion crates/cli-support/src/descriptor.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::char;

use crate::js::identifier::is_valid_ident;
use wasm_bindgen_shared::identifier::is_valid_ident;

macro_rules! tys {
($($a:ident)*) => (tys! { @ ($($a)*) 0 });
Expand Down
Loading

0 comments on commit b34ac03

Please sign in to comment.