Skip to content

Commit

Permalink
Auto merge of #25059 - erickt:pprint, r=acrichto
Browse files Browse the repository at this point in the history
The recent quote changes unfortunately broke unquoting statements like `let foo = 5` because the parser requires their to be a trailing semicolon in those statements. Along the way I added support for unquoting generics and where clauses as well as better pretty printing of `token::Interpolated`.
  • Loading branch information
bors committed May 15, 2015
2 parents 13a4b83 + b62290d commit 9bebe5f
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 16 deletions.
26 changes: 23 additions & 3 deletions src/libsyntax/ext/quote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ pub mod rt {
use ast;
use codemap::Spanned;
use ext::base::ExtCtxt;
use parse::token;
use parse;
use parse::{self, token, classify};
use ptr::P;
use std::rc::Rc;

Expand Down Expand Up @@ -94,6 +93,18 @@ pub mod rt {
}
}

impl ToTokens for ast::Generics {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
vec![ast::TtToken(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())))]
}
}

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())))]
Expand All @@ -114,7 +125,16 @@ pub mod rt {

impl ToTokens for P<ast::Stmt> {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
vec![ast::TtToken(self.span, token::Interpolated(token::NtStmt(self.clone())))]
let mut tts = vec![
ast::TtToken(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
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/libsyntax/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,9 @@ pub fn noop_fold_interpolated<T: Folder>(nt: token::Nonterminal, fld: &mut T)
token::NtTraitItem(arm) =>
token::NtTraitItem(fld.fold_trait_item(arm)
.expect_one("expected fold to produce exactly one item")),
token::NtGenerics(generics) => token::NtGenerics(fld.fold_generics(generics)),
token::NtWhereClause(where_clause) =>
token::NtWhereClause(fld.fold_where_clause(where_clause)),
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3808,6 +3808,8 @@ impl<'a> Parser<'a> {
/// | ( < lifetimes , typaramseq ( , )? > )
/// where typaramseq = ( typaram ) | ( typaram , typaramseq )
pub fn parse_generics(&mut self) -> PResult<ast::Generics> {
maybe_whole!(self, NtGenerics);

if try!(self.eat(&token::Lt) ){
let lifetime_defs = try!(self.parse_lifetime_defs());
let mut seen_default = false;
Expand Down Expand Up @@ -3928,6 +3930,8 @@ impl<'a> Parser<'a> {
/// where T : Trait<U, V> + 'b, 'a : 'b
/// ```
pub fn parse_where_clause(&mut self) -> PResult<ast::WhereClause> {
maybe_whole!(self, NtWhereClause);

let mut where_clause = WhereClause {
id: ast::DUMMY_NODE_ID,
predicates: Vec::new(),
Expand Down
4 changes: 4 additions & 0 deletions src/libsyntax/parse/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,8 @@ pub enum Nonterminal {
NtArm(ast::Arm),
NtImplItem(P<ast::ImplItem>),
NtTraitItem(P<ast::TraitItem>),
NtGenerics(ast::Generics),
NtWhereClause(ast::WhereClause),
}

impl fmt::Debug for Nonterminal {
Expand All @@ -403,6 +405,8 @@ impl fmt::Debug for Nonterminal {
NtArm(..) => f.pad("NtArm(..)"),
NtImplItem(..) => f.pad("NtImplItem(..)"),
NtTraitItem(..) => f.pad("NtTraitItem(..)"),
NtGenerics(..) => f.pad("NtGenerics(..)"),
NtWhereClause(..) => f.pad("NtWhereClause(..)"),
}
}
}
Expand Down
28 changes: 15 additions & 13 deletions src/libsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,19 +287,21 @@ pub fn token_to_string(tok: &Token) -> String {
token::SpecialVarNt(var) => format!("${}", var.as_str()),

token::Interpolated(ref nt) => match *nt {
token::NtExpr(ref e) => expr_to_string(&**e),
token::NtMeta(ref e) => meta_item_to_string(&**e),
token::NtTy(ref e) => ty_to_string(&**e),
token::NtPath(ref e) => path_to_string(&**e),
token::NtItem(..) => "an interpolated item".to_string(),
token::NtBlock(..) => "an interpolated block".to_string(),
token::NtStmt(..) => "an interpolated statement".to_string(),
token::NtPat(..) => "an interpolated pattern".to_string(),
token::NtIdent(..) => "an interpolated identifier".to_string(),
token::NtTT(..) => "an interpolated tt".to_string(),
token::NtArm(..) => "an interpolated arm".to_string(),
token::NtImplItem(..) => "an interpolated impl item".to_string(),
token::NtTraitItem(..) => "an interpolated trait item".to_string(),
token::NtExpr(ref e) => expr_to_string(&**e),
token::NtMeta(ref e) => meta_item_to_string(&**e),
token::NtTy(ref e) => ty_to_string(&**e),
token::NtPath(ref e) => path_to_string(&**e),
token::NtItem(ref e) => item_to_string(&**e),
token::NtBlock(ref e) => block_to_string(&**e),
token::NtStmt(ref e) => stmt_to_string(&**e),
token::NtPat(ref e) => pat_to_string(&**e),
token::NtIdent(ref e, _) => ident_to_string(&**e),
token::NtTT(ref e) => tt_to_string(&**e),
token::NtArm(ref e) => arm_to_string(&*e),
token::NtImplItem(ref e) => impl_item_to_string(&**e),
token::NtTraitItem(ref e) => trait_item_to_string(&**e),
token::NtGenerics(ref e) => generics_to_string(&*e),
token::NtWhereClause(ref e) => where_clause_to_string(&*e),
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/test/run-pass-fulldeps/quote-tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ fn syntax_extension(cx: &ExtCtxt) {
let _n: syntax::ast::Attribute = quote_attr!(cx, #![cfg(foo, bar = "baz")]);

let _o: Option<P<syntax::ast::Item>> = quote_item!(cx, fn foo<T: ?Sized>() {});

let stmts = vec![
quote_stmt!(cx, let x = 1;).unwrap(),
quote_stmt!(cx, let y = 2;).unwrap(),
];
let expr: P<syntax::ast::Expr> = quote_expr!(cx, x + y);
}

fn main() {
Expand Down

0 comments on commit 9bebe5f

Please sign in to comment.