aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_mbe/src
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-04-17 06:10:29 +0100
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-04-17 06:10:29 +0100
commit0e35603069b4f3cee97641204b09d91fd723d01d (patch)
tree5ce7ba4ec6fbf9ce8a25bfe2877abc78dd4e9f45 /crates/ra_mbe/src
parent546d9be2a7bf7b3942c125f922a01321aea6ad26 (diff)
parent57e4122b890d56c11f9d74c1bdfed40f186331a4 (diff)
Merge #1157
1157: Add mbe stmt matcher r=matklad a=edwin0cheng Add `stmt` matcher in `ra_mbe` , and added corresponding `stmt()` parser in `ra_syntax`. This PR also help PR #1148 for `MarcoKind::Items` parsing. Note: * According [the book](https://doc.rust-lang.org/reference/macros-by-example.html), mbe `stmt` matcher will only match statement without the trailing semicolon * `item` is a valid statement. Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates/ra_mbe/src')
-rw-r--r--crates/ra_mbe/src/lib.rs15
-rw-r--r--crates/ra_mbe/src/mbe_expander.rs4
-rw-r--r--crates/ra_mbe/src/subtree_parser.rs4
-rw-r--r--crates/ra_mbe/src/tt_cursor.rs5
4 files changed, 28 insertions, 0 deletions
diff --git a/crates/ra_mbe/src/lib.rs b/crates/ra_mbe/src/lib.rs
index a530f3b03..a1f438906 100644
--- a/crates/ra_mbe/src/lib.rs
+++ b/crates/ra_mbe/src/lib.rs
@@ -582,4 +582,19 @@ SOURCE_FILE@[0; 40)
582 ); 582 );
583 assert_expansion(&rules, "foo! { (a, b) }", "fn foo () {let (a , b) ;}"); 583 assert_expansion(&rules, "foo! { (a, b) }", "fn foo () {let (a , b) ;}");
584 } 584 }
585
586 #[test]
587 fn test_stmt() {
588 let rules = create_rules(
589 r#"
590 macro_rules! foo {
591 ($ i:stmt) => (
592 fn bar() { $ i; }
593 )
594 }
595"#,
596 );
597 assert_expansion(&rules, "foo! { 2 }", "fn bar () {2 ;}");
598 assert_expansion(&rules, "foo! { let a = 0 }", "fn bar () {let a = 0 ;}");
599 }
585} 600}
diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs
index 7a259f338..7587b575d 100644
--- a/crates/ra_mbe/src/mbe_expander.rs
+++ b/crates/ra_mbe/src/mbe_expander.rs
@@ -157,6 +157,10 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings,
157 let pat = input.eat_pat().ok_or(ExpandError::UnexpectedToken)?.clone(); 157 let pat = input.eat_pat().ok_or(ExpandError::UnexpectedToken)?.clone();
158 res.inner.insert(text.clone(), Binding::Simple(pat.into())); 158 res.inner.insert(text.clone(), Binding::Simple(pat.into()));
159 } 159 }
160 "stmt" => {
161 let pat = input.eat_stmt().ok_or(ExpandError::UnexpectedToken)?.clone();
162 res.inner.insert(text.clone(), Binding::Simple(pat.into()));
163 }
160 _ => return Err(ExpandError::UnexpectedToken), 164 _ => return Err(ExpandError::UnexpectedToken),
161 } 165 }
162 } 166 }
diff --git a/crates/ra_mbe/src/subtree_parser.rs b/crates/ra_mbe/src/subtree_parser.rs
index 13d5d2169..f075ce245 100644
--- a/crates/ra_mbe/src/subtree_parser.rs
+++ b/crates/ra_mbe/src/subtree_parser.rs
@@ -42,6 +42,10 @@ impl<'a> Parser<'a> {
42 self.parse(ra_parser::parse_pat) 42 self.parse(ra_parser::parse_pat)
43 } 43 }
44 44
45 pub fn parse_stmt(self) -> Option<tt::TokenTree> {
46 self.parse(|src, sink| ra_parser::parse_stmt(src, sink, false))
47 }
48
45 fn parse<F>(self, f: F) -> Option<tt::TokenTree> 49 fn parse<F>(self, f: F) -> Option<tt::TokenTree>
46 where 50 where
47 F: FnOnce(&dyn TokenSource, &mut dyn TreeSink), 51 F: FnOnce(&dyn TokenSource, &mut dyn TreeSink),
diff --git a/crates/ra_mbe/src/tt_cursor.rs b/crates/ra_mbe/src/tt_cursor.rs
index f6cefe087..adfe5520d 100644
--- a/crates/ra_mbe/src/tt_cursor.rs
+++ b/crates/ra_mbe/src/tt_cursor.rs
@@ -99,6 +99,11 @@ impl<'a> TtCursor<'a> {
99 parser.parse_pat() 99 parser.parse_pat()
100 } 100 }
101 101
102 pub(crate) fn eat_stmt(&mut self) -> Option<tt::TokenTree> {
103 let parser = Parser::new(&mut self.pos, self.subtree);
104 parser.parse_stmt()
105 }
106
102 pub(crate) fn expect_char(&mut self, char: char) -> Result<(), ParseError> { 107 pub(crate) fn expect_char(&mut self, char: char) -> Result<(), ParseError> {
103 if self.at_char(char) { 108 if self.at_char(char) {
104 self.bump(); 109 self.bump();