• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // force-host
2 // no-prefer-dynamic
3 
4 // Proc macros commonly used by tests.
5 // `panic`/`print` -> `panic_bang`/`print_bang` to avoid conflicts with standard macros.
6 
7 #![crate_type = "proc-macro"]
8 
9 extern crate proc_macro;
10 use proc_macro::{TokenStream, TokenTree};
11 
12 // Macro that return empty token stream.
13 
14 #[proc_macro]
empty(_: TokenStream) -> TokenStream15 pub fn empty(_: TokenStream) -> TokenStream {
16     TokenStream::new()
17 }
18 
19 #[proc_macro_attribute]
empty_attr(_: TokenStream, _: TokenStream) -> TokenStream20 pub fn empty_attr(_: TokenStream, _: TokenStream) -> TokenStream {
21     TokenStream::new()
22 }
23 
24 #[proc_macro_derive(Empty, attributes(empty_helper))]
empty_derive(_: TokenStream) -> TokenStream25 pub fn empty_derive(_: TokenStream) -> TokenStream {
26     TokenStream::new()
27 }
28 
29 // Macro that panics.
30 
31 #[proc_macro]
panic_bang(_: TokenStream) -> TokenStream32 pub fn panic_bang(_: TokenStream) -> TokenStream {
33     panic!("panic-bang");
34 }
35 
36 #[proc_macro_attribute]
panic_attr(_: TokenStream, _: TokenStream) -> TokenStream37 pub fn panic_attr(_: TokenStream, _: TokenStream) -> TokenStream {
38     panic!("panic-attr");
39 }
40 
41 #[proc_macro_derive(Panic, attributes(panic_helper))]
panic_derive(_: TokenStream) -> TokenStream42 pub fn panic_derive(_: TokenStream) -> TokenStream {
43     panic!("panic-derive");
44 }
45 
46 // Macros that return the input stream.
47 
48 #[proc_macro]
identity(input: TokenStream) -> TokenStream49 pub fn identity(input: TokenStream) -> TokenStream {
50     input
51 }
52 
53 #[proc_macro_attribute]
identity_attr(_: TokenStream, input: TokenStream) -> TokenStream54 pub fn identity_attr(_: TokenStream, input: TokenStream) -> TokenStream {
55     input
56 }
57 
58 #[proc_macro_derive(Identity, attributes(identity_helper))]
identity_derive(input: TokenStream) -> TokenStream59 pub fn identity_derive(input: TokenStream) -> TokenStream {
60     input
61 }
62 
63 // Macros that iterate and re-collect the input stream.
64 
65 #[proc_macro]
recollect(input: TokenStream) -> TokenStream66 pub fn recollect(input: TokenStream) -> TokenStream {
67     input.into_iter().collect()
68 }
69 
70 #[proc_macro_attribute]
recollect_attr(_: TokenStream, input: TokenStream) -> TokenStream71 pub fn recollect_attr(_: TokenStream, input: TokenStream) -> TokenStream {
72     input.into_iter().collect()
73 }
74 
75 #[proc_macro_derive(Recollect, attributes(recollect_helper))]
recollect_derive(input: TokenStream) -> TokenStream76 pub fn recollect_derive(input: TokenStream) -> TokenStream {
77     input.into_iter().collect()
78 }
79 
80 // Macros that print their input in the original and re-collected forms (if they differ).
81 
print_helper(input: TokenStream, kind: &str) -> TokenStream82 fn print_helper(input: TokenStream, kind: &str) -> TokenStream {
83     print_helper_ext(input, kind, true)
84 }
85 
deep_recollect(input: TokenStream) -> TokenStream86 fn deep_recollect(input: TokenStream) -> TokenStream {
87     input.into_iter().map(|tree| {
88         match tree {
89             TokenTree::Group(group) => {
90                 let inner = deep_recollect(group.stream());
91                 let mut new_group = TokenTree::Group(
92                     proc_macro::Group::new(group.delimiter(), inner)
93                 );
94                 new_group.set_span(group.span());
95                 new_group
96             }
97             _ => tree,
98         }
99     }).collect()
100 }
101 
print_helper_ext(input: TokenStream, kind: &str, debug: bool) -> TokenStream102 fn print_helper_ext(input: TokenStream, kind: &str, debug: bool) -> TokenStream {
103     let input_display = format!("{}", input);
104     let input_debug = format!("{:#?}", input);
105     let recollected = input.clone().into_iter().collect();
106     let recollected_display = format!("{}", recollected);
107     let recollected_debug = format!("{:#?}", recollected);
108 
109     let deep_recollected = deep_recollect(input);
110     let deep_recollected_display = format!("{}", deep_recollected);
111     let deep_recollected_debug = format!("{:#?}", deep_recollected);
112 
113 
114 
115     println!("PRINT-{} INPUT (DISPLAY): {}", kind, input_display);
116     if recollected_display != input_display {
117         println!("PRINT-{} RE-COLLECTED (DISPLAY): {}", kind, recollected_display);
118     }
119 
120     if deep_recollected_display != recollected_display {
121         println!("PRINT-{} DEEP-RE-COLLECTED (DISPLAY): {}", kind, deep_recollected_display);
122     }
123 
124     if debug {
125         println!("PRINT-{} INPUT (DEBUG): {}", kind, input_debug);
126         if recollected_debug != input_debug {
127             println!("PRINT-{} RE-COLLECTED (DEBUG): {}", kind, recollected_debug);
128         }
129         if deep_recollected_debug != recollected_debug {
130             println!("PRINT-{} DEEP-RE-COLLETED (DEBUG): {}", kind, deep_recollected_debug);
131         }
132     }
133     recollected
134 }
135 
136 #[proc_macro]
print_bang(input: TokenStream) -> TokenStream137 pub fn print_bang(input: TokenStream) -> TokenStream {
138     print_helper(input, "BANG")
139 }
140 
141 #[proc_macro]
print_bang_consume(input: TokenStream) -> TokenStream142 pub fn print_bang_consume(input: TokenStream) -> TokenStream {
143     print_helper(input, "BANG");
144     TokenStream::new()
145 }
146 
147 #[proc_macro_attribute]
print_attr(args: TokenStream, input: TokenStream) -> TokenStream148 pub fn print_attr(args: TokenStream, input: TokenStream) -> TokenStream {
149     let debug = match &args.into_iter().collect::<Vec<_>>()[..] {
150         [TokenTree::Ident(ident)] if ident.to_string() == "nodebug" => false,
151         _ => true,
152     };
153     print_helper_ext(input, "ATTR", debug)
154 }
155 
156 #[proc_macro_attribute]
print_attr_args(args: TokenStream, input: TokenStream) -> TokenStream157 pub fn print_attr_args(args: TokenStream, input: TokenStream) -> TokenStream {
158     print_helper(args, "ATTR_ARGS");
159     input
160 }
161 
162 #[proc_macro_attribute]
print_target_and_args(args: TokenStream, input: TokenStream) -> TokenStream163 pub fn print_target_and_args(args: TokenStream, input: TokenStream) -> TokenStream {
164     print_helper(args, "ATTR_ARGS");
165     print_helper(input.clone(), "ATTR");
166     input
167 }
168 
169 #[proc_macro_attribute]
print_target_and_args_consume(args: TokenStream, input: TokenStream) -> TokenStream170 pub fn print_target_and_args_consume(args: TokenStream, input: TokenStream) -> TokenStream {
171     print_helper(args, "ATTR_ARGS");
172     print_helper(input.clone(), "ATTR");
173     TokenStream::new()
174 }
175 
176 #[proc_macro_derive(Print, attributes(print_helper))]
print_derive(input: TokenStream) -> TokenStream177 pub fn print_derive(input: TokenStream) -> TokenStream {
178     print_helper(input, "DERIVE");
179     TokenStream::new()
180 }
181