Fix macro_rules separator parsing.

macro_rules rules are separated by ';' including an optional ';' at the
end
This commit is contained in:
Jeff Muizelaar 2019-02-02 12:11:12 -05:00
parent 4c0ab7db85
commit 31d143ba18
2 changed files with 49 additions and 1 deletions

View File

@ -160,4 +160,46 @@ impl_froms!(TokenTree: Leaf, Subtree);
impl From < Subtree > for TokenTree {fn from (it : Subtree) -> TokenTree {TokenTree :: Subtree (it)}}"
)
}
#[test]
fn test_fail_match_pattern_by_token() {
let macro_definition = r#"
macro_rules! foo {
($ i:ident) => (
mod $ i {}
);
(= $ i:ident) => (
fn $ i() {}
);
(+ $ i:ident) => (
struct $ i;
)
}
"#;
let macro_invocation = r#"
foo! { foo }
"#;
let source_file = ast::SourceFile::parse(macro_definition);
let macro_definition = source_file
.syntax()
.descendants()
.find_map(ast::MacroCall::cast)
.unwrap();
let source_file = ast::SourceFile::parse(macro_invocation);
let macro_invocation = source_file
.syntax()
.descendants()
.find_map(ast::MacroCall::cast)
.unwrap();
let definition_tt = ast_to_token_tree(macro_definition.token_tree().unwrap()).unwrap();
let invocation_tt = ast_to_token_tree(macro_invocation.token_tree().unwrap()).unwrap();
let rules = crate::MacroRules::parse(&definition_tt).unwrap();
let expansion = rules.expand(&invocation_tt).unwrap();
assert_eq!(expansion.to_string(), "mod foo {}")
}
}

View File

@ -7,7 +7,13 @@ pub(crate) fn parse(tt: &tt::Subtree) -> Option<crate::MacroRules> {
let mut parser = TtCursor::new(tt);
let mut rules = Vec::new();
while !parser.is_eof() {
rules.push(parse_rule(&mut parser)?)
rules.push(parse_rule(&mut parser)?);
if parser.expect_char(';') == None {
if !parser.is_eof() {
return None;
}
break;
}
}
Some(crate::MacroRules { rules })
}