]>
Commit | Line | Data |
---|---|---|
b03c1494 WB |
1 | use proc_macro2::TokenStream; |
2 | ||
3 | use quote::quote; | |
b03c1494 | 4 | use syn::punctuated::Punctuated; |
cb86559d | 5 | use syn::{Error, Meta, Token}; |
b03c1494 WB |
6 | |
7 | use crate::attribs::FunctionAttrs; | |
8 | use crate::package::Package; | |
9 | ||
cb86559d WB |
10 | pub fn handle_module( |
11 | attr: Punctuated<Meta, Token![,]>, | |
12 | mut module: syn::ItemMod, | |
13 | ) -> Result<TokenStream, Error> { | |
b03c1494 | 14 | let mut package = Package::with_attrs(attr)?; |
9525acd6 | 15 | let mangled_package_name = package.mangle_package_name(); |
b03c1494 WB |
16 | |
17 | if let Some((_brace, ref mut items)) = module.content { | |
18 | for item in items.iter_mut() { | |
19 | match core::mem::replace(item, syn::Item::Verbatim(TokenStream::new())) { | |
20 | syn::Item::Fn(mut func) => { | |
21 | let mut attribs = None; | |
81e9f757 | 22 | for attr in std::mem::take(&mut func.attrs) { |
cb86559d | 23 | if !attr.path().is_ident("export") { |
b03c1494 WB |
24 | // retain the attribute |
25 | func.attrs.push(attr); | |
cb86559d WB |
26 | continue; |
27 | } | |
28 | if attribs.is_some() { | |
29 | error!(attr => "multiple 'export' attributes not allowed"); | |
30 | continue; | |
b03c1494 | 31 | } |
cb86559d WB |
32 | |
33 | let args = match attr.meta { | |
34 | Meta::Path(_) => Default::default(), | |
35 | Meta::List(list) => list.parse_args_with( | |
36 | Punctuated::<syn::Meta, Token![,]>::parse_terminated, | |
37 | )?, | |
38 | _ => { | |
39 | error!(attr => "invalid 'export' attribute syntax"); | |
40 | continue; | |
41 | } | |
42 | }; | |
43 | ||
44 | attribs = Some(FunctionAttrs::try_from(args)?); | |
b03c1494 WB |
45 | } |
46 | ||
47 | // if we removed an #[export] macro this is an exported function: | |
48 | if let Some(attribs) = attribs { | |
9525acd6 WB |
49 | let func = crate::function::handle_function( |
50 | attribs, | |
51 | func, | |
52 | Some(&mangled_package_name), | |
54919078 | 53 | false, |
9525acd6 | 54 | )?; |
b03c1494 WB |
55 | *item = syn::Item::Verbatim(func.tokens); |
56 | ||
4b5b75f1 WB |
57 | package.export_named( |
58 | func.rust_name, | |
59 | func.perl_name, | |
60 | func.xs_name, | |
61 | func.prototype, | |
62 | ); | |
b03c1494 WB |
63 | } else { |
64 | *item = syn::Item::Fn(func); | |
65 | } | |
66 | } | |
67 | other => *item = other, | |
68 | } | |
69 | } | |
83f19b95 WB |
70 | |
71 | items.push(syn::Item::Verbatim(package.bootstrap_function())); | |
b03c1494 WB |
72 | } |
73 | ||
c15e1e14 WB |
74 | if package.attrs.write == Some(true) |
75 | || package.attrs.file_name.is_some() | |
daf48419 WB |
76 | || std::env::var("PERLMOD_WRITE_PACKAGES").ok().as_deref() == Some("1") |
77 | { | |
78 | package.write()?; | |
79 | } | |
b03c1494 WB |
80 | |
81 | Ok(quote! { #module }) | |
82 | } |