#![forbid(unsafe_code)]
#![allow(deprecated)]
#![deny(missing_docs)]
mod attrs;
mod function_expand;
mod macro_expand;
mod module_expand;
mod native_class_expand;
mod native_macro_expand;
mod native_number_expand;
mod parse;
mod shape;
use attrs::{bool_attr, camel_case, string_attr};
use parse::ParsedModule;
use proc_macro::TokenStream;
use proc_macro2::Span;
use quote::{format_ident, quote};
use syn::{ItemMod, LitStr, Token, parse_macro_input, punctuated::Punctuated};
#[proc_macro_attribute]
pub fn sim_lib(attr: TokenStream, item: TokenStream) -> TokenStream {
let attr =
parse_macro_input!(attr with Punctuated::<syn::MetaNameValue, Token![,]>::parse_terminated);
let mut module = parse_macro_input!(item as ItemMod);
let lib_id = match string_attr(&attr, "id") {
Ok(value) => value,
Err(err) => return err,
};
let version = match string_attr(&attr, "version") {
Ok(value) => value,
Err(err) => return err,
};
let native_export = match bool_attr(&attr, "native_export") {
Ok(value) => value,
Err(err) => return err,
};
let Some((_, items)) = &mut module.content else {
return syn::Error::new_spanned(&module, "#[sim_lib] requires an inline module")
.to_compile_error()
.into();
};
let parsed = match ParsedModule::parse(items) {
Ok(parsed) => parsed,
Err(err) => return err.to_compile_error().into(),
};
let lib_ident = format_ident!("{}Lib", camel_case(&module.ident.to_string()));
let generated = match parsed.expand(&module.vis, &lib_ident, &lib_id, &version, native_export) {
Ok(generated) => generated,
Err(err) => return err.to_compile_error().into(),
};
let expansion_text = generated.to_string();
let expansion_text = LitStr::new(&expansion_text, Span::call_site());
*items = parsed.cleaned_items;
items.push(syn::parse_quote! {
pub const __SIM_LIB_EXPANSION: &str = #expansion_text;
});
items.extend(
syn::parse2::<syn::File>(generated)
.expect("generated sim_lib items should parse")
.items,
);
quote!(#module).into()
}
#[proc_macro_attribute]
pub fn sim_class(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}
#[proc_macro_attribute]
pub fn sim_constructor(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}
#[proc_macro_attribute]
pub fn sim_fn(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}
#[proc_macro_attribute]
pub fn sim_macro(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}
#[proc_macro_attribute]
pub fn sim_codec(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}
#[proc_macro_attribute]
pub fn sim_number_domain(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}
#[proc_macro_attribute]
pub fn sim_site(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}
#[proc_macro_attribute]
pub fn case(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}
#[proc_macro_attribute]
pub fn shape(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}
#[cfg(test)]
mod tests;