blob: 87d833c0c52860bdabca381bef1cfcaa691e83bb [file] [log] [blame]
David Tolnayf790b612017-12-31 18:46:57 -05001use proc_macro2::{Span, TokenStream};
2use quote::{Tokens, ToTokens};
3
4pub trait Spanned {
5 /// Returns a `Span` covering the complete contents of this AST node, or
6 /// `Span::call_site()` if this node is empty.
7 fn span(&self) -> Span;
8}
9
10impl<T> Spanned for T
11where
12 T: ToTokens,
13{
14 fn span(&self) -> Span {
15 let mut tokens = Tokens::new();
16 self.to_tokens(&mut tokens);
17 let token_stream = TokenStream::from(tokens);
18 let mut iter = token_stream.into_iter();
19 let mut span = match iter.next() {
20 Some(tt) => tt.span,
21 None => {
22 return Span::call_site();
23 }
24 };
25 for tt in iter {
26 if let Some(joined) = span.join(tt.span) {
27 span = joined;
28 }
29 }
30 span
31 }
32}