Work-in-progress

This commit is contained in:
Edward Shen 2024-10-01 20:53:32 -07:00
parent 96de63cb10
commit 85b49cfc74
Signed by: edward
GPG key ID: 0A400FFE10097C30
4 changed files with 18 additions and 13 deletions

1
Cargo.lock generated
View file

@ -138,6 +138,7 @@ dependencies = [
name = "teto_macros" name = "teto_macros"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"proc-macro2",
"quote", "quote",
"syn", "syn",
"teto", "teto",

View file

@ -10,6 +10,7 @@ proc-macro = true
[dependencies] [dependencies]
syn = { version = "2.0.77", features = ["full", "extra-traits"] } syn = { version = "2.0.77", features = ["full", "extra-traits"] }
quote = "1.0.37" quote = "1.0.37"
proc-macro2 = "1.0.86"
[dev-dependencies] [dev-dependencies]
teto = { version = "*", path = "../teto", features = ["macros"] } teto = { version = "*", path = "../teto", features = ["macros"] }

View file

@ -6,21 +6,13 @@ use quote::quote;
use syn::{FnArg, ItemFn}; use syn::{FnArg, ItemFn};
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn test(_args: TokenStream, tokens: TokenStream) -> TokenStream { pub fn test(args: TokenStream, tokens: TokenStream) -> TokenStream {
let ItemFn { let ItemFn {
attrs, attrs,
vis, vis,
mut sig, mut sig,
block, block,
} = match syn::parse(tokens) { } = parse_token(args, tokens)?;
Ok(inner) => inner,
Err(e) => {
return TokenStream::from(
syn::Error::new(e.span(), "teto::test can only be called on functions")
.to_compile_error(),
)
}
};
let inputs = std::mem::take(&mut sig.inputs); let inputs = std::mem::take(&mut sig.inputs);
// Since this macro replaces #[test], we can assume that the only arg (if // Since this macro replaces #[test], we can assume that the only arg (if
@ -31,8 +23,8 @@ pub fn test(_args: TokenStream, tokens: TokenStream) -> TokenStream {
}); });
let inner_fn_invocation = if let Some(test_token_name) = test_token_name { let inner_fn_invocation = if let Some(test_token_name) = test_token_name {
quote! { quote! {
let token = const { #test_token_name::__private_teto_macros_only__create_teto_test_token }; let token = <#test_token_name>::__private_teto_macros_only__create_teto_test_token();
inner(token()) inner(token)
} }
} else { } else {
quote! { quote! {
@ -56,6 +48,17 @@ pub fn test(_args: TokenStream, tokens: TokenStream) -> TokenStream {
}; };
TokenStream::from(wrapped) TokenStream::from(wrapped)
}q
fn parse_token(args: TokenStream, tokens: TokenStream) -> syn::Result<ItemFn> {
if !args.is_empty() {
return Err(syn::Error::new_spanned(
proc_macro2::TokenStream::from(args),
"teto macros do not accept arguments",
));
}
syn::parse(tokens)
.map_err(|e| syn::Error::new(e.span(), "teto::test can only be called on functions"))
} }
// #[proc_macro_attribute] // #[proc_macro_attribute]

View file

@ -1,6 +1,6 @@
#[test] #[test]
fn ui() { fn ui() {
let t = trybuild::TestCases::new(); let t = trybuild::TestCases::new();
t.pass("tests/ui/pass/*.rs");
t.compile_fail("tests/ui/compile_fail/*.rs"); t.compile_fail("tests/ui/compile_fail/*.rs");
t.pass("tests/ui/pass/*.rs");
} }