From ee025c2a2c1fb99aabb3ab8d9128da036198e631 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Sat, 3 Feb 2024 10:31:24 +0100 Subject: [PATCH] Fix `#[wasm_bindgen(js_name = default)]` for module imports --- CHANGELOG.md | 3 ++ crates/macro-support/src/parser.rs | 53 ++++++++++++++++++------------ 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f51e847c4f5..2ba4d9acf70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,9 @@ * Fixed temporary folder detection by `wasm-bindgen-test-runner` on MacOS. [#3817](https://github.com/rustwasm/wasm-bindgen/pull/3817) +* Fixed using `#[wasm_bindgen(js_name = default)]` with `#[wasm_bindgen(module = ...)]`. + [#3823](https://github.com/rustwasm/wasm-bindgen/pull/3823) + ## [0.2.90](https://github.com/rustwasm/wasm-bindgen/compare/0.2.89...0.2.90) Released 2024-01-06 diff --git a/crates/macro-support/src/parser.rs b/crates/macro-support/src/parser.rs index 39ab459f864..eee4f66e95d 100644 --- a/crates/macro-support/src/parser.rs +++ b/crates/macro-support/src/parser.rs @@ -505,6 +505,7 @@ impl<'a> ConvertToAst<(&ast::Program, BindgenAttrs, &'a Option for syn::ItemFn { false, None, false, + None, )?; attrs.check_used(); Ok(ret.0) } } -pub(crate) fn is_js_keyword(keyword: &str) -> bool { - JS_KEYWORDS.contains(&keyword) +pub(crate) fn is_js_keyword(keyword: &str, skip: Option<&[&str]>) -> bool { + JS_KEYWORDS + .iter() + .filter(|keyword| skip.filter(|skip| skip.contains(keyword)).is_none()) + .any(|this| *this == keyword) } /// Construct a function (and gets the self type if appropriate) for our AST from a syn function. @@ -814,6 +819,7 @@ fn function_from_decl( allow_self: bool, self_ty: Option<&Ident>, is_from_impl: bool, + skip_keywords: Option<&[&str]>, ) -> Result<(ast::Function, Option), Diagnostic> { if sig.variadic.is_some() { bail_span!(sig.variadic, "can't #[wasm_bindgen] variadic functions"); @@ -852,7 +858,7 @@ fn function_from_decl( let replace_colliding_arg = |i: &mut syn::PatType| { if let syn::Pat::Ident(ref mut i) = *i.pat { let ident = i.ident.to_string(); - if is_js_keyword(ident.as_str()) { + if is_js_keyword(ident.as_str(), skip_keywords) { i.ident = Ident::new(format!("_{}", ident).as_str(), i.ident.span()); } } @@ -889,29 +895,33 @@ fn function_from_decl( syn::ReturnType::Type(_, ty) => Some(replace_self(*ty)), }; - let (name, name_span, renamed_via_js_name) = if let Some((js_name, js_name_span)) = - opts.js_name() - { - let kind = operation_kind(opts); - let prefix = match kind { - OperationKind::Setter(_) => "set_", - _ => "", - }; - let name = if prefix.is_empty() && opts.method().is_none() && is_js_keyword(js_name) { - format!("_{}", js_name) + let (name, name_span, renamed_via_js_name) = + if let Some((js_name, js_name_span)) = opts.js_name() { + let kind = operation_kind(opts); + let prefix = match kind { + OperationKind::Setter(_) => "set_", + _ => "", + }; + let name = if prefix.is_empty() + && opts.method().is_none() + && is_js_keyword(js_name, skip_keywords) + { + format!("_{}", js_name) + } else { + format!("{}{}", prefix, js_name) + }; + (name, js_name_span, true) } else { - format!("{}{}", prefix, js_name) - }; - (name, js_name_span, true) - } else { - let name = - if !is_from_impl && opts.method().is_none() && is_js_keyword(&decl_name.to_string()) { + let name = if !is_from_impl + && opts.method().is_none() + && is_js_keyword(&decl_name.to_string(), skip_keywords) + { format!("_{}", decl_name) } else { decl_name.to_string() }; - (name, decl_name.span(), false) - }; + (name, decl_name.span(), false) + }; Ok(( ast::Function { arguments, @@ -1188,6 +1198,7 @@ impl<'a> MacroParse<&ClassMarker> for &'a mut syn::ImplItemFn { true, Some(class), true, + None, )?; let method_kind = if opts.constructor().is_some() { ast::MethodKind::Constructor