Add vis matcher

This commit is contained in:
Edwin Cheng 2019-04-19 21:38:26 +08:00
parent c5983b85fc
commit 87ff908135
6 changed files with 33 additions and 1 deletions

View File

@ -809,4 +809,16 @@ macro_rules! foo {
); );
assert_expansion(&rules, r#"foo!(u8 0)"#, r#"const VALUE: u8 = 0;"#); assert_expansion(&rules, r#"foo!(u8 0)"#, r#"const VALUE: u8 = 0;"#);
} }
#[test]
fn test_vis() {
let rules = create_rules(
r#"
macro_rules! foo {
($ vis:vis $ name:ident) => { $ vis fn $ name() {}};
}
"#,
);
assert_expansion(&rules, r#"foo!(pub foo);"#, r#"pub fn foo() {}"#);
}
} }

View File

@ -193,6 +193,10 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings,
Binding::Simple(tt::Leaf::from(literal).into()), Binding::Simple(tt::Leaf::from(literal).into()),
); );
} }
"vis" => {
let vis = input.eat_vis().ok_or(ExpandError::UnexpectedToken)?.clone();
res.inner.insert(text.clone(), Binding::Simple(vis.into()));
}
_ => return Err(ExpandError::UnexpectedToken), _ => return Err(ExpandError::UnexpectedToken),
} }

View File

@ -58,6 +58,10 @@ pub fn parse_item(self) -> Option<tt::TokenTree> {
self.parse(ra_parser::parse_item) self.parse(ra_parser::parse_item)
} }
pub fn parse_vis(self) -> Option<tt::TokenTree> {
self.parse(ra_parser::parse_vis)
}
fn parse<F>(self, f: F) -> Option<tt::TokenTree> fn parse<F>(self, f: F) -> Option<tt::TokenTree>
where where
F: FnOnce(&dyn TokenSource, &mut dyn TreeSink), F: FnOnce(&dyn TokenSource, &mut dyn TreeSink),

View File

@ -137,6 +137,11 @@ pub(crate) fn eat_lifetime(&mut self) -> Option<tt::TokenTree> {
self.eat_ident().cloned().map(|ident| tt::Leaf::from(ident).into()) self.eat_ident().cloned().map(|ident| tt::Leaf::from(ident).into())
} }
pub(crate) fn eat_vis(&mut self) -> Option<tt::TokenTree> {
let parser = Parser::new(&mut self.pos, self.subtree);
parser.parse_vis()
}
pub(crate) fn expect_char(&mut self, char: char) -> Result<(), ParseError> { pub(crate) fn expect_char(&mut self, char: char) -> Result<(), ParseError> {
if self.at_char(char) { if self.at_char(char) {
self.bump(); self.bump();

View File

@ -167,7 +167,7 @@ fn is_block(self) -> bool {
} }
} }
fn opt_visibility(p: &mut Parser) -> bool { pub(crate) fn opt_visibility(p: &mut Parser) -> bool {
match p.current() { match p.current() {
PUB_KW => { PUB_KW => {
let m = p.start(); let m = p.start();

View File

@ -107,6 +107,13 @@ pub fn parse_item(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink)
parse_from_tokens(token_source, tree_sink, grammar::item); parse_from_tokens(token_source, tree_sink, grammar::item);
} }
/// Parse given tokens into the given sink as an visibility qualifier
pub fn parse_vis(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
parse_from_tokens(token_source, tree_sink, |p| {
grammar::opt_visibility(p);
});
}
pub fn parse_macro_items(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) { pub fn parse_macro_items(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
parse_from_tokens(token_source, tree_sink, grammar::macro_items); parse_from_tokens(token_source, tree_sink, grammar::macro_items);
} }