]> git.proxmox.com Git - perlmod.git/blame - perlmod-macro/src/module.rs
update to syn-2
[perlmod.git] / perlmod-macro / src / module.rs
CommitLineData
b03c1494
WB
1use proc_macro2::TokenStream;
2
3use quote::quote;
b03c1494 4use syn::punctuated::Punctuated;
cb86559d 5use syn::{Error, Meta, Token};
b03c1494
WB
6
7use crate::attribs::FunctionAttrs;
8use crate::package::Package;
9
cb86559d
WB
10pub 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}