aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_mbe/src/lib.rs
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-04-19 09:56:39 +0100
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-04-19 09:56:39 +0100
commitab0a96586fd54858106cb6ac112d61eb657426f6 (patch)
tree86bbf2601069f6b0007dc181c824ef706d08c60d /crates/ra_mbe/src/lib.rs
parentd55f1136d6444b1f50b9092c36a976d0e1c26202 (diff)
parenta6d51e09610989821aaf79871bcab0661c9b0f74 (diff)
Merge #1148
1148: Add token_tree_to_xxx functions r=matklad a=edwin0cheng <del>As discus in PR #1147 , this PR added a `mbe::MacroKind` . Currently only 2 kind of macro are supported, `SourceFile` and `Block`.</del> Added following functions for `tt::TokenTree` and `ast::Node` conversion: * token_tree_to_expr * token_tree_to_pat * token_tree_to_ty * token_tree_to_macro_stmts * token_tree_to_macro_items And added two new syntax kind: * MACRO_ITEMS * MACRO_STMTS Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates/ra_mbe/src/lib.rs')
-rw-r--r--crates/ra_mbe/src/lib.rs86
1 files changed, 76 insertions, 10 deletions
diff --git a/crates/ra_mbe/src/lib.rs b/crates/ra_mbe/src/lib.rs
index 8d5008d20..9d4744838 100644
--- a/crates/ra_mbe/src/lib.rs
+++ b/crates/ra_mbe/src/lib.rs
@@ -37,9 +37,19 @@ pub enum ExpandError {
37 NoMatchingRule, 37 NoMatchingRule,
38 UnexpectedToken, 38 UnexpectedToken,
39 BindingError(String), 39 BindingError(String),
40 ConversionError,
40} 41}
41 42
42pub use crate::syntax_bridge::{ast_to_token_tree, token_tree_to_ast_item_list, syntax_node_to_token_tree}; 43pub use crate::syntax_bridge::{
44 ast_to_token_tree,
45 token_tree_to_ast_item_list,
46 syntax_node_to_token_tree,
47 token_tree_to_expr,
48 token_tree_to_pat,
49 token_tree_to_ty,
50 token_tree_to_macro_items,
51 token_tree_to_macro_stmts,
52};
43 53
44/// This struct contains AST for a single `macro_rules` definition. What might 54/// This struct contains AST for a single `macro_rules` definition. What might
45/// be very confusing is that AST has almost exactly the same shape as 55/// be very confusing is that AST has almost exactly the same shape as
@@ -192,23 +202,26 @@ impl_froms!(TokenTree: Leaf, Subtree);
192 pub(crate) fn expand_to_syntax( 202 pub(crate) fn expand_to_syntax(
193 rules: &MacroRules, 203 rules: &MacroRules,
194 invocation: &str, 204 invocation: &str,
195 ) -> ra_syntax::TreeArc<ast::SourceFile> { 205 ) -> ra_syntax::TreeArc<ast::MacroItems> {
196 let expanded = expand(rules, invocation); 206 let expanded = expand(rules, invocation);
197 token_tree_to_ast_item_list(&expanded) 207 token_tree_to_macro_items(&expanded).unwrap()
198 } 208 }
199 209
200 pub(crate) fn assert_expansion(rules: &MacroRules, invocation: &str, expansion: &str) { 210 pub(crate) fn assert_expansion(rules: &MacroRules, invocation: &str, expansion: &str) {
201 let expanded = expand(rules, invocation); 211 let expanded = expand(rules, invocation);
202 assert_eq!(expanded.to_string(), expansion); 212 assert_eq!(expanded.to_string(), expansion);
203 213
204 let tree = token_tree_to_ast_item_list(&expanded); 214 let tree = token_tree_to_macro_items(&expanded);
205 215
206 // Eat all white space by parse it back and forth 216 // Eat all white space by parse it back and forth
207 let expansion = ast::SourceFile::parse(expansion); 217 let expansion = ast::SourceFile::parse(expansion);
208 let expansion = syntax_node_to_token_tree(expansion.syntax()).unwrap().0; 218 let expansion = syntax_node_to_token_tree(expansion.syntax()).unwrap().0;
209 let file = token_tree_to_ast_item_list(&expansion); 219 let file = token_tree_to_macro_items(&expansion);
210 220
211 assert_eq!(tree.syntax().debug_dump().trim(), file.syntax().debug_dump().trim()); 221 assert_eq!(
222 tree.unwrap().syntax().debug_dump().trim(),
223 file.unwrap().syntax().debug_dump().trim()
224 );
212 } 225 }
213 226
214 #[test] 227 #[test]
@@ -346,11 +359,11 @@ impl_froms!(TokenTree: Leaf, Subtree);
346 ", 359 ",
347 ); 360 );
348 let expansion = expand(&rules, "structs!(Foo, Bar)"); 361 let expansion = expand(&rules, "structs!(Foo, Bar)");
349 let tree = token_tree_to_ast_item_list(&expansion); 362 let tree = token_tree_to_macro_items(&expansion);
350 assert_eq!( 363 assert_eq!(
351 tree.syntax().debug_dump().trim(), 364 tree.unwrap().syntax().debug_dump().trim(),
352 r#" 365 r#"
353SOURCE_FILE@[0; 40) 366MACRO_ITEMS@[0; 40)
354 STRUCT_DEF@[0; 20) 367 STRUCT_DEF@[0; 20)
355 STRUCT_KW@[0; 6) "struct" 368 STRUCT_KW@[0; 6) "struct"
356 NAME@[6; 9) 369 NAME@[6; 9)
@@ -444,6 +457,59 @@ SOURCE_FILE@[0; 40)
444 assert_expansion(&rules, "foo! { foo, bar }", "fn foo () {let a = foo ; let b = bar ;}"); 457 assert_expansion(&rules, "foo! { foo, bar }", "fn foo () {let a = foo ; let b = bar ;}");
445 } 458 }
446 459
460 #[test]
461 fn test_tt_to_stmts() {
462 let rules = create_rules(
463 r#"
464 macro_rules! foo {
465 () => {
466 let a = 0;
467 a = 10 + 1;
468 a
469 }
470 }
471"#,
472 );
473
474 let expanded = expand(&rules, "foo!{}");
475 let stmts = token_tree_to_macro_stmts(&expanded);
476
477 assert_eq!(
478 stmts.unwrap().syntax().debug_dump().trim(),
479 r#"MACRO_STMTS@[0; 15)
480 LET_STMT@[0; 7)
481 LET_KW@[0; 3) "let"
482 BIND_PAT@[3; 4)
483 NAME@[3; 4)
484 IDENT@[3; 4) "a"
485 EQ@[4; 5) "="
486 LITERAL@[5; 6)
487 INT_NUMBER@[5; 6) "0"
488 SEMI@[6; 7) ";"
489 EXPR_STMT@[7; 14)
490 BIN_EXPR@[7; 13)
491 PATH_EXPR@[7; 8)
492 PATH@[7; 8)
493 PATH_SEGMENT@[7; 8)
494 NAME_REF@[7; 8)
495 IDENT@[7; 8) "a"
496 EQ@[8; 9) "="
497 BIN_EXPR@[9; 13)
498 LITERAL@[9; 11)
499 INT_NUMBER@[9; 11) "10"
500 PLUS@[11; 12) "+"
501 LITERAL@[12; 13)
502 INT_NUMBER@[12; 13) "1"
503 SEMI@[13; 14) ";"
504 EXPR_STMT@[14; 15)
505 PATH_EXPR@[14; 15)
506 PATH@[14; 15)
507 PATH_SEGMENT@[14; 15)
508 NAME_REF@[14; 15)
509 IDENT@[14; 15) "a""#,
510 );
511 }
512
447 // The following tests are port from intellij-rust directly 513 // The following tests are port from intellij-rust directly
448 // https://github.com/intellij-rust/intellij-rust/blob/c4e9feee4ad46e7953b1948c112533360b6087bb/src/test/kotlin/org/rust/lang/core/macros/RsMacroExpansionTest.kt 514 // https://github.com/intellij-rust/intellij-rust/blob/c4e9feee4ad46e7953b1948c112533360b6087bb/src/test/kotlin/org/rust/lang/core/macros/RsMacroExpansionTest.kt
449 515
@@ -527,7 +593,7 @@ SOURCE_FILE@[0; 40)
527 593
528 assert_eq!( 594 assert_eq!(
529 expand_to_syntax(&rules, "foo! { 1 + 1 }").syntax().debug_dump().trim(), 595 expand_to_syntax(&rules, "foo! { 1 + 1 }").syntax().debug_dump().trim(),
530 r#"SOURCE_FILE@[0; 15) 596 r#"MACRO_ITEMS@[0; 15)
531 FN_DEF@[0; 15) 597 FN_DEF@[0; 15)
532 FN_KW@[0; 2) "fn" 598 FN_KW@[0; 2) "fn"
533 NAME@[2; 5) 599 NAME@[2; 5)