1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//! Utils for implementing proc-macro. Works on stable.
//!
//!
//!

#![recursion_limit = "128"]

extern crate proc_macro;
pub use proc_macro2;
pub use quote;
pub use syn;

pub use self::span_ext::SpanExt;
use proc_macro2::TokenStream;
use quote::ToTokens;
pub use spanned_quote::Quote;
use syn::Ident;

pub mod comment;
pub mod prelude;
pub mod respan;
mod span_ext;
pub mod spanned_quote;
pub mod synom_ext;

/// Extension trait for [syn::Ident][].
///
///
///[syn::Ident]:../syn/struct.Ident.html
pub trait IdentExt {
    /// Creates a new ident with same span by applying `map` to `self`.
    fn new_ident_with<F, S>(&self, map: F) -> Ident
    where
        F: for<'a> FnOnce(&'a str) -> S,
        S: AsRef<str>;
}

impl IdentExt for Ident {
    /// Creates a new ident with same span by applying `map` to `self`.
    fn new_ident_with<F, S>(&self, map: F) -> Ident
    where
        F: for<'a> FnOnce(&'a str) -> S,
        S: AsRef<str>,
    {
        Ident::new(map(&format!("{}", self)).as_ref(), self.span())
    }
}

pub trait ToTokensExt: ToTokens {
    fn dump(&self) -> TokenStream {
        let mut tmp = TokenStream::new();
        self.to_tokens(&mut tmp);
        tmp
    }

    /// Usage: `Quote::new(body.first_last())`
    fn first_last(&self) -> respan::FirstLast {
        respan::FirstLast::from_tokens(&self)
    }
}

impl<T: ToTokens> ToTokensExt for T {}