Add block matcher

This commit is contained in:
Edwin Cheng 2019-04-19 18:30:43 +08:00
parent ab0a96586f
commit 8092b6487f
6 changed files with 35 additions and 0 deletions

View File

@ -731,4 +731,16 @@ MACRO_ITEMS@[0; 40)
}
"#, r#"extern crate a ; mod b ; mod c {} use d ; const E : i32 = 0 ; static F : i32 = 0 ; impl G {} struct H ; enum I {Foo} trait J {} fn h () {} extern {} type T = u8 ;"#);
}
#[test]
fn test_block() {
let rules = create_rules(
r#"
macro_rules! foo {
($ i:block) => { fn foo() $ i }
}
"#,
);
assert_expansion(&rules, "foo! { { 1; } }", "fn foo () {1 ;}");
}
}

View File

@ -161,6 +161,11 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings,
let pat = input.eat_stmt().ok_or(ExpandError::UnexpectedToken)?.clone();
res.inner.insert(text.clone(), Binding::Simple(pat.into()));
}
"block" => {
let block =
input.eat_block().ok_or(ExpandError::UnexpectedToken)?.clone();
res.inner.insert(text.clone(), Binding::Simple(block.into()));
}
"item" => {
let item =
input.eat_item().ok_or(ExpandError::UnexpectedToken)?.clone();

View File

@ -46,6 +46,10 @@ impl<'a> Parser<'a> {
self.parse(|src, sink| ra_parser::parse_stmt(src, sink, false))
}
pub fn parse_block(self) -> Option<tt::TokenTree> {
self.parse(ra_parser::parse_block)
}
pub fn parse_item(self) -> Option<tt::TokenTree> {
self.parse(ra_parser::parse_item)
}

View File

@ -104,6 +104,11 @@ impl<'a> TtCursor<'a> {
parser.parse_stmt()
}
pub(crate) fn eat_block(&mut self) -> Option<tt::TokenTree> {
let parser = Parser::new(&mut self.pos, self.subtree);
parser.parse_block()
}
pub(crate) fn eat_item(&mut self) -> Option<tt::TokenTree> {
let parser = Parser::new(&mut self.pos, self.subtree);
parser.parse_item()

View File

@ -95,6 +95,10 @@ pub(crate) fn stmt(p: &mut Parser, with_semi: bool) {
expressions::stmt(p, with_semi)
}
pub(crate) fn block(p: &mut Parser) {
expressions::block(p);
}
pub(crate) fn item(p: &mut Parser) {
items::item_or_macro(p, true, items::ItemFlavor::Mod)
}

View File

@ -93,6 +93,11 @@ pub fn parse_stmt(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink,
parse_from_tokens(token_source, tree_sink, |p| grammar::stmt(p, with_semi));
}
/// Parse given tokens into the given sink as a block
pub fn parse_block(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
parse_from_tokens(token_source, tree_sink, grammar::block);
}
/// Parse given tokens into the given sink as an item
pub fn parse_item(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
parse_from_tokens(token_source, tree_sink, grammar::item);