aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-02-04 00:50:48 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-02-04 00:50:48 +0000
commit13a2bdb0a89260e978ba8e55abd7a51a003e62a7 (patch)
tree35eb019bf768f8566156126d88175d33d7278f56
parent998ed13d09992d1fe24a45cc725c55390d9a5ca7 (diff)
parent0000f007873a3de2b454bd808083c0c0e8c6c6fa (diff)
Merge #736
736: mbe: Add support matching for matching idents r=jrmuizel a=jrmuizel Factors out a helper and adds support for matching idents. Co-authored-by: Jeff Muizelaar <[email protected]>
-rw-r--r--crates/ra_mbe/src/lib.rs68
-rw-r--r--crates/ra_mbe/src/mbe_expander.rs5
2 files changed, 49 insertions, 24 deletions
diff --git a/crates/ra_mbe/src/lib.rs b/crates/ra_mbe/src/lib.rs
index ec12192cc..6f719acbf 100644
--- a/crates/ra_mbe/src/lib.rs
+++ b/crates/ra_mbe/src/lib.rs
@@ -161,6 +161,18 @@ impl_froms!(TokenTree: Leaf, Subtree);
161 ) 161 )
162 } 162 }
163 163
164 fn create_rules(macro_definition: &str) -> MacroRules {
165 let source_file = ast::SourceFile::parse(macro_definition);
166 let macro_definition = source_file
167 .syntax()
168 .descendants()
169 .find_map(ast::MacroCall::cast)
170 .unwrap();
171
172 let definition_tt = ast_to_token_tree(macro_definition.token_tree().unwrap()).unwrap();
173 crate::MacroRules::parse(&definition_tt).unwrap()
174 }
175
164 fn assert_expansion(rules: &MacroRules, invocation: &str, expansion: &str) { 176 fn assert_expansion(rules: &MacroRules, invocation: &str, expansion: &str) {
165 let source_file = ast::SourceFile::parse(invocation); 177 let source_file = ast::SourceFile::parse(invocation);
166 let macro_invocation = source_file 178 let macro_invocation = source_file
@@ -177,7 +189,8 @@ impl_froms!(TokenTree: Leaf, Subtree);
177 189
178 #[test] 190 #[test]
179 fn test_fail_match_pattern_by_first_token() { 191 fn test_fail_match_pattern_by_first_token() {
180 let macro_definition = r#" 192 let rules = create_rules(
193 r#"
181 macro_rules! foo { 194 macro_rules! foo {
182 ($ i:ident) => ( 195 ($ i:ident) => (
183 mod $ i {} 196 mod $ i {}
@@ -189,17 +202,8 @@ impl_froms!(TokenTree: Leaf, Subtree);
189 struct $ i; 202 struct $ i;
190 ) 203 )
191 } 204 }
192"#; 205"#,
193 206 );
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 207
204 assert_expansion(&rules, "foo! { foo }", "mod foo {}"); 208 assert_expansion(&rules, "foo! { foo }", "mod foo {}");
205 assert_expansion(&rules, "foo! { = bar }", "fn bar () {}"); 209 assert_expansion(&rules, "foo! { = bar }", "fn bar () {}");
@@ -208,7 +212,8 @@ impl_froms!(TokenTree: Leaf, Subtree);
208 212
209 #[test] 213 #[test]
210 fn test_fail_match_pattern_by_last_token() { 214 fn test_fail_match_pattern_by_last_token() {
211 let macro_definition = r#" 215 let rules = create_rules(
216 r#"
212 macro_rules! foo { 217 macro_rules! foo {
213 ($ i:ident) => ( 218 ($ i:ident) => (
214 mod $ i {} 219 mod $ i {}
@@ -220,20 +225,35 @@ impl_froms!(TokenTree: Leaf, Subtree);
220 struct $ i; 225 struct $ i;
221 ) 226 )
222 } 227 }
223"#; 228"#,
224 229 );
225 let source_file = ast::SourceFile::parse(macro_definition);
226 let macro_definition = source_file
227 .syntax()
228 .descendants()
229 .find_map(ast::MacroCall::cast)
230 .unwrap();
231
232 let definition_tt = ast_to_token_tree(macro_definition.token_tree().unwrap()).unwrap();
233 let rules = crate::MacroRules::parse(&definition_tt).unwrap();
234 230
235 assert_expansion(&rules, "foo! { foo }", "mod foo {}"); 231 assert_expansion(&rules, "foo! { foo }", "mod foo {}");
236 assert_expansion(&rules, "foo! { bar = }", "fn bar () {}"); 232 assert_expansion(&rules, "foo! { bar = }", "fn bar () {}");
237 assert_expansion(&rules, "foo! { Baz + }", "struct Baz ;"); 233 assert_expansion(&rules, "foo! { Baz + }", "struct Baz ;");
238 } 234 }
235
236 #[test]
237 fn test_fail_match_pattern_by_word_token() {
238 let rules = create_rules(
239 r#"
240 macro_rules! foo {
241 ($ i:ident) => (
242 mod $ i {}
243 );
244 (spam $ i:ident) => (
245 fn $ i() {}
246 );
247 (eggs $ i:ident) => (
248 struct $ i;
249 )
250 }
251"#,
252 );
253
254 assert_expansion(&rules, "foo! { foo }", "mod foo {}");
255 assert_expansion(&rules, "foo! { spam bar }", "fn bar () {}");
256 assert_expansion(&rules, "foo! { eggs Baz }", "struct Baz ;");
257 }
258
239} 259}
diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs
index 2945e7359..212e2ea92 100644
--- a/crates/ra_mbe/src/mbe_expander.rs
+++ b/crates/ra_mbe/src/mbe_expander.rs
@@ -126,6 +126,11 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Option<Bindings>
126 return None; 126 return None;
127 } 127 }
128 } 128 }
129 crate::Leaf::Ident(ident) => {
130 if input.eat_ident()?.text != ident.text {
131 return None;
132 }
133 }
129 _ => return None, 134 _ => return None,
130 }, 135 },
131 crate::TokenTree::Repeat(crate::Repeat { 136 crate::TokenTree::Repeat(crate::Repeat {