aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdwin Cheng <[email protected]>2019-04-19 11:30:43 +0100
committerEdwin Cheng <[email protected]>2019-04-19 11:30:43 +0100
commit8092b6487f301bf9219c55fc714744fa2616fb9a (patch)
treeea65ea5146b62c5505737c81c7026bae9973693d
parentab0a96586fd54858106cb6ac112d61eb657426f6 (diff)
Add block matcher
-rw-r--r--crates/ra_mbe/src/lib.rs12
-rw-r--r--crates/ra_mbe/src/mbe_expander.rs5
-rw-r--r--crates/ra_mbe/src/subtree_parser.rs4
-rw-r--r--crates/ra_mbe/src/tt_cursor.rs5
-rw-r--r--crates/ra_parser/src/grammar.rs4
-rw-r--r--crates/ra_parser/src/lib.rs5
6 files changed, 35 insertions, 0 deletions
diff --git a/crates/ra_mbe/src/lib.rs b/crates/ra_mbe/src/lib.rs
index 9d4744838..8e3167e55 100644
--- a/crates/ra_mbe/src/lib.rs
+++ b/crates/ra_mbe/src/lib.rs
@@ -731,4 +731,16 @@ MACRO_ITEMS@[0; 40)
731 } 731 }
732"#, r#"extern crate a ; mod b ; mod c {} use d ; const E : i32 = 0 ; static F : i32 = 0 ; impl G {} struct H ; enum I {Foo} trait J {} fn h () {} extern {} type T = u8 ;"#); 732"#, r#"extern crate a ; mod b ; mod c {} use d ; const E : i32 = 0 ; static F : i32 = 0 ; impl G {} struct H ; enum I {Foo} trait J {} fn h () {} extern {} type T = u8 ;"#);
733 } 733 }
734
735 #[test]
736 fn test_block() {
737 let rules = create_rules(
738 r#"
739 macro_rules! foo {
740 ($ i:block) => { fn foo() $ i }
741 }
742"#,
743 );
744 assert_expansion(&rules, "foo! { { 1; } }", "fn foo () {1 ;}");
745 }
734} 746}
diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs
index acba42809..a74e477d6 100644
--- a/crates/ra_mbe/src/mbe_expander.rs
+++ b/crates/ra_mbe/src/mbe_expander.rs
@@ -161,6 +161,11 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings,
161 let pat = input.eat_stmt().ok_or(ExpandError::UnexpectedToken)?.clone(); 161 let pat = input.eat_stmt().ok_or(ExpandError::UnexpectedToken)?.clone();
162 res.inner.insert(text.clone(), Binding::Simple(pat.into())); 162 res.inner.insert(text.clone(), Binding::Simple(pat.into()));
163 } 163 }
164 "block" => {
165 let block =
166 input.eat_block().ok_or(ExpandError::UnexpectedToken)?.clone();
167 res.inner.insert(text.clone(), Binding::Simple(block.into()));
168 }
164 "item" => { 169 "item" => {
165 let item = 170 let item =
166 input.eat_item().ok_or(ExpandError::UnexpectedToken)?.clone(); 171 input.eat_item().ok_or(ExpandError::UnexpectedToken)?.clone();
diff --git a/crates/ra_mbe/src/subtree_parser.rs b/crates/ra_mbe/src/subtree_parser.rs
index 195e4c3ac..2b11186c4 100644
--- a/crates/ra_mbe/src/subtree_parser.rs
+++ b/crates/ra_mbe/src/subtree_parser.rs
@@ -46,6 +46,10 @@ impl<'a> Parser<'a> {
46 self.parse(|src, sink| ra_parser::parse_stmt(src, sink, false)) 46 self.parse(|src, sink| ra_parser::parse_stmt(src, sink, false))
47 } 47 }
48 48
49 pub fn parse_block(self) -> Option<tt::TokenTree> {
50 self.parse(ra_parser::parse_block)
51 }
52
49 pub fn parse_item(self) -> Option<tt::TokenTree> { 53 pub fn parse_item(self) -> Option<tt::TokenTree> {
50 self.parse(ra_parser::parse_item) 54 self.parse(ra_parser::parse_item)
51 } 55 }
diff --git a/crates/ra_mbe/src/tt_cursor.rs b/crates/ra_mbe/src/tt_cursor.rs
index 484437b0e..d700aad69 100644
--- a/crates/ra_mbe/src/tt_cursor.rs
+++ b/crates/ra_mbe/src/tt_cursor.rs
@@ -104,6 +104,11 @@ impl<'a> TtCursor<'a> {
104 parser.parse_stmt() 104 parser.parse_stmt()
105 } 105 }
106 106
107 pub(crate) fn eat_block(&mut self) -> Option<tt::TokenTree> {
108 let parser = Parser::new(&mut self.pos, self.subtree);
109 parser.parse_block()
110 }
111
107 pub(crate) fn eat_item(&mut self) -> Option<tt::TokenTree> { 112 pub(crate) fn eat_item(&mut self) -> Option<tt::TokenTree> {
108 let parser = Parser::new(&mut self.pos, self.subtree); 113 let parser = Parser::new(&mut self.pos, self.subtree);
109 parser.parse_item() 114 parser.parse_item()
diff --git a/crates/ra_parser/src/grammar.rs b/crates/ra_parser/src/grammar.rs
index e1762633e..7bae0bc7b 100644
--- a/crates/ra_parser/src/grammar.rs
+++ b/crates/ra_parser/src/grammar.rs
@@ -95,6 +95,10 @@ pub(crate) fn stmt(p: &mut Parser, with_semi: bool) {
95 expressions::stmt(p, with_semi) 95 expressions::stmt(p, with_semi)
96} 96}
97 97
98pub(crate) fn block(p: &mut Parser) {
99 expressions::block(p);
100}
101
98pub(crate) fn item(p: &mut Parser) { 102pub(crate) fn item(p: &mut Parser) {
99 items::item_or_macro(p, true, items::ItemFlavor::Mod) 103 items::item_or_macro(p, true, items::ItemFlavor::Mod)
100} 104}
diff --git a/crates/ra_parser/src/lib.rs b/crates/ra_parser/src/lib.rs
index 0ea942b6e..1e6a00642 100644
--- a/crates/ra_parser/src/lib.rs
+++ b/crates/ra_parser/src/lib.rs
@@ -93,6 +93,11 @@ pub fn parse_stmt(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink,
93 parse_from_tokens(token_source, tree_sink, |p| grammar::stmt(p, with_semi)); 93 parse_from_tokens(token_source, tree_sink, |p| grammar::stmt(p, with_semi));
94} 94}
95 95
96/// Parse given tokens into the given sink as a block
97pub fn parse_block(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
98 parse_from_tokens(token_source, tree_sink, grammar::block);
99}
100
96/// Parse given tokens into the given sink as an item 101/// Parse given tokens into the given sink as an item
97pub fn parse_item(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) { 102pub fn parse_item(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
98 parse_from_tokens(token_source, tree_sink, grammar::item); 103 parse_from_tokens(token_source, tree_sink, grammar::item);