macro_wasmer_universal_test/
lib.rs

1use proc_macro2::{Ident, Span, TokenStream};
2use syn::{
3    parse::{Parse, ParseStream},
4    Attribute, Signature, Visibility,
5};
6
7#[proc_macro_attribute]
8pub fn universal_test(
9    _attr: proc_macro::TokenStream,
10    item: proc_macro::TokenStream,
11) -> proc_macro::TokenStream {
12    let MaybeItemFn {
13        outer_attrs,
14        inner_attrs,
15        vis,
16        sig,
17        block,
18    } = syn::parse_macro_input!(item as MaybeItemFn);
19
20    let fn_call = Ident::new(&sig.ident.to_string(), Span::call_site());
21    let fn_js_call = Ident::new(&format!("{}_js", sig.ident), Span::call_site());
22
23    let tokens = quote::quote! {
24        #[cfg(feature = "js")]
25        #[cfg_attr(feature = "js", wasm_bindgen_test)]
26        #(#outer_attrs) *
27        fn #fn_js_call() { #fn_call().unwrap(); }
28
29        #[cfg_attr(any(feature = "sys", feature = "jsc", feature = "wasm-c-api"), test)]
30        #(#outer_attrs) *
31        #vis #sig
32        {
33            #(#inner_attrs) *
34            #block
35        }
36    };
37
38    proc_macro::TokenStream::from(tokens)
39}
40
41// ---- Taken from tracing::instrument ----
42// This is a more flexible/imprecise `ItemFn` type,
43// which's block is just a `TokenStream` (it may contain invalid code).
44#[derive(Debug, Clone)]
45struct MaybeItemFn {
46    outer_attrs: Vec<Attribute>,
47    inner_attrs: Vec<Attribute>,
48    vis: Visibility,
49    sig: Signature,
50    block: TokenStream,
51}
52
53/// This parses a `TokenStream` into a `MaybeItemFn`
54/// (just like `ItemFn`, but skips parsing the body).
55impl Parse for MaybeItemFn {
56    fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
57        let outer_attrs = input.call(Attribute::parse_outer)?;
58        let vis: Visibility = input.parse()?;
59        let sig: Signature = input.parse()?;
60        let inner_attrs = input.call(Attribute::parse_inner)?;
61        let block: TokenStream = input.parse()?;
62        Ok(Self {
63            outer_attrs,
64            inner_attrs,
65            vis,
66            sig,
67            block,
68        })
69    }
70}