aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_mbe/src/lib.rs46
-rw-r--r--crates/ra_mbe/src/mbe_parser.rs8
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0046_extern_inner_attributes.rs (renamed from crates/ra_syntax/tests/data/parser/ok/0045_extern_inner_attributes.rs)0
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0046_extern_inner_attributes.txt (renamed from crates/ra_syntax/tests/data/parser/ok/0045_extern_inner_attributes.txt)0
4 files changed, 53 insertions, 1 deletions
diff --git a/crates/ra_mbe/src/lib.rs b/crates/ra_mbe/src/lib.rs
index 3e7f458cf..922256c03 100644
--- a/crates/ra_mbe/src/lib.rs
+++ b/crates/ra_mbe/src/lib.rs
@@ -160,4 +160,50 @@ 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 fn assert_expansion(rules: &MacroRules, invocation: &str, expansion: &str) {
165 let source_file = ast::SourceFile::parse(invocation);
166 let macro_invocation = source_file
167 .syntax()
168 .descendants()
169 .find_map(ast::MacroCall::cast)
170 .unwrap();
171
172 let invocation_tt = ast_to_token_tree(macro_invocation.token_tree().unwrap()).unwrap();
173
174 let expaned = rules.expand(&invocation_tt).unwrap();
175 assert_eq!(expaned.to_string(), expansion);
176 }
177
178 #[test]
179 fn test_fail_match_pattern_by_token() {
180 let macro_definition = r#"
181 macro_rules! foo {
182 ($ i:ident) => (
183 mod $ i {}
184 );
185 (= $ i:ident) => (
186 fn $ i() {}
187 );
188 (+ $ i:ident) => (
189 struct $ i;
190 )
191 }
192"#;
193
194 let source_file = ast::SourceFile::parse(macro_definition);
195 let macro_definition = source_file
196 .syntax()
197 .descendants()
198 .find_map(ast::MacroCall::cast)
199 .unwrap();
200
201 let definition_tt = ast_to_token_tree(macro_definition.token_tree().unwrap()).unwrap();
202 let rules = crate::MacroRules::parse(&definition_tt).unwrap();
203
204 assert_expansion(&rules, "foo! { foo }", "mod foo {}");
205 assert_expansion(&rules, "foo! { = bar }", "fn bar () {}");
206 assert_expansion(&rules, "foo! { + Baz }", "struct Baz ;");
207 }
208
163} 209}
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}
diff --git a/crates/ra_syntax/tests/data/parser/ok/0045_extern_inner_attributes.rs b/crates/ra_syntax/tests/data/parser/ok/0046_extern_inner_attributes.rs
index fe67e2df4..fe67e2df4 100644
--- a/crates/ra_syntax/tests/data/parser/ok/0045_extern_inner_attributes.rs
+++ b/crates/ra_syntax/tests/data/parser/ok/0046_extern_inner_attributes.rs
diff --git a/crates/ra_syntax/tests/data/parser/ok/0045_extern_inner_attributes.txt b/crates/ra_syntax/tests/data/parser/ok/0046_extern_inner_attributes.txt
index c68e1b271..c68e1b271 100644
--- a/crates/ra_syntax/tests/data/parser/ok/0045_extern_inner_attributes.txt
+++ b/crates/ra_syntax/tests/data/parser/ok/0046_extern_inner_attributes.txt