diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-04-17 06:10:29 +0100 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-04-17 06:10:29 +0100 |
commit | 0e35603069b4f3cee97641204b09d91fd723d01d (patch) | |
tree | 5ce7ba4ec6fbf9ce8a25bfe2877abc78dd4e9f45 /crates/ra_mbe/src | |
parent | 546d9be2a7bf7b3942c125f922a01321aea6ad26 (diff) | |
parent | 57e4122b890d56c11f9d74c1bdfed40f186331a4 (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.rs | 15 | ||||
-rw-r--r-- | crates/ra_mbe/src/mbe_expander.rs | 4 | ||||
-rw-r--r-- | crates/ra_mbe/src/subtree_parser.rs | 4 | ||||
-rw-r--r-- | crates/ra_mbe/src/tt_cursor.rs | 5 |
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(); |