2014-07-27 11:50:46 +00:00
|
|
|
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
2012-12-04 00:48:01 +00:00
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2014-04-02 08:19:41 +00:00
|
|
|
use abi;
|
2014-08-06 02:44:21 +00:00
|
|
|
use ast::{FnUnboxedClosureKind, FnMutUnboxedClosureKind};
|
|
|
|
use ast::{FnOnceUnboxedClosureKind};
|
|
|
|
use ast::{MethodImplItem, RegionTyParamBound, TraitTyParamBound};
|
|
|
|
use ast::{RequiredMethod, ProvidedMethod, TypeImplItem, TypeTraitItem};
|
2014-11-04 21:25:15 +00:00
|
|
|
use ast::{UnboxedClosureKind};
|
2012-12-23 22:41:37 +00:00
|
|
|
use ast;
|
|
|
|
use ast_util;
|
2014-03-19 14:52:37 +00:00
|
|
|
use owned_slice::OwnedSlice;
|
2013-07-19 11:51:37 +00:00
|
|
|
use attr::{AttrMetaMethods, AttributeMethods};
|
2012-12-23 22:41:37 +00:00
|
|
|
use codemap::{CodeMap, BytePos};
|
|
|
|
use codemap;
|
|
|
|
use diagnostic;
|
2014-10-28 00:05:28 +00:00
|
|
|
use parse::token::{BinOpToken, Token};
|
2014-05-21 23:57:31 +00:00
|
|
|
use parse::token;
|
|
|
|
use parse::lexer::comments;
|
2012-12-23 22:41:37 +00:00
|
|
|
use parse;
|
2013-03-26 20:38:07 +00:00
|
|
|
use print::pp::{break_offset, word, space, zerobreak, hardbreak};
|
2014-01-09 13:05:33 +00:00
|
|
|
use print::pp::{Breaks, Consistent, Inconsistent, eof};
|
2012-12-23 22:41:37 +00:00
|
|
|
use print::pp;
|
2014-09-13 16:06:01 +00:00
|
|
|
use ptr::P;
|
2012-12-23 22:41:37 +00:00
|
|
|
|
2014-10-27 16:13:51 +00:00
|
|
|
use std::ascii;
|
2014-03-16 18:58:11 +00:00
|
|
|
use std::io::{IoResult, MemWriter};
|
2014-04-02 23:54:22 +00:00
|
|
|
use std::io;
|
core: Remove the cast module
This commit revisits the `cast` module in libcore and libstd, and scrutinizes
all functions inside of it. The result was to remove the `cast` module entirely,
folding all functionality into the `mem` module. Specifically, this is the fate
of each function in the `cast` module.
* transmute - This function was moved to `mem`, but it is now marked as
#[unstable]. This is due to planned changes to the `transmute`
function and how it can be invoked (see the #[unstable] comment).
For more information, see RFC 5 and #12898
* transmute_copy - This function was moved to `mem`, with clarification that is
is not an error to invoke it with T/U that are different
sizes, but rather that it is strongly discouraged. This
function is now #[stable]
* forget - This function was moved to `mem` and marked #[stable]
* bump_box_refcount - This function was removed due to the deprecation of
managed boxes as well as its questionable utility.
* transmute_mut - This function was previously deprecated, and removed as part
of this commit.
* transmute_mut_unsafe - This function doesn't serve much of a purpose when it
can be achieved with an `as` in safe code, so it was
removed.
* transmute_lifetime - This function was removed because it is likely a strong
indication that code is incorrect in the first place.
* transmute_mut_lifetime - This function was removed for the same reasons as
`transmute_lifetime`
* copy_lifetime - This function was moved to `mem`, but it is marked
`#[unstable]` now due to the likelihood of being removed in
the future if it is found to not be very useful.
* copy_mut_lifetime - This function was also moved to `mem`, but had the same
treatment as `copy_lifetime`.
* copy_lifetime_vec - This function was removed because it is not used today,
and its existence is not necessary with DST
(copy_lifetime will suffice).
In summary, the cast module was stripped down to these functions, and then the
functions were moved to the `mem` module.
transmute - #[unstable]
transmute_copy - #[stable]
forget - #[stable]
copy_lifetime - #[unstable]
copy_mut_lifetime - #[unstable]
[breaking-change]
2014-05-09 17:34:51 +00:00
|
|
|
use std::mem;
|
2013-05-25 02:35:29 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub enum AnnNode<'a> {
|
2014-08-11 12:01:37 +00:00
|
|
|
NodeIdent(&'a ast::Ident),
|
|
|
|
NodeName(&'a ast::Name),
|
2014-03-16 18:58:11 +00:00
|
|
|
NodeBlock(&'a ast::Block),
|
|
|
|
NodeItem(&'a ast::Item),
|
|
|
|
NodeExpr(&'a ast::Expr),
|
|
|
|
NodePat(&'a ast::Pat),
|
2011-07-05 09:48:19 +00:00
|
|
|
}
|
2013-08-29 22:24:33 +00:00
|
|
|
|
2014-01-09 13:05:33 +00:00
|
|
|
pub trait PpAnn {
|
2014-03-18 05:27:37 +00:00
|
|
|
fn pre(&self, _state: &mut State, _node: AnnNode) -> IoResult<()> { Ok(()) }
|
|
|
|
fn post(&self, _state: &mut State, _node: AnnNode) -> IoResult<()> { Ok(()) }
|
2013-08-29 22:24:33 +00:00
|
|
|
}
|
|
|
|
|
2014-01-09 13:05:33 +00:00
|
|
|
pub struct NoAnn;
|
2011-07-05 09:48:19 +00:00
|
|
|
|
2014-01-09 13:05:33 +00:00
|
|
|
impl PpAnn for NoAnn {}
|
2013-08-29 22:24:33 +00:00
|
|
|
|
2013-02-04 22:02:01 +00:00
|
|
|
pub struct CurrentCommentAndLiteral {
|
|
|
|
cur_cmnt: uint,
|
|
|
|
cur_lit: uint,
|
|
|
|
}
|
|
|
|
|
2014-03-18 05:27:37 +00:00
|
|
|
pub struct State<'a> {
|
2014-03-27 22:39:48 +00:00
|
|
|
pub s: pp::Printer,
|
2014-03-16 18:58:11 +00:00
|
|
|
cm: Option<&'a CodeMap>,
|
2014-02-28 21:09:09 +00:00
|
|
|
comments: Option<Vec<comments::Comment> >,
|
|
|
|
literals: Option<Vec<comments::Literal> >,
|
2013-12-27 23:42:43 +00:00
|
|
|
cur_cmnt_and_lit: CurrentCommentAndLiteral,
|
2014-03-27 17:31:00 +00:00
|
|
|
boxes: Vec<pp::Breaks>,
|
2014-08-28 01:46:52 +00:00
|
|
|
ann: &'a PpAnn+'a,
|
2014-08-01 15:11:53 +00:00
|
|
|
encode_idents_with_hygiene: bool,
|
2013-02-04 22:02:01 +00:00
|
|
|
}
|
2011-07-05 09:48:19 +00:00
|
|
|
|
2014-08-28 01:46:52 +00:00
|
|
|
pub fn rust_printer(writer: Box<io::Writer+'static>) -> State<'static> {
|
2014-03-16 18:58:11 +00:00
|
|
|
static NO_ANN: NoAnn = NoAnn;
|
|
|
|
rust_printer_annotated(writer, &NO_ANN)
|
2012-05-10 14:24:56 +00:00
|
|
|
}
|
2011-07-05 09:48:19 +00:00
|
|
|
|
2014-08-28 01:46:52 +00:00
|
|
|
pub fn rust_printer_annotated<'a>(writer: Box<io::Writer+'static>,
|
2014-03-18 05:27:37 +00:00
|
|
|
ann: &'a PpAnn) -> State<'a> {
|
2014-02-06 22:38:33 +00:00
|
|
|
State {
|
2013-02-04 22:02:01 +00:00
|
|
|
s: pp::mk_printer(writer, default_columns),
|
2014-01-09 13:05:33 +00:00
|
|
|
cm: None,
|
|
|
|
comments: None,
|
|
|
|
literals: None,
|
2013-12-27 23:42:43 +00:00
|
|
|
cur_cmnt_and_lit: CurrentCommentAndLiteral {
|
2013-02-04 22:02:01 +00:00
|
|
|
cur_cmnt: 0,
|
|
|
|
cur_lit: 0
|
|
|
|
},
|
2014-03-27 17:31:00 +00:00
|
|
|
boxes: Vec::new(),
|
2014-08-01 15:11:53 +00:00
|
|
|
ann: ann,
|
|
|
|
encode_idents_with_hygiene: false,
|
2014-02-06 22:38:33 +00:00
|
|
|
}
|
2011-07-05 09:48:19 +00:00
|
|
|
}
|
|
|
|
|
2014-10-27 22:37:07 +00:00
|
|
|
#[allow(non_upper_case_globals)]
|
2014-10-06 23:33:44 +00:00
|
|
|
pub const indent_unit: uint = 4u;
|
2011-07-05 09:48:19 +00:00
|
|
|
|
2014-10-27 22:37:07 +00:00
|
|
|
#[allow(non_upper_case_globals)]
|
2014-10-06 23:33:44 +00:00
|
|
|
pub const default_columns: uint = 78u;
|
2011-07-05 09:48:19 +00:00
|
|
|
|
2014-06-09 20:12:30 +00:00
|
|
|
/// Requires you to pass an input filename and reader so that
|
|
|
|
/// it can scan the input text for comments and literals to
|
|
|
|
/// copy forward.
|
2014-03-18 05:27:37 +00:00
|
|
|
pub fn print_crate<'a>(cm: &'a CodeMap,
|
|
|
|
span_diagnostic: &diagnostic::SpanHandler,
|
|
|
|
krate: &ast::Crate,
|
2014-05-22 23:57:53 +00:00
|
|
|
filename: String,
|
2014-03-18 05:27:37 +00:00
|
|
|
input: &mut io::Reader,
|
2014-08-28 01:46:52 +00:00
|
|
|
out: Box<io::Writer+'static>,
|
2014-03-18 05:27:37 +00:00
|
|
|
ann: &'a PpAnn,
|
|
|
|
is_expanded: bool) -> IoResult<()> {
|
2014-08-07 09:25:31 +00:00
|
|
|
let mut s = State::new_from_input(cm,
|
|
|
|
span_diagnostic,
|
|
|
|
filename,
|
|
|
|
input,
|
|
|
|
out,
|
|
|
|
ann,
|
|
|
|
is_expanded);
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(s.print_mod(&krate.module, krate.attrs.as_slice()));
|
|
|
|
try!(s.print_remaining_comments());
|
|
|
|
eof(&mut s.s)
|
2012-02-21 23:34:26 +00:00
|
|
|
}
|
|
|
|
|
2014-08-07 09:25:31 +00:00
|
|
|
impl<'a> State<'a> {
|
|
|
|
pub fn new_from_input(cm: &'a CodeMap,
|
|
|
|
span_diagnostic: &diagnostic::SpanHandler,
|
|
|
|
filename: String,
|
|
|
|
input: &mut io::Reader,
|
2014-08-28 01:46:52 +00:00
|
|
|
out: Box<io::Writer+'static>,
|
2014-08-07 09:25:31 +00:00
|
|
|
ann: &'a PpAnn,
|
|
|
|
is_expanded: bool) -> State<'a> {
|
|
|
|
let (cmnts, lits) = comments::gather_comments_and_literals(
|
|
|
|
span_diagnostic,
|
|
|
|
filename,
|
|
|
|
input);
|
|
|
|
|
|
|
|
State::new(
|
|
|
|
cm,
|
|
|
|
out,
|
|
|
|
ann,
|
|
|
|
Some(cmnts),
|
|
|
|
// If the code is post expansion, don't use the table of
|
|
|
|
// literals, since it doesn't correspond with the literals
|
|
|
|
// in the AST anymore.
|
|
|
|
if is_expanded { None } else { Some(lits) })
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn new(cm: &'a CodeMap,
|
2014-08-28 01:46:52 +00:00
|
|
|
out: Box<io::Writer+'static>,
|
2014-08-07 09:25:31 +00:00
|
|
|
ann: &'a PpAnn,
|
|
|
|
comments: Option<Vec<comments::Comment>>,
|
|
|
|
literals: Option<Vec<comments::Literal>>) -> State<'a> {
|
|
|
|
State {
|
|
|
|
s: pp::mk_printer(out, default_columns),
|
|
|
|
cm: Some(cm),
|
|
|
|
comments: comments,
|
|
|
|
literals: literals,
|
|
|
|
cur_cmnt_and_lit: CurrentCommentAndLiteral {
|
|
|
|
cur_cmnt: 0,
|
|
|
|
cur_lit: 0
|
|
|
|
},
|
|
|
|
boxes: Vec::new(),
|
2014-08-01 15:11:53 +00:00
|
|
|
ann: ann,
|
|
|
|
encode_idents_with_hygiene: false,
|
2014-08-07 09:25:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-21 10:39:03 +00:00
|
|
|
pub fn to_string(f: |&mut State| -> IoResult<()>) -> String {
|
DST coercions and DST structs
[breaking-change]
1. The internal layout for traits has changed from (vtable, data) to (data, vtable). If you were relying on this in unsafe transmutes, you might get some very weird and apparently unrelated errors. You should not be doing this! Prefer not to do this at all, but if you must, you should use raw::TraitObject rather than hardcoding rustc's internal representation into your code.
2. The minimal type of reference-to-vec-literals (e.g., `&[1, 2, 3]`) is now a fixed size vec (e.g., `&[int, ..3]`) where it used to be an unsized vec (e.g., `&[int]`). If you want the unszied type, you must explicitly give the type (e.g., `let x: &[_] = &[1, 2, 3]`). Note in particular where multiple blocks must have the same type (e.g., if and else clauses, vec elements), the compiler will not coerce to the unsized type without a hint. E.g., `[&[1], &[1, 2]]` used to be a valid expression of type '[&[int]]'. It no longer type checks since the first element now has type `&[int, ..1]` and the second has type &[int, ..2]` which are incompatible.
3. The type of blocks (including functions) must be coercible to the expected type (used to be a subtype). Mostly this makes things more flexible and not less (in particular, in the case of coercing function bodies to the return type). However, in some rare cases, this is less flexible. TBH, I'm not exactly sure of the exact effects. I think the change causes us to resolve inferred type variables slightly earlier which might make us slightly more restrictive. Possibly it only affects blocks with unreachable code. E.g., `if ... { fail!(); "Hello" }` used to type check, it no longer does. The fix is to add a semicolon after the string.
2014-08-04 12:20:11 +00:00
|
|
|
use std::raw::TraitObject;
|
2014-06-21 10:39:03 +00:00
|
|
|
let mut s = rust_printer(box MemWriter::new());
|
|
|
|
f(&mut s).unwrap();
|
|
|
|
eof(&mut s.s).unwrap();
|
2014-10-25 17:33:54 +00:00
|
|
|
let wr = unsafe {
|
2014-06-21 10:39:03 +00:00
|
|
|
// 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.
|
2014-10-25 17:33:54 +00:00
|
|
|
let obj: &TraitObject = mem::transmute(&s.s.out);
|
|
|
|
mem::transmute::<*mut (), &MemWriter>(obj.data)
|
|
|
|
};
|
|
|
|
String::from_utf8(wr.get_ref().to_vec()).unwrap()
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
2014-10-28 00:05:28 +00:00
|
|
|
pub fn binop_to_string(op: BinOpToken) -> &'static str {
|
|
|
|
match op {
|
|
|
|
token::Plus => "+",
|
|
|
|
token::Minus => "-",
|
|
|
|
token::Star => "*",
|
|
|
|
token::Slash => "/",
|
|
|
|
token::Percent => "%",
|
|
|
|
token::Caret => "^",
|
|
|
|
token::And => "&",
|
|
|
|
token::Or => "|",
|
|
|
|
token::Shl => "<<",
|
|
|
|
token::Shr => ">>",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn token_to_string(tok: &Token) -> String {
|
|
|
|
match *tok {
|
|
|
|
token::Eq => "=".into_string(),
|
|
|
|
token::Lt => "<".into_string(),
|
|
|
|
token::Le => "<=".into_string(),
|
|
|
|
token::EqEq => "==".into_string(),
|
|
|
|
token::Ne => "!=".into_string(),
|
|
|
|
token::Ge => ">=".into_string(),
|
|
|
|
token::Gt => ">".into_string(),
|
|
|
|
token::Not => "!".into_string(),
|
|
|
|
token::Tilde => "~".into_string(),
|
|
|
|
token::OrOr => "||".into_string(),
|
|
|
|
token::AndAnd => "&&".into_string(),
|
|
|
|
token::BinOp(op) => binop_to_string(op).into_string(),
|
|
|
|
token::BinOpEq(op) => format!("{}=", binop_to_string(op)),
|
|
|
|
|
|
|
|
/* Structural symbols */
|
|
|
|
token::At => "@".into_string(),
|
|
|
|
token::Dot => ".".into_string(),
|
|
|
|
token::DotDot => "..".into_string(),
|
|
|
|
token::DotDotDot => "...".into_string(),
|
|
|
|
token::Comma => ",".into_string(),
|
|
|
|
token::Semi => ";".into_string(),
|
|
|
|
token::Colon => ":".into_string(),
|
|
|
|
token::ModSep => "::".into_string(),
|
|
|
|
token::RArrow => "->".into_string(),
|
|
|
|
token::LArrow => "<-".into_string(),
|
|
|
|
token::FatArrow => "=>".into_string(),
|
2014-10-29 10:37:54 +00:00
|
|
|
token::OpenDelim(token::Paren) => "(".into_string(),
|
|
|
|
token::CloseDelim(token::Paren) => ")".into_string(),
|
|
|
|
token::OpenDelim(token::Bracket) => "[".into_string(),
|
|
|
|
token::CloseDelim(token::Bracket) => "]".into_string(),
|
|
|
|
token::OpenDelim(token::Brace) => "{".into_string(),
|
|
|
|
token::CloseDelim(token::Brace) => "}".into_string(),
|
2014-10-28 00:05:28 +00:00
|
|
|
token::Pound => "#".into_string(),
|
|
|
|
token::Dollar => "$".into_string(),
|
|
|
|
token::Question => "?".into_string(),
|
|
|
|
|
|
|
|
/* Literals */
|
|
|
|
token::LitByte(b) => format!("b'{}'", b.as_str()),
|
|
|
|
token::LitChar(c) => format!("'{}'", c.as_str()),
|
|
|
|
token::LitFloat(c) => c.as_str().into_string(),
|
|
|
|
token::LitInteger(c) => c.as_str().into_string(),
|
|
|
|
token::LitStr(s) => format!("\"{}\"", s.as_str()),
|
|
|
|
token::LitStrRaw(s, n) => format!("r{delim}\"{string}\"{delim}",
|
|
|
|
delim="#".repeat(n),
|
|
|
|
string=s.as_str()),
|
|
|
|
token::LitBinary(v) => format!("b\"{}\"", v.as_str()),
|
|
|
|
token::LitBinaryRaw(s, n) => format!("br{delim}\"{string}\"{delim}",
|
|
|
|
delim="#".repeat(n),
|
|
|
|
string=s.as_str()),
|
|
|
|
|
|
|
|
/* Name components */
|
|
|
|
token::Ident(s, _) => token::get_ident(s).get().into_string(),
|
|
|
|
token::Lifetime(s) => format!("{}", token::get_ident(s)),
|
|
|
|
token::Underscore => "_".into_string(),
|
|
|
|
|
|
|
|
/* Other */
|
|
|
|
token::DocComment(s) => s.as_str().into_string(),
|
2014-10-06 22:00:56 +00:00
|
|
|
token::SubstNt(s, _) => format!("${}", s),
|
|
|
|
token::MatchNt(s, t, _, _) => format!("${}:{}", s, t),
|
2014-10-28 00:05:28 +00:00
|
|
|
token::Eof => "<eof>".into_string(),
|
|
|
|
token::Whitespace => " ".into_string(),
|
|
|
|
token::Comment => "/* */".into_string(),
|
|
|
|
token::Shebang(s) => format!("/* shebang: {}*/", s.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".into_string(),
|
|
|
|
token::NtBlock(..) => "an interpolated block".into_string(),
|
|
|
|
token::NtStmt(..) => "an interpolated statement".into_string(),
|
|
|
|
token::NtPat(..) => "an interpolated pattern".into_string(),
|
|
|
|
token::NtIdent(..) => "an interpolated identifier".into_string(),
|
|
|
|
token::NtTT(..) => "an interpolated tt".into_string(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-01 15:11:53 +00:00
|
|
|
// FIXME (Issue #16472): the thing_to_string_impls macro should go away
|
|
|
|
// after we revise the syntax::ext::quote::ToToken impls to go directly
|
2014-09-02 05:35:58 +00:00
|
|
|
// to token-trees instead of thing -> string -> token-trees.
|
2014-08-01 15:11:53 +00:00
|
|
|
|
|
|
|
macro_rules! thing_to_string_impls {
|
|
|
|
($to_string:ident) => {
|
|
|
|
|
2014-06-21 10:39:03 +00:00
|
|
|
pub fn ty_to_string(ty: &ast::Ty) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| s.print_type(ty))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn pat_to_string(pat: &ast::Pat) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| s.print_pat(pat))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
2014-07-28 01:05:07 +00:00
|
|
|
pub fn arm_to_string(arm: &ast::Arm) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| s.print_arm(arm))
|
2014-07-28 01:05:07 +00:00
|
|
|
}
|
|
|
|
|
2014-06-21 10:39:03 +00:00
|
|
|
pub fn expr_to_string(e: &ast::Expr) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| s.print_expr(e))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn lifetime_to_string(e: &ast::Lifetime) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| s.print_lifetime(e))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn tt_to_string(tt: &ast::TokenTree) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| s.print_tt(tt))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn tts_to_string(tts: &[ast::TokenTree]) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| s.print_tts(tts))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn stmt_to_string(stmt: &ast::Stmt) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| s.print_stmt(stmt))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn item_to_string(i: &ast::Item) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| s.print_item(i))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
2014-10-23 14:56:33 +00:00
|
|
|
pub fn view_item_to_string(i: &ast::ViewItem) -> String {
|
|
|
|
$to_string(|s| s.print_view_item(i))
|
|
|
|
}
|
|
|
|
|
2014-06-21 10:39:03 +00:00
|
|
|
pub fn generics_to_string(generics: &ast::Generics) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| s.print_generics(generics))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn ty_method_to_string(p: &ast::TypeMethod) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| s.print_ty_method(p))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn method_to_string(p: &ast::Method) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| s.print_method(p))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn fn_block_to_string(p: &ast::FnDecl) -> String {
|
2014-07-30 05:08:39 +00:00
|
|
|
$to_string(|s| s.print_fn_block_args(p, None))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn path_to_string(p: &ast::Path) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| s.print_path(p, false))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn ident_to_string(id: &ast::Ident) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| s.print_ident(*id))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn fun_to_string(decl: &ast::FnDecl, fn_style: ast::FnStyle, name: ast::Ident,
|
2014-09-13 16:06:01 +00:00
|
|
|
opt_explicit_self: Option<&ast::ExplicitSelf_>,
|
2014-06-21 10:39:03 +00:00
|
|
|
generics: &ast::Generics) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| {
|
2014-06-21 10:39:03 +00:00
|
|
|
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
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn block_to_string(blk: &ast::Block) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| {
|
2014-06-21 10:39:03 +00:00
|
|
|
// 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)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn meta_item_to_string(mi: &ast::MetaItem) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| s.print_meta_item(mi))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn attribute_to_string(attr: &ast::Attribute) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| s.print_attribute(attr))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn lit_to_string(l: &ast::Lit) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| s.print_literal(l))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
2014-09-13 16:06:01 +00:00
|
|
|
pub fn explicit_self_to_string(explicit_self: &ast::ExplicitSelf_) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| s.print_explicit_self(explicit_self, ast::MutImmutable).map(|_| {}))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn variant_to_string(var: &ast::Variant) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| s.print_variant(var))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn arg_to_string(arg: &ast::Arg) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| s.print_arg(arg))
|
2014-06-21 10:39:03 +00:00
|
|
|
}
|
|
|
|
|
2014-07-12 04:22:11 +00:00
|
|
|
pub fn mac_to_string(arg: &ast::Mac) -> String {
|
2014-08-01 15:11:53 +00:00
|
|
|
$to_string(|s| s.print_mac(arg))
|
|
|
|
}
|
|
|
|
|
|
|
|
} }
|
|
|
|
|
|
|
|
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::IoResult;
|
|
|
|
use super::indent_unit;
|
|
|
|
|
|
|
|
// This function is the trick that all the rest of the routines
|
|
|
|
// hang on.
|
|
|
|
pub fn to_string_hyg(f: |&mut super::State| -> IoResult<()>) -> String {
|
|
|
|
super::to_string(|s| {
|
|
|
|
s.encode_idents_with_hygiene = true;
|
|
|
|
f(s)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
thing_to_string_impls!(to_string_hyg)
|
2014-07-12 04:22:11 +00:00
|
|
|
}
|
|
|
|
|
2014-05-22 23:57:53 +00:00
|
|
|
pub fn visibility_qualified(vis: ast::Visibility, s: &str) -> String {
|
2014-03-16 18:58:11 +00:00
|
|
|
match vis {
|
2014-06-26 06:15:14 +00:00
|
|
|
ast::Public => format!("pub {}", s),
|
2014-05-25 10:17:19 +00:00
|
|
|
ast::Inherited => s.to_string()
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
2011-05-29 02:16:18 +00:00
|
|
|
|
2014-04-16 20:33:58 +00:00
|
|
|
fn needs_parentheses(expr: &ast::Expr) -> bool {
|
|
|
|
match expr.node {
|
|
|
|
ast::ExprAssign(..) | ast::ExprBinary(..) |
|
|
|
|
ast::ExprFnBlock(..) | ast::ExprProc(..) |
|
2014-05-29 05:26:56 +00:00
|
|
|
ast::ExprUnboxedFn(..) | ast::ExprAssignOp(..) |
|
|
|
|
ast::ExprCast(..) => true,
|
2014-04-16 20:33:58 +00:00
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-18 05:27:37 +00:00
|
|
|
impl<'a> State<'a> {
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn ibox(&mut self, u: uint) -> IoResult<()> {
|
2014-03-27 17:31:00 +00:00
|
|
|
self.boxes.push(pp::Inconsistent);
|
2014-03-16 18:58:11 +00:00
|
|
|
pp::ibox(&mut self.s, u)
|
|
|
|
}
|
2011-05-29 02:16:18 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn end(&mut self) -> IoResult<()> {
|
2014-03-27 17:31:00 +00:00
|
|
|
self.boxes.pop().unwrap();
|
2014-03-16 18:58:11 +00:00
|
|
|
pp::end(&mut self.s)
|
|
|
|
}
|
2011-05-29 02:16:18 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn cbox(&mut self, u: uint) -> IoResult<()> {
|
2014-03-27 17:31:00 +00:00
|
|
|
self.boxes.push(pp::Consistent);
|
2014-03-16 18:58:11 +00:00
|
|
|
pp::cbox(&mut self.s, u)
|
|
|
|
}
|
2011-05-29 02:16:18 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
// "raw box"
|
|
|
|
pub fn rbox(&mut self, u: uint, b: pp::Breaks) -> IoResult<()> {
|
2014-03-27 17:31:00 +00:00
|
|
|
self.boxes.push(b);
|
2014-03-16 18:58:11 +00:00
|
|
|
pp::rbox(&mut self.s, u, b)
|
2012-11-05 04:41:00 +00:00
|
|
|
}
|
2011-05-29 02:16:18 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn nbsp(&mut self) -> IoResult<()> { word(&mut self.s, " ") }
|
2011-05-29 02:16:18 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn word_nbsp(&mut self, w: &str) -> IoResult<()> {
|
|
|
|
try!(word(&mut self.s, w));
|
|
|
|
self.nbsp()
|
|
|
|
}
|
2011-05-29 02:16:18 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn word_space(&mut self, w: &str) -> IoResult<()> {
|
|
|
|
try!(word(&mut self.s, w));
|
|
|
|
space(&mut self.s)
|
|
|
|
}
|
2011-08-02 22:25:06 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn popen(&mut self) -> IoResult<()> { word(&mut self.s, "(") }
|
2011-08-02 22:25:06 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn pclose(&mut self) -> IoResult<()> { word(&mut self.s, ")") }
|
2011-06-20 14:45:05 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn head(&mut self, w: &str) -> IoResult<()> {
|
|
|
|
// outer-box is consistent
|
|
|
|
try!(self.cbox(indent_unit));
|
|
|
|
// head-box is inconsistent
|
|
|
|
try!(self.ibox(w.len() + 1));
|
|
|
|
// keyword that starts the head
|
|
|
|
if !w.is_empty() {
|
|
|
|
try!(self.word_nbsp(w));
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
2012-04-19 21:46:11 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn bopen(&mut self) -> IoResult<()> {
|
|
|
|
try!(word(&mut self.s, "{"));
|
|
|
|
self.end() // close the head-box
|
2013-12-27 22:11:01 +00:00
|
|
|
}
|
2011-06-15 18:19:50 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn bclose_(&mut self, span: codemap::Span,
|
|
|
|
indented: uint) -> IoResult<()> {
|
|
|
|
self.bclose_maybe_open(span, indented, true)
|
|
|
|
}
|
|
|
|
pub fn bclose_maybe_open (&mut self, span: codemap::Span,
|
|
|
|
indented: uint, close_box: bool) -> IoResult<()> {
|
|
|
|
try!(self.maybe_print_comment(span.hi));
|
|
|
|
try!(self.break_offset_if_not_bol(1u, -(indented as int)));
|
|
|
|
try!(word(&mut self.s, "}"));
|
|
|
|
if close_box {
|
|
|
|
try!(self.end()); // close the outer-box
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
pub fn bclose(&mut self, span: codemap::Span) -> IoResult<()> {
|
|
|
|
self.bclose_(span, indent_unit)
|
|
|
|
}
|
2014-01-30 01:39:21 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn is_begin(&mut self) -> bool {
|
|
|
|
match self.s.last_token() { pp::Begin(_) => true, _ => false }
|
|
|
|
}
|
2011-07-05 23:23:07 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn is_end(&mut self) -> bool {
|
|
|
|
match self.s.last_token() { pp::End => true, _ => false }
|
|
|
|
}
|
2011-07-05 23:23:07 +00:00
|
|
|
|
2014-07-12 04:22:11 +00:00
|
|
|
// is this the beginning of a line?
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn is_bol(&mut self) -> bool {
|
|
|
|
self.s.last_token().is_eof() || self.s.last_token().is_hardbreak_tok()
|
|
|
|
}
|
2011-07-06 23:01:47 +00:00
|
|
|
|
2014-03-27 17:31:00 +00:00
|
|
|
pub fn in_cbox(&self) -> bool {
|
|
|
|
match self.boxes.last() {
|
2014-03-16 18:58:11 +00:00
|
|
|
Some(&last_box) => last_box == pp::Consistent,
|
|
|
|
None => false
|
|
|
|
}
|
|
|
|
}
|
2011-03-04 06:22:43 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn hardbreak_if_not_bol(&mut self) -> IoResult<()> {
|
|
|
|
if !self.is_bol() {
|
|
|
|
try!(hardbreak(&mut self.s))
|
|
|
|
}
|
|
|
|
Ok(())
|
2011-05-12 15:24:54 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn space_if_not_bol(&mut self) -> IoResult<()> {
|
|
|
|
if !self.is_bol() { try!(space(&mut self.s)); }
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
pub fn break_offset_if_not_bol(&mut self, n: uint,
|
|
|
|
off: int) -> IoResult<()> {
|
|
|
|
if !self.is_bol() {
|
|
|
|
break_offset(&mut self.s, n, off)
|
|
|
|
} else {
|
|
|
|
if off != 0 && self.s.last_token().is_hardbreak_tok() {
|
|
|
|
// We do something pretty sketchy here: tuck the nonzero
|
|
|
|
// offset-adjustment we were going to deposit along with the
|
|
|
|
// break into the previous hardbreak.
|
|
|
|
self.s.replace_last_token(pp::hardbreak_tok_offset(off));
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
2011-03-18 00:39:47 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
// Synthesizes a comment that was not textually present in the original source
|
|
|
|
// file.
|
2014-05-22 23:57:53 +00:00
|
|
|
pub fn synth_comment(&mut self, text: String) -> IoResult<()> {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "/*"));
|
|
|
|
try!(space(&mut self.s));
|
2014-05-07 23:33:43 +00:00
|
|
|
try!(word(&mut self.s, text.as_slice()));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(space(&mut self.s));
|
|
|
|
word(&mut self.s, "*/")
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
|
|
|
|
pub fn commasep<T>(&mut self, b: Breaks, elts: &[T],
|
2014-03-18 05:27:37 +00:00
|
|
|
op: |&mut State, &T| -> IoResult<()>)
|
2014-03-16 18:58:11 +00:00
|
|
|
-> IoResult<()> {
|
|
|
|
try!(self.rbox(0u, b));
|
|
|
|
let mut first = true;
|
|
|
|
for elt in elts.iter() {
|
|
|
|
if first { first = false; } else { try!(self.word_space(",")); }
|
|
|
|
try!(op(self, elt));
|
|
|
|
}
|
|
|
|
self.end()
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn commasep_cmnt<T>(
|
|
|
|
&mut self,
|
|
|
|
b: Breaks,
|
|
|
|
elts: &[T],
|
2014-03-18 05:27:37 +00:00
|
|
|
op: |&mut State, &T| -> IoResult<()>,
|
2014-03-16 18:58:11 +00:00
|
|
|
get_span: |&T| -> codemap::Span) -> IoResult<()> {
|
|
|
|
try!(self.rbox(0u, b));
|
|
|
|
let len = elts.len();
|
|
|
|
let mut i = 0u;
|
|
|
|
for elt in elts.iter() {
|
|
|
|
try!(self.maybe_print_comment(get_span(elt).hi));
|
|
|
|
try!(op(self, elt));
|
|
|
|
i += 1u;
|
|
|
|
if i < len {
|
|
|
|
try!(word(&mut self.s, ","));
|
|
|
|
try!(self.maybe_print_trailing_comment(get_span(elt),
|
|
|
|
Some(get_span(&elts[i]).hi)));
|
|
|
|
try!(self.space_if_not_bol());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.end()
|
2011-07-26 22:37:36 +00:00
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn commasep_exprs(&mut self, b: Breaks,
|
2014-09-13 16:06:01 +00:00
|
|
|
exprs: &[P<ast::Expr>]) -> IoResult<()> {
|
2014-05-16 07:16:13 +00:00
|
|
|
self.commasep_cmnt(b, exprs, |s, e| s.print_expr(&**e), |e| e.span)
|
2012-03-09 02:10:07 +00:00
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_mod(&mut self, _mod: &ast::Mod,
|
|
|
|
attrs: &[ast::Attribute]) -> IoResult<()> {
|
|
|
|
try!(self.print_inner_attributes(attrs));
|
|
|
|
for vitem in _mod.view_items.iter() {
|
|
|
|
try!(self.print_view_item(vitem));
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
for item in _mod.items.iter() {
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_item(&**item));
|
2014-01-09 13:05:33 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod,
|
|
|
|
attrs: &[ast::Attribute]) -> IoResult<()> {
|
|
|
|
try!(self.print_inner_attributes(attrs));
|
|
|
|
for vitem in nmod.view_items.iter() {
|
|
|
|
try!(self.print_view_item(vitem));
|
2014-01-09 13:05:33 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
for item in nmod.items.iter() {
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_foreign_item(&**item));
|
2014-01-09 13:05:33 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_opt_lifetime(&mut self,
|
|
|
|
lifetime: &Option<ast::Lifetime>) -> IoResult<()> {
|
|
|
|
for l in lifetime.iter() {
|
|
|
|
try!(self.print_lifetime(l));
|
|
|
|
try!(self.nbsp());
|
2013-02-19 01:45:56 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
Ok(())
|
2011-03-04 06:22:43 +00:00
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_type(&mut self, ty: &ast::Ty) -> IoResult<()> {
|
|
|
|
try!(self.maybe_print_comment(ty.span.lo));
|
|
|
|
try!(self.ibox(0u));
|
|
|
|
match ty.node {
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::TyVec(ref ty) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "["));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_type(&**ty));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "]"));
|
|
|
|
}
|
|
|
|
ast::TyPtr(ref mt) => {
|
|
|
|
try!(word(&mut self.s, "*"));
|
2014-06-25 19:47:34 +00:00
|
|
|
match mt.mutbl {
|
|
|
|
ast::MutMutable => try!(self.word_nbsp("mut")),
|
|
|
|
ast::MutImmutable => try!(self.word_nbsp("const")),
|
|
|
|
}
|
|
|
|
try!(self.print_type(&*mt.ty));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
ast::TyRptr(ref lifetime, ref mt) => {
|
|
|
|
try!(word(&mut self.s, "&"));
|
|
|
|
try!(self.print_opt_lifetime(lifetime));
|
|
|
|
try!(self.print_mt(mt));
|
|
|
|
}
|
|
|
|
ast::TyTup(ref elts) => {
|
|
|
|
try!(self.popen());
|
|
|
|
try!(self.commasep(Inconsistent, elts.as_slice(),
|
2014-09-13 16:06:01 +00:00
|
|
|
|s, ty| s.print_type(&**ty)));
|
2014-03-16 18:58:11 +00:00
|
|
|
if elts.len() == 1 {
|
|
|
|
try!(word(&mut self.s, ","));
|
|
|
|
}
|
|
|
|
try!(self.pclose());
|
|
|
|
}
|
2014-06-11 19:14:38 +00:00
|
|
|
ast::TyParen(ref typ) => {
|
|
|
|
try!(self.popen());
|
|
|
|
try!(self.print_type(&**typ));
|
|
|
|
try!(self.pclose());
|
|
|
|
}
|
2014-09-13 16:06:01 +00:00
|
|
|
ast::TyBareFn(ref f) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
let generics = ast::Generics {
|
|
|
|
lifetimes: f.lifetimes.clone(),
|
2014-08-11 16:32:26 +00:00
|
|
|
ty_params: OwnedSlice::empty(),
|
|
|
|
where_clause: ast::WhereClause {
|
|
|
|
id: ast::DUMMY_NODE_ID,
|
|
|
|
predicates: Vec::new(),
|
|
|
|
},
|
2014-03-16 18:58:11 +00:00
|
|
|
};
|
2014-06-02 01:41:46 +00:00
|
|
|
try!(self.print_ty_fn(Some(f.abi),
|
|
|
|
None,
|
|
|
|
f.fn_style,
|
|
|
|
ast::Many,
|
2014-05-16 07:16:13 +00:00
|
|
|
&*f.decl,
|
2014-06-02 01:41:46 +00:00
|
|
|
None,
|
2014-08-28 01:46:52 +00:00
|
|
|
&OwnedSlice::empty(),
|
2014-06-02 01:41:46 +00:00
|
|
|
Some(&generics),
|
2014-07-30 05:08:39 +00:00
|
|
|
None));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-09-13 16:06:01 +00:00
|
|
|
ast::TyClosure(ref f) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
let generics = ast::Generics {
|
|
|
|
lifetimes: f.lifetimes.clone(),
|
2014-08-11 16:32:26 +00:00
|
|
|
ty_params: OwnedSlice::empty(),
|
|
|
|
where_clause: ast::WhereClause {
|
|
|
|
id: ast::DUMMY_NODE_ID,
|
|
|
|
predicates: Vec::new(),
|
|
|
|
},
|
2014-03-16 18:58:11 +00:00
|
|
|
};
|
2014-06-02 01:41:46 +00:00
|
|
|
try!(self.print_ty_fn(None,
|
|
|
|
Some('&'),
|
|
|
|
f.fn_style,
|
|
|
|
f.onceness,
|
2014-05-16 07:16:13 +00:00
|
|
|
&*f.decl,
|
2014-06-02 01:41:46 +00:00
|
|
|
None,
|
|
|
|
&f.bounds,
|
|
|
|
Some(&generics),
|
2014-07-30 05:08:39 +00:00
|
|
|
None));
|
2014-04-09 12:33:42 +00:00
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::TyProc(ref f) => {
|
2014-04-09 12:33:42 +00:00
|
|
|
let generics = ast::Generics {
|
|
|
|
lifetimes: f.lifetimes.clone(),
|
2014-08-11 16:32:26 +00:00
|
|
|
ty_params: OwnedSlice::empty(),
|
|
|
|
where_clause: ast::WhereClause {
|
|
|
|
id: ast::DUMMY_NODE_ID,
|
|
|
|
predicates: Vec::new(),
|
|
|
|
},
|
2014-04-09 12:33:42 +00:00
|
|
|
};
|
2014-06-02 01:41:46 +00:00
|
|
|
try!(self.print_ty_fn(None,
|
|
|
|
Some('~'),
|
|
|
|
f.fn_style,
|
|
|
|
f.onceness,
|
2014-05-16 07:16:13 +00:00
|
|
|
&*f.decl,
|
2014-06-02 01:41:46 +00:00
|
|
|
None,
|
|
|
|
&f.bounds,
|
|
|
|
Some(&generics),
|
2014-07-30 05:08:39 +00:00
|
|
|
None));
|
2014-06-02 01:41:46 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
ast::TyPath(ref path, ref bounds, _) => {
|
|
|
|
try!(self.print_bounded_path(path, bounds));
|
|
|
|
}
|
2014-11-07 11:53:45 +00:00
|
|
|
ast::TyPolyTraitRef(ref poly_trait_ref) => {
|
|
|
|
try!(self.print_poly_trait_ref(&**poly_trait_ref));
|
|
|
|
}
|
2014-08-06 02:44:21 +00:00
|
|
|
ast::TyQPath(ref qpath) => {
|
|
|
|
try!(word(&mut self.s, "<"));
|
|
|
|
try!(self.print_type(&*qpath.for_type));
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.word_space("as"));
|
|
|
|
try!(self.print_path(&qpath.trait_name, false));
|
|
|
|
try!(word(&mut self.s, ">"));
|
|
|
|
try!(word(&mut self.s, "::"));
|
|
|
|
try!(self.print_ident(qpath.item_name));
|
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::TyFixedLengthVec(ref ty, ref v) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "["));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_type(&**ty));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, ", .."));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**v));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "]"));
|
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::TyTypeof(ref e) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "typeof("));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**e));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, ")"));
|
|
|
|
}
|
|
|
|
ast::TyInfer => {
|
|
|
|
try!(word(&mut self.s, "_"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.end()
|
|
|
|
}
|
2013-11-30 22:00:39 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_foreign_item(&mut self,
|
|
|
|
item: &ast::ForeignItem) -> IoResult<()> {
|
|
|
|
try!(self.hardbreak_if_not_bol());
|
|
|
|
try!(self.maybe_print_comment(item.span.lo));
|
|
|
|
try!(self.print_outer_attributes(item.attrs.as_slice()));
|
|
|
|
match item.node {
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ForeignItemFn(ref decl, ref generics) => {
|
|
|
|
try!(self.print_fn(&**decl, None, abi::Rust, item.ident, generics,
|
|
|
|
None, item.vis));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.end()); // end head-ibox
|
|
|
|
try!(word(&mut self.s, ";"));
|
|
|
|
self.end() // end the outer fn box
|
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ForeignItemStatic(ref t, m) => {
|
2014-05-07 23:33:43 +00:00
|
|
|
try!(self.head(visibility_qualified(item.vis,
|
|
|
|
"static").as_slice()));
|
2014-03-16 18:58:11 +00:00
|
|
|
if m {
|
|
|
|
try!(self.word_space("mut"));
|
|
|
|
}
|
|
|
|
try!(self.print_ident(item.ident));
|
|
|
|
try!(self.word_space(":"));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_type(&**t));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, ";"));
|
|
|
|
try!(self.end()); // end the head-ibox
|
|
|
|
self.end() // end the outer cbox
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-02-11 07:15:45 +00:00
|
|
|
|
2014-08-06 02:44:21 +00:00
|
|
|
fn print_associated_type(&mut self, typedef: &ast::AssociatedType)
|
2014-10-28 18:48:52 +00:00
|
|
|
-> IoResult<()>
|
|
|
|
{
|
|
|
|
try!(self.print_outer_attributes(typedef.attrs[]));
|
2014-08-06 02:44:21 +00:00
|
|
|
try!(self.word_space("type"));
|
2014-10-28 18:48:52 +00:00
|
|
|
try!(self.print_ty_param(&typedef.ty_param));
|
2014-08-06 02:44:21 +00:00
|
|
|
word(&mut self.s, ";")
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_typedef(&mut self, typedef: &ast::Typedef) -> IoResult<()> {
|
|
|
|
try!(self.word_space("type"));
|
|
|
|
try!(self.print_ident(typedef.ident));
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.word_space("="));
|
|
|
|
try!(self.print_type(&*typedef.typ));
|
|
|
|
word(&mut self.s, ";")
|
|
|
|
}
|
|
|
|
|
2014-07-12 04:22:11 +00:00
|
|
|
/// Pretty-print an item
|
2014-03-16 18:58:11 +00:00
|
|
|
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.print_outer_attributes(item.attrs.as_slice()));
|
|
|
|
try!(self.ann.pre(self, NodeItem(item)));
|
|
|
|
match item.node {
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ItemStatic(ref ty, m, ref expr) => {
|
2014-05-07 23:33:43 +00:00
|
|
|
try!(self.head(visibility_qualified(item.vis,
|
|
|
|
"static").as_slice()));
|
2014-03-16 18:58:11 +00:00
|
|
|
if m == ast::MutMutable {
|
|
|
|
try!(self.word_space("mut"));
|
2013-03-05 00:11:30 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.print_ident(item.ident));
|
|
|
|
try!(self.word_space(":"));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_type(&**ty));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.end()); // end the head-ibox
|
|
|
|
|
|
|
|
try!(self.word_space("="));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**expr));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, ";"));
|
|
|
|
try!(self.end()); // end the outer cbox
|
|
|
|
}
|
rustc: Add `const` globals to the language
This change is an implementation of [RFC 69][rfc] which adds a third kind of
global to the language, `const`. This global is most similar to what the old
`static` was, and if you're unsure about what to use then you should use a
`const`.
The semantics of these three kinds of globals are:
* A `const` does not represent a memory location, but only a value. Constants
are translated as rvalues, which means that their values are directly inlined
at usage location (similar to a #define in C/C++). Constant values are, well,
constant, and can not be modified. Any "modification" is actually a
modification to a local value on the stack rather than the actual constant
itself.
Almost all values are allowed inside constants, whether they have interior
mutability or not. There are a few minor restrictions listed in the RFC, but
they should in general not come up too often.
* A `static` now always represents a memory location (unconditionally). Any
references to the same `static` are actually a reference to the same memory
location. Only values whose types ascribe to `Sync` are allowed in a `static`.
This restriction is in place because many threads may access a `static`
concurrently. Lifting this restriction (and allowing unsafe access) is a
future extension not implemented at this time.
* A `static mut` continues to always represent a memory location. All references
to a `static mut` continue to be `unsafe`.
This is a large breaking change, and many programs will need to be updated
accordingly. A summary of the breaking changes is:
* Statics may no longer be used in patterns. Statics now always represent a
memory location, which can sometimes be modified. To fix code, repurpose the
matched-on-`static` to a `const`.
static FOO: uint = 4;
match n {
FOO => { /* ... */ }
_ => { /* ... */ }
}
change this code to:
const FOO: uint = 4;
match n {
FOO => { /* ... */ }
_ => { /* ... */ }
}
* Statics may no longer refer to other statics by value. Due to statics being
able to change at runtime, allowing them to reference one another could
possibly lead to confusing semantics. If you are in this situation, use a
constant initializer instead. Note, however, that statics may reference other
statics by address, however.
* Statics may no longer be used in constant expressions, such as array lengths.
This is due to the same restrictions as listed above. Use a `const` instead.
[breaking-change]
[rfc]: https://github.com/rust-lang/rfcs/pull/246
2014-10-06 15:17:01 +00:00
|
|
|
ast::ItemConst(ref ty, ref expr) => {
|
|
|
|
try!(self.head(visibility_qualified(item.vis,
|
|
|
|
"const").as_slice()));
|
|
|
|
try!(self.print_ident(item.ident));
|
|
|
|
try!(self.word_space(":"));
|
|
|
|
try!(self.print_type(&**ty));
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.end()); // end the head-ibox
|
|
|
|
|
|
|
|
try!(self.word_space("="));
|
|
|
|
try!(self.print_expr(&**expr));
|
|
|
|
try!(word(&mut self.s, ";"));
|
|
|
|
try!(self.end()); // end the outer cbox
|
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ItemFn(ref decl, fn_style, abi, ref typarams, ref body) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.print_fn(
|
2014-05-16 07:16:13 +00:00
|
|
|
&**decl,
|
2014-04-07 01:04:40 +00:00
|
|
|
Some(fn_style),
|
2014-03-16 18:58:11 +00:00
|
|
|
abi,
|
|
|
|
item.ident,
|
|
|
|
typarams,
|
|
|
|
None,
|
|
|
|
item.vis
|
|
|
|
));
|
|
|
|
try!(word(&mut self.s, " "));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_block_with_attrs(&**body, item.attrs.as_slice()));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
ast::ItemMod(ref _mod) => {
|
2014-05-07 23:33:43 +00:00
|
|
|
try!(self.head(visibility_qualified(item.vis,
|
|
|
|
"mod").as_slice()));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.print_ident(item.ident));
|
|
|
|
try!(self.nbsp());
|
|
|
|
try!(self.bopen());
|
|
|
|
try!(self.print_mod(_mod, item.attrs.as_slice()));
|
|
|
|
try!(self.bclose(item.span));
|
|
|
|
}
|
|
|
|
ast::ItemForeignMod(ref nmod) => {
|
|
|
|
try!(self.head("extern"));
|
2014-06-21 10:39:03 +00:00
|
|
|
try!(self.word_nbsp(nmod.abi.to_string().as_slice()));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.bopen());
|
|
|
|
try!(self.print_foreign_mod(nmod, item.attrs.as_slice()));
|
|
|
|
try!(self.bclose(item.span));
|
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ItemTy(ref ty, ref params) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.ibox(indent_unit));
|
|
|
|
try!(self.ibox(0u));
|
2014-05-07 23:33:43 +00:00
|
|
|
try!(self.word_nbsp(visibility_qualified(item.vis,
|
|
|
|
"type").as_slice()));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.print_ident(item.ident));
|
|
|
|
try!(self.print_generics(params));
|
|
|
|
try!(self.end()); // end the inner ibox
|
|
|
|
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.word_space("="));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_type(&**ty));
|
2014-08-11 16:32:26 +00:00
|
|
|
try!(self.print_where_clause(params));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, ";"));
|
|
|
|
try!(self.end()); // end the outer ibox
|
|
|
|
}
|
|
|
|
ast::ItemEnum(ref enum_definition, ref params) => {
|
|
|
|
try!(self.print_enum_def(
|
|
|
|
enum_definition,
|
|
|
|
params,
|
|
|
|
item.ident,
|
|
|
|
item.span,
|
|
|
|
item.vis
|
|
|
|
));
|
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ItemStruct(ref struct_def, ref generics) => {
|
2014-09-13 16:06:01 +00:00
|
|
|
try!(self.head(visibility_qualified(item.vis,"struct").as_slice()));
|
|
|
|
try!(self.print_struct(&**struct_def, generics, item.ident, item.span));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2012-08-07 23:08:09 +00:00
|
|
|
|
2014-08-04 20:56:56 +00:00
|
|
|
ast::ItemImpl(ref generics,
|
|
|
|
ref opt_trait,
|
|
|
|
ref ty,
|
|
|
|
ref impl_items) => {
|
2014-05-07 23:33:43 +00:00
|
|
|
try!(self.head(visibility_qualified(item.vis,
|
|
|
|
"impl").as_slice()));
|
2014-03-16 18:58:11 +00:00
|
|
|
if generics.is_parameterized() {
|
|
|
|
try!(self.print_generics(generics));
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
}
|
2013-03-27 10:16:28 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
match opt_trait {
|
|
|
|
&Some(ref t) => {
|
|
|
|
try!(self.print_trait_ref(t));
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.word_space("for"));
|
|
|
|
}
|
|
|
|
&None => {}
|
|
|
|
}
|
2012-08-09 00:14:25 +00:00
|
|
|
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_type(&**ty));
|
2014-08-11 16:32:26 +00:00
|
|
|
try!(self.print_where_clause(generics));
|
2012-08-08 21:17:52 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.bopen());
|
|
|
|
try!(self.print_inner_attributes(item.attrs.as_slice()));
|
2014-08-04 20:56:56 +00:00
|
|
|
for impl_item in impl_items.iter() {
|
|
|
|
match *impl_item {
|
2014-09-13 16:06:01 +00:00
|
|
|
ast::MethodImplItem(ref meth) => {
|
|
|
|
try!(self.print_method(&**meth));
|
2014-08-04 20:56:56 +00:00
|
|
|
}
|
2014-08-06 02:44:21 +00:00
|
|
|
ast::TypeImplItem(ref typ) => {
|
|
|
|
try!(self.print_typedef(&**typ));
|
|
|
|
}
|
2014-08-04 20:56:56 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
try!(self.bclose(item.span));
|
|
|
|
}
|
2014-08-28 01:46:52 +00:00
|
|
|
ast::ItemTrait(ref generics, ref unbound, ref bounds, ref methods) => {
|
2014-05-07 23:33:43 +00:00
|
|
|
try!(self.head(visibility_qualified(item.vis,
|
|
|
|
"trait").as_slice()));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.print_ident(item.ident));
|
|
|
|
try!(self.print_generics(generics));
|
2014-07-08 02:26:02 +00:00
|
|
|
match unbound {
|
2014-11-07 11:53:45 +00:00
|
|
|
&Some(ref tref) => {
|
2014-07-08 02:26:02 +00:00
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.word_space("for"));
|
|
|
|
try!(self.print_trait_ref(tref));
|
|
|
|
try!(word(&mut self.s, "?"));
|
|
|
|
}
|
|
|
|
_ => {}
|
2014-04-03 00:38:45 +00:00
|
|
|
}
|
2014-08-28 01:46:52 +00:00
|
|
|
try!(self.print_bounds(":", bounds));
|
2014-08-11 16:32:26 +00:00
|
|
|
try!(self.print_where_clause(generics));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, " "));
|
|
|
|
try!(self.bopen());
|
|
|
|
for meth in methods.iter() {
|
|
|
|
try!(self.print_trait_method(meth));
|
|
|
|
}
|
|
|
|
try!(self.bclose(item.span));
|
|
|
|
}
|
|
|
|
// I think it's reasonable to hide the context here:
|
|
|
|
ast::ItemMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _),
|
|
|
|
..}) => {
|
|
|
|
try!(self.print_visibility(item.vis));
|
|
|
|
try!(self.print_path(pth, false));
|
|
|
|
try!(word(&mut self.s, "! "));
|
|
|
|
try!(self.print_ident(item.ident));
|
|
|
|
try!(self.cbox(indent_unit));
|
|
|
|
try!(self.popen());
|
2014-04-18 06:48:47 +00:00
|
|
|
try!(self.print_tts(tts.as_slice()));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.pclose());
|
|
|
|
try!(self.end());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.ann.post(self, NodeItem(item))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_trait_ref(&mut self, t: &ast::TraitRef) -> IoResult<()> {
|
|
|
|
self.print_path(&t.path, false)
|
|
|
|
}
|
|
|
|
|
2014-11-07 11:53:45 +00:00
|
|
|
fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) -> IoResult<()> {
|
|
|
|
if !t.bound_lifetimes.is_empty() {
|
|
|
|
try!(word(&mut self.s, "for<"));
|
|
|
|
for lifetime_def in t.bound_lifetimes.iter() {
|
|
|
|
try!(self.print_lifetime_def(lifetime_def));
|
|
|
|
}
|
|
|
|
try!(word(&mut self.s, ">"));
|
|
|
|
}
|
|
|
|
|
|
|
|
self.print_trait_ref(&t.trait_ref)
|
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_enum_def(&mut self, enum_definition: &ast::EnumDef,
|
|
|
|
generics: &ast::Generics, ident: ast::Ident,
|
|
|
|
span: codemap::Span,
|
|
|
|
visibility: ast::Visibility) -> IoResult<()> {
|
2014-05-07 23:33:43 +00:00
|
|
|
try!(self.head(visibility_qualified(visibility, "enum").as_slice()));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.print_ident(ident));
|
|
|
|
try!(self.print_generics(generics));
|
2014-08-11 16:32:26 +00:00
|
|
|
try!(self.print_where_clause(generics));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(space(&mut self.s));
|
|
|
|
self.print_variants(enum_definition.variants.as_slice(), span)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_variants(&mut self,
|
|
|
|
variants: &[P<ast::Variant>],
|
|
|
|
span: codemap::Span) -> IoResult<()> {
|
|
|
|
try!(self.bopen());
|
2014-05-16 07:16:13 +00:00
|
|
|
for v in variants.iter() {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.space_if_not_bol());
|
|
|
|
try!(self.maybe_print_comment(v.span.lo));
|
|
|
|
try!(self.print_outer_attributes(v.node.attrs.as_slice()));
|
|
|
|
try!(self.ibox(indent_unit));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_variant(&**v));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, ","));
|
|
|
|
try!(self.end());
|
|
|
|
try!(self.maybe_print_trailing_comment(v.span, None));
|
|
|
|
}
|
|
|
|
self.bclose(span)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_visibility(&mut self, vis: ast::Visibility) -> IoResult<()> {
|
|
|
|
match vis {
|
|
|
|
ast::Public => self.word_nbsp("pub"),
|
|
|
|
ast::Inherited => Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_struct(&mut self,
|
|
|
|
struct_def: &ast::StructDef,
|
|
|
|
generics: &ast::Generics,
|
|
|
|
ident: ast::Ident,
|
|
|
|
span: codemap::Span) -> IoResult<()> {
|
|
|
|
try!(self.print_ident(ident));
|
|
|
|
try!(self.print_generics(generics));
|
|
|
|
if ast_util::struct_def_is_tuple_like(struct_def) {
|
|
|
|
if !struct_def.fields.is_empty() {
|
|
|
|
try!(self.popen());
|
|
|
|
try!(self.commasep(
|
|
|
|
Inconsistent, struct_def.fields.as_slice(),
|
|
|
|
|s, field| {
|
|
|
|
match field.node.kind {
|
2014-10-09 19:17:22 +00:00
|
|
|
ast::NamedField(..) => panic!("unexpected named field"),
|
2014-03-25 23:53:52 +00:00
|
|
|
ast::UnnamedField(vis) => {
|
|
|
|
try!(s.print_visibility(vis));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(s.maybe_print_comment(field.span.lo));
|
2014-05-16 07:16:13 +00:00
|
|
|
s.print_type(&*field.node.ty)
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
));
|
|
|
|
try!(self.pclose());
|
|
|
|
}
|
|
|
|
try!(word(&mut self.s, ";"));
|
|
|
|
try!(self.end());
|
|
|
|
self.end() // close the outer-box
|
|
|
|
} else {
|
|
|
|
try!(self.nbsp());
|
|
|
|
try!(self.bopen());
|
|
|
|
try!(self.hardbreak_if_not_bol());
|
2012-09-22 01:10:45 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
for field in struct_def.fields.iter() {
|
|
|
|
match field.node.kind {
|
2014-10-09 19:17:22 +00:00
|
|
|
ast::UnnamedField(..) => panic!("unexpected unnamed field"),
|
2014-03-16 18:58:11 +00:00
|
|
|
ast::NamedField(ident, visibility) => {
|
|
|
|
try!(self.hardbreak_if_not_bol());
|
|
|
|
try!(self.maybe_print_comment(field.span.lo));
|
|
|
|
try!(self.print_outer_attributes(field.node.attrs.as_slice()));
|
|
|
|
try!(self.print_visibility(visibility));
|
|
|
|
try!(self.print_ident(ident));
|
|
|
|
try!(self.word_nbsp(":"));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_type(&*field.node.ty));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, ","));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-09-22 01:10:45 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
self.bclose(span)
|
|
|
|
}
|
2012-09-22 01:10:45 +00:00
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
/// This doesn't deserve to be called "pretty" printing, but it should be
|
|
|
|
/// meaning-preserving. A quick hack that might help would be to look at the
|
|
|
|
/// spans embedded in the TTs to decide where to put spaces and newlines.
|
|
|
|
/// But it'd be better to parse these according to the grammar of the
|
|
|
|
/// appropriate macro, transcribe back into the grammar we just parsed from,
|
|
|
|
/// and then pretty-print the resulting AST nodes (so, e.g., we print
|
|
|
|
/// expression arguments as expressions). It can be done! I think.
|
|
|
|
pub fn print_tt(&mut self, tt: &ast::TokenTree) -> IoResult<()> {
|
|
|
|
match *tt {
|
2014-10-22 17:39:58 +00:00
|
|
|
ast::TtToken(_, ref tk) => {
|
2014-10-28 00:05:28 +00:00
|
|
|
try!(word(&mut self.s, token_to_string(tk).as_slice()));
|
2014-05-11 08:34:28 +00:00
|
|
|
match *tk {
|
2014-10-27 08:22:52 +00:00
|
|
|
parse::token::DocComment(..) => {
|
2014-05-11 08:34:28 +00:00
|
|
|
hardbreak(&mut self.s)
|
|
|
|
}
|
|
|
|
_ => Ok(())
|
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-10-06 22:00:56 +00:00
|
|
|
ast::TtDelimited(_, ref delimed) => {
|
|
|
|
try!(word(&mut self.s, token_to_string(&delimed.open_token()).as_slice()));
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.print_tts(delimed.tts.as_slice()));
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
word(&mut self.s, token_to_string(&delimed.close_token()).as_slice())
|
|
|
|
},
|
2014-11-02 11:21:16 +00:00
|
|
|
ast::TtSequence(_, ref seq) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "$("));
|
2014-11-02 11:21:16 +00:00
|
|
|
for tt_elt in seq.tts.iter() {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.print_tt(tt_elt));
|
2012-08-15 22:53:58 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, ")"));
|
2014-11-02 11:21:16 +00:00
|
|
|
match seq.separator {
|
2014-03-16 18:58:11 +00:00
|
|
|
Some(ref tk) => {
|
2014-10-28 00:05:28 +00:00
|
|
|
try!(word(&mut self.s, token_to_string(tk).as_slice()));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-10-28 00:05:28 +00:00
|
|
|
None => {},
|
2012-10-26 19:11:14 +00:00
|
|
|
}
|
2014-11-02 11:21:16 +00:00
|
|
|
match seq.op {
|
2014-10-23 00:24:20 +00:00
|
|
|
ast::ZeroOrMore => word(&mut self.s, "*"),
|
|
|
|
ast::OneOrMore => word(&mut self.s, "+"),
|
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2012-10-26 19:11:14 +00:00
|
|
|
}
|
2012-08-15 22:53:58 +00:00
|
|
|
}
|
2011-03-04 06:22:43 +00:00
|
|
|
|
2014-04-18 06:48:47 +00:00
|
|
|
pub fn print_tts(&mut self, tts: &[ast::TokenTree]) -> IoResult<()> {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.ibox(0));
|
|
|
|
for (i, tt) in tts.iter().enumerate() {
|
|
|
|
if i != 0 {
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
}
|
|
|
|
try!(self.print_tt(tt));
|
|
|
|
}
|
|
|
|
self.end()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_variant(&mut self, v: &ast::Variant) -> IoResult<()> {
|
|
|
|
try!(self.print_visibility(v.node.vis));
|
|
|
|
match v.node.kind {
|
|
|
|
ast::TupleVariantKind(ref args) => {
|
|
|
|
try!(self.print_ident(v.node.name));
|
|
|
|
if !args.is_empty() {
|
|
|
|
try!(self.popen());
|
|
|
|
try!(self.commasep(Consistent,
|
|
|
|
args.as_slice(),
|
2014-05-16 07:16:13 +00:00
|
|
|
|s, arg| s.print_type(&*arg.ty)));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.pclose());
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::StructVariantKind(ref struct_def) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.head(""));
|
|
|
|
let generics = ast_util::empty_generics();
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_struct(&**struct_def, &generics, v.node.name, v.span));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
match v.node.disr_expr {
|
2014-05-16 07:16:13 +00:00
|
|
|
Some(ref d) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.word_space("="));
|
2014-05-16 07:16:13 +00:00
|
|
|
self.print_expr(&**d)
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
_ => Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_ty_method(&mut self, m: &ast::TypeMethod) -> IoResult<()> {
|
|
|
|
try!(self.hardbreak_if_not_bol());
|
|
|
|
try!(self.maybe_print_comment(m.span.lo));
|
|
|
|
try!(self.print_outer_attributes(m.attrs.as_slice()));
|
|
|
|
try!(self.print_ty_fn(None,
|
|
|
|
None,
|
2014-04-07 01:04:40 +00:00
|
|
|
m.fn_style,
|
2014-03-16 18:58:11 +00:00
|
|
|
ast::Many,
|
2014-05-16 07:16:13 +00:00
|
|
|
&*m.decl,
|
2014-03-16 18:58:11 +00:00
|
|
|
Some(m.ident),
|
2014-08-28 01:46:52 +00:00
|
|
|
&OwnedSlice::empty(),
|
2014-03-16 18:58:11 +00:00
|
|
|
Some(&m.generics),
|
2014-11-04 21:25:15 +00:00
|
|
|
Some(&m.explicit_self.node)));
|
2014-03-16 18:58:11 +00:00
|
|
|
word(&mut self.s, ";")
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_trait_method(&mut self,
|
2014-08-04 20:56:56 +00:00
|
|
|
m: &ast::TraitItem) -> IoResult<()> {
|
2014-03-16 18:58:11 +00:00
|
|
|
match *m {
|
2014-08-04 20:56:56 +00:00
|
|
|
RequiredMethod(ref ty_m) => self.print_ty_method(ty_m),
|
2014-08-06 02:44:21 +00:00
|
|
|
ProvidedMethod(ref m) => self.print_method(&**m),
|
|
|
|
TypeTraitItem(ref t) => self.print_associated_type(&**t),
|
2014-08-04 20:56:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> IoResult<()> {
|
|
|
|
match *ii {
|
|
|
|
MethodImplItem(ref m) => self.print_method(&**m),
|
2014-08-06 02:44:21 +00:00
|
|
|
TypeImplItem(ref td) => self.print_typedef(&**td),
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_method(&mut self, meth: &ast::Method) -> IoResult<()> {
|
|
|
|
try!(self.hardbreak_if_not_bol());
|
|
|
|
try!(self.maybe_print_comment(meth.span.lo));
|
|
|
|
try!(self.print_outer_attributes(meth.attrs.as_slice()));
|
2014-07-12 04:22:11 +00:00
|
|
|
match meth.node {
|
2014-05-29 05:26:56 +00:00
|
|
|
ast::MethDecl(ident,
|
|
|
|
ref generics,
|
|
|
|
abi,
|
|
|
|
ref explicit_self,
|
|
|
|
fn_style,
|
2014-09-13 16:06:01 +00:00
|
|
|
ref decl,
|
|
|
|
ref body,
|
2014-05-29 05:26:56 +00:00
|
|
|
vis) => {
|
2014-09-13 16:06:01 +00:00
|
|
|
try!(self.print_fn(&**decl,
|
2014-05-29 05:26:56 +00:00
|
|
|
Some(fn_style),
|
|
|
|
abi,
|
|
|
|
ident,
|
|
|
|
generics,
|
2014-09-13 16:06:01 +00:00
|
|
|
Some(&explicit_self.node),
|
2014-07-12 04:22:11 +00:00
|
|
|
vis));
|
|
|
|
try!(word(&mut self.s, " "));
|
2014-09-13 16:06:01 +00:00
|
|
|
self.print_block_with_attrs(&**body, meth.attrs.as_slice())
|
2014-07-12 04:22:11 +00:00
|
|
|
},
|
|
|
|
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()
|
|
|
|
}
|
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_outer_attributes(&mut self,
|
|
|
|
attrs: &[ast::Attribute]) -> IoResult<()> {
|
2014-06-27 19:30:25 +00:00
|
|
|
let mut count = 0u;
|
2014-03-16 18:58:11 +00:00
|
|
|
for attr in attrs.iter() {
|
|
|
|
match attr.node.style {
|
|
|
|
ast::AttrOuter => {
|
|
|
|
try!(self.print_attribute(attr));
|
|
|
|
count += 1;
|
|
|
|
}
|
|
|
|
_ => {/* fallthrough */ }
|
|
|
|
}
|
2012-07-28 00:38:01 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
if count > 0 {
|
|
|
|
try!(self.hardbreak_if_not_bol());
|
2012-12-13 01:08:09 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
Ok(())
|
2012-12-13 01:08:09 +00:00
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_inner_attributes(&mut self,
|
|
|
|
attrs: &[ast::Attribute]) -> IoResult<()> {
|
2014-06-27 19:30:25 +00:00
|
|
|
let mut count = 0u;
|
2014-03-16 18:58:11 +00:00
|
|
|
for attr in attrs.iter() {
|
|
|
|
match attr.node.style {
|
|
|
|
ast::AttrInner => {
|
|
|
|
try!(self.print_attribute(attr));
|
|
|
|
count += 1;
|
2012-08-07 21:24:04 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
_ => {/* fallthrough */ }
|
2012-08-07 21:24:04 +00:00
|
|
|
}
|
2012-01-26 01:22:08 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
if count > 0 {
|
|
|
|
try!(self.hardbreak_if_not_bol());
|
2012-08-08 01:54:44 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
Ok(())
|
2012-01-26 01:22:08 +00:00
|
|
|
}
|
2012-07-10 20:44:20 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_attribute(&mut self, attr: &ast::Attribute) -> IoResult<()> {
|
|
|
|
try!(self.hardbreak_if_not_bol());
|
|
|
|
try!(self.maybe_print_comment(attr.span.lo));
|
|
|
|
if attr.node.is_sugared_doc {
|
|
|
|
word(&mut self.s, attr.value_str().unwrap().get())
|
|
|
|
} else {
|
2014-04-04 20:45:24 +00:00
|
|
|
match attr.node.style {
|
|
|
|
ast::AttrInner => try!(word(&mut self.s, "#![")),
|
|
|
|
ast::AttrOuter => try!(word(&mut self.s, "#[")),
|
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_meta_item(&*attr.meta()));
|
2014-03-16 18:58:11 +00:00
|
|
|
word(&mut self.s, "]")
|
2011-06-15 01:53:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
|
|
|
|
pub fn print_stmt(&mut self, st: &ast::Stmt) -> IoResult<()> {
|
|
|
|
try!(self.maybe_print_comment(st.span.lo));
|
|
|
|
match st.node {
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::StmtDecl(ref decl, _) => {
|
|
|
|
try!(self.print_decl(&**decl));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::StmtExpr(ref expr, _) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.space_if_not_bol());
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**expr));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::StmtSemi(ref expr, _) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.space_if_not_bol());
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**expr));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, ";"));
|
|
|
|
}
|
|
|
|
ast::StmtMac(ref mac, semi) => {
|
|
|
|
try!(self.space_if_not_bol());
|
|
|
|
try!(self.print_mac(mac));
|
|
|
|
if semi {
|
|
|
|
try!(word(&mut self.s, ";"));
|
|
|
|
}
|
2012-06-30 10:54:54 +00:00
|
|
|
}
|
2011-06-16 20:00:19 +00:00
|
|
|
}
|
2014-09-13 16:06:01 +00:00
|
|
|
if parse::classify::stmt_ends_with_semi(&st.node) {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, ";"));
|
|
|
|
}
|
|
|
|
self.maybe_print_trailing_comment(st.span, None)
|
2011-06-16 20:00:19 +00:00
|
|
|
}
|
2011-07-08 23:35:09 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_block(&mut self, blk: &ast::Block) -> IoResult<()> {
|
|
|
|
self.print_block_with_attrs(blk, &[])
|
|
|
|
}
|
2012-08-14 01:13:41 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_block_unclosed(&mut self, blk: &ast::Block) -> IoResult<()> {
|
|
|
|
self.print_block_unclosed_indent(blk, indent_unit)
|
|
|
|
}
|
2012-01-16 01:23:59 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_block_unclosed_indent(&mut self, blk: &ast::Block,
|
|
|
|
indented: uint) -> IoResult<()> {
|
|
|
|
self.print_block_maybe_unclosed(blk, indented, &[], false)
|
|
|
|
}
|
2011-08-15 21:42:33 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_block_with_attrs(&mut self,
|
|
|
|
blk: &ast::Block,
|
|
|
|
attrs: &[ast::Attribute]) -> IoResult<()> {
|
|
|
|
self.print_block_maybe_unclosed(blk, indent_unit, attrs, true)
|
|
|
|
}
|
2012-01-16 01:23:59 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_block_maybe_unclosed(&mut self,
|
2013-07-19 05:38:55 +00:00
|
|
|
blk: &ast::Block,
|
2013-01-29 22:41:40 +00:00
|
|
|
indented: uint,
|
2013-07-19 11:51:37 +00:00
|
|
|
attrs: &[ast::Attribute],
|
2014-03-16 18:58:11 +00:00
|
|
|
close_box: bool) -> IoResult<()> {
|
|
|
|
match blk.rules {
|
|
|
|
ast::UnsafeBlock(..) => try!(self.word_space("unsafe")),
|
|
|
|
ast::DefaultBlock => ()
|
|
|
|
}
|
|
|
|
try!(self.maybe_print_comment(blk.span.lo));
|
|
|
|
try!(self.ann.pre(self, NodeBlock(blk)));
|
|
|
|
try!(self.bopen());
|
|
|
|
|
|
|
|
try!(self.print_inner_attributes(attrs));
|
|
|
|
|
|
|
|
for vi in blk.view_items.iter() {
|
|
|
|
try!(self.print_view_item(vi));
|
|
|
|
}
|
|
|
|
for st in blk.stmts.iter() {
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_stmt(&**st));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
match blk.expr {
|
2014-05-16 07:16:13 +00:00
|
|
|
Some(ref expr) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.space_if_not_bol());
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**expr));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi)));
|
|
|
|
}
|
|
|
|
_ => ()
|
|
|
|
}
|
|
|
|
try!(self.bclose_maybe_open(blk.span, indented, close_box));
|
|
|
|
self.ann.post(self, NodeBlock(blk))
|
|
|
|
}
|
2011-03-04 06:22:43 +00:00
|
|
|
|
2014-09-13 16:06:01 +00:00
|
|
|
fn print_else(&mut self, els: Option<&ast::Expr>) -> IoResult<()> {
|
2012-08-06 19:34:08 +00:00
|
|
|
match els {
|
2014-01-30 01:39:21 +00:00
|
|
|
Some(_else) => {
|
|
|
|
match _else.node {
|
|
|
|
// "another else-if"
|
2014-09-13 16:06:01 +00:00
|
|
|
ast::ExprIf(ref i, ref then, ref e) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.cbox(indent_unit - 1u));
|
|
|
|
try!(self.ibox(0u));
|
|
|
|
try!(word(&mut self.s, " else if "));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**i));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(space(&mut self.s));
|
2014-09-13 16:06:01 +00:00
|
|
|
try!(self.print_block(&**then));
|
|
|
|
self.print_else(e.as_ref().map(|e| &**e))
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
2014-08-25 01:04:29 +00:00
|
|
|
// "another else-if-let"
|
|
|
|
ast::ExprIfLet(ref pat, ref expr, ref then, ref e) => {
|
|
|
|
try!(self.cbox(indent_unit - 1u));
|
|
|
|
try!(self.ibox(0u));
|
|
|
|
try!(word(&mut self.s, " else if let "));
|
|
|
|
try!(self.print_pat(&**pat));
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.word_space("="));
|
|
|
|
try!(self.print_expr(&**expr));
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.print_block(&**then));
|
|
|
|
self.print_else(e.as_ref().map(|e| &**e))
|
|
|
|
}
|
2014-01-30 01:39:21 +00:00
|
|
|
// "final else"
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ExprBlock(ref b) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.cbox(indent_unit - 1u));
|
|
|
|
try!(self.ibox(0u));
|
|
|
|
try!(word(&mut self.s, " else "));
|
2014-05-16 07:16:13 +00:00
|
|
|
self.print_block(&**b)
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
|
|
|
// BLEAH, constraints would be great here
|
|
|
|
_ => {
|
2014-10-09 19:17:22 +00:00
|
|
|
panic!("print_if saw if with weird alternative");
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
|
|
|
}
|
2011-06-16 21:08:17 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
_ => Ok(())
|
2011-06-16 21:08:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_if(&mut self, test: &ast::Expr, blk: &ast::Block,
|
2014-08-25 01:04:29 +00:00
|
|
|
elseopt: Option<&ast::Expr>) -> IoResult<()> {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.head("if"));
|
|
|
|
try!(self.print_expr(test));
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.print_block(blk));
|
|
|
|
self.print_else(elseopt)
|
2011-07-08 23:35:09 +00:00
|
|
|
}
|
|
|
|
|
2014-08-25 01:04:29 +00:00
|
|
|
pub fn print_if_let(&mut self, pat: &ast::Pat, expr: &ast::Expr, blk: &ast::Block,
|
|
|
|
elseopt: Option<&ast::Expr>) -> IoResult<()> {
|
|
|
|
try!(self.head("if let"));
|
|
|
|
try!(self.print_pat(pat));
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.word_space("="));
|
|
|
|
try!(self.print_expr(expr));
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.print_block(blk));
|
|
|
|
self.print_else(elseopt)
|
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_mac(&mut self, m: &ast::Mac) -> IoResult<()> {
|
|
|
|
match m.node {
|
|
|
|
// I think it's reasonable to hide the ctxt here:
|
|
|
|
ast::MacInvocTT(ref pth, ref tts, _) => {
|
|
|
|
try!(self.print_path(pth, false));
|
|
|
|
try!(word(&mut self.s, "!"));
|
|
|
|
try!(self.popen());
|
2014-04-18 06:48:47 +00:00
|
|
|
try!(self.print_tts(tts.as_slice()));
|
2014-03-16 18:58:11 +00:00
|
|
|
self.pclose()
|
|
|
|
}
|
|
|
|
}
|
2012-09-12 04:25:01 +00:00
|
|
|
}
|
2012-11-30 19:18:25 +00:00
|
|
|
|
2012-07-23 23:39:18 +00:00
|
|
|
|
2014-09-13 16:06:01 +00:00
|
|
|
fn print_call_post(&mut self, args: &[P<ast::Expr>]) -> IoResult<()> {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.popen());
|
|
|
|
try!(self.commasep_exprs(Inconsistent, args));
|
|
|
|
self.pclose()
|
|
|
|
}
|
|
|
|
|
2014-04-16 20:33:58 +00:00
|
|
|
pub fn print_expr_maybe_paren(&mut self, expr: &ast::Expr) -> IoResult<()> {
|
|
|
|
let needs_par = needs_parentheses(expr);
|
|
|
|
if needs_par {
|
|
|
|
try!(self.popen());
|
|
|
|
}
|
|
|
|
try!(self.print_expr(expr));
|
|
|
|
if needs_par {
|
|
|
|
try!(self.pclose());
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> {
|
|
|
|
try!(self.maybe_print_comment(expr.span.lo));
|
|
|
|
try!(self.ibox(indent_unit));
|
|
|
|
try!(self.ann.pre(self, NodeExpr(expr)));
|
|
|
|
match expr.node {
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ExprBox(ref p, ref e) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "box"));
|
|
|
|
try!(word(&mut self.s, "("));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**p));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.word_space(")"));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**e));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-04-04 10:12:18 +00:00
|
|
|
ast::ExprVec(ref exprs) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.ibox(indent_unit));
|
|
|
|
try!(word(&mut self.s, "["));
|
|
|
|
try!(self.commasep_exprs(Inconsistent, exprs.as_slice()));
|
|
|
|
try!(word(&mut self.s, "]"));
|
|
|
|
try!(self.end());
|
|
|
|
}
|
|
|
|
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ExprRepeat(ref element, ref count) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.ibox(indent_unit));
|
|
|
|
try!(word(&mut self.s, "["));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**element));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, ","));
|
|
|
|
try!(word(&mut self.s, ".."));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**count));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "]"));
|
|
|
|
try!(self.end());
|
|
|
|
}
|
|
|
|
|
2014-09-13 16:06:01 +00:00
|
|
|
ast::ExprStruct(ref path, ref fields, ref wth) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.print_path(path, true));
|
|
|
|
try!(word(&mut self.s, "{"));
|
|
|
|
try!(self.commasep_cmnt(
|
|
|
|
Consistent,
|
|
|
|
fields.as_slice(),
|
|
|
|
|s, field| {
|
|
|
|
try!(s.ibox(indent_unit));
|
|
|
|
try!(s.print_ident(field.ident.node));
|
|
|
|
try!(s.word_space(":"));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(s.print_expr(&*field.expr));
|
2014-03-16 18:58:11 +00:00
|
|
|
s.end()
|
|
|
|
},
|
|
|
|
|f| f.span));
|
2014-09-13 16:06:01 +00:00
|
|
|
match *wth {
|
2014-05-16 07:16:13 +00:00
|
|
|
Some(ref expr) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.ibox(indent_unit));
|
|
|
|
if !fields.is_empty() {
|
|
|
|
try!(word(&mut self.s, ","));
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
}
|
|
|
|
try!(word(&mut self.s, ".."));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**expr));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.end());
|
|
|
|
}
|
|
|
|
_ => try!(word(&mut self.s, ","))
|
2014-03-03 07:41:47 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "}"));
|
|
|
|
}
|
|
|
|
ast::ExprTup(ref exprs) => {
|
|
|
|
try!(self.popen());
|
|
|
|
try!(self.commasep_exprs(Inconsistent, exprs.as_slice()));
|
|
|
|
if exprs.len() == 1 {
|
|
|
|
try!(word(&mut self.s, ","));
|
2012-08-01 23:16:53 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.pclose());
|
2012-07-10 17:37:05 +00:00
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ExprCall(ref func, ref args) => {
|
|
|
|
try!(self.print_expr_maybe_paren(&**func));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.print_call_post(args.as_slice()));
|
2012-08-09 23:31:47 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
ast::ExprMethodCall(ident, ref tys, ref args) => {
|
|
|
|
let base_args = args.slice_from(1);
|
2014-10-15 06:05:01 +00:00
|
|
|
try!(self.print_expr(&*args[0]));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "."));
|
2014-04-23 21:19:23 +00:00
|
|
|
try!(self.print_ident(ident.node));
|
2014-03-16 18:58:11 +00:00
|
|
|
if tys.len() > 0u {
|
|
|
|
try!(word(&mut self.s, "::<"));
|
|
|
|
try!(self.commasep(Inconsistent, tys.as_slice(),
|
2014-09-13 16:06:01 +00:00
|
|
|
|s, ty| s.print_type(&**ty)));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, ">"));
|
|
|
|
}
|
|
|
|
try!(self.print_call_post(base_args));
|
2013-10-28 22:22:49 +00:00
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ExprBinary(op, ref lhs, ref rhs) => {
|
|
|
|
try!(self.print_expr(&**lhs));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(space(&mut self.s));
|
2014-06-21 10:39:03 +00:00
|
|
|
try!(self.word_space(ast_util::binop_to_string(op)));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**rhs));
|
2013-10-28 22:22:49 +00:00
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ExprUnary(op, ref expr) => {
|
2014-06-21 10:39:03 +00:00
|
|
|
try!(word(&mut self.s, ast_util::unop_to_string(op)));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr_maybe_paren(&**expr));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ExprAddrOf(m, ref expr) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "&"));
|
|
|
|
try!(self.print_mutability(m));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr_maybe_paren(&**expr));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ExprLit(ref lit) => try!(self.print_literal(&**lit)),
|
|
|
|
ast::ExprCast(ref expr, ref ty) => {
|
|
|
|
try!(self.print_expr(&**expr));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.word_space("as"));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_type(&**ty));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-09-13 16:06:01 +00:00
|
|
|
ast::ExprIf(ref test, ref blk, ref elseopt) => {
|
2014-08-25 01:04:29 +00:00
|
|
|
try!(self.print_if(&**test, &**blk, elseopt.as_ref().map(|e| &**e)));
|
|
|
|
}
|
|
|
|
ast::ExprIfLet(ref pat, ref expr, ref blk, ref elseopt) => {
|
|
|
|
try!(self.print_if_let(&**pat, &**expr, &** blk, elseopt.as_ref().map(|e| &**e)));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-07-26 00:12:51 +00:00
|
|
|
ast::ExprWhile(ref test, ref blk, opt_ident) => {
|
|
|
|
for ident in opt_ident.iter() {
|
|
|
|
try!(self.print_ident(*ident));
|
|
|
|
try!(self.word_space(":"));
|
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.head("while"));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**test));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(space(&mut self.s));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_block(&**blk));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-10-03 02:45:46 +00:00
|
|
|
ast::ExprWhileLet(ref pat, ref expr, ref blk, opt_ident) => {
|
|
|
|
for ident in opt_ident.iter() {
|
|
|
|
try!(self.print_ident(*ident));
|
|
|
|
try!(self.word_space(":"));
|
|
|
|
}
|
|
|
|
try!(self.head("while let"));
|
|
|
|
try!(self.print_pat(&**pat));
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.word_space("="));
|
|
|
|
try!(self.print_expr(&**expr));
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.print_block(&**blk));
|
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ExprForLoop(ref pat, ref iter, ref blk, opt_ident) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
for ident in opt_ident.iter() {
|
|
|
|
try!(self.print_ident(*ident));
|
|
|
|
try!(self.word_space(":"));
|
|
|
|
}
|
|
|
|
try!(self.head("for"));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_pat(&**pat));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.word_space("in"));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**iter));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(space(&mut self.s));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_block(&**blk));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ExprLoop(ref blk, opt_ident) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
for ident in opt_ident.iter() {
|
|
|
|
try!(self.print_ident(*ident));
|
|
|
|
try!(self.word_space(":"));
|
|
|
|
}
|
|
|
|
try!(self.head("loop"));
|
|
|
|
try!(space(&mut self.s));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_block(&**blk));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-08-25 21:55:00 +00:00
|
|
|
ast::ExprMatch(ref expr, ref arms, _) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.cbox(indent_unit));
|
|
|
|
try!(self.ibox(4));
|
|
|
|
try!(self.word_nbsp("match"));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**expr));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.bopen());
|
2014-07-28 01:05:07 +00:00
|
|
|
for arm in arms.iter() {
|
|
|
|
try!(self.print_arm(arm));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
try!(self.bclose_(expr.span, indent_unit));
|
|
|
|
}
|
2014-07-23 19:43:29 +00:00
|
|
|
ast::ExprFnBlock(capture_clause, ref decl, ref body) => {
|
|
|
|
try!(self.print_capture_clause(capture_clause));
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
// 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() {
|
2014-07-30 05:08:39 +00:00
|
|
|
try!(self.print_fn_block_args(&**decl, None));
|
2014-05-29 05:26:56 +00:00
|
|
|
try!(space(&mut self.s));
|
|
|
|
// }
|
|
|
|
|
|
|
|
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
|
2014-09-13 16:06:01 +00:00
|
|
|
match body.expr.as_ref().unwrap().node {
|
|
|
|
ast::ExprBlock(ref blk) => {
|
|
|
|
try!(self.print_block_unclosed(&**blk));
|
2014-05-29 05:26:56 +00:00
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
// this is a bare expression
|
2014-09-13 16:06:01 +00:00
|
|
|
try!(self.print_expr(&**body.expr.as_ref().unwrap()));
|
2014-05-29 05:26:56 +00:00
|
|
|
try!(self.end()); // need to close a box
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// 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));
|
|
|
|
}
|
2014-07-30 05:08:39 +00:00
|
|
|
ast::ExprUnboxedFn(capture_clause, kind, ref decl, ref body) => {
|
2014-07-23 19:43:29 +00:00
|
|
|
try!(self.print_capture_clause(capture_clause));
|
|
|
|
|
2014-05-29 05:26:56 +00:00
|
|
|
// 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() {
|
2014-07-30 05:08:39 +00:00
|
|
|
try!(self.print_fn_block_args(&**decl, Some(kind)));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(space(&mut self.s));
|
|
|
|
// }
|
2014-04-15 07:58:50 +00:00
|
|
|
|
|
|
|
if !body.stmts.is_empty() || !body.expr.is_some() {
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_block_unclosed(&**body));
|
2014-04-15 07:58:50 +00:00
|
|
|
} else {
|
|
|
|
// we extract the block, so as not to create another set of boxes
|
2014-09-13 16:06:01 +00:00
|
|
|
match body.expr.as_ref().unwrap().node {
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ExprBlock(ref blk) => {
|
|
|
|
try!(self.print_block_unclosed(&**blk));
|
2014-04-15 07:58:50 +00:00
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
// this is a bare expression
|
2014-09-13 16:06:01 +00:00
|
|
|
try!(self.print_expr(body.expr.as_ref().map(|e| &**e).unwrap()));
|
2014-04-15 07:58:50 +00:00
|
|
|
try!(self.end()); // need to close a box
|
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// 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));
|
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ExprProc(ref decl, ref body) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
// 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() {
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_proc_args(&**decl));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(space(&mut self.s));
|
|
|
|
// }
|
|
|
|
assert!(body.stmts.is_empty());
|
|
|
|
assert!(body.expr.is_some());
|
|
|
|
// we extract the block, so as not to create another set of boxes
|
2014-09-13 16:06:01 +00:00
|
|
|
match body.expr.as_ref().unwrap().node {
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ExprBlock(ref blk) => {
|
|
|
|
try!(self.print_block_unclosed(&**blk));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
// this is a bare expression
|
2014-09-13 16:06:01 +00:00
|
|
|
try!(self.print_expr(body.expr.as_ref().map(|e| &**e).unwrap()));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.end()); // need to close a box
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// 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));
|
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ExprBlock(ref blk) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
// containing cbox, will be closed by print-block at }
|
|
|
|
try!(self.cbox(indent_unit));
|
|
|
|
// head-box, will be closed by print-block after {
|
|
|
|
try!(self.ibox(0u));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_block(&**blk));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ExprAssign(ref lhs, ref rhs) => {
|
|
|
|
try!(self.print_expr(&**lhs));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.word_space("="));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**rhs));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ExprAssignOp(op, ref lhs, ref rhs) => {
|
|
|
|
try!(self.print_expr(&**lhs));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(space(&mut self.s));
|
2014-06-21 10:39:03 +00:00
|
|
|
try!(word(&mut self.s, ast_util::binop_to_string(op)));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.word_space("="));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**rhs));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ExprField(ref expr, id, ref tys) => {
|
|
|
|
try!(self.print_expr(&**expr));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "."));
|
2014-06-13 21:56:42 +00:00
|
|
|
try!(self.print_ident(id.node));
|
2014-03-16 18:58:11 +00:00
|
|
|
if tys.len() > 0u {
|
|
|
|
try!(word(&mut self.s, "::<"));
|
|
|
|
try!(self.commasep(
|
|
|
|
Inconsistent, tys.as_slice(),
|
2014-09-13 16:06:01 +00:00
|
|
|
|s, ty| s.print_type(&**ty)));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, ">"));
|
|
|
|
}
|
|
|
|
}
|
2014-08-10 03:54:33 +00:00
|
|
|
ast::ExprTupField(ref expr, id, ref tys) => {
|
|
|
|
try!(self.print_expr(&**expr));
|
|
|
|
try!(word(&mut self.s, "."));
|
|
|
|
try!(self.print_uint(id.node));
|
|
|
|
if tys.len() > 0u {
|
|
|
|
try!(word(&mut self.s, "::<"));
|
|
|
|
try!(self.commasep(
|
|
|
|
Inconsistent, tys.as_slice(),
|
2014-09-13 16:06:01 +00:00
|
|
|
|s, ty| s.print_type(&**ty)));
|
2014-08-10 03:54:33 +00:00
|
|
|
try!(word(&mut self.s, ">"));
|
|
|
|
}
|
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ExprIndex(ref expr, ref index) => {
|
|
|
|
try!(self.print_expr(&**expr));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "["));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**index));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "]"));
|
|
|
|
}
|
2014-09-15 08:48:58 +00:00
|
|
|
ast::ExprSlice(ref e, ref start, ref end, ref mutbl) => {
|
|
|
|
try!(self.print_expr(&**e));
|
|
|
|
try!(word(&mut self.s, "["));
|
|
|
|
if mutbl == &ast::MutMutable {
|
|
|
|
try!(word(&mut self.s, "mut"));
|
|
|
|
if start.is_some() || end.is_some() {
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
match start {
|
|
|
|
&Some(ref e) => try!(self.print_expr(&**e)),
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
if start.is_some() || end.is_some() {
|
|
|
|
try!(word(&mut self.s, ".."));
|
|
|
|
}
|
|
|
|
match end {
|
|
|
|
&Some(ref e) => try!(self.print_expr(&**e)),
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
try!(word(&mut self.s, "]"));
|
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
ast::ExprPath(ref path) => try!(self.print_path(path, true)),
|
|
|
|
ast::ExprBreak(opt_ident) => {
|
|
|
|
try!(word(&mut self.s, "break"));
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
for ident in opt_ident.iter() {
|
|
|
|
try!(self.print_ident(*ident));
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ast::ExprAgain(opt_ident) => {
|
|
|
|
try!(word(&mut self.s, "continue"));
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
for ident in opt_ident.iter() {
|
|
|
|
try!(self.print_ident(*ident));
|
|
|
|
try!(space(&mut self.s))
|
|
|
|
}
|
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ExprRet(ref result) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "return"));
|
2014-05-16 07:16:13 +00:00
|
|
|
match *result {
|
|
|
|
Some(ref expr) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, " "));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**expr));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
_ => ()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ast::ExprInlineAsm(ref a) => {
|
|
|
|
if a.volatile {
|
|
|
|
try!(word(&mut self.s, "__volatile__ asm!"));
|
|
|
|
} else {
|
|
|
|
try!(word(&mut self.s, "asm!"));
|
|
|
|
}
|
|
|
|
try!(self.popen());
|
|
|
|
try!(self.print_string(a.asm.get(), a.asm_str_style));
|
|
|
|
try!(self.word_space(":"));
|
2014-04-17 08:35:40 +00:00
|
|
|
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.commasep(Inconsistent, a.outputs.as_slice(),
|
2014-08-19 19:39:26 +00:00
|
|
|
|s, &(ref co, ref o, is_rw)| {
|
|
|
|
match co.get().slice_shift_char() {
|
|
|
|
(Some('='), operand) if is_rw => {
|
|
|
|
try!(s.print_string(format!("+{}", operand).as_slice(),
|
|
|
|
ast::CookedStr))
|
|
|
|
}
|
|
|
|
_ => try!(s.print_string(co.get(), ast::CookedStr))
|
|
|
|
}
|
2014-04-17 08:35:40 +00:00
|
|
|
try!(s.popen());
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(s.print_expr(&**o));
|
2014-04-17 08:35:40 +00:00
|
|
|
try!(s.pclose());
|
|
|
|
Ok(())
|
|
|
|
}));
|
|
|
|
try!(space(&mut self.s));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.word_space(":"));
|
2014-04-17 08:35:40 +00:00
|
|
|
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.commasep(Inconsistent, a.inputs.as_slice(),
|
|
|
|
|s, &(ref co, ref o)| {
|
2014-04-17 08:35:40 +00:00
|
|
|
try!(s.print_string(co.get(), ast::CookedStr));
|
|
|
|
try!(s.popen());
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(s.print_expr(&**o));
|
2014-04-17 08:35:40 +00:00
|
|
|
try!(s.pclose());
|
|
|
|
Ok(())
|
|
|
|
}));
|
|
|
|
try!(space(&mut self.s));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.word_space(":"));
|
2014-04-17 08:35:40 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.print_string(a.clobbers.get(), ast::CookedStr));
|
|
|
|
try!(self.pclose());
|
|
|
|
}
|
|
|
|
ast::ExprMac(ref m) => try!(self.print_mac(m)),
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::ExprParen(ref e) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.popen());
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**e));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.pclose());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
try!(self.ann.post(self, NodeExpr(expr)));
|
|
|
|
self.end()
|
2011-08-10 19:51:50 +00:00
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_local_decl(&mut self, loc: &ast::Local) -> IoResult<()> {
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_pat(&*loc.pat));
|
2014-03-16 18:58:11 +00:00
|
|
|
match loc.ty.node {
|
|
|
|
ast::TyInfer => Ok(()),
|
|
|
|
_ => {
|
|
|
|
try!(self.word_space(":"));
|
2014-05-16 07:16:13 +00:00
|
|
|
self.print_type(&*loc.ty)
|
2011-03-25 03:03:12 +00:00
|
|
|
}
|
2011-03-04 06:22:43 +00:00
|
|
|
}
|
|
|
|
}
|
2011-03-24 15:33:20 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_decl(&mut self, decl: &ast::Decl) -> IoResult<()> {
|
|
|
|
try!(self.maybe_print_comment(decl.span.lo));
|
|
|
|
match decl.node {
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::DeclLocal(ref loc) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.space_if_not_bol());
|
|
|
|
try!(self.ibox(indent_unit));
|
|
|
|
try!(self.word_nbsp("let"));
|
2013-09-10 19:01:44 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.ibox(indent_unit));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_local_decl(&**loc));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.end());
|
|
|
|
match loc.init {
|
2014-05-16 07:16:13 +00:00
|
|
|
Some(ref init) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.nbsp());
|
|
|
|
try!(self.word_space("="));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**init));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
self.end()
|
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::DeclItem(ref item) => self.print_item(&**item)
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
}
|
2014-01-30 01:39:21 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_ident(&mut self, ident: ast::Ident) -> IoResult<()> {
|
2014-08-01 15:11:53 +00:00
|
|
|
if self.encode_idents_with_hygiene {
|
|
|
|
let encoded = ident.encode_with_hygiene();
|
2014-08-11 12:01:37 +00:00
|
|
|
try!(word(&mut self.s, encoded.as_slice()))
|
2014-08-01 15:11:53 +00:00
|
|
|
} else {
|
2014-08-11 12:01:37 +00:00
|
|
|
try!(word(&mut self.s, token::get_ident(ident).get()))
|
2014-08-01 15:11:53 +00:00
|
|
|
}
|
2014-08-11 12:01:37 +00:00
|
|
|
self.ann.post(self, NodeIdent(&ident))
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2011-03-04 06:22:43 +00:00
|
|
|
|
2014-08-10 03:54:33 +00:00
|
|
|
pub fn print_uint(&mut self, i: uint) -> IoResult<()> {
|
|
|
|
word(&mut self.s, i.to_string().as_slice())
|
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_name(&mut self, name: ast::Name) -> IoResult<()> {
|
2014-08-11 12:01:37 +00:00
|
|
|
try!(word(&mut self.s, token::get_name(name).get()));
|
|
|
|
self.ann.post(self, NodeName(&name))
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2013-08-07 16:47:28 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_for_decl(&mut self, loc: &ast::Local,
|
|
|
|
coll: &ast::Expr) -> IoResult<()> {
|
|
|
|
try!(self.print_local_decl(loc));
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.word_space("in"));
|
|
|
|
self.print_expr(coll)
|
|
|
|
}
|
2013-08-07 16:47:28 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
fn print_path_(&mut self,
|
|
|
|
path: &ast::Path,
|
|
|
|
colons_before_params: bool,
|
2014-03-19 14:52:37 +00:00
|
|
|
opt_bounds: &Option<OwnedSlice<ast::TyParamBound>>)
|
2014-03-16 18:58:11 +00:00
|
|
|
-> IoResult<()> {
|
|
|
|
try!(self.maybe_print_comment(path.span.lo));
|
|
|
|
if path.global {
|
|
|
|
try!(word(&mut self.s, "::"));
|
2013-09-17 20:13:47 +00:00
|
|
|
}
|
2013-08-07 16:47:28 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
let mut first = true;
|
2014-03-22 16:20:22 +00:00
|
|
|
for segment in path.segments.iter() {
|
2014-03-16 18:58:11 +00:00
|
|
|
if first {
|
|
|
|
first = false
|
|
|
|
} else {
|
|
|
|
try!(word(&mut self.s, "::"))
|
2013-08-07 16:47:28 +00:00
|
|
|
}
|
2013-02-28 00:41:02 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.print_ident(segment.identifier));
|
|
|
|
|
2014-11-04 02:52:52 +00:00
|
|
|
try!(self.print_path_parameters(&segment.parameters, colons_before_params));
|
|
|
|
}
|
|
|
|
|
|
|
|
match *opt_bounds {
|
|
|
|
None => Ok(()),
|
|
|
|
Some(ref bounds) => self.print_bounds("+", bounds)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_path_parameters(&mut self,
|
|
|
|
parameters: &ast::PathParameters,
|
|
|
|
colons_before_params: bool)
|
|
|
|
-> IoResult<()>
|
|
|
|
{
|
|
|
|
if parameters.is_empty() {
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
|
|
|
|
if colons_before_params {
|
|
|
|
try!(word(&mut self.s, "::"))
|
|
|
|
}
|
|
|
|
|
|
|
|
match *parameters {
|
|
|
|
ast::AngleBracketedParameters(ref data) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "<"));
|
|
|
|
|
|
|
|
let mut comma = false;
|
2014-11-04 02:52:52 +00:00
|
|
|
for lifetime in data.lifetimes.iter() {
|
2014-03-16 18:58:11 +00:00
|
|
|
if comma {
|
|
|
|
try!(self.word_space(","))
|
|
|
|
}
|
|
|
|
try!(self.print_lifetime(lifetime));
|
|
|
|
comma = true;
|
2013-11-09 03:25:22 +00:00
|
|
|
}
|
2013-02-28 00:41:02 +00:00
|
|
|
|
2014-11-04 02:52:52 +00:00
|
|
|
if !data.types.is_empty() {
|
2014-03-16 18:58:11 +00:00
|
|
|
if comma {
|
|
|
|
try!(self.word_space(","))
|
|
|
|
}
|
|
|
|
try!(self.commasep(
|
|
|
|
Inconsistent,
|
2014-11-04 02:52:52 +00:00
|
|
|
data.types.as_slice(),
|
2014-09-13 16:06:01 +00:00
|
|
|
|s, ty| s.print_type(&**ty)));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
try!(word(&mut self.s, ">"))
|
|
|
|
}
|
2014-03-22 16:20:22 +00:00
|
|
|
|
2014-11-04 02:52:52 +00:00
|
|
|
ast::ParenthesizedParameters(ref data) => {
|
|
|
|
try!(word(&mut self.s, "("));
|
|
|
|
try!(self.commasep(
|
|
|
|
Inconsistent,
|
|
|
|
data.inputs.as_slice(),
|
|
|
|
|s, ty| s.print_type(&**ty)));
|
|
|
|
try!(word(&mut self.s, ")"));
|
|
|
|
|
|
|
|
match data.output {
|
|
|
|
None => { }
|
|
|
|
Some(ref ty) => {
|
|
|
|
try!(self.word_space("->"));
|
|
|
|
try!(self.print_type(&**ty));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-03-22 16:20:22 +00:00
|
|
|
}
|
2014-11-04 02:52:52 +00:00
|
|
|
|
|
|
|
Ok(())
|
2011-03-24 15:33:20 +00:00
|
|
|
}
|
2011-03-04 06:22:43 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
fn print_path(&mut self, path: &ast::Path,
|
|
|
|
colons_before_params: bool) -> IoResult<()> {
|
|
|
|
self.print_path_(path, colons_before_params, &None)
|
|
|
|
}
|
2013-06-17 19:16:30 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
fn print_bounded_path(&mut self, path: &ast::Path,
|
2014-03-19 14:52:37 +00:00
|
|
|
bounds: &Option<OwnedSlice<ast::TyParamBound>>)
|
2014-03-16 18:58:11 +00:00
|
|
|
-> IoResult<()> {
|
|
|
|
self.print_path_(path, false, bounds)
|
|
|
|
}
|
2013-06-24 17:30:35 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> {
|
|
|
|
try!(self.maybe_print_comment(pat.span.lo));
|
|
|
|
try!(self.ann.pre(self, NodePat(pat)));
|
|
|
|
/* Pat isn't normalized, but the beauty of it
|
|
|
|
is that it doesn't matter */
|
|
|
|
match pat.node {
|
2014-08-06 15:04:44 +00:00
|
|
|
ast::PatWild(ast::PatWildSingle) => try!(word(&mut self.s, "_")),
|
|
|
|
ast::PatWild(ast::PatWildMulti) => try!(word(&mut self.s, "..")),
|
2014-09-13 16:06:01 +00:00
|
|
|
ast::PatIdent(binding_mode, ref path1, ref sub) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
match binding_mode {
|
|
|
|
ast::BindByRef(mutbl) => {
|
|
|
|
try!(self.word_nbsp("ref"));
|
|
|
|
try!(self.print_mutability(mutbl));
|
|
|
|
}
|
|
|
|
ast::BindByValue(ast::MutImmutable) => {}
|
|
|
|
ast::BindByValue(ast::MutMutable) => {
|
|
|
|
try!(self.word_nbsp("mut"));
|
|
|
|
}
|
|
|
|
}
|
2014-07-01 01:02:14 +00:00
|
|
|
try!(self.print_ident(path1.node));
|
2014-09-13 16:06:01 +00:00
|
|
|
match *sub {
|
2014-05-16 07:16:13 +00:00
|
|
|
Some(ref p) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "@"));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_pat(&**p));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
None => ()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ast::PatEnum(ref path, ref args_) => {
|
|
|
|
try!(self.print_path(path, true));
|
|
|
|
match *args_ {
|
|
|
|
None => try!(word(&mut self.s, "(..)")),
|
|
|
|
Some(ref args) => {
|
|
|
|
if !args.is_empty() {
|
|
|
|
try!(self.popen());
|
|
|
|
try!(self.commasep(Inconsistent, args.as_slice(),
|
2014-05-16 07:16:13 +00:00
|
|
|
|s, p| s.print_pat(&**p)));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.pclose());
|
|
|
|
}
|
|
|
|
}
|
2013-11-08 03:25:39 +00:00
|
|
|
}
|
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
ast::PatStruct(ref path, ref fields, etc) => {
|
|
|
|
try!(self.print_path(path, true));
|
2014-07-07 18:54:50 +00:00
|
|
|
try!(self.nbsp());
|
|
|
|
try!(self.word_space("{"));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.commasep_cmnt(
|
|
|
|
Consistent, fields.as_slice(),
|
|
|
|
|s, f| {
|
|
|
|
try!(s.cbox(indent_unit));
|
2014-10-27 07:11:26 +00:00
|
|
|
if !f.node.is_shorthand {
|
|
|
|
try!(s.print_ident(f.node.ident));
|
|
|
|
try!(s.word_nbsp(":"));
|
|
|
|
}
|
2014-10-06 00:36:53 +00:00
|
|
|
try!(s.print_pat(&*f.node.pat));
|
2014-03-16 18:58:11 +00:00
|
|
|
s.end()
|
|
|
|
},
|
2014-10-06 00:36:53 +00:00
|
|
|
|f| f.node.pat.span));
|
2014-03-16 18:58:11 +00:00
|
|
|
if etc {
|
|
|
|
if fields.len() != 0u { try!(self.word_space(",")); }
|
|
|
|
try!(word(&mut self.s, ".."));
|
|
|
|
}
|
2014-07-07 18:54:50 +00:00
|
|
|
try!(space(&mut self.s));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "}"));
|
|
|
|
}
|
|
|
|
ast::PatTup(ref elts) => {
|
|
|
|
try!(self.popen());
|
|
|
|
try!(self.commasep(Inconsistent,
|
|
|
|
elts.as_slice(),
|
2014-05-16 07:16:13 +00:00
|
|
|
|s, p| s.print_pat(&**p)));
|
2014-03-16 18:58:11 +00:00
|
|
|
if elts.len() == 1 {
|
|
|
|
try!(word(&mut self.s, ","));
|
|
|
|
}
|
|
|
|
try!(self.pclose());
|
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::PatBox(ref inner) => {
|
2014-05-06 01:56:44 +00:00
|
|
|
try!(word(&mut self.s, "box "));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_pat(&**inner));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::PatRegion(ref inner) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "&"));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_pat(&**inner));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::PatLit(ref e) => try!(self.print_expr(&**e)),
|
|
|
|
ast::PatRange(ref begin, ref end) => {
|
|
|
|
try!(self.print_expr(&**begin));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(space(&mut self.s));
|
2014-09-15 08:48:58 +00:00
|
|
|
try!(word(&mut self.s, "..."));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_expr(&**end));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-09-13 16:06:01 +00:00
|
|
|
ast::PatVec(ref before, ref slice, ref after) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "["));
|
|
|
|
try!(self.commasep(Inconsistent,
|
|
|
|
before.as_slice(),
|
2014-05-16 07:16:13 +00:00
|
|
|
|s, p| s.print_pat(&**p)));
|
|
|
|
for p in slice.iter() {
|
2014-03-16 18:58:11 +00:00
|
|
|
if !before.is_empty() { try!(self.word_space(",")); }
|
2014-09-06 22:23:55 +00:00
|
|
|
try!(self.print_pat(&**p));
|
2014-05-16 07:16:13 +00:00
|
|
|
match **p {
|
2014-08-06 15:04:44 +00:00
|
|
|
ast::Pat { node: ast::PatWild(ast::PatWildMulti), .. } => {
|
2014-03-16 18:58:11 +00:00
|
|
|
// this case is handled by print_pat
|
|
|
|
}
|
|
|
|
_ => try!(word(&mut self.s, "..")),
|
|
|
|
}
|
|
|
|
if !after.is_empty() { try!(self.word_space(",")); }
|
|
|
|
}
|
|
|
|
try!(self.commasep(Inconsistent,
|
|
|
|
after.as_slice(),
|
2014-05-16 07:16:13 +00:00
|
|
|
|s, p| s.print_pat(&**p)));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "]"));
|
|
|
|
}
|
2014-05-19 20:29:41 +00:00
|
|
|
ast::PatMac(ref m) => try!(self.print_mac(m)),
|
2013-02-26 18:58:46 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
self.ann.post(self, NodePat(pat))
|
2013-12-27 22:11:01 +00:00
|
|
|
}
|
2011-03-04 06:22:43 +00:00
|
|
|
|
2014-07-28 01:05:07 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
// Returns whether it printed anything
|
|
|
|
fn print_explicit_self(&mut self,
|
2014-09-13 16:06:01 +00:00
|
|
|
explicit_self: &ast::ExplicitSelf_,
|
2014-03-16 18:58:11 +00:00
|
|
|
mutbl: ast::Mutability) -> IoResult<bool> {
|
|
|
|
try!(self.print_mutability(mutbl));
|
2014-09-13 16:06:01 +00:00
|
|
|
match *explicit_self {
|
2014-03-16 18:58:11 +00:00
|
|
|
ast::SelfStatic => { return Ok(false); }
|
2014-07-06 22:10:57 +00:00
|
|
|
ast::SelfValue(_) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "self"));
|
|
|
|
}
|
2014-07-06 22:10:57 +00:00
|
|
|
ast::SelfRegion(ref lt, m, _) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "&"));
|
|
|
|
try!(self.print_opt_lifetime(lt));
|
|
|
|
try!(self.print_mutability(m));
|
|
|
|
try!(word(&mut self.s, "self"));
|
|
|
|
}
|
2014-05-06 23:37:32 +00:00
|
|
|
ast::SelfExplicit(ref typ, _) => {
|
|
|
|
try!(word(&mut self.s, "self"));
|
|
|
|
try!(self.word_space(":"));
|
2014-07-07 23:35:15 +00:00
|
|
|
try!(self.print_type(&**typ));
|
2014-05-06 23:37:32 +00:00
|
|
|
}
|
2013-03-10 00:43:53 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
return Ok(true);
|
2012-08-17 23:14:57 +00:00
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_fn(&mut self,
|
|
|
|
decl: &ast::FnDecl,
|
2014-04-07 01:04:40 +00:00
|
|
|
fn_style: Option<ast::FnStyle>,
|
2014-04-02 08:19:41 +00:00
|
|
|
abi: abi::Abi,
|
2014-03-16 18:58:11 +00:00
|
|
|
name: ast::Ident,
|
|
|
|
generics: &ast::Generics,
|
2014-09-13 16:06:01 +00:00
|
|
|
opt_explicit_self: Option<&ast::ExplicitSelf_>,
|
2014-03-16 18:58:11 +00:00
|
|
|
vis: ast::Visibility) -> IoResult<()> {
|
|
|
|
try!(self.head(""));
|
2014-04-09 12:33:42 +00:00
|
|
|
try!(self.print_fn_header_info(opt_explicit_self, fn_style, abi, vis));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.nbsp());
|
|
|
|
try!(self.print_ident(name));
|
|
|
|
try!(self.print_generics(generics));
|
2014-08-11 16:32:26 +00:00
|
|
|
try!(self.print_fn_args_and_ret(decl, opt_explicit_self))
|
|
|
|
self.print_where_clause(generics)
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_fn_args(&mut self, decl: &ast::FnDecl,
|
2014-09-13 16:06:01 +00:00
|
|
|
opt_explicit_self: Option<&ast::ExplicitSelf_>)
|
2014-03-16 18:58:11 +00:00
|
|
|
-> IoResult<()> {
|
|
|
|
// It is unfortunate to duplicate the commasep logic, but we want the
|
|
|
|
// self type and the args all in the same box.
|
|
|
|
try!(self.rbox(0u, Inconsistent));
|
|
|
|
let mut first = true;
|
|
|
|
for &explicit_self in opt_explicit_self.iter() {
|
|
|
|
let m = match explicit_self {
|
2014-09-13 16:06:01 +00:00
|
|
|
&ast::SelfStatic => ast::MutImmutable,
|
2014-10-15 06:05:01 +00:00
|
|
|
_ => match decl.inputs[0].pat.node {
|
2014-03-16 18:58:11 +00:00
|
|
|
ast::PatIdent(ast::BindByValue(m), _, _) => m,
|
|
|
|
_ => ast::MutImmutable
|
|
|
|
}
|
|
|
|
};
|
|
|
|
first = !try!(self.print_explicit_self(explicit_self, m));
|
|
|
|
}
|
2011-06-14 13:20:04 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
// HACK(eddyb) ignore the separately printed self argument.
|
|
|
|
let args = if first {
|
|
|
|
decl.inputs.as_slice()
|
|
|
|
} else {
|
|
|
|
decl.inputs.slice_from(1)
|
2014-01-27 12:18:36 +00:00
|
|
|
};
|
2012-08-17 23:14:57 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
for arg in args.iter() {
|
|
|
|
if first { first = false; } else { try!(self.word_space(",")); }
|
|
|
|
try!(self.print_arg(arg));
|
|
|
|
}
|
2014-01-27 12:18:36 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
self.end()
|
2011-12-30 21:32:42 +00:00
|
|
|
}
|
2012-08-17 23:14:57 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl,
|
2014-09-13 16:06:01 +00:00
|
|
|
opt_explicit_self: Option<&ast::ExplicitSelf_>)
|
2014-03-16 18:58:11 +00:00
|
|
|
-> IoResult<()> {
|
|
|
|
try!(self.popen());
|
|
|
|
try!(self.print_fn_args(decl, opt_explicit_self));
|
|
|
|
if decl.variadic {
|
|
|
|
try!(word(&mut self.s, ", ..."));
|
|
|
|
}
|
|
|
|
try!(self.pclose());
|
2011-12-30 21:32:42 +00:00
|
|
|
|
2014-11-09 15:14:15 +00:00
|
|
|
self.print_fn_output(decl)
|
2013-10-25 05:56:34 +00:00
|
|
|
}
|
2012-02-22 10:16:25 +00:00
|
|
|
|
2014-07-30 05:08:39 +00:00
|
|
|
pub fn print_fn_block_args(
|
|
|
|
&mut self,
|
|
|
|
decl: &ast::FnDecl,
|
|
|
|
unboxed_closure_kind: Option<UnboxedClosureKind>)
|
|
|
|
-> IoResult<()> {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "|"));
|
2014-07-30 05:08:39 +00:00
|
|
|
match unboxed_closure_kind {
|
|
|
|
None => {}
|
|
|
|
Some(FnUnboxedClosureKind) => try!(self.word_space("&:")),
|
|
|
|
Some(FnMutUnboxedClosureKind) => try!(self.word_space("&mut:")),
|
|
|
|
Some(FnOnceUnboxedClosureKind) => try!(self.word_space(":")),
|
2014-05-29 05:26:56 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.print_fn_args(decl, None));
|
|
|
|
try!(word(&mut self.s, "|"));
|
|
|
|
|
2014-11-09 15:14:15 +00:00
|
|
|
if let ast::Return(ref ty) = decl.output {
|
|
|
|
if ty.node == ast::TyInfer {
|
|
|
|
return self.maybe_print_comment(ty.span.lo);
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2012-09-08 01:53:14 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
|
2014-11-09 15:14:15 +00:00
|
|
|
try!(self.space_if_not_bol());
|
|
|
|
try!(self.word_space("->"));
|
|
|
|
match decl.output {
|
|
|
|
ast::Return(ref ty) => {
|
|
|
|
try!(self.print_type(&**ty));
|
|
|
|
self.maybe_print_comment(ty.span.lo)
|
|
|
|
}
|
|
|
|
ast::NoReturn(span) => {
|
|
|
|
try!(self.word_nbsp("!"));
|
|
|
|
self.maybe_print_comment(span.lo)
|
|
|
|
}
|
|
|
|
}
|
2011-03-24 15:33:20 +00:00
|
|
|
}
|
2011-03-04 06:22:43 +00:00
|
|
|
|
2014-07-23 19:43:29 +00:00
|
|
|
pub fn print_capture_clause(&mut self, capture_clause: ast::CaptureClause)
|
|
|
|
-> IoResult<()> {
|
|
|
|
match capture_clause {
|
2014-09-24 17:58:53 +00:00
|
|
|
ast::CaptureByValue => self.word_space("move"),
|
|
|
|
ast::CaptureByRef => Ok(()),
|
2014-07-23 19:43:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_proc_args(&mut self, decl: &ast::FnDecl) -> IoResult<()> {
|
|
|
|
try!(word(&mut self.s, "proc"));
|
|
|
|
try!(word(&mut self.s, "("));
|
|
|
|
try!(self.print_fn_args(decl, None));
|
|
|
|
try!(word(&mut self.s, ")"));
|
2012-09-08 01:53:14 +00:00
|
|
|
|
2014-11-09 15:14:15 +00:00
|
|
|
if let ast::Return(ref ty) = decl.output {
|
|
|
|
if ty.node == ast::TyInfer {
|
|
|
|
return self.maybe_print_comment(ty.span.lo);
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2012-09-08 01:53:14 +00:00
|
|
|
}
|
|
|
|
|
2014-11-09 15:14:15 +00:00
|
|
|
try!(self.space_if_not_bol());
|
|
|
|
try!(self.word_space("->"));
|
|
|
|
match decl.output {
|
|
|
|
ast::Return(ref ty) => {
|
|
|
|
try!(self.print_type(&**ty));
|
|
|
|
self.maybe_print_comment(ty.span.lo)
|
|
|
|
}
|
|
|
|
ast::NoReturn(span) => {
|
|
|
|
try!(self.word_nbsp("!"));
|
|
|
|
self.maybe_print_comment(span.lo)
|
|
|
|
}
|
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2011-08-15 21:42:33 +00:00
|
|
|
|
2014-04-02 16:47:11 +00:00
|
|
|
pub fn print_bounds(&mut self,
|
2014-08-28 01:46:52 +00:00
|
|
|
prefix: &str,
|
|
|
|
bounds: &OwnedSlice<ast::TyParamBound>)
|
2014-06-11 19:14:38 +00:00
|
|
|
-> IoResult<()> {
|
2014-08-28 01:46:52 +00:00
|
|
|
if !bounds.is_empty() {
|
|
|
|
try!(word(&mut self.s, prefix));
|
2014-03-16 18:58:11 +00:00
|
|
|
let mut first = true;
|
|
|
|
for bound in bounds.iter() {
|
|
|
|
try!(self.nbsp());
|
|
|
|
if first {
|
|
|
|
first = false;
|
|
|
|
} else {
|
|
|
|
try!(self.word_space("+"));
|
|
|
|
}
|
2013-10-28 22:22:49 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(match *bound {
|
2014-08-28 01:46:52 +00:00
|
|
|
TraitTyParamBound(ref tref) => {
|
2014-11-07 11:53:45 +00:00
|
|
|
self.print_poly_trait_ref(tref)
|
2014-08-28 01:46:52 +00:00
|
|
|
}
|
|
|
|
RegionTyParamBound(ref lt) => {
|
|
|
|
self.print_lifetime(lt)
|
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
} else {
|
|
|
|
Ok(())
|
2013-10-28 22:22:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_lifetime(&mut self,
|
2014-08-06 02:59:24 +00:00
|
|
|
lifetime: &ast::Lifetime)
|
|
|
|
-> IoResult<()>
|
|
|
|
{
|
2014-03-16 18:58:11 +00:00
|
|
|
self.print_name(lifetime.name)
|
|
|
|
}
|
2013-10-28 22:22:49 +00:00
|
|
|
|
2014-08-06 02:59:24 +00:00
|
|
|
pub fn print_lifetime_def(&mut self,
|
|
|
|
lifetime: &ast::LifetimeDef)
|
|
|
|
-> IoResult<()>
|
|
|
|
{
|
|
|
|
try!(self.print_lifetime(&lifetime.lifetime));
|
|
|
|
let mut sep = ":";
|
|
|
|
for v in lifetime.bounds.iter() {
|
|
|
|
try!(word(&mut self.s, sep));
|
|
|
|
try!(self.print_lifetime(v));
|
|
|
|
sep = "+";
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2014-08-28 01:46:52 +00:00
|
|
|
pub fn print_generics(&mut self,
|
|
|
|
generics: &ast::Generics)
|
|
|
|
-> IoResult<()>
|
|
|
|
{
|
|
|
|
let total = generics.lifetimes.len() + generics.ty_params.len();
|
|
|
|
if total == 0 {
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
|
|
|
|
try!(word(&mut self.s, "<"));
|
|
|
|
|
2014-08-11 16:32:26 +00:00
|
|
|
let mut ints = Vec::new();
|
|
|
|
for i in range(0u, total) {
|
|
|
|
ints.push(i);
|
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
|
2014-08-28 01:46:52 +00:00
|
|
|
try!(self.commasep(Inconsistent, ints.as_slice(), |s, &idx| {
|
|
|
|
if idx < generics.lifetimes.len() {
|
2014-10-15 06:05:01 +00:00
|
|
|
let lifetime = &generics.lifetimes[idx];
|
2014-08-11 16:32:26 +00:00
|
|
|
s.print_lifetime_def(lifetime)
|
|
|
|
} else {
|
2014-08-28 01:46:52 +00:00
|
|
|
let idx = idx - generics.lifetimes.len();
|
|
|
|
let param = generics.ty_params.get(idx);
|
2014-10-28 18:48:52 +00:00
|
|
|
s.print_ty_param(param)
|
2014-08-11 16:32:26 +00:00
|
|
|
}
|
2014-08-28 01:46:52 +00:00
|
|
|
}));
|
2014-08-11 16:32:26 +00:00
|
|
|
|
2014-08-28 01:46:52 +00:00
|
|
|
try!(word(&mut self.s, ">"));
|
|
|
|
Ok(())
|
2011-08-03 04:26:54 +00:00
|
|
|
}
|
|
|
|
|
2014-10-28 18:48:52 +00:00
|
|
|
pub fn print_ty_param(&mut self, param: &ast::TyParam) -> IoResult<()> {
|
|
|
|
match param.unbound {
|
2014-11-07 11:53:45 +00:00
|
|
|
Some(ref tref) => {
|
2014-10-28 18:48:52 +00:00
|
|
|
try!(self.print_trait_ref(tref));
|
|
|
|
try!(self.word_space("?"));
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
try!(self.print_ident(param.ident));
|
|
|
|
try!(self.print_bounds(":", ¶m.bounds));
|
|
|
|
match param.default {
|
|
|
|
Some(ref default) => {
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.word_space("="));
|
|
|
|
self.print_type(&**default)
|
|
|
|
}
|
|
|
|
_ => Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-11 16:32:26 +00:00
|
|
|
pub fn print_where_clause(&mut self, generics: &ast::Generics)
|
|
|
|
-> IoResult<()> {
|
|
|
|
if generics.where_clause.predicates.len() == 0 {
|
|
|
|
return Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
try!(self.word_space("where"));
|
|
|
|
|
|
|
|
for (i, predicate) in generics.where_clause
|
|
|
|
.predicates
|
|
|
|
.iter()
|
|
|
|
.enumerate() {
|
|
|
|
if i != 0 {
|
|
|
|
try!(self.word_space(","));
|
|
|
|
}
|
|
|
|
|
|
|
|
try!(self.print_ident(predicate.ident));
|
2014-08-28 01:46:52 +00:00
|
|
|
try!(self.print_bounds(":", &predicate.bounds));
|
2014-08-11 16:32:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_meta_item(&mut self, item: &ast::MetaItem) -> IoResult<()> {
|
|
|
|
try!(self.ibox(indent_unit));
|
|
|
|
match item.node {
|
|
|
|
ast::MetaWord(ref name) => {
|
|
|
|
try!(word(&mut self.s, name.get()));
|
|
|
|
}
|
|
|
|
ast::MetaNameValue(ref name, ref value) => {
|
|
|
|
try!(self.word_space(name.get()));
|
|
|
|
try!(self.word_space("="));
|
|
|
|
try!(self.print_literal(value));
|
|
|
|
}
|
|
|
|
ast::MetaList(ref name, ref items) => {
|
|
|
|
try!(word(&mut self.s, name.get()));
|
|
|
|
try!(self.popen());
|
|
|
|
try!(self.commasep(Consistent,
|
|
|
|
items.as_slice(),
|
2014-05-16 07:16:13 +00:00
|
|
|
|s, i| s.print_meta_item(&**i)));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.pclose());
|
2013-02-15 05:50:03 +00:00
|
|
|
}
|
2011-07-28 17:22:59 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
self.end()
|
|
|
|
}
|
2013-02-15 05:50:03 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> IoResult<()> {
|
|
|
|
match vp.node {
|
|
|
|
ast::ViewPathSimple(ident, ref path, _) => {
|
2014-08-13 02:25:05 +00:00
|
|
|
try!(self.print_path(path, false));
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
// FIXME(#6993) can't compare identifiers directly here
|
2014-08-13 02:25:05 +00:00
|
|
|
if path.segments.last().unwrap().identifier.name !=
|
|
|
|
ident.name {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(space(&mut self.s));
|
2014-08-13 02:25:05 +00:00
|
|
|
try!(self.word_space("as"));
|
|
|
|
try!(self.print_ident(ident));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-08-13 02:25:05 +00:00
|
|
|
|
|
|
|
Ok(())
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2013-02-15 05:50:03 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
ast::ViewPathGlob(ref path, _) => {
|
|
|
|
try!(self.print_path(path, false));
|
|
|
|
word(&mut self.s, "::*")
|
|
|
|
}
|
2011-03-04 06:22:43 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
ast::ViewPathList(ref path, ref idents, _) => {
|
|
|
|
if path.segments.is_empty() {
|
|
|
|
try!(word(&mut self.s, "{"));
|
|
|
|
} else {
|
|
|
|
try!(self.print_path(path, false));
|
|
|
|
try!(word(&mut self.s, "::{"));
|
|
|
|
}
|
|
|
|
try!(self.commasep(Inconsistent, idents.as_slice(), |s, w| {
|
2014-07-17 22:56:56 +00:00
|
|
|
match w.node {
|
|
|
|
ast::PathListIdent { name, .. } => {
|
|
|
|
s.print_ident(name)
|
|
|
|
},
|
|
|
|
ast::PathListMod { .. } => {
|
|
|
|
word(&mut s.s, "mod")
|
|
|
|
}
|
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
}));
|
|
|
|
word(&mut self.s, "}")
|
|
|
|
}
|
2014-02-01 19:24:42 +00:00
|
|
|
}
|
2011-06-21 21:23:16 +00:00
|
|
|
}
|
2011-06-15 01:53:12 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_view_item(&mut self, item: &ast::ViewItem) -> IoResult<()> {
|
|
|
|
try!(self.hardbreak_if_not_bol());
|
|
|
|
try!(self.maybe_print_comment(item.span.lo));
|
|
|
|
try!(self.print_outer_attributes(item.attrs.as_slice()));
|
|
|
|
try!(self.print_visibility(item.vis));
|
|
|
|
match item.node {
|
|
|
|
ast::ViewItemExternCrate(id, ref optional_path, _) => {
|
|
|
|
try!(self.head("extern crate"));
|
|
|
|
for &(ref p, style) in optional_path.iter() {
|
2014-08-23 04:02:00 +00:00
|
|
|
try!(self.print_string(p.get(), style));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(space(&mut self.s));
|
2014-08-23 04:02:00 +00:00
|
|
|
try!(word(&mut self.s, "as"));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(space(&mut self.s));
|
|
|
|
}
|
2014-08-23 04:02:00 +00:00
|
|
|
try!(self.print_ident(id));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2012-02-18 07:05:20 +00:00
|
|
|
|
2014-04-26 13:33:45 +00:00
|
|
|
ast::ViewItemUse(ref vp) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.head("use"));
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_view_path(&**vp));
|
2013-07-31 20:47:32 +00:00
|
|
|
}
|
2011-03-24 15:33:20 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, ";"));
|
|
|
|
try!(self.end()); // end inner head-block
|
|
|
|
self.end() // end outer head-block
|
|
|
|
}
|
2012-02-18 07:05:20 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_mutability(&mut self,
|
|
|
|
mutbl: ast::Mutability) -> IoResult<()> {
|
|
|
|
match mutbl {
|
|
|
|
ast::MutMutable => self.word_nbsp("mut"),
|
|
|
|
ast::MutImmutable => Ok(()),
|
2013-01-31 01:20:02 +00:00
|
|
|
}
|
2011-03-04 06:22:43 +00:00
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_mt(&mut self, mt: &ast::MutTy) -> IoResult<()> {
|
|
|
|
try!(self.print_mutability(mt.mutbl));
|
2014-05-16 07:16:13 +00:00
|
|
|
self.print_type(&*mt.ty)
|
2011-03-24 15:33:20 +00:00
|
|
|
}
|
2011-03-04 06:22:43 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_arg(&mut self, input: &ast::Arg) -> IoResult<()> {
|
|
|
|
try!(self.ibox(indent_unit));
|
|
|
|
match input.ty.node {
|
2014-05-16 07:16:13 +00:00
|
|
|
ast::TyInfer => try!(self.print_pat(&*input.pat)),
|
2014-03-16 18:58:11 +00:00
|
|
|
_ => {
|
|
|
|
match input.pat.node {
|
2014-07-01 01:02:14 +00:00
|
|
|
ast::PatIdent(_, ref path1, _) if
|
|
|
|
path1.node.name ==
|
2014-03-16 18:58:11 +00:00
|
|
|
parse::token::special_idents::invalid.name => {
|
|
|
|
// Do nothing.
|
|
|
|
}
|
|
|
|
_ => {
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_pat(&*input.pat));
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, ":"));
|
|
|
|
try!(space(&mut self.s));
|
|
|
|
}
|
2014-01-09 13:05:33 +00:00
|
|
|
}
|
2014-05-16 07:16:13 +00:00
|
|
|
try!(self.print_type(&*input.ty));
|
2012-11-07 02:41:06 +00:00
|
|
|
}
|
2012-05-04 19:33:04 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
self.end()
|
|
|
|
}
|
|
|
|
|
2014-09-06 04:27:47 +00:00
|
|
|
pub fn print_fn_output(&mut self, decl: &ast::FnDecl) -> IoResult<()> {
|
2014-11-09 15:14:15 +00:00
|
|
|
if let ast::Return(ref ty) = decl.output {
|
|
|
|
match ty.node {
|
|
|
|
ast::TyTup(ref tys) if tys.is_empty() => {
|
|
|
|
return self.maybe_print_comment(ty.span.lo);
|
2014-09-06 04:27:47 +00:00
|
|
|
}
|
2014-11-09 15:14:15 +00:00
|
|
|
_ => ()
|
2014-09-06 04:27:47 +00:00
|
|
|
}
|
|
|
|
}
|
2014-11-09 15:14:15 +00:00
|
|
|
|
|
|
|
try!(self.space_if_not_bol());
|
|
|
|
try!(self.ibox(indent_unit));
|
|
|
|
try!(self.word_space("->"));
|
|
|
|
match decl.output {
|
|
|
|
ast::NoReturn(_) =>
|
|
|
|
try!(self.word_nbsp("!")),
|
|
|
|
ast::Return(ref ty) =>
|
|
|
|
try!(self.print_type(&**ty))
|
|
|
|
}
|
|
|
|
try!(self.end());
|
|
|
|
|
|
|
|
match decl.output {
|
|
|
|
ast::Return(ref output) => self.maybe_print_comment(output.span.lo),
|
|
|
|
_ => Ok(())
|
|
|
|
}
|
2014-09-06 04:27:47 +00:00
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_ty_fn(&mut self,
|
2014-04-02 08:19:41 +00:00
|
|
|
opt_abi: Option<abi::Abi>,
|
2014-04-09 12:33:42 +00:00
|
|
|
opt_sigil: Option<char>,
|
2014-04-07 01:04:40 +00:00
|
|
|
fn_style: ast::FnStyle,
|
2014-03-16 18:58:11 +00:00
|
|
|
onceness: ast::Onceness,
|
|
|
|
decl: &ast::FnDecl,
|
|
|
|
id: Option<ast::Ident>,
|
2014-08-28 01:46:52 +00:00
|
|
|
bounds: &OwnedSlice<ast::TyParamBound>,
|
2014-03-16 18:58:11 +00:00
|
|
|
generics: Option<&ast::Generics>,
|
2014-11-04 21:25:15 +00:00
|
|
|
opt_explicit_self: Option<&ast::ExplicitSelf_>)
|
2014-06-02 01:41:46 +00:00
|
|
|
-> IoResult<()> {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.ibox(indent_unit));
|
|
|
|
|
|
|
|
// Duplicates the logic in `print_fn_header_info()`. This is because that
|
|
|
|
// function prints the sigil in the wrong place. That should be fixed.
|
2014-04-09 12:33:42 +00:00
|
|
|
if opt_sigil == Some('~') && onceness == ast::Once {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "proc"));
|
2014-04-09 12:33:42 +00:00
|
|
|
} else if opt_sigil == Some('&') {
|
2014-04-07 01:04:40 +00:00
|
|
|
try!(self.print_fn_style(fn_style));
|
2014-05-09 23:30:57 +00:00
|
|
|
try!(self.print_extern_opt_abi(opt_abi));
|
2014-03-16 18:58:11 +00:00
|
|
|
} else {
|
2014-04-09 12:33:42 +00:00
|
|
|
assert!(opt_sigil.is_none());
|
2014-04-07 01:04:40 +00:00
|
|
|
try!(self.print_fn_style(fn_style));
|
2014-05-09 23:30:57 +00:00
|
|
|
try!(self.print_opt_abi_and_extern_if_nondefault(opt_abi));
|
2014-11-04 21:25:15 +00:00
|
|
|
try!(word(&mut self.s, "fn"));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
match id {
|
|
|
|
Some(id) => {
|
|
|
|
try!(word(&mut self.s, " "));
|
|
|
|
try!(self.print_ident(id));
|
|
|
|
}
|
|
|
|
_ => ()
|
|
|
|
}
|
2012-05-04 19:33:04 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
match generics { Some(g) => try!(self.print_generics(g)), _ => () }
|
|
|
|
try!(zerobreak(&mut self.s));
|
2012-09-08 01:53:14 +00:00
|
|
|
|
2014-11-04 21:25:15 +00:00
|
|
|
if opt_sigil == Some('&') {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "|"));
|
|
|
|
} else {
|
|
|
|
try!(self.popen());
|
|
|
|
}
|
|
|
|
|
|
|
|
try!(self.print_fn_args(decl, opt_explicit_self));
|
|
|
|
|
2014-11-04 21:25:15 +00:00
|
|
|
if opt_sigil == Some('&') {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(word(&mut self.s, "|"));
|
|
|
|
} else {
|
|
|
|
if decl.variadic {
|
|
|
|
try!(word(&mut self.s, ", ..."));
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.pclose());
|
2012-09-08 01:53:14 +00:00
|
|
|
}
|
|
|
|
|
2014-08-28 01:46:52 +00:00
|
|
|
try!(self.print_bounds(":", bounds));
|
2014-04-02 16:47:11 +00:00
|
|
|
|
2014-09-06 04:27:47 +00:00
|
|
|
try!(self.print_fn_output(decl));
|
2011-03-24 15:33:20 +00:00
|
|
|
|
2014-08-11 16:32:26 +00:00
|
|
|
match generics {
|
|
|
|
Some(generics) => try!(self.print_where_clause(generics)),
|
|
|
|
None => {}
|
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
self.end()
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
|
|
|
|
pub fn maybe_print_trailing_comment(&mut self, span: codemap::Span,
|
|
|
|
next_pos: Option<BytePos>)
|
|
|
|
-> IoResult<()> {
|
|
|
|
let cm = match self.cm {
|
|
|
|
Some(cm) => cm,
|
|
|
|
_ => return Ok(())
|
|
|
|
};
|
|
|
|
match self.next_comment() {
|
2014-01-30 01:39:21 +00:00
|
|
|
Some(ref cmnt) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
if (*cmnt).style != comments::Trailing { return Ok(()) }
|
|
|
|
let span_line = cm.lookup_char_pos(span.hi);
|
|
|
|
let comment_line = cm.lookup_char_pos((*cmnt).pos);
|
|
|
|
let mut next = (*cmnt).pos + BytePos(1);
|
|
|
|
match next_pos { None => (), Some(p) => next = p }
|
|
|
|
if span.hi < (*cmnt).pos && (*cmnt).pos < next &&
|
|
|
|
span_line.line == comment_line.line {
|
|
|
|
try!(self.print_comment(cmnt));
|
|
|
|
self.cur_cmnt_and_lit.cur_cmnt += 1u;
|
|
|
|
}
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
_ => ()
|
2011-03-24 15:33:20 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
Ok(())
|
2011-03-24 15:33:20 +00:00
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_remaining_comments(&mut self) -> IoResult<()> {
|
|
|
|
// If there aren't any remaining comments, then we need to manually
|
|
|
|
// make sure there is a line break at the end.
|
|
|
|
if self.next_comment().is_none() {
|
|
|
|
try!(hardbreak(&mut self.s));
|
|
|
|
}
|
|
|
|
loop {
|
|
|
|
match self.next_comment() {
|
|
|
|
Some(ref cmnt) => {
|
|
|
|
try!(self.print_comment(cmnt));
|
|
|
|
self.cur_cmnt_and_lit.cur_cmnt += 1u;
|
|
|
|
}
|
|
|
|
_ => break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
2011-07-05 09:48:19 +00:00
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_literal(&mut self, lit: &ast::Lit) -> IoResult<()> {
|
|
|
|
try!(self.maybe_print_comment(lit.span.lo));
|
|
|
|
match self.next_lit(lit.span.lo) {
|
|
|
|
Some(ref ltrl) => {
|
2014-05-07 23:33:43 +00:00
|
|
|
return word(&mut self.s, (*ltrl).lit.as_slice());
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
_ => ()
|
|
|
|
}
|
|
|
|
match lit.node {
|
|
|
|
ast::LitStr(ref st, style) => self.print_string(st.get(), style),
|
2014-06-06 15:04:04 +00:00
|
|
|
ast::LitByte(byte) => {
|
|
|
|
let mut res = String::from_str("b'");
|
2014-10-27 16:13:51 +00:00
|
|
|
ascii::escape_default(byte, |c| res.push(c as char));
|
2014-10-15 06:05:01 +00:00
|
|
|
res.push('\'');
|
2014-06-06 15:04:04 +00:00
|
|
|
word(&mut self.s, res.as_slice())
|
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
ast::LitChar(ch) => {
|
2014-05-22 23:57:53 +00:00
|
|
|
let mut res = String::from_str("'");
|
2014-10-15 06:05:01 +00:00
|
|
|
ch.escape_default(|c| res.push(c));
|
|
|
|
res.push('\'');
|
2014-05-20 00:23:26 +00:00
|
|
|
word(&mut self.s, res.as_slice())
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
ast::LitInt(i, t) => {
|
2014-08-05 07:59:03 +00:00
|
|
|
match t {
|
|
|
|
ast::SignedIntLit(st, ast::Plus) => {
|
|
|
|
word(&mut self.s,
|
|
|
|
ast_util::int_ty_to_string(st, Some(i as i64)).as_slice())
|
|
|
|
}
|
|
|
|
ast::SignedIntLit(st, ast::Minus) => {
|
2014-10-19 15:39:39 +00:00
|
|
|
let istr = ast_util::int_ty_to_string(st, Some(-(i as i64)));
|
2014-08-05 07:59:03 +00:00
|
|
|
word(&mut self.s,
|
2014-10-19 15:39:39 +00:00
|
|
|
format!("-{}", istr).as_slice())
|
2014-08-05 07:59:03 +00:00
|
|
|
}
|
|
|
|
ast::UnsignedIntLit(ut) => {
|
|
|
|
word(&mut self.s, ast_util::uint_ty_to_string(ut, Some(i)).as_slice())
|
|
|
|
}
|
|
|
|
ast::UnsuffixedIntLit(ast::Plus) => {
|
|
|
|
word(&mut self.s, format!("{}", i).as_slice())
|
|
|
|
}
|
|
|
|
ast::UnsuffixedIntLit(ast::Minus) => {
|
|
|
|
word(&mut self.s, format!("-{}", i).as_slice())
|
|
|
|
}
|
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
ast::LitFloat(ref f, t) => {
|
2014-05-07 23:33:43 +00:00
|
|
|
word(&mut self.s,
|
2014-05-20 06:19:56 +00:00
|
|
|
format!(
|
|
|
|
"{}{}",
|
|
|
|
f.get(),
|
2014-06-21 10:39:03 +00:00
|
|
|
ast_util::float_ty_to_string(t).as_slice()).as_slice())
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
ast::LitFloatUnsuffixed(ref f) => word(&mut self.s, f.get()),
|
|
|
|
ast::LitBool(val) => {
|
|
|
|
if val { word(&mut self.s, "true") } else { word(&mut self.s, "false") }
|
|
|
|
}
|
2014-06-07 14:32:01 +00:00
|
|
|
ast::LitBinary(ref v) => {
|
2014-10-27 16:13:51 +00:00
|
|
|
let mut escaped: String = String::new();
|
|
|
|
for &ch in v.iter() {
|
|
|
|
ascii::escape_default(ch as u8,
|
|
|
|
|ch| escaped.push(ch as char));
|
|
|
|
}
|
|
|
|
word(&mut self.s, format!("b\"{}\"", escaped).as_slice())
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2012-01-16 09:50:34 +00:00
|
|
|
}
|
2011-07-05 09:48:19 +00:00
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn next_lit(&mut self, pos: BytePos) -> Option<comments::Literal> {
|
|
|
|
match self.literals {
|
|
|
|
Some(ref lits) => {
|
|
|
|
while self.cur_cmnt_and_lit.cur_lit < lits.len() {
|
2014-10-15 06:05:01 +00:00
|
|
|
let ltrl = (*lits)[self.cur_cmnt_and_lit.cur_lit].clone();
|
2014-03-16 18:58:11 +00:00
|
|
|
if ltrl.pos > pos { return None; }
|
|
|
|
self.cur_cmnt_and_lit.cur_lit += 1u;
|
|
|
|
if ltrl.pos == pos { return Some(ltrl); }
|
|
|
|
}
|
|
|
|
None
|
|
|
|
}
|
|
|
|
_ => None
|
2011-07-05 09:48:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn maybe_print_comment(&mut self, pos: BytePos) -> IoResult<()> {
|
|
|
|
loop {
|
|
|
|
match self.next_comment() {
|
|
|
|
Some(ref cmnt) => {
|
|
|
|
if (*cmnt).pos < pos {
|
|
|
|
try!(self.print_comment(cmnt));
|
|
|
|
self.cur_cmnt_and_lit.cur_cmnt += 1u;
|
|
|
|
} else { break; }
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
_ => break
|
2011-08-19 02:19:38 +00:00
|
|
|
}
|
2011-07-05 09:48:19 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn print_comment(&mut self,
|
|
|
|
cmnt: &comments::Comment) -> IoResult<()> {
|
|
|
|
match cmnt.style {
|
|
|
|
comments::Mixed => {
|
|
|
|
assert_eq!(cmnt.lines.len(), 1u);
|
|
|
|
try!(zerobreak(&mut self.s));
|
2014-10-15 06:05:01 +00:00
|
|
|
try!(word(&mut self.s, cmnt.lines[0].as_slice()));
|
2014-03-16 18:58:11 +00:00
|
|
|
zerobreak(&mut self.s)
|
|
|
|
}
|
|
|
|
comments::Isolated => {
|
|
|
|
try!(self.hardbreak_if_not_bol());
|
2014-01-09 13:05:33 +00:00
|
|
|
for line in cmnt.lines.iter() {
|
2014-03-16 18:58:11 +00:00
|
|
|
// Don't print empty lines because they will end up as trailing
|
|
|
|
// whitespace
|
2014-01-30 01:39:21 +00:00
|
|
|
if !line.is_empty() {
|
2014-05-07 23:33:43 +00:00
|
|
|
try!(word(&mut self.s, line.as_slice()));
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(hardbreak(&mut self.s));
|
2014-01-09 13:05:33 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
Ok(())
|
2014-01-09 13:05:33 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
comments::Trailing => {
|
|
|
|
try!(word(&mut self.s, " "));
|
|
|
|
if cmnt.lines.len() == 1u {
|
2014-10-15 06:05:01 +00:00
|
|
|
try!(word(&mut self.s, cmnt.lines[0].as_slice()));
|
2014-03-16 18:58:11 +00:00
|
|
|
hardbreak(&mut self.s)
|
|
|
|
} else {
|
|
|
|
try!(self.ibox(0u));
|
|
|
|
for line in cmnt.lines.iter() {
|
|
|
|
if !line.is_empty() {
|
2014-05-07 23:33:43 +00:00
|
|
|
try!(word(&mut self.s, line.as_slice()));
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
try!(hardbreak(&mut self.s));
|
|
|
|
}
|
|
|
|
self.end()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
comments::BlankLine => {
|
|
|
|
// We need to do at least one, possibly two hardbreaks.
|
|
|
|
let is_semi = match self.s.last_token() {
|
2014-05-07 23:33:43 +00:00
|
|
|
pp::String(s, _) => ";" == s.as_slice(),
|
2014-03-16 18:58:11 +00:00
|
|
|
_ => false
|
|
|
|
};
|
|
|
|
if is_semi || self.is_begin() || self.is_end() {
|
|
|
|
try!(hardbreak(&mut self.s));
|
|
|
|
}
|
|
|
|
hardbreak(&mut self.s)
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
2014-01-09 13:05:33 +00:00
|
|
|
}
|
2011-07-05 09:48:19 +00:00
|
|
|
}
|
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_string(&mut self, st: &str,
|
|
|
|
style: ast::StrStyle) -> IoResult<()> {
|
|
|
|
let st = match style {
|
2014-05-16 17:45:16 +00:00
|
|
|
ast::CookedStr => {
|
|
|
|
(format!("\"{}\"", st.escape_default()))
|
|
|
|
}
|
|
|
|
ast::RawStr(n) => {
|
|
|
|
(format!("r{delim}\"{string}\"{delim}",
|
|
|
|
delim="#".repeat(n),
|
|
|
|
string=st))
|
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
};
|
2014-05-16 17:45:16 +00:00
|
|
|
word(&mut self.s, st.as_slice())
|
2013-12-27 22:28:54 +00:00
|
|
|
}
|
2011-07-05 09:48:19 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn next_comment(&mut self) -> Option<comments::Comment> {
|
|
|
|
match self.comments {
|
|
|
|
Some(ref cmnts) => {
|
|
|
|
if self.cur_cmnt_and_lit.cur_cmnt < cmnts.len() {
|
2014-10-15 06:05:01 +00:00
|
|
|
Some(cmnts[self.cur_cmnt_and_lit.cur_cmnt].clone())
|
2014-03-16 18:58:11 +00:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
2014-01-09 13:05:33 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
_ => None
|
2013-07-02 19:47:32 +00:00
|
|
|
}
|
2011-07-05 09:48:19 +00:00
|
|
|
}
|
|
|
|
|
2014-04-07 01:04:40 +00:00
|
|
|
pub fn print_opt_fn_style(&mut self,
|
|
|
|
opt_fn_style: Option<ast::FnStyle>) -> IoResult<()> {
|
|
|
|
match opt_fn_style {
|
|
|
|
Some(fn_style) => self.print_fn_style(fn_style),
|
2014-03-16 18:58:11 +00:00
|
|
|
None => Ok(())
|
2013-03-14 02:25:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-02 08:19:41 +00:00
|
|
|
pub fn print_opt_abi_and_extern_if_nondefault(&mut self,
|
|
|
|
opt_abi: Option<abi::Abi>)
|
2014-03-16 18:58:11 +00:00
|
|
|
-> IoResult<()> {
|
2014-04-02 08:19:41 +00:00
|
|
|
match opt_abi {
|
|
|
|
Some(abi::Rust) => Ok(()),
|
|
|
|
Some(abi) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.word_nbsp("extern"));
|
2014-06-21 10:39:03 +00:00
|
|
|
self.word_nbsp(abi.to_string().as_slice())
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2014-04-02 08:19:41 +00:00
|
|
|
None => Ok(())
|
2013-10-29 22:06:13 +00:00
|
|
|
}
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
2013-10-29 22:06:13 +00:00
|
|
|
|
2014-04-02 08:19:41 +00:00
|
|
|
pub fn print_extern_opt_abi(&mut self,
|
|
|
|
opt_abi: Option<abi::Abi>) -> IoResult<()> {
|
|
|
|
match opt_abi {
|
|
|
|
Some(abi) => {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.word_nbsp("extern"));
|
2014-06-21 10:39:03 +00:00
|
|
|
self.word_nbsp(abi.to_string().as_slice())
|
2014-03-16 18:58:11 +00:00
|
|
|
}
|
|
|
|
None => Ok(())
|
2013-03-14 02:25:28 +00:00
|
|
|
}
|
2014-01-30 01:39:21 +00:00
|
|
|
}
|
2013-02-01 01:12:29 +00:00
|
|
|
|
2014-03-16 18:58:11 +00:00
|
|
|
pub fn print_fn_header_info(&mut self,
|
2014-09-13 16:06:01 +00:00
|
|
|
_opt_explicit_self: Option<&ast::ExplicitSelf_>,
|
2014-04-07 01:04:40 +00:00
|
|
|
opt_fn_style: Option<ast::FnStyle>,
|
2014-04-02 08:19:41 +00:00
|
|
|
abi: abi::Abi,
|
2014-03-16 18:58:11 +00:00
|
|
|
vis: ast::Visibility) -> IoResult<()> {
|
2014-05-07 23:33:43 +00:00
|
|
|
try!(word(&mut self.s, visibility_qualified(vis, "").as_slice()));
|
2014-05-07 01:43:56 +00:00
|
|
|
try!(self.print_opt_fn_style(opt_fn_style));
|
2014-05-07 23:33:43 +00:00
|
|
|
|
2014-04-02 08:19:41 +00:00
|
|
|
if abi != abi::Rust {
|
2014-03-16 18:58:11 +00:00
|
|
|
try!(self.word_nbsp("extern"));
|
2014-06-21 10:39:03 +00:00
|
|
|
try!(self.word_nbsp(abi.to_string().as_slice()));
|
2013-03-14 02:25:28 +00:00
|
|
|
}
|
|
|
|
|
2014-04-09 12:33:42 +00:00
|
|
|
word(&mut self.s, "fn")
|
2012-05-25 06:44:58 +00:00
|
|
|
}
|
|
|
|
|
2014-04-07 01:04:40 +00:00
|
|
|
pub fn print_fn_style(&mut self, s: ast::FnStyle) -> IoResult<()> {
|
|
|
|
match s {
|
|
|
|
ast::NormalFn => Ok(()),
|
2014-03-16 18:58:11 +00:00
|
|
|
ast::UnsafeFn => self.word_nbsp("unsafe"),
|
|
|
|
}
|
2012-05-25 06:44:58 +00:00
|
|
|
}
|
2012-11-05 04:41:00 +00:00
|
|
|
}
|
|
|
|
|
2013-01-24 22:10:38 +00:00
|
|
|
#[cfg(test)]
|
2013-04-15 15:08:52 +00:00
|
|
|
mod test {
|
2013-02-25 19:11:21 +00:00
|
|
|
use super::*;
|
|
|
|
|
2013-01-24 22:10:38 +00:00
|
|
|
use ast;
|
|
|
|
use ast_util;
|
2013-02-25 19:11:21 +00:00
|
|
|
use codemap;
|
2013-06-04 19:34:25 +00:00
|
|
|
use parse::token;
|
2014-04-05 13:24:28 +00:00
|
|
|
use ptr::P;
|
2013-01-24 22:10:38 +00:00
|
|
|
|
|
|
|
#[test]
|
2014-06-21 10:39:03 +00:00
|
|
|
fn test_fun_to_string() {
|
2013-06-04 19:34:25 +00:00
|
|
|
let abba_ident = token::str_to_ident("abba");
|
2013-01-24 22:10:38 +00:00
|
|
|
|
2014-01-09 13:05:33 +00:00
|
|
|
let decl = ast::FnDecl {
|
2014-02-28 21:09:09 +00:00
|
|
|
inputs: Vec::new(),
|
2014-11-09 15:14:15 +00:00
|
|
|
output: ast::Return(P(ast::Ty {id: 0,
|
|
|
|
node: ast::TyTup(vec![]),
|
|
|
|
span: codemap::DUMMY_SP})),
|
2013-10-25 05:56:34 +00:00
|
|
|
variadic: false
|
2013-01-24 22:10:38 +00:00
|
|
|
};
|
2013-02-15 05:50:03 +00:00
|
|
|
let generics = ast_util::empty_generics();
|
2014-06-21 10:39:03 +00:00
|
|
|
assert_eq!(&fun_to_string(&decl, ast::NormalFn, abba_ident,
|
2014-02-14 05:07:09 +00:00
|
|
|
None, &generics),
|
2014-05-25 10:17:19 +00:00
|
|
|
&"fn abba()".to_string());
|
2013-01-24 22:10:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2014-06-21 10:39:03 +00:00
|
|
|
fn test_variant_to_string() {
|
2013-06-04 19:34:25 +00:00
|
|
|
let ident = token::str_to_ident("principal_skinner");
|
2013-01-24 22:10:38 +00:00
|
|
|
|
2014-01-09 13:05:33 +00:00
|
|
|
let var = codemap::respan(codemap::DUMMY_SP, ast::Variant_ {
|
2013-01-24 22:10:38 +00:00
|
|
|
name: ident,
|
2014-02-28 21:09:09 +00:00
|
|
|
attrs: Vec::new(),
|
2013-01-24 22:10:38 +00:00
|
|
|
// making this up as I go.... ?
|
2014-02-28 21:09:09 +00:00
|
|
|
kind: ast::TupleVariantKind(Vec::new()),
|
2013-01-24 22:10:38 +00:00
|
|
|
id: 0,
|
|
|
|
disr_expr: None,
|
2014-01-09 13:05:33 +00:00
|
|
|
vis: ast::Public,
|
2013-01-24 22:10:38 +00:00
|
|
|
});
|
|
|
|
|
2014-06-21 10:39:03 +00:00
|
|
|
let varstr = variant_to_string(&var);
|
2014-05-25 10:17:19 +00:00
|
|
|
assert_eq!(&varstr,&"pub principal_skinner".to_string());
|
2013-01-24 22:10:38 +00:00
|
|
|
}
|
2014-10-19 15:39:39 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_signed_int_to_string() {
|
|
|
|
let pos_int = ast::LitInt(42, ast::SignedIntLit(ast::TyI32, ast::Plus));
|
|
|
|
let neg_int = ast::LitInt((-42) as u64, ast::SignedIntLit(ast::TyI32, ast::Minus));
|
|
|
|
assert_eq!(format!("-{}", lit_to_string(&codemap::dummy_spanned(pos_int))),
|
|
|
|
lit_to_string(&codemap::dummy_spanned(neg_int)));
|
|
|
|
}
|
2013-01-24 22:10:38 +00:00
|
|
|
}
|