• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 extern crate proc_macro;
2 use proc_macro::*;
3 
4 #[proc_macro]
a_proc_macro(_item: TokenStream) -> TokenStream5 pub fn a_proc_macro(_item: TokenStream) -> TokenStream {
6     "fn ex() { foobar::f(); }".parse().unwrap()
7 }
8 
9 // inserts foobar::f() to the end of the function
10 #[proc_macro_attribute]
an_attr_macro(attr: TokenStream, item: TokenStream) -> TokenStream11 pub fn an_attr_macro(attr: TokenStream, item: TokenStream) -> TokenStream {
12     let new_call: TokenStream = "foobar::f();".parse().unwrap();
13 
14     let mut tokens = item.into_iter();
15 
16     let fn_tok = tokens.next().unwrap();
17     let ident_tok = tokens.next().unwrap();
18     let args_tok = tokens.next().unwrap();
19     let body = match tokens.next().unwrap() {
20         TokenTree::Group(g) => {
21             let new_g = Group::new(g.delimiter(), new_call);
22             let mut outer_g = Group::new(
23                 g.delimiter(),
24                 [TokenTree::Group(g.clone()), TokenTree::Group(new_g)].into_iter().collect(),
25             );
26 
27             if attr.to_string() == "with_span" {
28                 outer_g.set_span(g.span());
29             }
30 
31             TokenTree::Group(outer_g)
32         }
33         _ => unreachable!(),
34     };
35 
36     let tokens = vec![fn_tok, ident_tok, args_tok, body].into_iter().collect::<TokenStream>();
37 
38     tokens
39 }
40