#![forbid(unsafe_code)]
use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use proc_macro_error::{abort_call_site, proc_macro_error};
use quote::quote;
use syn::{parse_macro_input, visit_mut::VisitMut, File};
use crate::pre_attr::PreAttrVisitor;
mod call;
mod call_handling;
mod documentation;
mod extern_crate;
mod helpers;
mod pre_attr;
mod precondition;
cfg_if::cfg_if! {
if #[cfg(nightly)] {
mod const_generics_impl;
pub(crate) use crate::const_generics_impl::{render_assure, render_pre};
} else {
mod struct_impl;
pub(crate) use crate::struct_impl::{render_assure, render_pre};
}
}
#[proc_macro_attribute]
#[proc_macro_error]
pub fn pre(attr: TokenStream, file: TokenStream) -> TokenStream {
let dummy_file: TokenStream2 = file.clone().into();
proc_macro_error::set_dummy(quote! {
#dummy_file
});
let mut file = parse_macro_input!(file as File);
PreAttrVisitor::new(attr.into()).visit_file_mut(&mut file);
let output = quote! {
#file
};
proc_macro_error::set_dummy(quote! {
#output
});
output.into()
}
#[proc_macro_attribute]
#[proc_macro_error]
pub fn assure(_: TokenStream, _: TokenStream) -> TokenStream {
abort_call_site!(
"this attribute by itself is currently non-functional";
help = "use it on an expression in an item wrapped by a `pre` attribute"
)
}
#[proc_macro_attribute]
#[proc_macro_error]
pub fn forward(_: TokenStream, _: TokenStream) -> TokenStream {
abort_call_site!(
"this attribute by itself is currently non-functional";
help = "use it on an expression in an item wrapped by a `pre` attribute"
)
}
#[proc_macro_attribute]
#[proc_macro_error]
pub fn extern_crate(attr: TokenStream, module: TokenStream) -> TokenStream {
let attr = parse_macro_input!(attr as extern_crate::ExternCrateAttr);
let module = parse_macro_input!(module as extern_crate::Module);
let output = module.render(attr);
proc_macro_error::set_dummy(quote! {
#output
});
output.into()
}