Auto merge of #29780 - KyleMayes:quote-ext, r=nrc
This is my first code contribution to Rust, so I'm sure there are some issues with the changes I've made. I've added the `quote_arg!`, `quote_block!`, `quote_path!`, and `quote_meta_item!` quasiquoting macros. From my experience trying to build AST in compiler plugins, I would like to be able to build any AST piece with a quasiquoting macro (e.g., `quote_struct_field!` or `quote_variant!`) and then use those AST pieces in other quasiquoting macros, but this pull request just adds some of the low-hanging fruit. I'm not sure if these additions are desirable, and I'm sure these macros can be implemented in an external crate if not.
This commit is contained in:
@@ -512,6 +512,18 @@ fn initial_syntax_expander_table<'feat>(ecfg: &expand::ExpansionConfig<'feat>)
|
||||
syntax_expanders.insert(intern("quote_attr"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_attr));
|
||||
syntax_expanders.insert(intern("quote_arg"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_arg));
|
||||
syntax_expanders.insert(intern("quote_block"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_block));
|
||||
syntax_expanders.insert(intern("quote_meta_item"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_meta_item));
|
||||
syntax_expanders.insert(intern("quote_path"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_path));
|
||||
}
|
||||
|
||||
syntax_expanders.insert(intern("line"),
|
||||
|
||||
@@ -158,6 +158,18 @@ pub mod rt {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for ast::Arg {
|
||||
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
|
||||
vec![TokenTree::Token(DUMMY_SP, token::Interpolated(token::NtArg(self.clone())))]
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for P<ast::Block> {
|
||||
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
|
||||
vec![TokenTree::Token(DUMMY_SP, token::Interpolated(token::NtBlock(self.clone())))]
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_to_tokens_slice {
|
||||
($t: ty, $sep: expr) => {
|
||||
impl ToTokens for [$t] {
|
||||
@@ -177,6 +189,7 @@ pub mod rt {
|
||||
|
||||
impl_to_tokens_slice! { ast::Ty, [TokenTree::Token(DUMMY_SP, token::Comma)] }
|
||||
impl_to_tokens_slice! { P<ast::Item>, [] }
|
||||
impl_to_tokens_slice! { ast::Arg, [TokenTree::Token(DUMMY_SP, token::Comma)] }
|
||||
|
||||
impl ToTokens for P<ast::MetaItem> {
|
||||
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
|
||||
@@ -383,6 +396,39 @@ pub fn expand_quote_attr(cx: &mut ExtCtxt,
|
||||
base::MacEager::expr(expanded)
|
||||
}
|
||||
|
||||
pub fn expand_quote_arg(cx: &mut ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
let expanded = expand_parse_call(cx, sp, "parse_arg_panic", vec!(), tts);
|
||||
base::MacEager::expr(expanded)
|
||||
}
|
||||
|
||||
pub fn expand_quote_block(cx: &mut ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
let expanded = expand_parse_call(cx, sp, "parse_block_panic", vec!(), tts);
|
||||
base::MacEager::expr(expanded)
|
||||
}
|
||||
|
||||
pub fn expand_quote_meta_item(cx: &mut ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
let expanded = expand_parse_call(cx, sp, "parse_meta_item_panic", vec!(), tts);
|
||||
base::MacEager::expr(expanded)
|
||||
}
|
||||
|
||||
pub fn expand_quote_path(cx: &mut ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
let mode = mk_parser_path(cx, sp, "LifetimeAndTypesWithoutColons");
|
||||
let expanded = expand_parse_call(cx, sp, "parse_path_panic", vec!(mode), tts);
|
||||
base::MacEager::expr(expanded)
|
||||
}
|
||||
|
||||
pub fn expand_quote_matcher(cx: &mut ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[TokenTree])
|
||||
@@ -440,6 +486,11 @@ fn mk_token_path(cx: &ExtCtxt, sp: Span, name: &str) -> P<ast::Expr> {
|
||||
cx.expr_path(cx.path_global(sp, idents))
|
||||
}
|
||||
|
||||
fn mk_parser_path(cx: &ExtCtxt, sp: Span, name: &str) -> P<ast::Expr> {
|
||||
let idents = vec!(id_ext("syntax"), id_ext("parse"), id_ext("parser"), id_ext(name));
|
||||
cx.expr_path(cx.path_global(sp, idents))
|
||||
}
|
||||
|
||||
fn mk_binop(cx: &ExtCtxt, sp: Span, bop: token::BinOpToken) -> P<ast::Expr> {
|
||||
let name = match bop {
|
||||
token::Plus => "Plus",
|
||||
|
||||
Reference in New Issue
Block a user