From 1291efda04ab7cd72cf6e9628d81b55486ce4cd3 Mon Sep 17 00:00:00 2001 From: Oscar Beaumont Date: Sun, 24 Dec 2023 20:26:41 +0800 Subject: [PATCH] fix #196 - fix Specta with wasm bindgen --- Cargo.toml | 1 + macros/src/specta.rs | 14 ++++++++++++++ macros/src/utils.rs | 8 +++++--- tests/macro/compile_error.rs | 4 ++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b2d21e12..9f2cd246 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -139,3 +139,4 @@ once_cell = "1.18.0" doc-comment = "0.3.3" serde = { version = "1.0.183", features = ["derive"] } trybuild = "1.0.82" +wasm-bindgen = "0.2.89" diff --git a/macros/src/specta.rs b/macros/src/specta.rs index dffe3f9d..ceec4b53 100644 --- a/macros/src/specta.rs +++ b/macros/src/specta.rs @@ -10,6 +10,20 @@ pub fn attribute(item: proc_macro::TokenStream) -> syn::Result(item)?; let wrapper = format_fn_wrapper(&function.sig.ident); + // While using wasm_bindgen and Specta is rare, this should make the DX nicer. + if function.sig.unsafety.is_some() + && function + .sig + .ident + .to_string() + .starts_with("__wasm_bindgen_generated") + { + return Err(syn::Error::new_spanned( + function.sig.ident, + "specta: You must apply the #[specta] macro before the #[wasm_bindgen] macro", + )); + } + let visibility = &function.vis; let (maybe_macro_export, pub_the_trait) = match &visibility { Visibility::Public(_) => (quote!(#[macro_export]), Default::default()), diff --git a/macros/src/utils.rs b/macros/src/utils.rs index c68e7042..ad232642 100644 --- a/macros/src/utils.rs +++ b/macros/src/utils.rs @@ -168,9 +168,11 @@ pub fn parse_attrs(attrs: &[syn::Attribute]) -> syn::Result> { for attr in attrs { let ident = attr .path - .get_ident() - .expect("Attribute path must be an ident") - .clone(); + .segments + .last() + .expect("Attribute path must have at least one segment") + .clone() + .ident; // TODO: We should somehow build this up from the macro output automatically -> if not our attribute parser is applied to stuff like `allow` and that's bad. if !(ident == "specta" diff --git a/tests/macro/compile_error.rs b/tests/macro/compile_error.rs index f4209468..15260078 100644 --- a/tests/macro/compile_error.rs +++ b/tests/macro/compile_error.rs @@ -103,4 +103,8 @@ pub struct InvalidSpectaAttribute1; #[specta = "todo"] pub struct InvalidSpectaAttribute2; +#[wasm_bindgen::prelude::wasm_bindgen] +#[specta] +pub fn testing() {} + // TODO: https://docs.rs/trybuild/latest/trybuild/#what-to-test