use codemap::{CodeMap, BytePos};
use codemap;
use diagnostic;
-use parse::classify::expr_is_simple_block;
use parse::token;
use parse::lexer::comments;
use parse;
use std::io::{IoResult, MemWriter};
use std::io;
use std::mem;
-use std::str;
pub enum AnnNode<'a> {
NodeBlock(&'a ast::Block),
// downcasts.
let (_, wr): (uint, Box<MemWriter>) = mem::transmute_copy(&s.s.out);
let result =
- str::from_utf8_owned(Vec::from_slice(wr.get_ref())).unwrap();
+ String::from_utf8(Vec::from_slice(wr.get_ref().as_slice())).unwrap();
mem::forget(wr);
result.to_string()
}
to_string(|s| s.print_pat(pat))
}
+pub fn arm_to_string(arm: &ast::Arm) -> String {
+ to_string(|s| s.print_arm(arm))
+}
+
pub fn expr_to_string(e: &ast::Expr) -> String {
to_string(|s| s.print_expr(e))
}
}
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, false))
}
pub fn path_to_string(p: &ast::Path) -> String {
to_string(|s| s.print_arg(arg))
}
-
-
-#[cfg(stage0)]
-pub fn to_str(f: |&mut State| -> IoResult<()>) -> String {
- let mut s = rust_printer(box MemWriter::new());
- f(&mut s).unwrap();
- eof(&mut s.s).unwrap();
- unsafe {
- // FIXME(pcwalton): A nasty function to extract the string from an `io::Writer`
- // that we "know" to be a `MemWriter` that works around the lack of checked
- // downcasts.
- let (_, wr): (uint, Box<MemWriter>) = mem::transmute_copy(&s.s.out);
- let result =
- str::from_utf8_owned(Vec::from_slice(wr.get_ref())).unwrap();
- mem::forget(wr);
- result.to_string()
- }
-}
-
-#[cfg(stage0)]
-pub fn ty_to_str(ty: &ast::Ty) -> String {
- to_str(|s| s.print_type(ty))
-}
-
-#[cfg(stage0)]
-pub fn pat_to_str(pat: &ast::Pat) -> String {
- to_str(|s| s.print_pat(pat))
-}
-
-#[cfg(stage0)]
-pub fn expr_to_str(e: &ast::Expr) -> String {
- to_str(|s| s.print_expr(e))
-}
-
-#[cfg(stage0)]
-pub fn lifetime_to_str(e: &ast::Lifetime) -> String {
- to_str(|s| s.print_lifetime(e))
-}
-
-#[cfg(stage0)]
-pub fn tt_to_str(tt: &ast::TokenTree) -> String {
- to_str(|s| s.print_tt(tt))
-}
-
-#[cfg(stage0)]
-pub fn tts_to_str(tts: &[ast::TokenTree]) -> String {
- to_str(|s| s.print_tts(tts))
-}
-
-#[cfg(stage0)]
-pub fn stmt_to_str(stmt: &ast::Stmt) -> String {
- to_str(|s| s.print_stmt(stmt))
-}
-
-#[cfg(stage0)]
-pub fn item_to_str(i: &ast::Item) -> String {
- to_str(|s| s.print_item(i))
-}
-
-#[cfg(stage0)]
-pub fn generics_to_str(generics: &ast::Generics) -> String {
- to_str(|s| s.print_generics(generics))
-}
-
-#[cfg(stage0)]
-pub fn ty_method_to_str(p: &ast::TypeMethod) -> String {
- to_str(|s| s.print_ty_method(p))
-}
-
-#[cfg(stage0)]
-pub fn method_to_str(p: &ast::Method) -> String {
- to_str(|s| s.print_method(p))
-}
-
-#[cfg(stage0)]
-pub fn fn_block_to_str(p: &ast::FnDecl) -> String {
- to_str(|s| s.print_fn_block_args(p))
+pub fn mac_to_string(arg: &ast::Mac) -> String {
+ to_string(|s| s.print_mac(arg))
}
-#[cfg(stage0)]
-pub fn path_to_str(p: &ast::Path) -> String {
- to_str(|s| s.print_path(p, false))
-}
-
-#[cfg(stage0)]
-pub fn fun_to_str(decl: &ast::FnDecl, fn_style: ast::FnStyle, name: ast::Ident,
- opt_explicit_self: Option<ast::ExplicitSelf_>,
- generics: &ast::Generics) -> String {
- to_str(|s| {
- try!(s.print_fn(decl, Some(fn_style), abi::Rust,
- name, generics, opt_explicit_self, ast::Inherited));
- try!(s.end()); // Close the head box
- s.end() // Close the outer box
- })
-}
-
-#[cfg(stage0)]
-pub fn block_to_str(blk: &ast::Block) -> String {
- to_str(|s| {
- // containing cbox, will be closed by print-block at }
- try!(s.cbox(indent_unit));
- // head-ibox, will be closed by print-block after {
- try!(s.ibox(0u));
- s.print_block(blk)
- })
-}
-
-#[cfg(stage0)]
-pub fn meta_item_to_str(mi: &ast::MetaItem) -> String {
- to_str(|s| s.print_meta_item(mi))
-}
-
-#[cfg(stage0)]
-pub fn attribute_to_str(attr: &ast::Attribute) -> String {
- to_str(|s| s.print_attribute(attr))
-}
-
-#[cfg(stage0)]
-pub fn lit_to_str(l: &ast::Lit) -> String {
- to_str(|s| s.print_literal(l))
-}
-
-#[cfg(stage0)]
-pub fn explicit_self_to_str(explicit_self: ast::ExplicitSelf_) -> String {
- to_str(|s| s.print_explicit_self(explicit_self, ast::MutImmutable).map(|_| {}))
-}
-
-#[cfg(stage0)]
-pub fn variant_to_str(var: &ast::Variant) -> String {
- to_str(|s| s.print_variant(var))
-}
-
-#[cfg(stage0)]
-pub fn arg_to_str(arg: &ast::Arg) -> String {
- to_str(|s| s.print_arg(arg))
-}
-
-
-
-
pub fn visibility_qualified(vis: ast::Visibility, s: &str) -> String {
match vis {
ast::Public => format!("pub {}", s),
match expr.node {
ast::ExprAssign(..) | ast::ExprBinary(..) |
ast::ExprFnBlock(..) | ast::ExprProc(..) |
- ast::ExprAssignOp(..) | ast::ExprCast(..) => true,
+ ast::ExprUnboxedFn(..) | ast::ExprAssignOp(..) |
+ ast::ExprCast(..) => true,
_ => false,
}
}
match self.s.last_token() { pp::End => true, _ => false }
}
+ // is this the beginning of a line?
pub fn is_bol(&mut self) -> bool {
self.s.last_token().is_eof() || self.s.last_token().is_hardbreak_tok()
}
}
}
+ /// Pretty-print an item
pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
try!(self.hardbreak_if_not_bol());
try!(self.maybe_print_comment(item.span.lo));
try!(self.hardbreak_if_not_bol());
try!(self.maybe_print_comment(meth.span.lo));
try!(self.print_outer_attributes(meth.attrs.as_slice()));
- try!(self.print_fn(&*meth.decl, Some(meth.fn_style), abi::Rust,
- meth.ident, &meth.generics, Some(meth.explicit_self.node),
- meth.vis));
- try!(word(&mut self.s, " "));
- self.print_block_with_attrs(&*meth.body, meth.attrs.as_slice())
+ match meth.node {
+ ast::MethDecl(ident,
+ ref generics,
+ abi,
+ ref explicit_self,
+ fn_style,
+ decl,
+ body,
+ vis) => {
+ try!(self.print_fn(&*decl,
+ Some(fn_style),
+ abi,
+ ident,
+ generics,
+ Some(explicit_self.node),
+ vis));
+ try!(word(&mut self.s, " "));
+ self.print_block_with_attrs(&*body, meth.attrs.as_slice())
+ },
+ ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _),
+ ..}) => {
+ // code copied from ItemMac:
+ try!(self.print_path(pth, false));
+ try!(word(&mut self.s, "! "));
+ try!(self.cbox(indent_unit));
+ try!(self.popen());
+ try!(self.print_tts(tts.as_slice()));
+ try!(self.pclose());
+ self.end()
+ }
+ }
}
pub fn print_outer_attributes(&mut self,
try!(self.print_expr(&**expr));
try!(space(&mut self.s));
try!(self.bopen());
- let len = arms.len();
- for (i, arm) in arms.iter().enumerate() {
- // I have no idea why this check is necessary, but here it
- // is :(
- if arm.attrs.is_empty() {
- try!(space(&mut self.s));
- }
- try!(self.cbox(indent_unit));
- try!(self.ibox(0u));
- try!(self.print_outer_attributes(arm.attrs.as_slice()));
- let mut first = true;
- for p in arm.pats.iter() {
- if first {
- first = false;
- } else {
- try!(space(&mut self.s));
- try!(self.word_space("|"));
- }
- try!(self.print_pat(&**p));
- }
- try!(space(&mut self.s));
- match arm.guard {
- Some(ref e) => {
- try!(self.word_space("if"));
- try!(self.print_expr(&**e));
- try!(space(&mut self.s));
- }
- None => ()
- }
- try!(self.word_space("=>"));
+ for arm in arms.iter() {
+ try!(self.print_arm(arm));
+ }
+ try!(self.bclose_(expr.span, indent_unit));
+ }
+ ast::ExprFnBlock(ref decl, ref body) => {
+ // in do/for blocks we don't want to show an empty
+ // argument list, but at this point we don't know which
+ // we are inside.
+ //
+ // if !decl.inputs.is_empty() {
+ try!(self.print_fn_block_args(&**decl, false));
+ try!(space(&mut self.s));
+ // }
- match arm.body.node {
- ast::ExprBlock(ref blk) => {
- // the block will close the pattern's ibox
- try!(self.print_block_unclosed_indent(&**blk,
- indent_unit));
+ if !body.stmts.is_empty() || !body.expr.is_some() {
+ try!(self.print_block_unclosed(&**body));
+ } else {
+ // we extract the block, so as not to create another set of boxes
+ match body.expr.unwrap().node {
+ ast::ExprBlock(blk) => {
+ try!(self.print_block_unclosed(&*blk));
}
_ => {
- try!(self.end()); // close the ibox for the pattern
- try!(self.print_expr(&*arm.body));
+ // this is a bare expression
+ try!(self.print_expr(&*body.expr.unwrap()));
+ try!(self.end()); // need to close a box
}
}
- if !expr_is_simple_block(expr.clone())
- && i < len - 1 {
- try!(word(&mut self.s, ","));
- }
- try!(self.end()); // close enclosing cbox
}
- try!(self.bclose_(expr.span, indent_unit));
+ // a box will be closed by print_expr, but we didn't want an overall
+ // wrapper so we closed the corresponding opening. so create an
+ // empty box to satisfy the close.
+ try!(self.ibox(0));
}
- ast::ExprFnBlock(ref decl, ref body) => {
+ ast::ExprUnboxedFn(ref decl, ref body) => {
// in do/for blocks we don't want to show an empty
// argument list, but at this point we don't know which
// we are inside.
//
// if !decl.inputs.is_empty() {
- try!(self.print_fn_block_args(&**decl));
+ try!(self.print_fn_block_args(&**decl, true));
try!(space(&mut self.s));
// }
self.ann.post(self, NodePat(pat))
}
+ fn print_arm(&mut self, arm: &ast::Arm) -> IoResult<()> {
+ // I have no idea why this check is necessary, but here it
+ // is :(
+ if arm.attrs.is_empty() {
+ try!(space(&mut self.s));
+ }
+ try!(self.cbox(indent_unit));
+ try!(self.ibox(0u));
+ try!(self.print_outer_attributes(arm.attrs.as_slice()));
+ let mut first = true;
+ for p in arm.pats.iter() {
+ if first {
+ first = false;
+ } else {
+ try!(space(&mut self.s));
+ try!(self.word_space("|"));
+ }
+ try!(self.print_pat(&**p));
+ }
+ try!(space(&mut self.s));
+ match arm.guard {
+ Some(ref e) => {
+ try!(self.word_space("if"));
+ try!(self.print_expr(&**e));
+ try!(space(&mut self.s));
+ }
+ None => ()
+ }
+ try!(self.word_space("=>"));
+
+ match arm.body.node {
+ ast::ExprBlock(ref blk) => {
+ // the block will close the pattern's ibox
+ try!(self.print_block_unclosed_indent(&**blk,
+ indent_unit));
+ }
+ _ => {
+ try!(self.end()); // close the ibox for the pattern
+ try!(self.print_expr(&*arm.body));
+ try!(word(&mut self.s, ","));
+ }
+ }
+ self.end() // close enclosing cbox
+ }
+
// Returns whether it printed anything
fn print_explicit_self(&mut self,
explicit_self: ast::ExplicitSelf_,
ast::SelfValue(_) => {
try!(word(&mut self.s, "self"));
}
- ast::SelfUniq(_) => {
- try!(word(&mut self.s, "~self"));
- }
ast::SelfRegion(ref lt, m, _) => {
try!(word(&mut self.s, "&"));
try!(self.print_opt_lifetime(lt));
try!(self.print_mutability(m));
try!(word(&mut self.s, "self"));
}
+ ast::SelfExplicit(ref typ, _) => {
+ try!(word(&mut self.s, "self"));
+ try!(self.word_space(":"));
+ try!(self.print_type(&**typ));
+ }
}
return Ok(true);
}
}
pub fn print_fn_block_args(&mut self,
- decl: &ast::FnDecl) -> IoResult<()> {
+ decl: &ast::FnDecl,
+ is_unboxed: bool)
+ -> IoResult<()> {
try!(word(&mut self.s, "|"));
+ if is_unboxed {
+ try!(self.word_space("&mut:"));
+ }
try!(self.print_fn_args(decl, None));
try!(word(&mut self.s, "|"));
try!(word(&mut self.s, "::{"));
}
try!(self.commasep(Inconsistent, idents.as_slice(), |s, w| {
- s.print_ident(w.node.name)
+ match w.node {
+ ast::PathListIdent { name, .. } => {
+ s.print_ident(name)
+ },
+ ast::PathListMod { .. } => {
+ word(&mut s.s, "mod")
+ }
+ }
}));
word(&mut self.s, "}")
}