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 {
match expr.node {
ast::ExprAssign(..) | ast::ExprBinary(..) |
ast::ExprFnBlock(..) | ast::ExprProc(..) |
- ast::ExprAssignOp(..) | ast::ExprCast(..) => true,
+ ast::ExprUnboxedFn(..) | ast::ExprAssignOp(..) |
+ ast::ExprCast(..) => true,
_ => false,
}
}
try!(self.maybe_print_comment(meth.span.lo));
try!(self.print_outer_attributes(meth.attrs.as_slice()));
match meth.node {
- ast::MethDecl(ident, ref generics, ref explicit_self, fn_style, decl, body, vis) => {
- try!(self.print_fn(&*decl, Some(fn_style), abi::Rust,
- ident, generics, Some(explicit_self.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())
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, "}")
}