use ptr::P;
use std_inject;
-use std::{ascii, mem};
+use std::ascii;
use std::io::{self, Write, Read};
use std::iter;
cur_cmnt_and_lit: CurrentCommentAndLiteral,
boxes: Vec<pp::Breaks>,
ann: &'a (PpAnn+'a),
- encode_idents_with_hygiene: bool,
}
pub fn rust_printer<'a>(writer: Box<Write+'a>) -> State<'a> {
},
boxes: Vec::new(),
ann: ann,
- encode_idents_with_hygiene: false,
}
}
},
boxes: Vec::new(),
ann: ann,
- encode_idents_with_hygiene: false,
}
}
}
pub fn to_string<F>(f: F) -> String where
F: FnOnce(&mut State) -> io::Result<()>,
{
- use std::raw::TraitObject;
- let mut s = rust_printer(box Vec::new());
- f(&mut s).unwrap();
- eof(&mut s.s).unwrap();
- let wr = unsafe {
- // FIXME(pcwalton): A nasty function to extract the string from an `Write`
- // that we "know" to be a `Vec<u8>` that works around the lack of checked
- // downcasts.
- let obj: &TraitObject = mem::transmute(&s.s.out);
- mem::transmute::<*mut (), &Vec<u8>>(obj.data)
- };
- String::from_utf8(wr.clone()).unwrap()
+ let mut wr = Vec::new();
+ {
+ let mut printer = rust_printer(Box::new(&mut wr));
+ f(&mut printer).unwrap();
+ eof(&mut printer.s).unwrap();
+ }
+ String::from_utf8(wr).unwrap()
}
pub fn binop_to_string(op: BinOpToken) -> &'static str {
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::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),
}
}
}
-// FIXME (Issue #16472): the thing_to_string_impls macro should go away
-// after we revise the syntax::ext::quote::ToToken impls to go directly
-// to token-trees instead of thing -> string -> token-trees.
-
-macro_rules! thing_to_string_impls {
- ($to_string:ident) => {
-
pub fn ty_to_string(ty: &ast::Ty) -> String {
- $to_string(|s| s.print_type(ty))
+ to_string(|s| s.print_type(ty))
}
pub fn bounds_to_string(bounds: &[ast::TyParamBound]) -> String {
- $to_string(|s| s.print_bounds("", bounds))
+ to_string(|s| s.print_bounds("", bounds))
}
pub fn pat_to_string(pat: &ast::Pat) -> String {
- $to_string(|s| s.print_pat(pat))
+ to_string(|s| s.print_pat(pat))
}
pub fn arm_to_string(arm: &ast::Arm) -> String {
- $to_string(|s| s.print_arm(arm))
+ to_string(|s| s.print_arm(arm))
}
pub fn expr_to_string(e: &ast::Expr) -> String {
- $to_string(|s| s.print_expr(e))
+ to_string(|s| s.print_expr(e))
}
pub fn lifetime_to_string(e: &ast::Lifetime) -> String {
- $to_string(|s| s.print_lifetime(e))
+ to_string(|s| s.print_lifetime(e))
}
pub fn tt_to_string(tt: &ast::TokenTree) -> String {
- $to_string(|s| s.print_tt(tt))
+ to_string(|s| s.print_tt(tt))
}
pub fn tts_to_string(tts: &[ast::TokenTree]) -> String {
- $to_string(|s| s.print_tts(tts))
+ to_string(|s| s.print_tts(tts))
}
pub fn stmt_to_string(stmt: &ast::Stmt) -> String {
- $to_string(|s| s.print_stmt(stmt))
+ to_string(|s| s.print_stmt(stmt))
}
pub fn attr_to_string(attr: &ast::Attribute) -> String {
- $to_string(|s| s.print_attribute(attr))
+ to_string(|s| s.print_attribute(attr))
}
pub fn item_to_string(i: &ast::Item) -> String {
- $to_string(|s| s.print_item(i))
+ to_string(|s| s.print_item(i))
}
pub fn impl_item_to_string(i: &ast::ImplItem) -> String {
- $to_string(|s| s.print_impl_item(i))
+ to_string(|s| s.print_impl_item(i))
}
pub fn trait_item_to_string(i: &ast::TraitItem) -> String {
- $to_string(|s| s.print_trait_item(i))
+ to_string(|s| s.print_trait_item(i))
}
pub fn generics_to_string(generics: &ast::Generics) -> String {
- $to_string(|s| s.print_generics(generics))
+ to_string(|s| s.print_generics(generics))
}
pub fn where_clause_to_string(i: &ast::WhereClause) -> String {
- $to_string(|s| s.print_where_clause(i))
+ to_string(|s| s.print_where_clause(i))
}
pub fn fn_block_to_string(p: &ast::FnDecl) -> String {
- $to_string(|s| s.print_fn_block_args(p))
+ to_string(|s| s.print_fn_block_args(p))
}
pub fn path_to_string(p: &ast::Path) -> String {
- $to_string(|s| s.print_path(p, false, 0))
+ to_string(|s| s.print_path(p, false, 0))
}
pub fn ident_to_string(id: &ast::Ident) -> String {
- $to_string(|s| s.print_ident(*id))
+ to_string(|s| s.print_ident(*id))
}
pub fn fun_to_string(decl: &ast::FnDecl, unsafety: ast::Unsafety, name: ast::Ident,
opt_explicit_self: Option<&ast::ExplicitSelf_>,
generics: &ast::Generics) -> String {
- $to_string(|s| {
+ to_string(|s| {
try!(s.head(""));
try!(s.print_fn(decl, unsafety, abi::Rust, Some(name),
generics, opt_explicit_self, ast::Inherited));
}
pub fn block_to_string(blk: &ast::Block) -> String {
- $to_string(|s| {
+ to_string(|s| {
// containing cbox, will be closed by print-block at }
try!(s.cbox(indent_unit));
// head-ibox, will be closed by print-block after {
}
pub fn meta_item_to_string(mi: &ast::MetaItem) -> String {
- $to_string(|s| s.print_meta_item(mi))
+ to_string(|s| s.print_meta_item(mi))
}
pub fn attribute_to_string(attr: &ast::Attribute) -> String {
- $to_string(|s| s.print_attribute(attr))
+ to_string(|s| s.print_attribute(attr))
}
pub fn lit_to_string(l: &ast::Lit) -> String {
- $to_string(|s| s.print_literal(l))
+ to_string(|s| s.print_literal(l))
}
pub fn explicit_self_to_string(explicit_self: &ast::ExplicitSelf_) -> String {
- $to_string(|s| s.print_explicit_self(explicit_self, ast::MutImmutable).map(|_| {}))
+ to_string(|s| s.print_explicit_self(explicit_self, ast::MutImmutable).map(|_| {}))
}
pub fn variant_to_string(var: &ast::Variant) -> String {
- $to_string(|s| s.print_variant(var))
+ to_string(|s| s.print_variant(var))
}
pub fn arg_to_string(arg: &ast::Arg) -> String {
- $to_string(|s| s.print_arg(arg))
+ to_string(|s| s.print_arg(arg))
}
pub fn mac_to_string(arg: &ast::Mac) -> String {
- $to_string(|s| s.print_mac(arg, ::parse::token::Paren))
-}
-
-} }
-
-thing_to_string_impls! { to_string }
-
-// FIXME (Issue #16472): the whole `with_hygiene` mod should go away
-// after we revise the syntax::ext::quote::ToToken impls to go directly
-// to token-trees instea of thing -> string -> token-trees.
-
-pub mod with_hygiene {
- use abi;
- use ast;
- use std::io;
- use super::indent_unit;
-
- // This function is the trick that all the rest of the routines
- // hang on.
- pub fn to_string_hyg<F>(f: F) -> String where
- F: FnOnce(&mut super::State) -> io::Result<()>,
- {
- super::to_string(move |s| {
- s.encode_idents_with_hygiene = true;
- f(s)
- })
- }
-
- thing_to_string_impls! { to_string_hyg }
+ to_string(|s| s.print_mac(arg, ::parse::token::Paren))
}
pub fn visibility_qualified(vis: ast::Visibility, s: &str) -> String {
}
}
+ fn print_associated_const(&mut self,
+ ident: ast::Ident,
+ ty: &ast::Ty,
+ default: Option<&ast::Expr>,
+ vis: ast::Visibility)
+ -> io::Result<()>
+ {
+ try!(word(&mut self.s, &visibility_qualified(vis, "")));
+ try!(self.word_space("const"));
+ try!(self.print_ident(ident));
+ try!(self.word_space(":"));
+ try!(self.print_type(ty));
+ if let Some(expr) = default {
+ try!(space(&mut self.s));
+ try!(self.word_space("="));
+ try!(self.print_expr(expr));
+ }
+ word(&mut self.s, ";")
+ }
+
fn print_associated_type(&mut self,
ident: ast::Ident,
bounds: Option<&ast::TyParamBounds>,
word(&mut self.s, ";")
}
-
/// Pretty-print an item
pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
try!(self.hardbreak_if_not_bol());
try!(self.print_generics(params));
try!(self.end()); // end the inner ibox
+ try!(self.print_where_clause(¶ms.where_clause));
try!(space(&mut self.s));
try!(self.word_space("="));
try!(self.print_type(&**ty));
- try!(self.print_where_clause(¶ms.where_clause));
try!(word(&mut self.s, ";"));
try!(self.end()); // end the outer ibox
}
try!(self.maybe_print_comment(ti.span.lo));
try!(self.print_outer_attributes(&ti.attrs));
match ti.node {
+ ast::ConstTraitItem(ref ty, ref default) => {
+ try!(self.print_associated_const(ti.ident, &ty,
+ default.as_ref().map(|expr| &**expr),
+ ast::Inherited));
+ }
ast::MethodTraitItem(ref sig, ref body) => {
if body.is_some() {
try!(self.head(""));
try!(self.maybe_print_comment(ii.span.lo));
try!(self.print_outer_attributes(&ii.attrs));
match ii.node {
+ ast::ConstImplItem(ref ty, ref expr) => {
+ try!(self.print_associated_const(ii.ident, &ty, Some(&expr), ii.vis));
+ }
ast::MethodImplItem(ref sig, ref body) => {
try!(self.head(""));
try!(self.print_method_sig(ii.ident, sig, ii.vis));
}
pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> {
- if self.encode_idents_with_hygiene {
- let encoded = ident.encode_with_hygiene();
- try!(word(&mut self.s, &encoded[..]))
- } else {
- try!(word(&mut self.s, &token::get_ident(ident)))
- }
+ try!(word(&mut self.s, &token::get_ident(ident)));
self.ann.post(self, NodeIdent(&ident))
}
}
}
}
+ ast::PatQPath(ref qself, ref path) => {
+ try!(self.print_qpath(path, qself, false));
+ }
ast::PatStruct(ref path, ref fields, etc) => {
try!(self.print_path(path, true, 0));
try!(self.nbsp());
match lit.node {
ast::LitStr(ref st, style) => self.print_string(&st, style),
ast::LitByte(byte) => {
- let mut res = String::from_str("b'");
+ let mut res = String::from("b'");
res.extend(ascii::escape_default(byte).map(|c| c as char));
res.push('\'');
word(&mut self.s, &res[..])
}
ast::LitChar(ch) => {
- let mut res = String::from_str("'");
+ let mut res = String::from("'");
res.extend(ch.escape_default());
res.push('\'');
word(&mut self.s, &res[..])
fn repeat(s: &str, n: usize) -> String { iter::repeat(s).take(n).collect() }
#[cfg(test)]
-mod test {
+mod tests {
use super::*;
use ast;