4 // Proc macros commonly used by tests.
5 // `panic`/`print` -> `panic_bang`/`print_bang` to avoid conflicts with standard macros.
7 #![crate_type = "proc-macro"]
9 extern crate proc_macro;
10 use proc_macro::{TokenStream, TokenTree};
12 // Macro that return empty token stream.
15 pub fn empty(_: TokenStream) -> TokenStream {
19 #[proc_macro_attribute]
20 pub fn empty_attr(_: TokenStream, _: TokenStream) -> TokenStream {
24 #[proc_macro_derive(Empty, attributes(empty_helper))]
25 pub fn empty_derive(_: TokenStream) -> TokenStream {
32 pub fn panic_bang(_: TokenStream) -> TokenStream {
36 #[proc_macro_attribute]
37 pub fn panic_attr(_: TokenStream, _: TokenStream) -> TokenStream {
41 #[proc_macro_derive(Panic, attributes(panic_helper))]
42 pub fn panic_derive(_: TokenStream) -> TokenStream {
43 panic!("panic-derive");
46 // Macros that return the input stream.
49 pub fn identity(input: TokenStream) -> TokenStream {
53 #[proc_macro_attribute]
54 pub fn identity_attr(_: TokenStream, input: TokenStream) -> TokenStream {
58 #[proc_macro_derive(Identity, attributes(identity_helper))]
59 pub fn identity_derive(input: TokenStream) -> TokenStream {
63 // Macros that iterate and re-collect the input stream.
66 pub fn recollect(input: TokenStream) -> TokenStream {
67 input.into_iter().collect()
70 #[proc_macro_attribute]
71 pub fn recollect_attr(_: TokenStream, input: TokenStream) -> TokenStream {
72 input.into_iter().collect()
75 #[proc_macro_derive(Recollect, attributes(recollect_helper))]
76 pub fn recollect_derive(input: TokenStream) -> TokenStream {
77 input.into_iter().collect()
80 // Macros that print their input in the original and re-collected forms (if they differ).
82 fn print_helper(input: TokenStream, kind: &str) -> TokenStream {
83 print_helper_ext(input, kind, true)
86 fn print_helper_ext(input: TokenStream, kind: &str, debug: bool) -> TokenStream {
87 let input_display = format!("{}", input);
88 let input_debug = format!("{:#?}", input);
89 let recollected = input.into_iter().collect();
90 let recollected_display = format!("{}", recollected);
91 let recollected_debug = format!("{:#?}", recollected);
92 println!("PRINT-{} INPUT (DISPLAY): {}", kind, input_display);
93 if recollected_display != input_display {
94 println!("PRINT-{} RE-COLLECTED (DISPLAY): {}", kind, recollected_display);
97 println!("PRINT-{} INPUT (DEBUG): {}", kind, input_debug);
98 if recollected_debug != input_debug {
99 println!("PRINT-{} RE-COLLECTED (DEBUG): {}", kind, recollected_debug);
106 pub fn print_bang(input: TokenStream) -> TokenStream {
107 print_helper(input, "BANG")
111 pub fn print_bang_consume(input: TokenStream) -> TokenStream {
112 print_helper(input, "BANG");
116 #[proc_macro_attribute]
117 pub fn print_attr(args: TokenStream, input: TokenStream) -> TokenStream {
118 let debug = match &args.into_iter().collect::<Vec<_>>()[..] {
119 [TokenTree::Ident(ident)] if ident.to_string() == "nodebug" => false,
122 print_helper_ext(input, "ATTR", debug)
125 #[proc_macro_attribute]
126 pub fn print_attr_args(args: TokenStream, input: TokenStream) -> TokenStream {
127 print_helper(args, "ATTR_ARGS");
131 #[proc_macro_attribute]
132 pub fn print_target_and_args(args: TokenStream, input: TokenStream) -> TokenStream {
133 print_helper(args, "ATTR_ARGS");
134 print_helper(input.clone(), "ATTR");
138 #[proc_macro_attribute]
139 pub fn print_target_and_args_consume(args: TokenStream, input: TokenStream) -> TokenStream {
140 print_helper(args, "ATTR_ARGS");
141 print_helper(input.clone(), "ATTR");
145 #[proc_macro_derive(Print, attributes(print_helper))]
146 pub fn print_derive(input: TokenStream) -> TokenStream {
147 print_helper(input, "DERIVE");