diff options
author | Edwin Cheng <[email protected]> | 2019-04-19 12:33:29 +0100 |
---|---|---|
committer | Edwin Cheng <[email protected]> | 2019-04-19 12:33:29 +0100 |
commit | 762819864fd78f2e8904a6bde6181b80895db360 (patch) | |
tree | 1cade2d6eb97a52785a91258cfd3f03c57fba027 | |
parent | 8092b6487f301bf9219c55fc714744fa2616fb9a (diff) |
add block matcher
-rw-r--r-- | crates/ra_mbe/src/lib.rs | 19 | ||||
-rw-r--r-- | crates/ra_mbe/src/mbe_expander.rs | 5 | ||||
-rw-r--r-- | crates/ra_mbe/src/subtree_parser.rs | 4 | ||||
-rw-r--r-- | crates/ra_mbe/src/tt_cursor.rs | 5 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar.rs | 27 | ||||
-rw-r--r-- | crates/ra_parser/src/lib.rs | 4 |
6 files changed, 64 insertions, 0 deletions
diff --git a/crates/ra_mbe/src/lib.rs b/crates/ra_mbe/src/lib.rs index 8e3167e55..d7462d09d 100644 --- a/crates/ra_mbe/src/lib.rs +++ b/crates/ra_mbe/src/lib.rs | |||
@@ -743,4 +743,23 @@ MACRO_ITEMS@[0; 40) | |||
743 | ); | 743 | ); |
744 | assert_expansion(&rules, "foo! { { 1; } }", "fn foo () {1 ;}"); | 744 | assert_expansion(&rules, "foo! { { 1; } }", "fn foo () {1 ;}"); |
745 | } | 745 | } |
746 | |||
747 | #[test] | ||
748 | fn test_meta() { | ||
749 | let rules = create_rules( | ||
750 | r#" | ||
751 | macro_rules! foo { | ||
752 | ($ i:meta) => ( | ||
753 | #[$ i] | ||
754 | fn bar() {} | ||
755 | ) | ||
756 | } | ||
757 | "#, | ||
758 | ); | ||
759 | assert_expansion( | ||
760 | &rules, | ||
761 | r#"foo! { cfg(target_os = "windows") }"#, | ||
762 | r#"# [cfg (target_os = "windows")] fn bar () {}"#, | ||
763 | ); | ||
764 | } | ||
746 | } | 765 | } |
diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs index a74e477d6..6ada580cc 100644 --- a/crates/ra_mbe/src/mbe_expander.rs +++ b/crates/ra_mbe/src/mbe_expander.rs | |||
@@ -166,6 +166,11 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings, | |||
166 | input.eat_block().ok_or(ExpandError::UnexpectedToken)?.clone(); | 166 | input.eat_block().ok_or(ExpandError::UnexpectedToken)?.clone(); |
167 | res.inner.insert(text.clone(), Binding::Simple(block.into())); | 167 | res.inner.insert(text.clone(), Binding::Simple(block.into())); |
168 | } | 168 | } |
169 | "meta" => { | ||
170 | let meta = | ||
171 | input.eat_meta().ok_or(ExpandError::UnexpectedToken)?.clone(); | ||
172 | res.inner.insert(text.clone(), Binding::Simple(meta.into())); | ||
173 | } | ||
169 | "item" => { | 174 | "item" => { |
170 | let item = | 175 | let item = |
171 | input.eat_item().ok_or(ExpandError::UnexpectedToken)?.clone(); | 176 | 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 2b11186c4..5d5557113 100644 --- a/crates/ra_mbe/src/subtree_parser.rs +++ b/crates/ra_mbe/src/subtree_parser.rs | |||
@@ -50,6 +50,10 @@ impl<'a> Parser<'a> { | |||
50 | self.parse(ra_parser::parse_block) | 50 | self.parse(ra_parser::parse_block) |
51 | } | 51 | } |
52 | 52 | ||
53 | pub fn parse_meta(self) -> Option<tt::TokenTree> { | ||
54 | self.parse(ra_parser::parse_meta) | ||
55 | } | ||
56 | |||
53 | pub fn parse_item(self) -> Option<tt::TokenTree> { | 57 | pub fn parse_item(self) -> Option<tt::TokenTree> { |
54 | self.parse(ra_parser::parse_item) | 58 | self.parse(ra_parser::parse_item) |
55 | } | 59 | } |
diff --git a/crates/ra_mbe/src/tt_cursor.rs b/crates/ra_mbe/src/tt_cursor.rs index d700aad69..04bb6b563 100644 --- a/crates/ra_mbe/src/tt_cursor.rs +++ b/crates/ra_mbe/src/tt_cursor.rs | |||
@@ -109,6 +109,11 @@ impl<'a> TtCursor<'a> { | |||
109 | parser.parse_block() | 109 | parser.parse_block() |
110 | } | 110 | } |
111 | 111 | ||
112 | pub(crate) fn eat_meta(&mut self) -> Option<tt::TokenTree> { | ||
113 | let parser = Parser::new(&mut self.pos, self.subtree); | ||
114 | parser.parse_meta() | ||
115 | } | ||
116 | |||
112 | pub(crate) fn eat_item(&mut self) -> Option<tt::TokenTree> { | 117 | pub(crate) fn eat_item(&mut self) -> Option<tt::TokenTree> { |
113 | let parser = Parser::new(&mut self.pos, self.subtree); | 118 | let parser = Parser::new(&mut self.pos, self.subtree); |
114 | parser.parse_item() | 119 | parser.parse_item() |
diff --git a/crates/ra_parser/src/grammar.rs b/crates/ra_parser/src/grammar.rs index 7bae0bc7b..13c50c79c 100644 --- a/crates/ra_parser/src/grammar.rs +++ b/crates/ra_parser/src/grammar.rs | |||
@@ -99,6 +99,33 @@ pub(crate) fn block(p: &mut Parser) { | |||
99 | expressions::block(p); | 99 | expressions::block(p); |
100 | } | 100 | } |
101 | 101 | ||
102 | // Parse a meta item , which excluded [], e.g : #[ MetaItem ] | ||
103 | pub(crate) fn meta_item(p: &mut Parser) { | ||
104 | fn is_delimiter(p: &mut Parser) -> bool { | ||
105 | match p.current() { | ||
106 | L_CURLY | L_PAREN | L_BRACK => true, | ||
107 | _ => false, | ||
108 | } | ||
109 | } | ||
110 | |||
111 | if is_delimiter(p) { | ||
112 | items::token_tree(p); | ||
113 | return; | ||
114 | } | ||
115 | |||
116 | let m = p.start(); | ||
117 | while !p.at(EOF) { | ||
118 | if is_delimiter(p) { | ||
119 | items::token_tree(p); | ||
120 | break; | ||
121 | } else { | ||
122 | p.bump(); | ||
123 | } | ||
124 | } | ||
125 | |||
126 | m.complete(p, TOKEN_TREE); | ||
127 | } | ||
128 | |||
102 | pub(crate) fn item(p: &mut Parser) { | 129 | pub(crate) fn item(p: &mut Parser) { |
103 | items::item_or_macro(p, true, items::ItemFlavor::Mod) | 130 | items::item_or_macro(p, true, items::ItemFlavor::Mod) |
104 | } | 131 | } |
diff --git a/crates/ra_parser/src/lib.rs b/crates/ra_parser/src/lib.rs index 1e6a00642..4787b5b9e 100644 --- a/crates/ra_parser/src/lib.rs +++ b/crates/ra_parser/src/lib.rs | |||
@@ -98,6 +98,10 @@ pub fn parse_block(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) | |||
98 | parse_from_tokens(token_source, tree_sink, grammar::block); | 98 | parse_from_tokens(token_source, tree_sink, grammar::block); |
99 | } | 99 | } |
100 | 100 | ||
101 | pub fn parse_meta(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) { | ||
102 | parse_from_tokens(token_source, tree_sink, grammar::meta_item); | ||
103 | } | ||
104 | |||
101 | /// Parse given tokens into the given sink as an item | 105 | /// Parse given tokens into the given sink as an item |
102 | pub fn parse_item(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) { | 106 | pub fn parse_item(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) { |
103 | parse_from_tokens(token_source, tree_sink, grammar::item); | 107 | parse_from_tokens(token_source, tree_sink, grammar::item); |