From 19d952c603344d853567aeac42dcfa6fe40ba04b Mon Sep 17 00:00:00 2001
From: Edwin Cheng <edwin0cheng@gmail.com>
Date: Thu, 9 Apr 2020 23:48:08 +0800
Subject: Improve tt::Subtree debug print

---
 crates/ra_tt/src/lib.rs | 57 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 56 insertions(+), 1 deletion(-)

(limited to 'crates/ra_tt/src')

diff --git a/crates/ra_tt/src/lib.rs b/crates/ra_tt/src/lib.rs
index bd484aa30..5248e026c 100644
--- a/crates/ra_tt/src/lib.rs
+++ b/crates/ra_tt/src/lib.rs
@@ -57,7 +57,7 @@ pub enum Leaf {
 }
 impl_froms!(Leaf: Literal, Punct, Ident);
 
-#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
+#[derive(Clone, PartialEq, Eq, Hash, Default)]
 pub struct Subtree {
     pub delimiter: Option<Delimiter>,
     pub token_trees: Vec<TokenTree>,
@@ -101,6 +101,61 @@ pub struct Ident {
     pub id: TokenId,
 }
 
+fn print_debug_subtree(f: &mut fmt::Formatter<'_>, subtree: &Subtree, level: usize) -> fmt::Result {
+    let align = std::iter::repeat("  ").take(level).collect::<String>();
+
+    let aux = match subtree.delimiter.map(|it| (it.kind, it.id.0)) {
+        None => "$".to_string(),
+        Some((DelimiterKind::Parenthesis, id)) => format!("() {}", id),
+        Some((DelimiterKind::Brace, id)) => format!("{{}} {}", id),
+        Some((DelimiterKind::Bracket, id)) => format!("[] {}", id),
+    };
+
+    if subtree.token_trees.is_empty() {
+        write!(f, "{}SUBTREE {}", align, aux)?;
+    } else {
+        writeln!(f, "{}SUBTREE {}", align, aux)?;
+        for (idx, child) in subtree.token_trees.iter().enumerate() {
+            print_debug_token(f, child, level + 1)?;
+            if idx != subtree.token_trees.len() - 1 {
+                writeln!(f, "")?;
+            }
+        }
+    }
+
+    Ok(())
+}
+
+fn print_debug_token(f: &mut fmt::Formatter<'_>, tkn: &TokenTree, level: usize) -> fmt::Result {
+    let align = std::iter::repeat("  ").take(level).collect::<String>();
+
+    match tkn {
+        TokenTree::Leaf(leaf) => match leaf {
+            Leaf::Literal(lit) => write!(f, "{}LITERAL {} {}", align, lit.text, lit.id.0)?,
+            Leaf::Punct(punct) => write!(
+                f,
+                "{}PUNCH   {} [{}] {}",
+                align,
+                punct.char,
+                if punct.spacing == Spacing::Alone { "alone" } else { "joint" },
+                punct.id.0
+            )?,
+            Leaf::Ident(ident) => write!(f, "{}IDENT   {} {}", align, ident.text, ident.id.0)?,
+        },
+        TokenTree::Subtree(subtree) => {
+            print_debug_subtree(f, subtree, level)?;
+        }
+    }
+
+    Ok(())
+}
+
+impl Debug for Subtree {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        print_debug_subtree(f, self, 0)
+    }
+}
+
 impl fmt::Display for TokenTree {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
-- 
cgit v1.2.3