roc/crates/compiler/test_mono_macros/src/lib.rs
2023-06-06 16:05:12 -05:00

59 lines
1.7 KiB
Rust

//! Macros for use in `test_mono`.
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
#[proc_macro_attribute]
pub fn mono_test(args: TokenStream, item: TokenStream) -> TokenStream {
let mut no_check = false;
let mut allow_type_errors = false;
let mut mode = "exec".to_owned();
let mut large_stack = false;
for arg in syn::parse_macro_input!(args as syn::AttributeArgs) {
use syn::{Lit, Meta, MetaNameValue, NestedMeta};
if let NestedMeta::Meta(Meta::NameValue(MetaNameValue {
path,
eq_token: _,
lit: Lit::Str(s),
})) = arg
{
if path.is_ident("mode") {
mode = s.value();
}
if path.is_ident("no_check") {
no_check = true;
}
if path.is_ident("allow_type_errors") {
allow_type_errors = true;
}
if path.is_ident("large_stack") {
large_stack = true;
}
}
}
let task_fn = syn::parse_macro_input!(item as syn::ItemFn);
let args = task_fn.sig.inputs.clone();
let name = task_fn.sig.ident.clone();
let name_str = name.to_string();
let body = task_fn.block.clone();
let visibility = &task_fn.vis;
let attributes = task_fn.attrs;
let result = quote! {
#[test]
#(#attributes)*
#visibility fn #name(#args) {
if #large_stack {
with_larger_debug_stack(|| compiles_to_ir(#name_str, #body, &#mode, #allow_type_errors, #no_check));
} else {
compiles_to_ir(#name_str, #body, &#mode, #allow_type_errors, #no_check);
}
}
};
result.into()
}