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 <jrmuizel@gmail.com>
This commit is contained in:
bors[bot] 2019-02-04 00:50:48 +00:00
commit 13a2bdb0a8
2 changed files with 49 additions and 24 deletions

View file

@ -161,6 +161,18 @@ impl_froms!(TokenTree: Leaf, Subtree);
) )
} }
fn create_rules(macro_definition: &str) -> MacroRules {
let source_file = ast::SourceFile::parse(macro_definition);
let macro_definition = source_file
.syntax()
.descendants()
.find_map(ast::MacroCall::cast)
.unwrap();
let definition_tt = ast_to_token_tree(macro_definition.token_tree().unwrap()).unwrap();
crate::MacroRules::parse(&definition_tt).unwrap()
}
fn assert_expansion(rules: &MacroRules, invocation: &str, expansion: &str) { fn assert_expansion(rules: &MacroRules, invocation: &str, expansion: &str) {
let source_file = ast::SourceFile::parse(invocation); let source_file = ast::SourceFile::parse(invocation);
let macro_invocation = source_file let macro_invocation = source_file
@ -177,7 +189,8 @@ impl_froms!(TokenTree: Leaf, Subtree);
#[test] #[test]
fn test_fail_match_pattern_by_first_token() { fn test_fail_match_pattern_by_first_token() {
let macro_definition = r#" let rules = create_rules(
r#"
macro_rules! foo { macro_rules! foo {
($ i:ident) => ( ($ i:ident) => (
mod $ i {} mod $ i {}
@ -189,17 +202,8 @@ impl_froms!(TokenTree: Leaf, Subtree);
struct $ i; struct $ i;
) )
} }
"#; "#,
);
let source_file = ast::SourceFile::parse(macro_definition);
let macro_definition = source_file
.syntax()
.descendants()
.find_map(ast::MacroCall::cast)
.unwrap();
let definition_tt = ast_to_token_tree(macro_definition.token_tree().unwrap()).unwrap();
let rules = crate::MacroRules::parse(&definition_tt).unwrap();
assert_expansion(&rules, "foo! { foo }", "mod foo {}"); assert_expansion(&rules, "foo! { foo }", "mod foo {}");
assert_expansion(&rules, "foo! { = bar }", "fn bar () {}"); assert_expansion(&rules, "foo! { = bar }", "fn bar () {}");
@ -208,7 +212,8 @@ impl_froms!(TokenTree: Leaf, Subtree);
#[test] #[test]
fn test_fail_match_pattern_by_last_token() { fn test_fail_match_pattern_by_last_token() {
let macro_definition = r#" let rules = create_rules(
r#"
macro_rules! foo { macro_rules! foo {
($ i:ident) => ( ($ i:ident) => (
mod $ i {} mod $ i {}
@ -220,20 +225,35 @@ impl_froms!(TokenTree: Leaf, Subtree);
struct $ i; struct $ i;
) )
} }
"#; "#,
);
let source_file = ast::SourceFile::parse(macro_definition);
let macro_definition = source_file
.syntax()
.descendants()
.find_map(ast::MacroCall::cast)
.unwrap();
let definition_tt = ast_to_token_tree(macro_definition.token_tree().unwrap()).unwrap();
let rules = crate::MacroRules::parse(&definition_tt).unwrap();
assert_expansion(&rules, "foo! { foo }", "mod foo {}"); assert_expansion(&rules, "foo! { foo }", "mod foo {}");
assert_expansion(&rules, "foo! { bar = }", "fn bar () {}"); assert_expansion(&rules, "foo! { bar = }", "fn bar () {}");
assert_expansion(&rules, "foo! { Baz + }", "struct Baz ;"); assert_expansion(&rules, "foo! { Baz + }", "struct Baz ;");
} }
#[test]
fn test_fail_match_pattern_by_word_token() {
let rules = create_rules(
r#"
macro_rules! foo {
($ i:ident) => (
mod $ i {}
);
(spam $ i:ident) => (
fn $ i() {}
);
(eggs $ i:ident) => (
struct $ i;
)
}
"#,
);
assert_expansion(&rules, "foo! { foo }", "mod foo {}");
assert_expansion(&rules, "foo! { spam bar }", "fn bar () {}");
assert_expansion(&rules, "foo! { eggs Baz }", "struct Baz ;");
}
} }

View file

@ -126,6 +126,11 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Option<Bindings>
return None; return None;
} }
} }
crate::Leaf::Ident(ident) => {
if input.eat_ident()?.text != ident.text {
return None;
}
}
_ => return None, _ => return None,
}, },
crate::TokenTree::Repeat(crate::Repeat { crate::TokenTree::Repeat(crate::Repeat {