Spanned trait to get the full span of ast node
diff --git a/src/lib.rs b/src/lib.rs
index 5ba8c20..74a13bd 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -98,6 +98,9 @@
 #[cfg(feature = "parsing")]
 mod tt;
 
+#[cfg(all(procmacro2_unstable, feature = "parsing", feature = "printing"))]
+pub mod spanned;
+
 mod gen {
     #[cfg(feature = "visit")]
     pub mod visit;
diff --git a/src/spanned.rs b/src/spanned.rs
new file mode 100644
index 0000000..87d833c
--- /dev/null
+++ b/src/spanned.rs
@@ -0,0 +1,32 @@
+use proc_macro2::{Span, TokenStream};
+use quote::{Tokens, ToTokens};
+
+pub trait Spanned {
+    /// Returns a `Span` covering the complete contents of this AST node, or
+    /// `Span::call_site()` if this node is empty.
+    fn span(&self) -> Span;
+}
+
+impl<T> Spanned for T
+where
+    T: ToTokens,
+{
+    fn span(&self) -> Span {
+        let mut tokens = Tokens::new();
+        self.to_tokens(&mut tokens);
+        let token_stream = TokenStream::from(tokens);
+        let mut iter = token_stream.into_iter();
+        let mut span = match iter.next() {
+            Some(tt) => tt.span,
+            None => {
+                return Span::call_site();
+            }
+        };
+        for tt in iter {
+            if let Some(joined) = span.join(tt.span) {
+                span = joined;
+            }
+        }
+        span
+    }
+}