use convert_case::{Case, Casing};
use proc_macro::TokenStream;
use proc_macro2::{Ident, Span};
use quote::quote;
use std::error::Error;
const CREATE_FUNCTION_PREFIX: &str = "mlirCreate";
pub fn generate(
names: &[Ident],
extract_pass_name: impl Fn(&str) -> String,
) -> Result<TokenStream, Box<dyn Error>> {
let mut stream = TokenStream::new();
for name in names {
let foreign_name = name.to_string();
let foreign_name = foreign_name.strip_prefix(CREATE_FUNCTION_PREFIX).unwrap();
let pass_name = extract_pass_name(foreign_name);
let function_name = create_function_name("create", &pass_name, name.span());
let document = format!(" Creates a `{}` pass.", pass_name);
stream.extend(TokenStream::from(quote! {
#[doc = #document]
pub fn #function_name() -> crate::pass::Pass {
unsafe { crate::pass::Pass::__private_from_raw_fn(mlir_sys::#name) }
}
}));
let foreign_function_name =
Ident::new(&("mlirRegister".to_owned() + foreign_name), name.span());
let function_name = create_function_name("register", &pass_name, name.span());
let document = format!(" Registers a `{}` pass.", pass_name);
stream.extend(TokenStream::from(quote! {
#[doc = #document]
pub fn #function_name() {
unsafe { mlir_sys::#foreign_function_name() }
}
}));
}
Ok(stream)
}
fn create_function_name(prefix: &str, pass_name: &str, span: Span) -> Ident {
Ident::new(
&format!("{}_{}", prefix, &pass_name.to_case(Case::Snake)),
span,
)
}