add block matcher
This commit is contained in:
parent
8092b6487f
commit
762819864f
6 changed files with 64 additions and 0 deletions
|
@ -743,4 +743,23 @@ MACRO_ITEMS@[0; 40)
|
|||
);
|
||||
assert_expansion(&rules, "foo! { { 1; } }", "fn foo () {1 ;}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_meta() {
|
||||
let rules = create_rules(
|
||||
r#"
|
||||
macro_rules! foo {
|
||||
($ i:meta) => (
|
||||
#[$ i]
|
||||
fn bar() {}
|
||||
)
|
||||
}
|
||||
"#,
|
||||
);
|
||||
assert_expansion(
|
||||
&rules,
|
||||
r#"foo! { cfg(target_os = "windows") }"#,
|
||||
r#"# [cfg (target_os = "windows")] fn bar () {}"#,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -166,6 +166,11 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings,
|
|||
input.eat_block().ok_or(ExpandError::UnexpectedToken)?.clone();
|
||||
res.inner.insert(text.clone(), Binding::Simple(block.into()));
|
||||
}
|
||||
"meta" => {
|
||||
let meta =
|
||||
input.eat_meta().ok_or(ExpandError::UnexpectedToken)?.clone();
|
||||
res.inner.insert(text.clone(), Binding::Simple(meta.into()));
|
||||
}
|
||||
"item" => {
|
||||
let item =
|
||||
input.eat_item().ok_or(ExpandError::UnexpectedToken)?.clone();
|
||||
|
|
|
@ -50,6 +50,10 @@ impl<'a> Parser<'a> {
|
|||
self.parse(ra_parser::parse_block)
|
||||
}
|
||||
|
||||
pub fn parse_meta(self) -> Option<tt::TokenTree> {
|
||||
self.parse(ra_parser::parse_meta)
|
||||
}
|
||||
|
||||
pub fn parse_item(self) -> Option<tt::TokenTree> {
|
||||
self.parse(ra_parser::parse_item)
|
||||
}
|
||||
|
|
|
@ -109,6 +109,11 @@ impl<'a> TtCursor<'a> {
|
|||
parser.parse_block()
|
||||
}
|
||||
|
||||
pub(crate) fn eat_meta(&mut self) -> Option<tt::TokenTree> {
|
||||
let parser = Parser::new(&mut self.pos, self.subtree);
|
||||
parser.parse_meta()
|
||||
}
|
||||
|
||||
pub(crate) fn eat_item(&mut self) -> Option<tt::TokenTree> {
|
||||
let parser = Parser::new(&mut self.pos, self.subtree);
|
||||
parser.parse_item()
|
||||
|
|
|
@ -99,6 +99,33 @@ pub(crate) fn block(p: &mut Parser) {
|
|||
expressions::block(p);
|
||||
}
|
||||
|
||||
// Parse a meta item , which excluded [], e.g : #[ MetaItem ]
|
||||
pub(crate) fn meta_item(p: &mut Parser) {
|
||||
fn is_delimiter(p: &mut Parser) -> bool {
|
||||
match p.current() {
|
||||
L_CURLY | L_PAREN | L_BRACK => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
if is_delimiter(p) {
|
||||
items::token_tree(p);
|
||||
return;
|
||||
}
|
||||
|
||||
let m = p.start();
|
||||
while !p.at(EOF) {
|
||||
if is_delimiter(p) {
|
||||
items::token_tree(p);
|
||||
break;
|
||||
} else {
|
||||
p.bump();
|
||||
}
|
||||
}
|
||||
|
||||
m.complete(p, TOKEN_TREE);
|
||||
}
|
||||
|
||||
pub(crate) fn item(p: &mut Parser) {
|
||||
items::item_or_macro(p, true, items::ItemFlavor::Mod)
|
||||
}
|
||||
|
|
|
@ -98,6 +98,10 @@ pub fn parse_block(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink)
|
|||
parse_from_tokens(token_source, tree_sink, grammar::block);
|
||||
}
|
||||
|
||||
pub fn parse_meta(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
|
||||
parse_from_tokens(token_source, tree_sink, grammar::meta_item);
|
||||
}
|
||||
|
||||
/// 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);
|
||||
|
|
Loading…
Add table
Reference in a new issue