1use proc_macro::TokenStream;
4use proc_macro2::{Ident, Span};
5use quote::quote;
6use syn::{parse_quote, ItemFn};
7use zabi::Abi;
8
9pub fn external(mut item: ItemFn) -> TokenStream {
11 item.sig.abi = Some(parse_quote! { extern "C" });
12 item.attrs.push(parse_quote! { #[no_mangle] });
13 item.attrs
14 .push(parse_quote! { #[allow(improper_ctypes_definitions)] });
15
16 let selector: ItemFn = {
17 let func = item.sig.ident.clone().to_string();
18 let ident = Ident::new(&(func.clone() + "_selector"), Span::call_site());
19 let abi = Abi::from(&item.sig).to_hex().expect("ABI is not supported");
20 let abi_len = abi.len() as u32;
21 let doc = " EVM selector for the function `".to_string() + &func + "`";
22
23 parse_quote! {
24 #[no_mangle]
25 #[cfg(target_arch = "wasm32")]
26 #[doc = #doc]
27 pub extern "C" fn #ident() {
28 unsafe {
29 zink::ffi::emit_abi(#abi.as_ptr() as u32, #abi_len);
30 }
31 }
32 }
33 };
34
35 quote! {
36 #item
37
38 #selector
39 }
40 .into()
41}