diff --git a/crates/backend/src/ast.rs b/crates/backend/src/ast.rs index 12305bb1..a75a8526 100644 --- a/crates/backend/src/ast.rs +++ b/crates/backend/src/ast.rs @@ -251,7 +251,8 @@ pub struct StructField { #[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))] #[derive(Clone)] pub struct Enum { - pub name: Ident, + pub rust_name: Ident, + pub js_name: String, pub variants: Vec, pub comments: Vec, pub hole: u32, diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs index ba515c0a..ef1ccc1f 100644 --- a/crates/backend/src/codegen.rs +++ b/crates/backend/src/codegen.rs @@ -1113,7 +1113,7 @@ impl<'a> ToTokens for DescribeImport<'a> { impl ToTokens for ast::Enum { fn to_tokens(&self, into: &mut TokenStream) { - let enum_name = &self.name; + let enum_name = &self.rust_name; let hole = &self.hole; let cast_clauses = self.variants.iter().map(|variant| { let variant_name = &variant.name; diff --git a/crates/backend/src/encode.rs b/crates/backend/src/encode.rs index 67e6bd64..4e4faf45 100644 --- a/crates/backend/src/encode.rs +++ b/crates/backend/src/encode.rs @@ -212,7 +212,7 @@ fn shared_function<'a>(func: &'a ast::Function, _intern: &'a Interner) -> Functi fn shared_enum<'a>(e: &'a ast::Enum, intern: &'a Interner) -> Enum<'a> { Enum { - name: intern.intern(&e.name), + name: &e.js_name, variants: e .variants .iter() diff --git a/crates/macro-support/src/parser.rs b/crates/macro-support/src/parser.rs index b4850bc1..a44eed84 100644 --- a/crates/macro-support/src/parser.rs +++ b/crates/macro-support/src/parser.rs @@ -1058,7 +1058,6 @@ impl<'a> MacroParse<(&'a mut TokenStream, BindgenAttrs)> for syn::ItemEnum { bail_span!(self, "cannot export empty enums to JS"); } let generate_typescript = opts.skip_typescript().is_none(); - opts.check_used()?; // Check if the first value is a string literal match self.variants[0].discriminant { @@ -1069,10 +1068,16 @@ impl<'a> MacroParse<(&'a mut TokenStream, BindgenAttrs)> for syn::ItemEnum { lit: syn::Lit::Str(_), }), )) => { + opts.check_used()?; return import_enum(self, program); } _ => {} } + let js_name = opts + .js_name() + .map(|s| s.0) + .map_or_else(|| self.ident.to_string(), |s| s.to_string()); + opts.check_used()?; let has_discriminant = self.variants[0].discriminant.is_some(); @@ -1155,7 +1160,8 @@ impl<'a> MacroParse<(&'a mut TokenStream, BindgenAttrs)> for syn::ItemEnum { self.to_tokens(tokens); program.enums.push(ast::Enum { - name: self.ident, + rust_name: self.ident, + js_name, variants, comments, hole, diff --git a/tests/wasm/enums.js b/tests/wasm/enums.js index 4a4debb2..7a78c060 100644 --- a/tests/wasm/enums.js +++ b/tests/wasm/enums.js @@ -28,3 +28,7 @@ exports.js_expect_enum = (a, b) => { exports.js_expect_enum_none = a => { assert.strictEqual(a, undefined); }; + +exports.js_renamed_enum = b => { + assert.strictEqual(wasm.JsRenamedEnum.B, b); +}; diff --git a/tests/wasm/enums.rs b/tests/wasm/enums.rs index f6bacad9..959a3e27 100644 --- a/tests/wasm/enums.rs +++ b/tests/wasm/enums.rs @@ -9,6 +9,7 @@ extern "C" { fn js_handle_optional_enums(x: Option) -> Option; fn js_expect_enum(x: Color, y: Option); fn js_expect_enum_none(x: Option); + fn js_renamed_enum(b: RenamedEnum); } #[wasm_bindgen] @@ -30,6 +31,13 @@ pub mod inner { } } +#[wasm_bindgen(js_name = JsRenamedEnum)] +#[derive(Copy, Clone)] +pub enum RenamedEnum { + A = 10, + B = 20, +} + #[wasm_bindgen] pub fn enum_cycle(color: Color) -> Color { match color { @@ -82,3 +90,8 @@ fn test_optional_enum_values() { js_expect_enum(Red, Some(Red)); js_expect_enum_none(None); } + +#[wasm_bindgen_test] +fn test_renamed_enum() { + js_renamed_enum(RenamedEnum::B); +}