aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Muizelaar <[email protected]>2019-02-02 17:11:12 +0000
committerJeff Muizelaar <[email protected]>2019-02-03 03:39:13 +0000
commit31d143ba18b74bdbe032a305c7705123e055b39e (patch)
tree00b4393d1e4caa2c77ee2f3492553d3a6bd01c62
parent4c0ab7db85d2084870db4a2f92d92a3ae67a3bb1 (diff)
Fix macro_rules separator parsing.
macro_rules rules are separated by ';' including an optional ';' at the end
-rw-r--r--crates/ra_mbe/src/lib.rs42
-rw-r--r--crates/ra_mbe/src/mbe_parser.rs8
2 files changed, 49 insertions, 1 deletions
diff --git a/crates/ra_mbe/src/lib.rs b/crates/ra_mbe/src/lib.rs
index 3e7f458cf..bafa301ea 100644
--- a/crates/ra_mbe/src/lib.rs
+++ b/crates/ra_mbe/src/lib.rs
@@ -160,4 +160,46 @@ impl_froms!(TokenTree: Leaf, Subtree);
160 impl From < Subtree > for TokenTree {fn from (it : Subtree) -> TokenTree {TokenTree :: Subtree (it)}}" 160 impl From < Subtree > for TokenTree {fn from (it : Subtree) -> TokenTree {TokenTree :: Subtree (it)}}"
161 ) 161 )
162 } 162 }
163
164 #[test]
165 fn test_fail_match_pattern_by_token() {
166 let macro_definition = r#"
167 macro_rules! foo {
168 ($ i:ident) => (
169 mod $ i {}
170 );
171 (= $ i:ident) => (
172 fn $ i() {}
173 );
174 (+ $ i:ident) => (
175 struct $ i;
176 )
177 }
178"#;
179
180 let macro_invocation = r#"
181foo! { foo }
182"#;
183
184 let source_file = ast::SourceFile::parse(macro_definition);
185 let macro_definition = source_file
186 .syntax()
187 .descendants()
188 .find_map(ast::MacroCall::cast)
189 .unwrap();
190
191 let source_file = ast::SourceFile::parse(macro_invocation);
192 let macro_invocation = source_file
193 .syntax()
194 .descendants()
195 .find_map(ast::MacroCall::cast)
196 .unwrap();
197
198 let definition_tt = ast_to_token_tree(macro_definition.token_tree().unwrap()).unwrap();
199 let invocation_tt = ast_to_token_tree(macro_invocation.token_tree().unwrap()).unwrap();
200 let rules = crate::MacroRules::parse(&definition_tt).unwrap();
201 let expansion = rules.expand(&invocation_tt).unwrap();
202 assert_eq!(expansion.to_string(), "mod foo {}")
203 }
204
163} 205}
diff --git a/crates/ra_mbe/src/mbe_parser.rs b/crates/ra_mbe/src/mbe_parser.rs
index a3e6abffc..abad2e8c8 100644
--- a/crates/ra_mbe/src/mbe_parser.rs
+++ b/crates/ra_mbe/src/mbe_parser.rs
@@ -7,7 +7,13 @@ pub(crate) fn parse(tt: &tt::Subtree) -> Option<crate::MacroRules> {
7 let mut parser = TtCursor::new(tt); 7 let mut parser = TtCursor::new(tt);
8 let mut rules = Vec::new(); 8 let mut rules = Vec::new();
9 while !parser.is_eof() { 9 while !parser.is_eof() {
10 rules.push(parse_rule(&mut parser)?) 10 rules.push(parse_rule(&mut parser)?);
11 if parser.expect_char(';') == None {
12 if !parser.is_eof() {
13 return None;
14 }
15 break;
16 }
11 } 17 }
12 Some(crate::MacroRules { rules }) 18 Some(crate::MacroRules { rules })
13} 19}