diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/macros.rs | 114 |
1 files changed, 0 insertions, 114 deletions
diff --git a/crates/ra_hir/src/macros.rs b/crates/ra_hir/src/macros.rs index ffcf1c3f9..7ca34d434 100644 --- a/crates/ra_hir/src/macros.rs +++ b/crates/ra_hir/src/macros.rs | |||
@@ -11,7 +11,6 @@ use std::sync::Arc; | |||
11 | 11 | ||
12 | use ra_syntax::{ | 12 | use ra_syntax::{ |
13 | TextRange, TextUnit, SourceFile, AstNode, SyntaxNode, TreeArc, SyntaxNodePtr, | 13 | TextRange, TextUnit, SourceFile, AstNode, SyntaxNode, TreeArc, SyntaxNodePtr, |
14 | SyntaxKind::*, | ||
15 | ast::{self, NameOwner}, | 14 | ast::{self, NameOwner}, |
16 | }; | 15 | }; |
17 | 16 | ||
@@ -196,116 +195,3 @@ pub(crate) fn expand_macro_invocation( | |||
196 | let (def, input) = MacroDef::from_call(macro_call)?; | 195 | let (def, input) = MacroDef::from_call(macro_call)?; |
197 | def.expand(input).map(Arc::new) | 196 | def.expand(input).map(Arc::new) |
198 | } | 197 | } |
199 | |||
200 | fn macro_call_to_tt(call: &ast::MacroCall) -> Option<tt::Subtree> { | ||
201 | let tt = call.token_tree()?; | ||
202 | convert_tt(tt.syntax()) | ||
203 | } | ||
204 | |||
205 | fn convert_tt(tt: &SyntaxNode) -> Option<tt::Subtree> { | ||
206 | let first_child = tt.first_child()?; | ||
207 | let last_child = tt.last_child()?; | ||
208 | let delimiter = match (first_child.kind(), last_child.kind()) { | ||
209 | (L_PAREN, R_PAREN) => tt::Delimiter::Parenthesis, | ||
210 | (L_CURLY, R_CURLY) => tt::Delimiter::Brace, | ||
211 | (L_BRACK, R_BRACK) => tt::Delimiter::Bracket, | ||
212 | _ => return None, | ||
213 | }; | ||
214 | let mut token_trees = Vec::new(); | ||
215 | for child in tt.children().skip(1) { | ||
216 | if child == first_child || child == last_child || child.kind().is_trivia() { | ||
217 | continue; | ||
218 | } | ||
219 | if child.kind().is_punct() { | ||
220 | let mut prev = None; | ||
221 | for char in child.leaf_text().unwrap().chars() { | ||
222 | if let Some(char) = prev { | ||
223 | token_trees.push( | ||
224 | tt::Leaf::from(tt::Punct { | ||
225 | char, | ||
226 | spacing: tt::Spacing::Joint, | ||
227 | }) | ||
228 | .into(), | ||
229 | ); | ||
230 | } | ||
231 | prev = Some(char) | ||
232 | } | ||
233 | if let Some(char) = prev { | ||
234 | token_trees.push( | ||
235 | tt::Leaf::from(tt::Punct { | ||
236 | char, | ||
237 | spacing: tt::Spacing::Alone, | ||
238 | }) | ||
239 | .into(), | ||
240 | ); | ||
241 | } | ||
242 | } else { | ||
243 | let child: tt::TokenTree = if child.kind() == TOKEN_TREE { | ||
244 | convert_tt(child)?.into() | ||
245 | } else if child.kind().is_keyword() || child.kind() == IDENT { | ||
246 | let text = child.leaf_text().unwrap().clone(); | ||
247 | tt::Leaf::from(tt::Ident { text }).into() | ||
248 | } else if child.kind().is_literal() { | ||
249 | tt::Leaf::from(tt::Literal { | ||
250 | text: child.leaf_text().unwrap().clone(), | ||
251 | }) | ||
252 | .into() | ||
253 | } else { | ||
254 | log::error!("unknown kind: {:?}", child); | ||
255 | return None; | ||
256 | }; | ||
257 | token_trees.push(child) | ||
258 | } | ||
259 | } | ||
260 | |||
261 | let res = tt::Subtree { | ||
262 | delimiter, | ||
263 | token_trees, | ||
264 | }; | ||
265 | Some(res) | ||
266 | } | ||
267 | |||
268 | #[test] | ||
269 | fn test_convert_tt() { | ||
270 | let macro_definition = r#" | ||
271 | macro_rules! impl_froms { | ||
272 | ($e:ident: $($v:ident),*) => { | ||
273 | $( | ||
274 | impl From<$v> for $e { | ||
275 | fn from(it: $v) -> $e { | ||
276 | $e::$v(it) | ||
277 | } | ||
278 | } | ||
279 | )* | ||
280 | } | ||
281 | } | ||
282 | "#; | ||
283 | |||
284 | let macro_invocation = r#" | ||
285 | impl_froms!(TokenTree: Leaf, Subtree); | ||
286 | "#; | ||
287 | |||
288 | let source_file = ast::SourceFile::parse(macro_definition); | ||
289 | let macro_definition = source_file | ||
290 | .syntax() | ||
291 | .descendants() | ||
292 | .find_map(ast::MacroCall::cast) | ||
293 | .unwrap(); | ||
294 | |||
295 | let source_file = ast::SourceFile::parse(macro_invocation); | ||
296 | let macro_invocation = source_file | ||
297 | .syntax() | ||
298 | .descendants() | ||
299 | .find_map(ast::MacroCall::cast) | ||
300 | .unwrap(); | ||
301 | |||
302 | let definition_tt = macro_call_to_tt(macro_definition).unwrap(); | ||
303 | let invocation_tt = macro_call_to_tt(macro_invocation).unwrap(); | ||
304 | let mbe = mbe::parse(&definition_tt).unwrap(); | ||
305 | let expansion = mbe::exapnd(&mbe, &invocation_tt).unwrap(); | ||
306 | assert_eq!( | ||
307 | expansion.to_string(), | ||
308 | "{(impl From < Leaf > for TokenTree {fn from (it : Leaf) -> TokenTree {TokenTree :: Leaf (it)}}) \ | ||
309 | (impl From < Subtree > for TokenTree {fn from (it : Subtree) -> TokenTree {TokenTree :: Subtree (it)}})}" | ||
310 | ) | ||
311 | } | ||