// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use ast;
+use ast::{self, Arg, Arm, Block, Expr, Item, Pat, Path, Stmt, TokenTree, Ty};
use codemap::Span;
use ext::base::ExtCtxt;
use ext::base;
use ext::build::AstBuilder;
+use parse::parser::{Parser, PathParsingMode};
use parse::token::*;
use parse::token;
use ptr::P;
impl<T: ToTokens> ToTokens for Option<T> {
fn to_tokens(&self, cx: &ExtCtxt) -> Vec<TokenTree> {
- match self {
- &Some(ref t) => t.to_tokens(cx),
- &None => Vec::new(),
+ match *self {
+ Some(ref t) => t.to_tokens(cx),
+ None => Vec::new(),
}
}
}
impl ToTokens for ast::Ident {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
- vec![ast::TtToken(DUMMY_SP, token::Ident(*self, token::Plain))]
+ vec![TokenTree::Token(DUMMY_SP, token::Ident(*self, token::Plain))]
}
}
impl ToTokens for ast::Path {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
- vec![ast::TtToken(DUMMY_SP, token::Interpolated(token::NtPath(Box::new(self.clone()))))]
+ vec![TokenTree::Token(DUMMY_SP,
+ token::Interpolated(token::NtPath(Box::new(self.clone()))))]
}
}
impl ToTokens for ast::Ty {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
- vec![ast::TtToken(self.span, token::Interpolated(token::NtTy(P(self.clone()))))]
+ vec![TokenTree::Token(self.span, token::Interpolated(token::NtTy(P(self.clone()))))]
}
}
impl ToTokens for ast::Block {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
- vec![ast::TtToken(self.span, token::Interpolated(token::NtBlock(P(self.clone()))))]
+ vec![TokenTree::Token(self.span, token::Interpolated(token::NtBlock(P(self.clone()))))]
}
}
impl ToTokens for ast::Generics {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
- vec![ast::TtToken(DUMMY_SP, token::Interpolated(token::NtGenerics(self.clone())))]
+ vec![TokenTree::Token(DUMMY_SP, token::Interpolated(token::NtGenerics(self.clone())))]
}
}
impl ToTokens for ast::WhereClause {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
- vec![ast::TtToken(DUMMY_SP, token::Interpolated(token::NtWhereClause(self.clone())))]
+ vec![TokenTree::Token(DUMMY_SP,
+ token::Interpolated(token::NtWhereClause(self.clone())))]
}
}
impl ToTokens for P<ast::Item> {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
- vec![ast::TtToken(self.span, token::Interpolated(token::NtItem(self.clone())))]
+ vec![TokenTree::Token(self.span, token::Interpolated(token::NtItem(self.clone())))]
}
}
impl ToTokens for P<ast::ImplItem> {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
- vec![ast::TtToken(self.span, token::Interpolated(token::NtImplItem(self.clone())))]
+ vec![TokenTree::Token(self.span, token::Interpolated(token::NtImplItem(self.clone())))]
}
}
impl ToTokens for P<ast::TraitItem> {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
- vec![ast::TtToken(self.span, token::Interpolated(token::NtTraitItem(self.clone())))]
+ vec![TokenTree::Token(self.span, token::Interpolated(token::NtTraitItem(self.clone())))]
}
}
impl ToTokens for P<ast::Stmt> {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
let mut tts = vec![
- ast::TtToken(self.span, token::Interpolated(token::NtStmt(self.clone())))
+ TokenTree::Token(self.span, token::Interpolated(token::NtStmt(self.clone())))
];
// Some statements require a trailing semicolon.
if classify::stmt_ends_with_semi(&self.node) {
- tts.push(ast::TtToken(self.span, token::Semi));
+ tts.push(TokenTree::Token(self.span, token::Semi));
}
tts
impl ToTokens for P<ast::Expr> {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
- vec![ast::TtToken(self.span, token::Interpolated(token::NtExpr(self.clone())))]
+ vec![TokenTree::Token(self.span, token::Interpolated(token::NtExpr(self.clone())))]
}
}
impl ToTokens for P<ast::Pat> {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
- vec![ast::TtToken(self.span, token::Interpolated(token::NtPat(self.clone())))]
+ vec![TokenTree::Token(self.span, token::Interpolated(token::NtPat(self.clone())))]
}
}
impl ToTokens for ast::Arm {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
- vec![ast::TtToken(DUMMY_SP, token::Interpolated(token::NtArm(self.clone())))]
+ vec![TokenTree::Token(DUMMY_SP, token::Interpolated(token::NtArm(self.clone())))]
+ }
+ }
+
+ 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())))]
}
}
};
}
- impl_to_tokens_slice! { ast::Ty, [ast::TtToken(DUMMY_SP, token::Comma)] }
+ 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> {
- vec![ast::TtToken(DUMMY_SP, token::Interpolated(token::NtMeta(self.clone())))]
+ vec![TokenTree::Token(DUMMY_SP, token::Interpolated(token::NtMeta(self.clone())))]
}
}
fn to_tokens(&self, cx: &ExtCtxt) -> Vec<TokenTree> {
let mut r = vec![];
// FIXME: The spans could be better
- r.push(ast::TtToken(self.span, token::Pound));
- if self.node.style == ast::AttrInner {
- r.push(ast::TtToken(self.span, token::Not));
+ r.push(TokenTree::Token(self.span, token::Pound));
+ if self.node.style == ast::AttrStyle::Inner {
+ r.push(TokenTree::Token(self.span, token::Not));
}
- r.push(ast::TtDelimited(self.span, Rc::new(ast::Delimited {
+ r.push(TokenTree::Delimited(self.span, Rc::new(ast::Delimited {
delim: token::Bracket,
open_span: self.span,
tts: self.node.value.to_tokens(cx),
impl ToTokens for () {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
- vec![ast::TtDelimited(DUMMY_SP, Rc::new(ast::Delimited {
+ vec![TokenTree::Delimited(DUMMY_SP, Rc::new(ast::Delimited {
delim: token::Paren,
open_span: DUMMY_SP,
tts: vec![],
fn parse_item(&self, s: String) -> P<ast::Item>;
fn parse_expr(&self, s: String) -> P<ast::Expr>;
fn parse_stmt(&self, s: String) -> P<ast::Stmt>;
- fn parse_tts(&self, s: String) -> Vec<ast::TokenTree>;
+ fn parse_tts(&self, s: String) -> Vec<TokenTree>;
}
impl<'a> ExtParseUtils for ExtCtxt<'a> {
self.parse_sess())
}
- fn parse_tts(&self, s: String) -> Vec<ast::TokenTree> {
+ fn parse_tts(&self, s: String) -> Vec<TokenTree> {
parse::parse_tts_from_source_str("<quote expansion>".to_string(),
s,
self.cfg(),
}
}
+// These panicking parsing functions are used by the quote_*!() syntax extensions,
+// but shouldn't be used otherwise.
+pub fn parse_expr_panic(parser: &mut Parser) -> P<Expr> {
+ panictry!(parser.parse_expr())
+}
+
+pub fn parse_item_panic(parser: &mut Parser) -> Option<P<Item>> {
+ panictry!(parser.parse_item())
+}
+
+pub fn parse_pat_panic(parser: &mut Parser) -> P<Pat> {
+ panictry!(parser.parse_pat())
+}
+
+pub fn parse_arm_panic(parser: &mut Parser) -> Arm {
+ panictry!(parser.parse_arm())
+}
+
+pub fn parse_ty_panic(parser: &mut Parser) -> P<Ty> {
+ panictry!(parser.parse_ty())
+}
+
+pub fn parse_stmt_panic(parser: &mut Parser) -> Option<P<Stmt>> {
+ panictry!(parser.parse_stmt())
+}
+
+pub fn parse_attribute_panic(parser: &mut Parser, permit_inner: bool) -> ast::Attribute {
+ panictry!(parser.parse_attribute(permit_inner))
+}
+
+pub fn parse_arg_panic(parser: &mut Parser) -> Arg {
+ panictry!(parser.parse_arg())
+}
+
+pub fn parse_block_panic(parser: &mut Parser) -> P<Block> {
+ panictry!(parser.parse_block())
+}
+
+pub fn parse_meta_item_panic(parser: &mut Parser) -> P<ast::MetaItem> {
+ panictry!(parser.parse_meta_item())
+}
+
+pub fn parse_path_panic(parser: &mut Parser, mode: PathParsingMode) -> ast::Path {
+ panictry!(parser.parse_path(mode))
+}
+
pub fn expand_quote_tokens<'cx>(cx: &'cx mut ExtCtxt,
sp: Span,
- tts: &[ast::TokenTree])
+ tts: &[TokenTree])
-> Box<base::MacResult+'cx> {
let (cx_expr, expr) = expand_tts(cx, sp, tts);
let expanded = expand_wrapper(cx, sp, cx_expr, expr, &[&["syntax", "ext", "quote", "rt"]]);
pub fn expand_quote_expr<'cx>(cx: &'cx mut ExtCtxt,
sp: Span,
- tts: &[ast::TokenTree])
+ tts: &[TokenTree])
-> Box<base::MacResult+'cx> {
- let expanded = expand_parse_call(cx, sp, "parse_expr", vec!(), tts);
+ let expanded = expand_parse_call(cx, sp, "parse_expr_panic", vec!(), tts);
base::MacEager::expr(expanded)
}
pub fn expand_quote_item<'cx>(cx: &mut ExtCtxt,
sp: Span,
- tts: &[ast::TokenTree])
+ tts: &[TokenTree])
-> Box<base::MacResult+'cx> {
- let expanded = expand_parse_call(cx, sp, "parse_item", vec!(), tts);
+ let expanded = expand_parse_call(cx, sp, "parse_item_panic", vec!(), tts);
base::MacEager::expr(expanded)
}
pub fn expand_quote_pat<'cx>(cx: &'cx mut ExtCtxt,
sp: Span,
- tts: &[ast::TokenTree])
+ tts: &[TokenTree])
-> Box<base::MacResult+'cx> {
- let expanded = expand_parse_call(cx, sp, "parse_pat", vec!(), tts);
+ let expanded = expand_parse_call(cx, sp, "parse_pat_panic", vec!(), tts);
base::MacEager::expr(expanded)
}
pub fn expand_quote_arm(cx: &mut ExtCtxt,
sp: Span,
- tts: &[ast::TokenTree])
+ tts: &[TokenTree])
-> Box<base::MacResult+'static> {
- let expanded = expand_parse_call(cx, sp, "parse_arm", vec!(), tts);
+ let expanded = expand_parse_call(cx, sp, "parse_arm_panic", vec!(), tts);
base::MacEager::expr(expanded)
}
pub fn expand_quote_ty(cx: &mut ExtCtxt,
sp: Span,
- tts: &[ast::TokenTree])
+ tts: &[TokenTree])
-> Box<base::MacResult+'static> {
- let expanded = expand_parse_call(cx, sp, "parse_ty", vec!(), tts);
+ let expanded = expand_parse_call(cx, sp, "parse_ty_panic", vec!(), tts);
base::MacEager::expr(expanded)
}
pub fn expand_quote_stmt(cx: &mut ExtCtxt,
sp: Span,
- tts: &[ast::TokenTree])
+ tts: &[TokenTree])
-> Box<base::MacResult+'static> {
- let expanded = expand_parse_call(cx, sp, "parse_stmt", vec!(), tts);
+ let expanded = expand_parse_call(cx, sp, "parse_stmt_panic", vec!(), tts);
base::MacEager::expr(expanded)
}
pub fn expand_quote_attr(cx: &mut ExtCtxt,
sp: Span,
- tts: &[ast::TokenTree])
+ tts: &[TokenTree])
-> Box<base::MacResult+'static> {
- let expanded = expand_parse_call(cx, sp, "parse_attribute",
+ let expanded = expand_parse_call(cx, sp, "parse_attribute_panic",
vec!(cx.expr_bool(sp, true)), tts);
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: &[ast::TokenTree])
+ tts: &[TokenTree])
-> Box<base::MacResult+'static> {
let (cx_expr, tts) = parse_arguments_to_quote(cx, tts);
let mut vector = mk_stmts_let(cx, sp);
vec!(e_str))
}
+fn mk_tt_path(cx: &ExtCtxt, sp: Span, name: &str) -> P<ast::Expr> {
+ let idents = vec!(id_ext("syntax"), id_ext("ast"), id_ext("TokenTree"), id_ext(name));
+ cx.expr_path(cx.path_global(sp, idents))
+}
+
fn mk_ast_path(cx: &ExtCtxt, sp: Span, name: &str) -> P<ast::Expr> {
let idents = vec!(id_ext("syntax"), id_ext("ast"), id_ext(name));
cx.expr_path(cx.path_global(sp, idents))
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",
mk_token_path(cx, sp, name)
}
-fn statements_mk_tt(cx: &ExtCtxt, tt: &ast::TokenTree, matcher: bool) -> Vec<P<ast::Stmt>> {
+fn statements_mk_tt(cx: &ExtCtxt, tt: &TokenTree, matcher: bool) -> Vec<P<ast::Stmt>> {
match *tt {
- ast::TtToken(sp, SubstNt(ident, _)) => {
+ TokenTree::Token(sp, SubstNt(ident, _)) => {
// tt.extend($ident.to_tokens(ext_cx))
let e_to_toks =
vec!(cx.stmt_expr(e_push))
}
- ref tt @ ast::TtToken(_, MatchNt(..)) if !matcher => {
+ ref tt @ TokenTree::Token(_, MatchNt(..)) if !matcher => {
let mut seq = vec![];
for i in 0..tt.len() {
seq.push(tt.get_tt(i));
}
statements_mk_tts(cx, &seq[..], matcher)
}
- ast::TtToken(sp, ref tok) => {
+ TokenTree::Token(sp, ref tok) => {
let e_sp = cx.expr_ident(sp, id_ext("_sp"));
let e_tok = cx.expr_call(sp,
- mk_ast_path(cx, sp, "TtToken"),
+ mk_tt_path(cx, sp, "Token"),
vec!(e_sp, expr_mk_token(cx, sp, tok)));
let e_push =
cx.expr_method_call(sp,
vec!(e_tok));
vec!(cx.stmt_expr(e_push))
},
- ast::TtDelimited(_, ref delimed) => {
+ TokenTree::Delimited(_, ref delimed) => {
statements_mk_tt(cx, &delimed.open_tt(), matcher).into_iter()
.chain(delimed.tts.iter()
.flat_map(|tt| statements_mk_tt(cx, tt, matcher)))
.chain(statements_mk_tt(cx, &delimed.close_tt(), matcher))
.collect()
},
- ast::TtSequence(sp, ref seq) => {
+ TokenTree::Sequence(sp, ref seq) => {
if !matcher {
- panic!("TtSequence in quote!");
+ panic!("TokenTree::Sequence in quote!");
}
let e_sp = cx.expr_ident(sp, id_ext("_sp"));
id_ext("new")],
vec![e_seq_struct]);
let e_tok = cx.expr_call(sp,
- mk_ast_path(cx, sp, "TtSequence"),
+ mk_tt_path(cx, sp, "Sequence"),
vec!(e_sp, e_rc_new));
let e_push =
cx.expr_method_call(sp,
}
}
-fn parse_arguments_to_quote(cx: &ExtCtxt, tts: &[ast::TokenTree])
- -> (P<ast::Expr>, Vec<ast::TokenTree>) {
+fn parse_arguments_to_quote(cx: &ExtCtxt, tts: &[TokenTree])
+ -> (P<ast::Expr>, Vec<TokenTree>) {
// NB: It appears that the main parser loses its mind if we consider
// $foo as a SubstNt during the main parse, so we have to re-parse
// under quote_depth > 0. This is silly and should go away; the _guess_ is
let mut p = cx.new_parser_from_tts(tts);
p.quote_depth += 1;
- let cx_expr = p.parse_expr();
+ let cx_expr = panictry!(p.parse_expr());
if !panictry!(p.eat(&token::Comma)) {
panic!(p.fatal("expected token `,`"));
}
vec!(stmt_let_sp, stmt_let_tt)
}
-fn statements_mk_tts(cx: &ExtCtxt, tts: &[ast::TokenTree], matcher: bool) -> Vec<P<ast::Stmt>> {
+fn statements_mk_tts(cx: &ExtCtxt, tts: &[TokenTree], matcher: bool) -> Vec<P<ast::Stmt>> {
let mut ss = Vec::new();
for tt in tts {
ss.extend(statements_mk_tt(cx, tt, matcher));
ss
}
-fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
+fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[TokenTree])
-> (P<ast::Expr>, P<ast::Expr>) {
let (cx_expr, tts) = parse_arguments_to_quote(cx, tts);
sp: Span,
parse_method: &str,
arg_exprs: Vec<P<ast::Expr>> ,
- tts: &[ast::TokenTree]) -> P<ast::Expr> {
+ tts: &[TokenTree]) -> P<ast::Expr> {
let (cx_expr, tts_expr) = expand_tts(cx, sp, tts);
let cfg_call = || cx.expr_method_call(
cx.expr_ident(sp, id_ext("new_parser_from_tts")),
vec!(parse_sess_call(), cfg_call(), tts_expr));
- let expr = cx.expr_method_call(sp, new_parser_call, id_ext(parse_method),
- arg_exprs);
+ let path = vec![id_ext("syntax"), id_ext("ext"), id_ext("quote"), id_ext(parse_method)];
+ let mut args = vec![cx.expr_mut_addr_of(sp, new_parser_call)];
+ args.extend(arg_exprs);
+ let expr = cx.expr_call_global(sp, path, args);
if parse_method == "parse_attribute" {
expand_wrapper(cx, sp, cx_expr, expr, &[&["syntax", "ext", "quote", "rt"],