aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir_expand/src/quote.rs2
-rw-r--r--crates/ra_mbe/src/tests.rs79
-rw-r--r--crates/ra_tt/src/lib.rs57
3 files changed, 136 insertions, 2 deletions
diff --git a/crates/ra_hir_expand/src/quote.rs b/crates/ra_hir_expand/src/quote.rs
index 3fd4233da..219bc2097 100644
--- a/crates/ra_hir_expand/src/quote.rs
+++ b/crates/ra_hir_expand/src/quote.rs
@@ -232,7 +232,7 @@ mod tests {
232 let quoted = quote!(#a); 232 let quoted = quote!(#a);
233 assert_eq!(quoted.to_string(), "hello"); 233 assert_eq!(quoted.to_string(), "hello");
234 let t = format!("{:?}", quoted); 234 let t = format!("{:?}", quoted);
235 assert_eq!(t, "Subtree { delimiter: None, token_trees: [Leaf(Ident(Ident { text: \"hello\", id: TokenId(4294967295) }))] }"); 235 assert_eq!(t, "SUBTREE $\n IDENT hello 4294967295");
236 } 236 }
237 237
238 #[test] 238 #[test]
diff --git a/crates/ra_mbe/src/tests.rs b/crates/ra_mbe/src/tests.rs
index 254318e23..1ef6f6eed 100644
--- a/crates/ra_mbe/src/tests.rs
+++ b/crates/ra_mbe/src/tests.rs
@@ -142,6 +142,79 @@ macro_rules! impl_froms {
142} 142}
143 143
144#[test] 144#[test]
145fn test_convert_tt2() {
146 parse_macro(
147 r#"
148macro_rules! impl_froms {
149 ($e:ident: $($v:ident),*) => {
150 $(
151 impl From<$v> for $e {
152 fn from(it: $v) -> $e {
153 $e::$v(it)
154 }
155 }
156 )*
157 }
158}
159"#,
160 )
161 .assert_expand(
162 "impl_froms!(TokenTree: Leaf, Subtree);",
163 r#"
164SUBTREE $
165 IDENT impl 20
166 IDENT From 21
167 PUNCH < [joint] 22
168 IDENT Leaf 53
169 PUNCH > [alone] 25
170 IDENT for 26
171 IDENT TokenTree 51
172 SUBTREE {} 29
173 IDENT fn 30
174 IDENT from 31
175 SUBTREE () 32
176 IDENT it 33
177 PUNCH : [alone] 34
178 IDENT Leaf 53
179 PUNCH - [joint] 37
180 PUNCH > [alone] 38
181 IDENT TokenTree 51
182 SUBTREE {} 41
183 IDENT TokenTree 51
184 PUNCH : [joint] 44
185 PUNCH : [joint] 45
186 IDENT Leaf 53
187 SUBTREE () 48
188 IDENT it 49
189 IDENT impl 20
190 IDENT From 21
191 PUNCH < [joint] 22
192 IDENT Subtree 55
193 PUNCH > [alone] 25
194 IDENT for 26
195 IDENT TokenTree 51
196 SUBTREE {} 29
197 IDENT fn 30
198 IDENT from 31
199 SUBTREE () 32
200 IDENT it 33
201 PUNCH : [alone] 34
202 IDENT Subtree 55
203 PUNCH - [joint] 37
204 PUNCH > [alone] 38
205 IDENT TokenTree 51
206 SUBTREE {} 41
207 IDENT TokenTree 51
208 PUNCH : [joint] 44
209 PUNCH : [joint] 45
210 IDENT Subtree 55
211 SUBTREE () 48
212 IDENT it 49
213"#,
214 );
215}
216
217#[test]
145fn test_expr_order() { 218fn test_expr_order() {
146 let expanded = parse_macro( 219 let expanded = parse_macro(
147 r#" 220 r#"
@@ -1479,6 +1552,12 @@ impl MacroFixture {
1479 assert_eq!(expansion.to_string(), expected); 1552 assert_eq!(expansion.to_string(), expected);
1480 } 1553 }
1481 1554
1555 fn assert_expand(&self, invocation: &str, expected: &str) {
1556 let expansion = self.expand_tt(invocation);
1557 let actual = format!("{:?}", expansion);
1558 test_utils::assert_eq_text!(&actual.trim(), &expected.trim());
1559 }
1560
1482 fn assert_expand_items(&self, invocation: &str, expected: &str) -> &MacroFixture { 1561 fn assert_expand_items(&self, invocation: &str, expected: &str) -> &MacroFixture {
1483 self.assert_expansion(FragmentKind::Items, invocation, expected); 1562 self.assert_expansion(FragmentKind::Items, invocation, expected);
1484 self 1563 self
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 {
57} 57}
58impl_froms!(Leaf: Literal, Punct, Ident); 58impl_froms!(Leaf: Literal, Punct, Ident);
59 59
60#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)] 60#[derive(Clone, PartialEq, Eq, Hash, Default)]
61pub struct Subtree { 61pub struct Subtree {
62 pub delimiter: Option<Delimiter>, 62 pub delimiter: Option<Delimiter>,
63 pub token_trees: Vec<TokenTree>, 63 pub token_trees: Vec<TokenTree>,
@@ -101,6 +101,61 @@ pub struct Ident {
101 pub id: TokenId, 101 pub id: TokenId,
102} 102}
103 103
104fn print_debug_subtree(f: &mut fmt::Formatter<'_>, subtree: &Subtree, level: usize) -> fmt::Result {
105 let align = std::iter::repeat(" ").take(level).collect::<String>();
106
107 let aux = match subtree.delimiter.map(|it| (it.kind, it.id.0)) {
108 None => "$".to_string(),
109 Some((DelimiterKind::Parenthesis, id)) => format!("() {}", id),
110 Some((DelimiterKind::Brace, id)) => format!("{{}} {}", id),
111 Some((DelimiterKind::Bracket, id)) => format!("[] {}", id),
112 };
113
114 if subtree.token_trees.is_empty() {
115 write!(f, "{}SUBTREE {}", align, aux)?;
116 } else {
117 writeln!(f, "{}SUBTREE {}", align, aux)?;
118 for (idx, child) in subtree.token_trees.iter().enumerate() {
119 print_debug_token(f, child, level + 1)?;
120 if idx != subtree.token_trees.len() - 1 {
121 writeln!(f, "")?;
122 }
123 }
124 }
125
126 Ok(())
127}
128
129fn print_debug_token(f: &mut fmt::Formatter<'_>, tkn: &TokenTree, level: usize) -> fmt::Result {
130 let align = std::iter::repeat(" ").take(level).collect::<String>();
131
132 match tkn {
133 TokenTree::Leaf(leaf) => match leaf {
134 Leaf::Literal(lit) => write!(f, "{}LITERAL {} {}", align, lit.text, lit.id.0)?,
135 Leaf::Punct(punct) => write!(
136 f,
137 "{}PUNCH {} [{}] {}",
138 align,
139 punct.char,
140 if punct.spacing == Spacing::Alone { "alone" } else { "joint" },
141 punct.id.0
142 )?,
143 Leaf::Ident(ident) => write!(f, "{}IDENT {} {}", align, ident.text, ident.id.0)?,
144 },
145 TokenTree::Subtree(subtree) => {
146 print_debug_subtree(f, subtree, level)?;
147 }
148 }
149
150 Ok(())
151}
152
153impl Debug for Subtree {
154 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
155 print_debug_subtree(f, self, 0)
156 }
157}
158
104impl fmt::Display for TokenTree { 159impl fmt::Display for TokenTree {
105 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 160 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
106 match self { 161 match self {