1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 pub use self::AnnNode
::*;
15 use ast
::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}
;
18 use owned_slice
::OwnedSlice
;
19 use attr
::{AttrMetaMethods, AttributeMethods}
;
20 use codemap
::{self, CodeMap, BytePos}
;
22 use parse
::token
::{self, BinOpToken, Token, InternedString}
;
23 use parse
::lexer
::comments
;
25 use print
::pp
::{self, break_offset, word, space, zerobreak, hardbreak}
;
26 use print
::pp
::{Breaks, eof}
;
27 use print
::pp
::Breaks
::{Consistent, Inconsistent}
;
32 use std
::io
::{self, Write, Read}
;
35 pub enum AnnNode
<'a
> {
36 NodeIdent(&'a ast
::Ident
),
37 NodeName(&'a ast
::Name
),
38 NodeBlock(&'a ast
::Block
),
39 NodeItem(&'a ast
::Item
),
40 NodeSubItem(ast
::NodeId
),
41 NodeExpr(&'a ast
::Expr
),
42 NodePat(&'a ast
::Pat
),
46 fn pre(&self, _state
: &mut State
, _node
: AnnNode
) -> io
::Result
<()> { Ok(()) }
47 fn post(&self, _state
: &mut State
, _node
: AnnNode
) -> io
::Result
<()> { Ok(()) }
50 #[derive(Copy, Clone)]
53 impl PpAnn
for NoAnn {}
55 #[derive(Copy, Clone)]
56 pub struct CurrentCommentAndLiteral
{
61 pub struct State
<'a
> {
62 pub s
: pp
::Printer
<'a
>,
63 cm
: Option
<&'a CodeMap
>,
64 comments
: Option
<Vec
<comments
::Comment
> >,
65 literals
: Option
<Vec
<comments
::Literal
> >,
66 cur_cmnt_and_lit
: CurrentCommentAndLiteral
,
67 boxes
: Vec
<pp
::Breaks
>,
71 pub fn rust_printer
<'a
>(writer
: Box
<Write
+'a
>) -> State
<'a
> {
72 static NO_ANN
: NoAnn
= NoAnn
;
73 rust_printer_annotated(writer
, &NO_ANN
)
76 pub fn rust_printer_annotated
<'a
>(writer
: Box
<Write
+'a
>,
77 ann
: &'a PpAnn
) -> State
<'a
> {
79 s
: pp
::mk_printer(writer
, default_columns
),
83 cur_cmnt_and_lit
: CurrentCommentAndLiteral
{
92 #[allow(non_upper_case_globals)]
93 pub const indent_unit
: usize = 4;
95 #[allow(non_upper_case_globals)]
96 pub const default_columns
: usize = 78;
98 /// Requires you to pass an input filename and reader so that
99 /// it can scan the input text for comments and literals to
101 pub fn print_crate
<'a
>(cm
: &'a CodeMap
,
102 span_diagnostic
: &diagnostic
::SpanHandler
,
108 is_expanded
: bool
) -> io
::Result
<()> {
109 let mut s
= State
::new_from_input(cm
,
116 if is_expanded
&& std_inject
::use_std(krate
) {
117 // We need to print `#![no_std]` (and its feature gate) so that
118 // compiling pretty-printed source won't inject libstd again.
119 // However we don't want these attributes in the AST because
120 // of the feature gate, so we fake them up here.
122 let no_std_meta
= attr
::mk_word_item(InternedString
::new("no_std"));
124 // #![feature(no_std)]
125 let fake_attr
= attr
::mk_attr_inner(attr
::mk_attr_id(),
126 attr
::mk_list_item(InternedString
::new("feature"),
127 vec
![no_std_meta
.clone()]));
128 try
!(s
.print_attribute(&fake_attr
));
131 let fake_attr
= attr
::mk_attr_inner(attr
::mk_attr_id(), no_std_meta
);
132 try
!(s
.print_attribute(&fake_attr
));
135 try
!(s
.print_mod(&krate
.module
, &krate
.attrs
));
136 try
!(s
.print_remaining_comments());
141 pub fn new_from_input(cm
: &'a CodeMap
,
142 span_diagnostic
: &diagnostic
::SpanHandler
,
147 is_expanded
: bool
) -> State
<'a
> {
148 let (cmnts
, lits
) = comments
::gather_comments_and_literals(
158 // If the code is post expansion, don't use the table of
159 // literals, since it doesn't correspond with the literals
160 // in the AST anymore.
161 if is_expanded { None }
else { Some(lits) }
)
164 pub fn new(cm
: &'a CodeMap
,
167 comments
: Option
<Vec
<comments
::Comment
>>,
168 literals
: Option
<Vec
<comments
::Literal
>>) -> State
<'a
> {
170 s
: pp
::mk_printer(out
, default_columns
),
174 cur_cmnt_and_lit
: CurrentCommentAndLiteral
{
184 pub fn to_string
<F
>(f
: F
) -> String
where
185 F
: FnOnce(&mut State
) -> io
::Result
<()>,
187 let mut wr
= Vec
::new();
189 let mut printer
= rust_printer(Box
::new(&mut wr
));
190 f(&mut printer
).unwrap();
191 eof(&mut printer
.s
).unwrap();
193 String
::from_utf8(wr
).unwrap()
196 pub fn binop_to_string(op
: BinOpToken
) -> &'
static str {
202 token
::Percent
=> "%",
211 pub fn token_to_string(tok
: &Token
) -> String
{
213 token
::Eq
=> "=".to_string(),
214 token
::Lt
=> "<".to_string(),
215 token
::Le
=> "<=".to_string(),
216 token
::EqEq
=> "==".to_string(),
217 token
::Ne
=> "!=".to_string(),
218 token
::Ge
=> ">=".to_string(),
219 token
::Gt
=> ">".to_string(),
220 token
::Not
=> "!".to_string(),
221 token
::Tilde
=> "~".to_string(),
222 token
::OrOr
=> "||".to_string(),
223 token
::AndAnd
=> "&&".to_string(),
224 token
::BinOp(op
) => binop_to_string(op
).to_string(),
225 token
::BinOpEq(op
) => format
!("{}=", binop_to_string(op
)),
227 /* Structural symbols */
228 token
::At
=> "@".to_string(),
229 token
::Dot
=> ".".to_string(),
230 token
::DotDot
=> "..".to_string(),
231 token
::DotDotDot
=> "...".to_string(),
232 token
::Comma
=> ",".to_string(),
233 token
::Semi
=> ";".to_string(),
234 token
::Colon
=> ":".to_string(),
235 token
::ModSep
=> "::".to_string(),
236 token
::RArrow
=> "->".to_string(),
237 token
::LArrow
=> "<-".to_string(),
238 token
::FatArrow
=> "=>".to_string(),
239 token
::OpenDelim(token
::Paren
) => "(".to_string(),
240 token
::CloseDelim(token
::Paren
) => ")".to_string(),
241 token
::OpenDelim(token
::Bracket
) => "[".to_string(),
242 token
::CloseDelim(token
::Bracket
) => "]".to_string(),
243 token
::OpenDelim(token
::Brace
) => "{".to_string(),
244 token
::CloseDelim(token
::Brace
) => "}".to_string(),
245 token
::Pound
=> "#".to_string(),
246 token
::Dollar
=> "$".to_string(),
247 token
::Question
=> "?".to_string(),
250 token
::Literal(lit
, suf
) => {
251 let mut out
= match lit
{
252 token
::Byte(b
) => format
!("b'{}'", b
.as_str()),
253 token
::Char(c
) => format
!("'{}'", c
.as_str()),
254 token
::Float(c
) => c
.as_str().to_string(),
255 token
::Integer(c
) => c
.as_str().to_string(),
256 token
::Str_(s
) => format
!("\"{}\"", s
.as_str()),
257 token
::StrRaw(s
, n
) => format
!("r{delim}\"{string}\"{delim}",
258 delim
=repeat("#", n
),
260 token
::Binary(v
) => format
!("b\"{}\"", v
.as_str()),
261 token
::BinaryRaw(s
, n
) => format
!("br{delim}\"{string}\"{delim}",
262 delim
=repeat("#", n
),
266 if let Some(s
) = suf
{
267 out
.push_str(s
.as_str())
273 /* Name components */
274 token
::Ident(s
, _
) => token
::get_ident(s
).to_string(),
275 token
::Lifetime(s
) => format
!("{}", token
::get_ident(s
)),
276 token
::Underscore
=> "_".to_string(),
279 token
::DocComment(s
) => s
.as_str().to_string(),
280 token
::SubstNt(s
, _
) => format
!("${}", s
),
281 token
::MatchNt(s
, t
, _
, _
) => format
!("${}:{}", s
, t
),
282 token
::Eof
=> "<eof>".to_string(),
283 token
::Whitespace
=> " ".to_string(),
284 token
::Comment
=> "/* */".to_string(),
285 token
::Shebang(s
) => format
!("/* shebang: {}*/", s
.as_str()),
287 token
::SpecialVarNt(var
) => format
!("${}", var
.as_str()),
289 token
::Interpolated(ref nt
) => match *nt
{
290 token
::NtExpr(ref e
) => expr_to_string(&**e
),
291 token
::NtMeta(ref e
) => meta_item_to_string(&**e
),
292 token
::NtTy(ref e
) => ty_to_string(&**e
),
293 token
::NtPath(ref e
) => path_to_string(&**e
),
294 token
::NtItem(ref e
) => item_to_string(&**e
),
295 token
::NtBlock(ref e
) => block_to_string(&**e
),
296 token
::NtStmt(ref e
) => stmt_to_string(&**e
),
297 token
::NtPat(ref e
) => pat_to_string(&**e
),
298 token
::NtIdent(ref e
, _
) => ident_to_string(&**e
),
299 token
::NtTT(ref e
) => tt_to_string(&**e
),
300 token
::NtArm(ref e
) => arm_to_string(&*e
),
301 token
::NtImplItem(ref e
) => impl_item_to_string(&**e
),
302 token
::NtTraitItem(ref e
) => trait_item_to_string(&**e
),
303 token
::NtGenerics(ref e
) => generics_to_string(&*e
),
304 token
::NtWhereClause(ref e
) => where_clause_to_string(&*e
),
309 pub fn ty_to_string(ty
: &ast
::Ty
) -> String
{
310 to_string(|s
| s
.print_type(ty
))
313 pub fn bounds_to_string(bounds
: &[ast
::TyParamBound
]) -> String
{
314 to_string(|s
| s
.print_bounds("", bounds
))
317 pub fn pat_to_string(pat
: &ast
::Pat
) -> String
{
318 to_string(|s
| s
.print_pat(pat
))
321 pub fn arm_to_string(arm
: &ast
::Arm
) -> String
{
322 to_string(|s
| s
.print_arm(arm
))
325 pub fn expr_to_string(e
: &ast
::Expr
) -> String
{
326 to_string(|s
| s
.print_expr(e
))
329 pub fn lifetime_to_string(e
: &ast
::Lifetime
) -> String
{
330 to_string(|s
| s
.print_lifetime(e
))
333 pub fn tt_to_string(tt
: &ast
::TokenTree
) -> String
{
334 to_string(|s
| s
.print_tt(tt
))
337 pub fn tts_to_string(tts
: &[ast
::TokenTree
]) -> String
{
338 to_string(|s
| s
.print_tts(tts
))
341 pub fn stmt_to_string(stmt
: &ast
::Stmt
) -> String
{
342 to_string(|s
| s
.print_stmt(stmt
))
345 pub fn attr_to_string(attr
: &ast
::Attribute
) -> String
{
346 to_string(|s
| s
.print_attribute(attr
))
349 pub fn item_to_string(i
: &ast
::Item
) -> String
{
350 to_string(|s
| s
.print_item(i
))
353 pub fn impl_item_to_string(i
: &ast
::ImplItem
) -> String
{
354 to_string(|s
| s
.print_impl_item(i
))
357 pub fn trait_item_to_string(i
: &ast
::TraitItem
) -> String
{
358 to_string(|s
| s
.print_trait_item(i
))
361 pub fn generics_to_string(generics
: &ast
::Generics
) -> String
{
362 to_string(|s
| s
.print_generics(generics
))
365 pub fn where_clause_to_string(i
: &ast
::WhereClause
) -> String
{
366 to_string(|s
| s
.print_where_clause(i
))
369 pub fn fn_block_to_string(p
: &ast
::FnDecl
) -> String
{
370 to_string(|s
| s
.print_fn_block_args(p
))
373 pub fn path_to_string(p
: &ast
::Path
) -> String
{
374 to_string(|s
| s
.print_path(p
, false, 0))
377 pub fn ident_to_string(id
: &ast
::Ident
) -> String
{
378 to_string(|s
| s
.print_ident(*id
))
381 pub fn fun_to_string(decl
: &ast
::FnDecl
, unsafety
: ast
::Unsafety
, name
: ast
::Ident
,
382 opt_explicit_self
: Option
<&ast
::ExplicitSelf_
>,
383 generics
: &ast
::Generics
) -> String
{
386 try
!(s
.print_fn(decl
, unsafety
, abi
::Rust
, Some(name
),
387 generics
, opt_explicit_self
, ast
::Inherited
));
388 try
!(s
.end()); // Close the head box
389 s
.end() // Close the outer box
393 pub fn block_to_string(blk
: &ast
::Block
) -> String
{
395 // containing cbox, will be closed by print-block at }
396 try
!(s
.cbox(indent_unit
));
397 // head-ibox, will be closed by print-block after {
403 pub fn meta_item_to_string(mi
: &ast
::MetaItem
) -> String
{
404 to_string(|s
| s
.print_meta_item(mi
))
407 pub fn attribute_to_string(attr
: &ast
::Attribute
) -> String
{
408 to_string(|s
| s
.print_attribute(attr
))
411 pub fn lit_to_string(l
: &ast
::Lit
) -> String
{
412 to_string(|s
| s
.print_literal(l
))
415 pub fn explicit_self_to_string(explicit_self
: &ast
::ExplicitSelf_
) -> String
{
416 to_string(|s
| s
.print_explicit_self(explicit_self
, ast
::MutImmutable
).map(|_
| {}
))
419 pub fn variant_to_string(var
: &ast
::Variant
) -> String
{
420 to_string(|s
| s
.print_variant(var
))
423 pub fn arg_to_string(arg
: &ast
::Arg
) -> String
{
424 to_string(|s
| s
.print_arg(arg
))
427 pub fn mac_to_string(arg
: &ast
::Mac
) -> String
{
428 to_string(|s
| s
.print_mac(arg
, ::parse
::token
::Paren
))
431 pub fn visibility_qualified(vis
: ast
::Visibility
, s
: &str) -> String
{
433 ast
::Public
=> format
!("pub {}", s
),
434 ast
::Inherited
=> s
.to_string()
438 fn needs_parentheses(expr
: &ast
::Expr
) -> bool
{
440 ast
::ExprAssign(..) | ast
::ExprBinary(..) |
441 ast
::ExprClosure(..) |
442 ast
::ExprAssignOp(..) | ast
::ExprCast(..) => true,
448 pub fn ibox(&mut self, u
: usize) -> io
::Result
<()> {
449 self.boxes
.push(pp
::Breaks
::Inconsistent
);
450 pp
::ibox(&mut self.s
, u
)
453 pub fn end(&mut self) -> io
::Result
<()> {
454 self.boxes
.pop().unwrap();
458 pub fn cbox(&mut self, u
: usize) -> io
::Result
<()> {
459 self.boxes
.push(pp
::Breaks
::Consistent
);
460 pp
::cbox(&mut self.s
, u
)
464 pub fn rbox(&mut self, u
: usize, b
: pp
::Breaks
) -> io
::Result
<()> {
466 pp
::rbox(&mut self.s
, u
, b
)
469 pub fn nbsp(&mut self) -> io
::Result
<()> { word(&mut self.s, " ") }
471 pub fn word_nbsp(&mut self, w
: &str) -> io
::Result
<()> {
472 try
!(word(&mut self.s
, w
));
476 pub fn word_space(&mut self, w
: &str) -> io
::Result
<()> {
477 try
!(word(&mut self.s
, w
));
481 pub fn popen(&mut self) -> io
::Result
<()> { word(&mut self.s, "(") }
483 pub fn pclose(&mut self) -> io
::Result
<()> { word(&mut self.s, ")") }
485 pub fn head(&mut self, w
: &str) -> io
::Result
<()> {
486 // outer-box is consistent
487 try
!(self.cbox(indent_unit
));
488 // head-box is inconsistent
489 try
!(self.ibox(w
.len() + 1));
490 // keyword that starts the head
492 try
!(self.word_nbsp(w
));
497 pub fn bopen(&mut self) -> io
::Result
<()> {
498 try
!(word(&mut self.s
, "{"));
499 self.end() // close the head-box
502 pub fn bclose_(&mut self, span
: codemap
::Span
,
503 indented
: usize) -> io
::Result
<()> {
504 self.bclose_maybe_open(span
, indented
, true)
506 pub fn bclose_maybe_open (&mut self, span
: codemap
::Span
,
507 indented
: usize, close_box
: bool
) -> io
::Result
<()> {
508 try
!(self.maybe_print_comment(span
.hi
));
509 try
!(self.break_offset_if_not_bol(1, -(indented
as isize)));
510 try
!(word(&mut self.s
, "}"));
512 try
!(self.end()); // close the outer-box
516 pub fn bclose(&mut self, span
: codemap
::Span
) -> io
::Result
<()> {
517 self.bclose_(span
, indent_unit
)
520 pub fn is_begin(&mut self) -> bool
{
521 match self.s
.last_token() {
522 pp
::Token
::Begin(_
) => true,
527 pub fn is_end(&mut self) -> bool
{
528 match self.s
.last_token() {
529 pp
::Token
::End
=> true,
534 // is this the beginning of a line?
535 pub fn is_bol(&mut self) -> bool
{
536 self.s
.last_token().is_eof() || self.s
.last_token().is_hardbreak_tok()
539 pub fn in_cbox(&self) -> bool
{
540 match self.boxes
.last() {
541 Some(&last_box
) => last_box
== pp
::Breaks
::Consistent
,
546 pub fn hardbreak_if_not_bol(&mut self) -> io
::Result
<()> {
548 try
!(hardbreak(&mut self.s
))
552 pub fn space_if_not_bol(&mut self) -> io
::Result
<()> {
553 if !self.is_bol() { try!(space(&mut self.s)); }
556 pub fn break_offset_if_not_bol(&mut self, n
: usize,
557 off
: isize) -> io
::Result
<()> {
559 break_offset(&mut self.s
, n
, off
)
561 if off
!= 0 && self.s
.last_token().is_hardbreak_tok() {
562 // We do something pretty sketchy here: tuck the nonzero
563 // offset-adjustment we were going to deposit along with the
564 // break into the previous hardbreak.
565 self.s
.replace_last_token(pp
::hardbreak_tok_offset(off
));
571 // Synthesizes a comment that was not textually present in the original source
573 pub fn synth_comment(&mut self, text
: String
) -> io
::Result
<()> {
574 try
!(word(&mut self.s
, "/*"));
575 try
!(space(&mut self.s
));
576 try
!(word(&mut self.s
, &text
[..]));
577 try
!(space(&mut self.s
));
578 word(&mut self.s
, "*/")
581 pub fn commasep
<T
, F
>(&mut self, b
: Breaks
, elts
: &[T
], mut op
: F
) -> io
::Result
<()> where
582 F
: FnMut(&mut State
, &T
) -> io
::Result
<()>,
584 try
!(self.rbox(0, b
));
585 let mut first
= true;
587 if first { first = false; }
else { try!(self.word_space(",")); }
594 pub fn commasep_cmnt
<T
, F
, G
>(&mut self,
598 mut get_span
: G
) -> io
::Result
<()> where
599 F
: FnMut(&mut State
, &T
) -> io
::Result
<()>,
600 G
: FnMut(&T
) -> codemap
::Span
,
602 try
!(self.rbox(0, b
));
603 let len
= elts
.len();
606 try
!(self.maybe_print_comment(get_span(elt
).hi
));
610 try
!(word(&mut self.s
, ","));
611 try
!(self.maybe_print_trailing_comment(get_span(elt
),
612 Some(get_span(&elts
[i
]).hi
)));
613 try
!(self.space_if_not_bol());
619 pub fn commasep_exprs(&mut self, b
: Breaks
,
620 exprs
: &[P
<ast
::Expr
>]) -> io
::Result
<()> {
621 self.commasep_cmnt(b
, exprs
, |s
, e
| s
.print_expr(&**e
), |e
| e
.span
)
624 pub fn print_mod(&mut self, _mod
: &ast
::Mod
,
625 attrs
: &[ast
::Attribute
]) -> io
::Result
<()> {
626 try
!(self.print_inner_attributes(attrs
));
627 for item
in &_mod
.items
{
628 try
!(self.print_item(&**item
));
633 pub fn print_foreign_mod(&mut self, nmod
: &ast
::ForeignMod
,
634 attrs
: &[ast
::Attribute
]) -> io
::Result
<()> {
635 try
!(self.print_inner_attributes(attrs
));
636 for item
in &nmod
.items
{
637 try
!(self.print_foreign_item(&**item
));
642 pub fn print_opt_lifetime(&mut self,
643 lifetime
: &Option
<ast
::Lifetime
>) -> io
::Result
<()> {
644 if let Some(l
) = *lifetime
{
645 try
!(self.print_lifetime(&l
));
651 pub fn print_type(&mut self, ty
: &ast
::Ty
) -> io
::Result
<()> {
652 try
!(self.maybe_print_comment(ty
.span
.lo
));
655 ast
::TyVec(ref ty
) => {
656 try
!(word(&mut self.s
, "["));
657 try
!(self.print_type(&**ty
));
658 try
!(word(&mut self.s
, "]"));
660 ast
::TyPtr(ref mt
) => {
661 try
!(word(&mut self.s
, "*"));
663 ast
::MutMutable
=> try
!(self.word_nbsp("mut")),
664 ast
::MutImmutable
=> try
!(self.word_nbsp("const")),
666 try
!(self.print_type(&*mt
.ty
));
668 ast
::TyRptr(ref lifetime
, ref mt
) => {
669 try
!(word(&mut self.s
, "&"));
670 try
!(self.print_opt_lifetime(lifetime
));
671 try
!(self.print_mt(mt
));
673 ast
::TyTup(ref elts
) => {
675 try
!(self.commasep(Inconsistent
, &elts
[..],
676 |s
, ty
| s
.print_type(&**ty
)));
678 try
!(word(&mut self.s
, ","));
682 ast
::TyParen(ref typ
) => {
684 try
!(self.print_type(&**typ
));
687 ast
::TyBareFn(ref f
) => {
688 let generics
= ast
::Generics
{
689 lifetimes
: f
.lifetimes
.clone(),
690 ty_params
: OwnedSlice
::empty(),
691 where_clause
: ast
::WhereClause
{
692 id
: ast
::DUMMY_NODE_ID
,
693 predicates
: Vec
::new(),
696 try
!(self.print_ty_fn(f
.abi
,
703 ast
::TyPath(None
, ref path
) => {
704 try
!(self.print_path(path
, false, 0));
706 ast
::TyPath(Some(ref qself
), ref path
) => {
707 try
!(self.print_qpath(path
, qself
, false))
709 ast
::TyObjectSum(ref ty
, ref bounds
) => {
710 try
!(self.print_type(&**ty
));
711 try
!(self.print_bounds("+", &bounds
[..]));
713 ast
::TyPolyTraitRef(ref bounds
) => {
714 try
!(self.print_bounds("", &bounds
[..]));
716 ast
::TyFixedLengthVec(ref ty
, ref v
) => {
717 try
!(word(&mut self.s
, "["));
718 try
!(self.print_type(&**ty
));
719 try
!(word(&mut self.s
, "; "));
720 try
!(self.print_expr(&**v
));
721 try
!(word(&mut self.s
, "]"));
723 ast
::TyTypeof(ref e
) => {
724 try
!(word(&mut self.s
, "typeof("));
725 try
!(self.print_expr(&**e
));
726 try
!(word(&mut self.s
, ")"));
729 try
!(word(&mut self.s
, "_"));
735 pub fn print_foreign_item(&mut self,
736 item
: &ast
::ForeignItem
) -> io
::Result
<()> {
737 try
!(self.hardbreak_if_not_bol());
738 try
!(self.maybe_print_comment(item
.span
.lo
));
739 try
!(self.print_outer_attributes(&item
.attrs
));
741 ast
::ForeignItemFn(ref decl
, ref generics
) => {
743 try
!(self.print_fn(&**decl
, ast
::Unsafety
::Normal
,
744 abi
::Rust
, Some(item
.ident
),
745 generics
, None
, item
.vis
));
746 try
!(self.end()); // end head-ibox
747 try
!(word(&mut self.s
, ";"));
748 self.end() // end the outer fn box
750 ast
::ForeignItemStatic(ref t
, m
) => {
751 try
!(self.head(&visibility_qualified(item
.vis
,
754 try
!(self.word_space("mut"));
756 try
!(self.print_ident(item
.ident
));
757 try
!(self.word_space(":"));
758 try
!(self.print_type(&**t
));
759 try
!(word(&mut self.s
, ";"));
760 try
!(self.end()); // end the head-ibox
761 self.end() // end the outer cbox
766 fn print_associated_const(&mut self,
769 default: Option
<&ast
::Expr
>,
770 vis
: ast
::Visibility
)
773 try
!(word(&mut self.s
, &visibility_qualified(vis
, "")));
774 try
!(self.word_space("const"));
775 try
!(self.print_ident(ident
));
776 try
!(self.word_space(":"));
777 try
!(self.print_type(ty
));
778 if let Some(expr
) = default {
779 try
!(space(&mut self.s
));
780 try
!(self.word_space("="));
781 try
!(self.print_expr(expr
));
783 word(&mut self.s
, ";")
786 fn print_associated_type(&mut self,
788 bounds
: Option
<&ast
::TyParamBounds
>,
789 ty
: Option
<&ast
::Ty
>)
791 try
!(self.word_space("type"));
792 try
!(self.print_ident(ident
));
793 if let Some(bounds
) = bounds
{
794 try
!(self.print_bounds(":", bounds
));
796 if let Some(ty
) = ty
{
797 try
!(space(&mut self.s
));
798 try
!(self.word_space("="));
799 try
!(self.print_type(ty
));
801 word(&mut self.s
, ";")
804 /// Pretty-print an item
805 pub fn print_item(&mut self, item
: &ast
::Item
) -> io
::Result
<()> {
806 try
!(self.hardbreak_if_not_bol());
807 try
!(self.maybe_print_comment(item
.span
.lo
));
808 try
!(self.print_outer_attributes(&item
.attrs
));
809 try
!(self.ann
.pre(self, NodeItem(item
)));
811 ast
::ItemExternCrate(ref optional_path
) => {
812 try
!(self.head(&visibility_qualified(item
.vis
,
814 if let Some(p
) = *optional_path
{
815 let val
= token
::get_name(p
);
816 if val
.contains("-") {
817 try
!(self.print_string(&val
, ast
::CookedStr
));
819 try
!(self.print_name(p
));
821 try
!(space(&mut self.s
));
822 try
!(word(&mut self.s
, "as"));
823 try
!(space(&mut self.s
));
825 try
!(self.print_ident(item
.ident
));
826 try
!(word(&mut self.s
, ";"));
827 try
!(self.end()); // end inner head-block
828 try
!(self.end()); // end outer head-block
830 ast
::ItemUse(ref vp
) => {
831 try
!(self.head(&visibility_qualified(item
.vis
,
833 try
!(self.print_view_path(&**vp
));
834 try
!(word(&mut self.s
, ";"));
835 try
!(self.end()); // end inner head-block
836 try
!(self.end()); // end outer head-block
838 ast
::ItemStatic(ref ty
, m
, ref expr
) => {
839 try
!(self.head(&visibility_qualified(item
.vis
,
841 if m
== ast
::MutMutable
{
842 try
!(self.word_space("mut"));
844 try
!(self.print_ident(item
.ident
));
845 try
!(self.word_space(":"));
846 try
!(self.print_type(&**ty
));
847 try
!(space(&mut self.s
));
848 try
!(self.end()); // end the head-ibox
850 try
!(self.word_space("="));
851 try
!(self.print_expr(&**expr
));
852 try
!(word(&mut self.s
, ";"));
853 try
!(self.end()); // end the outer cbox
855 ast
::ItemConst(ref ty
, ref expr
) => {
856 try
!(self.head(&visibility_qualified(item
.vis
,
858 try
!(self.print_ident(item
.ident
));
859 try
!(self.word_space(":"));
860 try
!(self.print_type(&**ty
));
861 try
!(space(&mut self.s
));
862 try
!(self.end()); // end the head-ibox
864 try
!(self.word_space("="));
865 try
!(self.print_expr(&**expr
));
866 try
!(word(&mut self.s
, ";"));
867 try
!(self.end()); // end the outer cbox
869 ast
::ItemFn(ref decl
, unsafety
, abi
, ref typarams
, ref body
) => {
880 try
!(word(&mut self.s
, " "));
881 try
!(self.print_block_with_attrs(&**body
, &item
.attrs
));
883 ast
::ItemMod(ref _mod
) => {
884 try
!(self.head(&visibility_qualified(item
.vis
,
886 try
!(self.print_ident(item
.ident
));
889 try
!(self.print_mod(_mod
, &item
.attrs
));
890 try
!(self.bclose(item
.span
));
892 ast
::ItemForeignMod(ref nmod
) => {
893 try
!(self.head("extern"));
894 try
!(self.word_nbsp(&nmod
.abi
.to_string()));
896 try
!(self.print_foreign_mod(nmod
, &item
.attrs
));
897 try
!(self.bclose(item
.span
));
899 ast
::ItemTy(ref ty
, ref params
) => {
900 try
!(self.ibox(indent_unit
));
902 try
!(self.word_nbsp(&visibility_qualified(item
.vis
, "type")));
903 try
!(self.print_ident(item
.ident
));
904 try
!(self.print_generics(params
));
905 try
!(self.end()); // end the inner ibox
907 try
!(self.print_where_clause(¶ms
.where_clause
));
908 try
!(space(&mut self.s
));
909 try
!(self.word_space("="));
910 try
!(self.print_type(&**ty
));
911 try
!(word(&mut self.s
, ";"));
912 try
!(self.end()); // end the outer ibox
914 ast
::ItemEnum(ref enum_definition
, ref params
) => {
915 try
!(self.print_enum_def(
923 ast
::ItemStruct(ref struct_def
, ref generics
) => {
924 try
!(self.head(&visibility_qualified(item
.vis
,"struct")));
925 try
!(self.print_struct(&**struct_def
, generics
, item
.ident
, item
.span
));
928 ast
::ItemDefaultImpl(unsafety
, ref trait_ref
) => {
930 try
!(self.print_visibility(item
.vis
));
931 try
!(self.print_unsafety(unsafety
));
932 try
!(self.word_nbsp("impl"));
933 try
!(self.print_trait_ref(trait_ref
));
934 try
!(space(&mut self.s
));
935 try
!(self.word_space("for"));
936 try
!(self.word_space(".."));
938 try
!(self.bclose(item
.span
));
940 ast
::ItemImpl(unsafety
,
947 try
!(self.print_visibility(item
.vis
));
948 try
!(self.print_unsafety(unsafety
));
949 try
!(self.word_nbsp("impl"));
951 if generics
.is_parameterized() {
952 try
!(self.print_generics(generics
));
953 try
!(space(&mut self.s
));
957 ast
::ImplPolarity
::Negative
=> {
958 try
!(word(&mut self.s
, "!"));
965 try
!(self.print_trait_ref(t
));
966 try
!(space(&mut self.s
));
967 try
!(self.word_space("for"));
972 try
!(self.print_type(&**ty
));
973 try
!(self.print_where_clause(&generics
.where_clause
));
975 try
!(space(&mut self.s
));
977 try
!(self.print_inner_attributes(&item
.attrs
));
978 for impl_item
in impl_items
{
979 try
!(self.print_impl_item(impl_item
));
981 try
!(self.bclose(item
.span
));
983 ast
::ItemTrait(unsafety
, ref generics
, ref bounds
, ref trait_items
) => {
985 try
!(self.print_visibility(item
.vis
));
986 try
!(self.print_unsafety(unsafety
));
987 try
!(self.word_nbsp("trait"));
988 try
!(self.print_ident(item
.ident
));
989 try
!(self.print_generics(generics
));
990 let mut real_bounds
= Vec
::with_capacity(bounds
.len());
991 for b
in bounds
.iter() {
992 if let TraitTyParamBound(ref ptr
, ast
::TraitBoundModifier
::Maybe
) = *b
{
993 try
!(space(&mut self.s
));
994 try
!(self.word_space("for ?"));
995 try
!(self.print_trait_ref(&ptr
.trait_ref
));
997 real_bounds
.push(b
.clone());
1000 try
!(self.print_bounds(":", &real_bounds
[..]));
1001 try
!(self.print_where_clause(&generics
.where_clause
));
1002 try
!(word(&mut self.s
, " "));
1004 for trait_item
in trait_items
{
1005 try
!(self.print_trait_item(trait_item
));
1007 try
!(self.bclose(item
.span
));
1009 // I think it's reasonable to hide the context here:
1010 ast
::ItemMac(codemap
::Spanned
{ node
: ast
::MacInvocTT(ref pth
, ref tts
, _
),
1012 try
!(self.print_visibility(item
.vis
));
1013 try
!(self.print_path(pth
, false, 0));
1014 try
!(word(&mut self.s
, "! "));
1015 try
!(self.print_ident(item
.ident
));
1016 try
!(self.cbox(indent_unit
));
1018 try
!(self.print_tts(&tts
[..]));
1019 try
!(self.pclose());
1020 try
!(word(&mut self.s
, ";"));
1024 self.ann
.post(self, NodeItem(item
))
1027 fn print_trait_ref(&mut self, t
: &ast
::TraitRef
) -> io
::Result
<()> {
1028 self.print_path(&t
.path
, false, 0)
1031 fn print_formal_lifetime_list(&mut self, lifetimes
: &[ast
::LifetimeDef
]) -> io
::Result
<()> {
1032 if !lifetimes
.is_empty() {
1033 try
!(word(&mut self.s
, "for<"));
1034 let mut comma
= false;
1035 for lifetime_def
in lifetimes
{
1037 try
!(self.word_space(","))
1039 try
!(self.print_lifetime_def(lifetime_def
));
1042 try
!(word(&mut self.s
, ">"));
1047 fn print_poly_trait_ref(&mut self, t
: &ast
::PolyTraitRef
) -> io
::Result
<()> {
1048 try
!(self.print_formal_lifetime_list(&t
.bound_lifetimes
));
1049 self.print_trait_ref(&t
.trait_ref
)
1052 pub fn print_enum_def(&mut self, enum_definition
: &ast
::EnumDef
,
1053 generics
: &ast
::Generics
, ident
: ast
::Ident
,
1054 span
: codemap
::Span
,
1055 visibility
: ast
::Visibility
) -> io
::Result
<()> {
1056 try
!(self.head(&visibility_qualified(visibility
, "enum")));
1057 try
!(self.print_ident(ident
));
1058 try
!(self.print_generics(generics
));
1059 try
!(self.print_where_clause(&generics
.where_clause
));
1060 try
!(space(&mut self.s
));
1061 self.print_variants(&enum_definition
.variants
, span
)
1064 pub fn print_variants(&mut self,
1065 variants
: &[P
<ast
::Variant
>],
1066 span
: codemap
::Span
) -> io
::Result
<()> {
1069 try
!(self.space_if_not_bol());
1070 try
!(self.maybe_print_comment(v
.span
.lo
));
1071 try
!(self.print_outer_attributes(&v
.node
.attrs
));
1072 try
!(self.ibox(indent_unit
));
1073 try
!(self.print_variant(&**v
));
1074 try
!(word(&mut self.s
, ","));
1076 try
!(self.maybe_print_trailing_comment(v
.span
, None
));
1081 pub fn print_visibility(&mut self, vis
: ast
::Visibility
) -> io
::Result
<()> {
1083 ast
::Public
=> self.word_nbsp("pub"),
1084 ast
::Inherited
=> Ok(())
1088 pub fn print_struct(&mut self,
1089 struct_def
: &ast
::StructDef
,
1090 generics
: &ast
::Generics
,
1092 span
: codemap
::Span
) -> io
::Result
<()> {
1093 try
!(self.print_ident(ident
));
1094 try
!(self.print_generics(generics
));
1095 if ast_util
::struct_def_is_tuple_like(struct_def
) {
1096 if !struct_def
.fields
.is_empty() {
1099 Inconsistent
, &struct_def
.fields
,
1101 match field
.node
.kind
{
1102 ast
::NamedField(..) => panic
!("unexpected named field"),
1103 ast
::UnnamedField(vis
) => {
1104 try
!(s
.print_visibility(vis
));
1105 try
!(s
.maybe_print_comment(field
.span
.lo
));
1106 s
.print_type(&*field
.node
.ty
)
1111 try
!(self.pclose());
1113 try
!(self.print_where_clause(&generics
.where_clause
));
1114 try
!(word(&mut self.s
, ";"));
1116 self.end() // close the outer-box
1118 try
!(self.print_where_clause(&generics
.where_clause
));
1121 try
!(self.hardbreak_if_not_bol());
1123 for field
in &struct_def
.fields
{
1124 match field
.node
.kind
{
1125 ast
::UnnamedField(..) => panic
!("unexpected unnamed field"),
1126 ast
::NamedField(ident
, visibility
) => {
1127 try
!(self.hardbreak_if_not_bol());
1128 try
!(self.maybe_print_comment(field
.span
.lo
));
1129 try
!(self.print_outer_attributes(&field
.node
.attrs
));
1130 try
!(self.print_visibility(visibility
));
1131 try
!(self.print_ident(ident
));
1132 try
!(self.word_nbsp(":"));
1133 try
!(self.print_type(&*field
.node
.ty
));
1134 try
!(word(&mut self.s
, ","));
1143 /// This doesn't deserve to be called "pretty" printing, but it should be
1144 /// meaning-preserving. A quick hack that might help would be to look at the
1145 /// spans embedded in the TTs to decide where to put spaces and newlines.
1146 /// But it'd be better to parse these according to the grammar of the
1147 /// appropriate macro, transcribe back into the grammar we just parsed from,
1148 /// and then pretty-print the resulting AST nodes (so, e.g., we print
1149 /// expression arguments as expressions). It can be done! I think.
1150 pub fn print_tt(&mut self, tt
: &ast
::TokenTree
) -> io
::Result
<()> {
1152 ast
::TtToken(_
, ref tk
) => {
1153 try
!(word(&mut self.s
, &token_to_string(tk
)));
1155 parse
::token
::DocComment(..) => {
1156 hardbreak(&mut self.s
)
1161 ast
::TtDelimited(_
, ref delimed
) => {
1162 try
!(word(&mut self.s
, &token_to_string(&delimed
.open_token())));
1163 try
!(space(&mut self.s
));
1164 try
!(self.print_tts(&delimed
.tts
));
1165 try
!(space(&mut self.s
));
1166 word(&mut self.s
, &token_to_string(&delimed
.close_token()))
1168 ast
::TtSequence(_
, ref seq
) => {
1169 try
!(word(&mut self.s
, "$("));
1170 for tt_elt
in &seq
.tts
{
1171 try
!(self.print_tt(tt_elt
));
1173 try
!(word(&mut self.s
, ")"));
1174 match seq
.separator
{
1176 try
!(word(&mut self.s
, &token_to_string(tk
)));
1181 ast
::ZeroOrMore
=> word(&mut self.s
, "*"),
1182 ast
::OneOrMore
=> word(&mut self.s
, "+"),
1188 pub fn print_tts(&mut self, tts
: &[ast
::TokenTree
]) -> io
::Result
<()> {
1190 let mut suppress_space
= false;
1191 for (i
, tt
) in tts
.iter().enumerate() {
1192 if i
!= 0 && !suppress_space
{
1193 try
!(space(&mut self.s
));
1195 try
!(self.print_tt(tt
));
1196 // There should be no space between the module name and the following `::` in paths,
1197 // otherwise imported macros get re-parsed from crate metadata incorrectly (#20701)
1198 suppress_space
= match tt
{
1199 &ast
::TtToken(_
, token
::Ident(_
, token
::ModName
)) |
1200 &ast
::TtToken(_
, token
::MatchNt(_
, _
, _
, token
::ModName
)) |
1201 &ast
::TtToken(_
, token
::SubstNt(_
, token
::ModName
)) => true,
1208 pub fn print_variant(&mut self, v
: &ast
::Variant
) -> io
::Result
<()> {
1209 try
!(self.print_visibility(v
.node
.vis
));
1211 ast
::TupleVariantKind(ref args
) => {
1212 try
!(self.print_ident(v
.node
.name
));
1213 if !args
.is_empty() {
1215 try
!(self.commasep(Consistent
,
1217 |s
, arg
| s
.print_type(&*arg
.ty
)));
1218 try
!(self.pclose());
1221 ast
::StructVariantKind(ref struct_def
) => {
1222 try
!(self.head(""));
1223 let generics
= ast_util
::empty_generics();
1224 try
!(self.print_struct(&**struct_def
, &generics
, v
.node
.name
, v
.span
));
1227 match v
.node
.disr_expr
{
1229 try
!(space(&mut self.s
));
1230 try
!(self.word_space("="));
1231 self.print_expr(&**d
)
1237 pub fn print_method_sig(&mut self,
1240 vis
: ast
::Visibility
)
1242 self.print_fn(&m
.decl
,
1247 Some(&m
.explicit_self
.node
),
1251 pub fn print_trait_item(&mut self, ti
: &ast
::TraitItem
)
1253 try
!(self.ann
.pre(self, NodeSubItem(ti
.id
)));
1254 try
!(self.hardbreak_if_not_bol());
1255 try
!(self.maybe_print_comment(ti
.span
.lo
));
1256 try
!(self.print_outer_attributes(&ti
.attrs
));
1258 ast
::ConstTraitItem(ref ty
, ref default) => {
1259 try
!(self.print_associated_const(ti
.ident
, &ty
,
1260 default.as_ref().map(|expr
| &**expr
),
1263 ast
::MethodTraitItem(ref sig
, ref body
) => {
1265 try
!(self.head(""));
1267 try
!(self.print_method_sig(ti
.ident
, sig
, ast
::Inherited
));
1268 if let Some(ref body
) = *body
{
1270 try
!(self.print_block_with_attrs(body
, &ti
.attrs
));
1272 try
!(word(&mut self.s
, ";"));
1275 ast
::TypeTraitItem(ref bounds
, ref default) => {
1276 try
!(self.print_associated_type(ti
.ident
, Some(bounds
),
1277 default.as_ref().map(|ty
| &**ty
)));
1280 self.ann
.post(self, NodeSubItem(ti
.id
))
1283 pub fn print_impl_item(&mut self, ii
: &ast
::ImplItem
) -> io
::Result
<()> {
1284 try
!(self.ann
.pre(self, NodeSubItem(ii
.id
)));
1285 try
!(self.hardbreak_if_not_bol());
1286 try
!(self.maybe_print_comment(ii
.span
.lo
));
1287 try
!(self.print_outer_attributes(&ii
.attrs
));
1289 ast
::ConstImplItem(ref ty
, ref expr
) => {
1290 try
!(self.print_associated_const(ii
.ident
, &ty
, Some(&expr
), ii
.vis
));
1292 ast
::MethodImplItem(ref sig
, ref body
) => {
1293 try
!(self.head(""));
1294 try
!(self.print_method_sig(ii
.ident
, sig
, ii
.vis
));
1296 try
!(self.print_block_with_attrs(body
, &ii
.attrs
));
1298 ast
::TypeImplItem(ref ty
) => {
1299 try
!(self.print_associated_type(ii
.ident
, None
, Some(ty
)));
1301 ast
::MacImplItem(codemap
::Spanned
{ node
: ast
::MacInvocTT(ref pth
, ref tts
, _
),
1303 // code copied from ItemMac:
1304 try
!(self.print_path(pth
, false, 0));
1305 try
!(word(&mut self.s
, "! "));
1306 try
!(self.cbox(indent_unit
));
1308 try
!(self.print_tts(&tts
[..]));
1309 try
!(self.pclose());
1310 try
!(word(&mut self.s
, ";"));
1314 self.ann
.post(self, NodeSubItem(ii
.id
))
1317 pub fn print_outer_attributes(&mut self,
1318 attrs
: &[ast
::Attribute
]) -> io
::Result
<()> {
1321 match attr
.node
.style
{
1323 try
!(self.print_attribute(attr
));
1326 _
=> {/* fallthrough */ }
1330 try
!(self.hardbreak_if_not_bol());
1335 pub fn print_inner_attributes(&mut self,
1336 attrs
: &[ast
::Attribute
]) -> io
::Result
<()> {
1339 match attr
.node
.style
{
1341 try
!(self.print_attribute(attr
));
1344 _
=> {/* fallthrough */ }
1348 try
!(self.hardbreak_if_not_bol());
1353 pub fn print_attribute(&mut self, attr
: &ast
::Attribute
) -> io
::Result
<()> {
1354 try
!(self.hardbreak_if_not_bol());
1355 try
!(self.maybe_print_comment(attr
.span
.lo
));
1356 if attr
.node
.is_sugared_doc
{
1357 word(&mut self.s
, &attr
.value_str().unwrap())
1359 match attr
.node
.style
{
1360 ast
::AttrInner
=> try
!(word(&mut self.s
, "#![")),
1361 ast
::AttrOuter
=> try
!(word(&mut self.s
, "#[")),
1363 try
!(self.print_meta_item(&*attr
.meta()));
1364 word(&mut self.s
, "]")
1369 pub fn print_stmt(&mut self, st
: &ast
::Stmt
) -> io
::Result
<()> {
1370 try
!(self.maybe_print_comment(st
.span
.lo
));
1372 ast
::StmtDecl(ref decl
, _
) => {
1373 try
!(self.print_decl(&**decl
));
1375 ast
::StmtExpr(ref expr
, _
) => {
1376 try
!(self.space_if_not_bol());
1377 try
!(self.print_expr(&**expr
));
1379 ast
::StmtSemi(ref expr
, _
) => {
1380 try
!(self.space_if_not_bol());
1381 try
!(self.print_expr(&**expr
));
1382 try
!(word(&mut self.s
, ";"));
1384 ast
::StmtMac(ref mac
, style
) => {
1385 try
!(self.space_if_not_bol());
1386 let delim
= match style
{
1387 ast
::MacStmtWithBraces
=> token
::Brace
,
1390 try
!(self.print_mac(&**mac
, delim
));
1392 ast
::MacStmtWithBraces
=> {}
1393 _
=> try
!(word(&mut self.s
, ";")),
1397 if parse
::classify
::stmt_ends_with_semi(&st
.node
) {
1398 try
!(word(&mut self.s
, ";"));
1400 self.maybe_print_trailing_comment(st
.span
, None
)
1403 pub fn print_block(&mut self, blk
: &ast
::Block
) -> io
::Result
<()> {
1404 self.print_block_with_attrs(blk
, &[])
1407 pub fn print_block_unclosed(&mut self, blk
: &ast
::Block
) -> io
::Result
<()> {
1408 self.print_block_unclosed_indent(blk
, indent_unit
)
1411 pub fn print_block_unclosed_indent(&mut self, blk
: &ast
::Block
,
1412 indented
: usize) -> io
::Result
<()> {
1413 self.print_block_maybe_unclosed(blk
, indented
, &[], false)
1416 pub fn print_block_with_attrs(&mut self,
1418 attrs
: &[ast
::Attribute
]) -> io
::Result
<()> {
1419 self.print_block_maybe_unclosed(blk
, indent_unit
, attrs
, true)
1422 pub fn print_block_maybe_unclosed(&mut self,
1425 attrs
: &[ast
::Attribute
],
1426 close_box
: bool
) -> io
::Result
<()> {
1428 ast
::UnsafeBlock(..) => try
!(self.word_space("unsafe")),
1429 ast
::DefaultBlock
=> ()
1431 try
!(self.maybe_print_comment(blk
.span
.lo
));
1432 try
!(self.ann
.pre(self, NodeBlock(blk
)));
1435 try
!(self.print_inner_attributes(attrs
));
1437 for st
in &blk
.stmts
{
1438 try
!(self.print_stmt(&**st
));
1442 try
!(self.space_if_not_bol());
1443 try
!(self.print_expr(&**expr
));
1444 try
!(self.maybe_print_trailing_comment(expr
.span
, Some(blk
.span
.hi
)));
1448 try
!(self.bclose_maybe_open(blk
.span
, indented
, close_box
));
1449 self.ann
.post(self, NodeBlock(blk
))
1452 fn print_else(&mut self, els
: Option
<&ast
::Expr
>) -> io
::Result
<()> {
1456 // "another else-if"
1457 ast
::ExprIf(ref i
, ref then
, ref e
) => {
1458 try
!(self.cbox(indent_unit
- 1));
1460 try
!(word(&mut self.s
, " else if "));
1461 try
!(self.print_expr(&**i
));
1462 try
!(space(&mut self.s
));
1463 try
!(self.print_block(&**then
));
1464 self.print_else(e
.as_ref().map(|e
| &**e
))
1466 // "another else-if-let"
1467 ast
::ExprIfLet(ref pat
, ref expr
, ref then
, ref e
) => {
1468 try
!(self.cbox(indent_unit
- 1));
1470 try
!(word(&mut self.s
, " else if let "));
1471 try
!(self.print_pat(&**pat
));
1472 try
!(space(&mut self.s
));
1473 try
!(self.word_space("="));
1474 try
!(self.print_expr(&**expr
));
1475 try
!(space(&mut self.s
));
1476 try
!(self.print_block(&**then
));
1477 self.print_else(e
.as_ref().map(|e
| &**e
))
1480 ast
::ExprBlock(ref b
) => {
1481 try
!(self.cbox(indent_unit
- 1));
1483 try
!(word(&mut self.s
, " else "));
1484 self.print_block(&**b
)
1486 // BLEAH, constraints would be great here
1488 panic
!("print_if saw if with weird alternative");
1496 pub fn print_if(&mut self, test
: &ast
::Expr
, blk
: &ast
::Block
,
1497 elseopt
: Option
<&ast
::Expr
>) -> io
::Result
<()> {
1498 try
!(self.head("if"));
1499 try
!(self.print_expr(test
));
1500 try
!(space(&mut self.s
));
1501 try
!(self.print_block(blk
));
1502 self.print_else(elseopt
)
1505 pub fn print_if_let(&mut self, pat
: &ast
::Pat
, expr
: &ast
::Expr
, blk
: &ast
::Block
,
1506 elseopt
: Option
<&ast
::Expr
>) -> io
::Result
<()> {
1507 try
!(self.head("if let"));
1508 try
!(self.print_pat(pat
));
1509 try
!(space(&mut self.s
));
1510 try
!(self.word_space("="));
1511 try
!(self.print_expr(expr
));
1512 try
!(space(&mut self.s
));
1513 try
!(self.print_block(blk
));
1514 self.print_else(elseopt
)
1517 pub fn print_mac(&mut self, m
: &ast
::Mac
, delim
: token
::DelimToken
)
1520 // I think it's reasonable to hide the ctxt here:
1521 ast
::MacInvocTT(ref pth
, ref tts
, _
) => {
1522 try
!(self.print_path(pth
, false, 0));
1523 try
!(word(&mut self.s
, "!"));
1525 token
::Paren
=> try
!(self.popen()),
1526 token
::Bracket
=> try
!(word(&mut self.s
, "[")),
1527 token
::Brace
=> try
!(self.bopen()),
1529 try
!(self.print_tts(tts
));
1531 token
::Paren
=> self.pclose(),
1532 token
::Bracket
=> word(&mut self.s
, "]"),
1533 token
::Brace
=> self.bclose(m
.span
),
1540 fn print_call_post(&mut self, args
: &[P
<ast
::Expr
>]) -> io
::Result
<()> {
1542 try
!(self.commasep_exprs(Inconsistent
, args
));
1546 pub fn print_expr_maybe_paren(&mut self, expr
: &ast
::Expr
) -> io
::Result
<()> {
1547 let needs_par
= needs_parentheses(expr
);
1551 try
!(self.print_expr(expr
));
1553 try
!(self.pclose());
1558 fn print_expr_box(&mut self,
1559 place
: &Option
<P
<ast
::Expr
>>,
1560 expr
: &ast
::Expr
) -> io
::Result
<()> {
1561 try
!(word(&mut self.s
, "box"));
1562 try
!(word(&mut self.s
, "("));
1563 try
!(place
.as_ref().map_or(Ok(()), |e
|self.print_expr(&**e
)));
1564 try
!(self.word_space(")"));
1565 self.print_expr(expr
)
1568 fn print_expr_vec(&mut self, exprs
: &[P
<ast
::Expr
>]) -> io
::Result
<()> {
1569 try
!(self.ibox(indent_unit
));
1570 try
!(word(&mut self.s
, "["));
1571 try
!(self.commasep_exprs(Inconsistent
, &exprs
[..]));
1572 try
!(word(&mut self.s
, "]"));
1576 fn print_expr_repeat(&mut self,
1577 element
: &ast
::Expr
,
1578 count
: &ast
::Expr
) -> io
::Result
<()> {
1579 try
!(self.ibox(indent_unit
));
1580 try
!(word(&mut self.s
, "["));
1581 try
!(self.print_expr(element
));
1582 try
!(self.word_space(";"));
1583 try
!(self.print_expr(count
));
1584 try
!(word(&mut self.s
, "]"));
1588 fn print_expr_struct(&mut self,
1590 fields
: &[ast
::Field
],
1591 wth
: &Option
<P
<ast
::Expr
>>) -> io
::Result
<()> {
1592 try
!(self.print_path(path
, true, 0));
1593 if !(fields
.is_empty() && wth
.is_none()) {
1594 try
!(word(&mut self.s
, "{"));
1595 try
!(self.commasep_cmnt(
1599 try
!(s
.ibox(indent_unit
));
1600 try
!(s
.print_ident(field
.ident
.node
));
1601 try
!(s
.word_space(":"));
1602 try
!(s
.print_expr(&*field
.expr
));
1608 try
!(self.ibox(indent_unit
));
1609 if !fields
.is_empty() {
1610 try
!(word(&mut self.s
, ","));
1611 try
!(space(&mut self.s
));
1613 try
!(word(&mut self.s
, ".."));
1614 try
!(self.print_expr(&**expr
));
1617 _
=> try
!(word(&mut self.s
, ",")),
1619 try
!(word(&mut self.s
, "}"));
1624 fn print_expr_tup(&mut self, exprs
: &[P
<ast
::Expr
>]) -> io
::Result
<()> {
1626 try
!(self.commasep_exprs(Inconsistent
, &exprs
[..]));
1627 if exprs
.len() == 1 {
1628 try
!(word(&mut self.s
, ","));
1633 fn print_expr_call(&mut self,
1635 args
: &[P
<ast
::Expr
>]) -> io
::Result
<()> {
1636 try
!(self.print_expr_maybe_paren(func
));
1637 self.print_call_post(args
)
1640 fn print_expr_method_call(&mut self,
1641 ident
: ast
::SpannedIdent
,
1643 args
: &[P
<ast
::Expr
>]) -> io
::Result
<()> {
1644 let base_args
= &args
[1..];
1645 try
!(self.print_expr(&*args
[0]));
1646 try
!(word(&mut self.s
, "."));
1647 try
!(self.print_ident(ident
.node
));
1648 if !tys
.is_empty() {
1649 try
!(word(&mut self.s
, "::<"));
1650 try
!(self.commasep(Inconsistent
, tys
,
1651 |s
, ty
| s
.print_type(&**ty
)));
1652 try
!(word(&mut self.s
, ">"));
1654 self.print_call_post(base_args
)
1657 fn print_expr_binary(&mut self,
1660 rhs
: &ast
::Expr
) -> io
::Result
<()> {
1661 try
!(self.print_expr(lhs
));
1662 try
!(space(&mut self.s
));
1663 try
!(self.word_space(ast_util
::binop_to_string(op
.node
)));
1664 self.print_expr(rhs
)
1667 fn print_expr_unary(&mut self,
1669 expr
: &ast
::Expr
) -> io
::Result
<()> {
1670 try
!(word(&mut self.s
, ast_util
::unop_to_string(op
)));
1671 self.print_expr_maybe_paren(expr
)
1674 fn print_expr_addr_of(&mut self,
1675 mutability
: ast
::Mutability
,
1676 expr
: &ast
::Expr
) -> io
::Result
<()> {
1677 try
!(word(&mut self.s
, "&"));
1678 try
!(self.print_mutability(mutability
));
1679 self.print_expr_maybe_paren(expr
)
1682 pub fn print_expr(&mut self, expr
: &ast
::Expr
) -> io
::Result
<()> {
1683 try
!(self.maybe_print_comment(expr
.span
.lo
));
1684 try
!(self.ibox(indent_unit
));
1685 try
!(self.ann
.pre(self, NodeExpr(expr
)));
1687 ast
::ExprBox(ref place
, ref expr
) => {
1688 try
!(self.print_expr_box(place
, &**expr
));
1690 ast
::ExprVec(ref exprs
) => {
1691 try
!(self.print_expr_vec(&exprs
[..]));
1693 ast
::ExprRepeat(ref element
, ref count
) => {
1694 try
!(self.print_expr_repeat(&**element
, &**count
));
1696 ast
::ExprStruct(ref path
, ref fields
, ref wth
) => {
1697 try
!(self.print_expr_struct(path
, &fields
[..], wth
));
1699 ast
::ExprTup(ref exprs
) => {
1700 try
!(self.print_expr_tup(&exprs
[..]));
1702 ast
::ExprCall(ref func
, ref args
) => {
1703 try
!(self.print_expr_call(&**func
, &args
[..]));
1705 ast
::ExprMethodCall(ident
, ref tys
, ref args
) => {
1706 try
!(self.print_expr_method_call(ident
, &tys
[..], &args
[..]));
1708 ast
::ExprBinary(op
, ref lhs
, ref rhs
) => {
1709 try
!(self.print_expr_binary(op
, &**lhs
, &**rhs
));
1711 ast
::ExprUnary(op
, ref expr
) => {
1712 try
!(self.print_expr_unary(op
, &**expr
));
1714 ast
::ExprAddrOf(m
, ref expr
) => {
1715 try
!(self.print_expr_addr_of(m
, &**expr
));
1717 ast
::ExprLit(ref lit
) => {
1718 try
!(self.print_literal(&**lit
));
1720 ast
::ExprCast(ref expr
, ref ty
) => {
1721 try
!(self.print_expr(&**expr
));
1722 try
!(space(&mut self.s
));
1723 try
!(self.word_space("as"));
1724 try
!(self.print_type(&**ty
));
1726 ast
::ExprIf(ref test
, ref blk
, ref elseopt
) => {
1727 try
!(self.print_if(&**test
, &**blk
, elseopt
.as_ref().map(|e
| &**e
)));
1729 ast
::ExprIfLet(ref pat
, ref expr
, ref blk
, ref elseopt
) => {
1730 try
!(self.print_if_let(&**pat
, &**expr
, &** blk
, elseopt
.as_ref().map(|e
| &**e
)));
1732 ast
::ExprWhile(ref test
, ref blk
, opt_ident
) => {
1733 if let Some(ident
) = opt_ident
{
1734 try
!(self.print_ident(ident
));
1735 try
!(self.word_space(":"));
1737 try
!(self.head("while"));
1738 try
!(self.print_expr(&**test
));
1739 try
!(space(&mut self.s
));
1740 try
!(self.print_block(&**blk
));
1742 ast
::ExprWhileLet(ref pat
, ref expr
, ref blk
, opt_ident
) => {
1743 if let Some(ident
) = opt_ident
{
1744 try
!(self.print_ident(ident
));
1745 try
!(self.word_space(":"));
1747 try
!(self.head("while let"));
1748 try
!(self.print_pat(&**pat
));
1749 try
!(space(&mut self.s
));
1750 try
!(self.word_space("="));
1751 try
!(self.print_expr(&**expr
));
1752 try
!(space(&mut self.s
));
1753 try
!(self.print_block(&**blk
));
1755 ast
::ExprForLoop(ref pat
, ref iter
, ref blk
, opt_ident
) => {
1756 if let Some(ident
) = opt_ident
{
1757 try
!(self.print_ident(ident
));
1758 try
!(self.word_space(":"));
1760 try
!(self.head("for"));
1761 try
!(self.print_pat(&**pat
));
1762 try
!(space(&mut self.s
));
1763 try
!(self.word_space("in"));
1764 try
!(self.print_expr(&**iter
));
1765 try
!(space(&mut self.s
));
1766 try
!(self.print_block(&**blk
));
1768 ast
::ExprLoop(ref blk
, opt_ident
) => {
1769 if let Some(ident
) = opt_ident
{
1770 try
!(self.print_ident(ident
));
1771 try
!(self.word_space(":"));
1773 try
!(self.head("loop"));
1774 try
!(space(&mut self.s
));
1775 try
!(self.print_block(&**blk
));
1777 ast
::ExprMatch(ref expr
, ref arms
, _
) => {
1778 try
!(self.cbox(indent_unit
));
1780 try
!(self.word_nbsp("match"));
1781 try
!(self.print_expr(&**expr
));
1782 try
!(space(&mut self.s
));
1785 try
!(self.print_arm(arm
));
1787 try
!(self.bclose_(expr
.span
, indent_unit
));
1789 ast
::ExprClosure(capture_clause
, ref decl
, ref body
) => {
1790 try
!(self.print_capture_clause(capture_clause
));
1792 try
!(self.print_fn_block_args(&**decl
));
1793 try
!(space(&mut self.s
));
1795 let default_return
= match decl
.output
{
1796 ast
::DefaultReturn(..) => true,
1800 if !default_return
|| !body
.stmts
.is_empty() || body
.expr
.is_none() {
1801 try
!(self.print_block_unclosed(&**body
));
1803 // we extract the block, so as not to create another set of boxes
1804 match body
.expr
.as_ref().unwrap().node
{
1805 ast
::ExprBlock(ref blk
) => {
1806 try
!(self.print_block_unclosed(&**blk
));
1809 // this is a bare expression
1810 try
!(self.print_expr(body
.expr
.as_ref().map(|e
| &**e
).unwrap()));
1811 try
!(self.end()); // need to close a box
1815 // a box will be closed by print_expr, but we didn't want an overall
1816 // wrapper so we closed the corresponding opening. so create an
1817 // empty box to satisfy the close.
1820 ast
::ExprBlock(ref blk
) => {
1821 // containing cbox, will be closed by print-block at }
1822 try
!(self.cbox(indent_unit
));
1823 // head-box, will be closed by print-block after {
1825 try
!(self.print_block(&**blk
));
1827 ast
::ExprAssign(ref lhs
, ref rhs
) => {
1828 try
!(self.print_expr(&**lhs
));
1829 try
!(space(&mut self.s
));
1830 try
!(self.word_space("="));
1831 try
!(self.print_expr(&**rhs
));
1833 ast
::ExprAssignOp(op
, ref lhs
, ref rhs
) => {
1834 try
!(self.print_expr(&**lhs
));
1835 try
!(space(&mut self.s
));
1836 try
!(word(&mut self.s
, ast_util
::binop_to_string(op
.node
)));
1837 try
!(self.word_space("="));
1838 try
!(self.print_expr(&**rhs
));
1840 ast
::ExprField(ref expr
, id
) => {
1841 try
!(self.print_expr(&**expr
));
1842 try
!(word(&mut self.s
, "."));
1843 try
!(self.print_ident(id
.node
));
1845 ast
::ExprTupField(ref expr
, id
) => {
1846 try
!(self.print_expr(&**expr
));
1847 try
!(word(&mut self.s
, "."));
1848 try
!(self.print_usize(id
.node
));
1850 ast
::ExprIndex(ref expr
, ref index
) => {
1851 try
!(self.print_expr(&**expr
));
1852 try
!(word(&mut self.s
, "["));
1853 try
!(self.print_expr(&**index
));
1854 try
!(word(&mut self.s
, "]"));
1856 ast
::ExprRange(ref start
, ref end
) => {
1857 if let &Some(ref e
) = start
{
1858 try
!(self.print_expr(&**e
));
1860 try
!(word(&mut self.s
, ".."));
1861 if let &Some(ref e
) = end
{
1862 try
!(self.print_expr(&**e
));
1865 ast
::ExprPath(None
, ref path
) => {
1866 try
!(self.print_path(path
, true, 0))
1868 ast
::ExprPath(Some(ref qself
), ref path
) => {
1869 try
!(self.print_qpath(path
, qself
, true))
1871 ast
::ExprBreak(opt_ident
) => {
1872 try
!(word(&mut self.s
, "break"));
1873 try
!(space(&mut self.s
));
1874 if let Some(ident
) = opt_ident
{
1875 try
!(self.print_ident(ident
));
1876 try
!(space(&mut self.s
));
1879 ast
::ExprAgain(opt_ident
) => {
1880 try
!(word(&mut self.s
, "continue"));
1881 try
!(space(&mut self.s
));
1882 if let Some(ident
) = opt_ident
{
1883 try
!(self.print_ident(ident
));
1884 try
!(space(&mut self.s
))
1887 ast
::ExprRet(ref result
) => {
1888 try
!(word(&mut self.s
, "return"));
1891 try
!(word(&mut self.s
, " "));
1892 try
!(self.print_expr(&**expr
));
1897 ast
::ExprInlineAsm(ref a
) => {
1898 try
!(word(&mut self.s
, "asm!"));
1900 try
!(self.print_string(&a
.asm
, a
.asm_str_style
));
1901 try
!(self.word_space(":"));
1903 try
!(self.commasep(Inconsistent
, &a
.outputs
,
1904 |s
, &(ref co
, ref o
, is_rw
)| {
1905 match co
.slice_shift_char() {
1906 Some(('
='
, operand
)) if is_rw
=> {
1907 try
!(s
.print_string(&format
!("+{}", operand
),
1910 _
=> try
!(s
.print_string(&co
, ast
::CookedStr
))
1913 try
!(s
.print_expr(&**o
));
1917 try
!(space(&mut self.s
));
1918 try
!(self.word_space(":"));
1920 try
!(self.commasep(Inconsistent
, &a
.inputs
,
1921 |s
, &(ref co
, ref o
)| {
1922 try
!(s
.print_string(&co
, ast
::CookedStr
));
1924 try
!(s
.print_expr(&**o
));
1928 try
!(space(&mut self.s
));
1929 try
!(self.word_space(":"));
1931 try
!(self.commasep(Inconsistent
, &a
.clobbers
,
1933 try
!(s
.print_string(&co
, ast
::CookedStr
));
1937 let mut options
= vec
!();
1939 options
.push("volatile");
1942 options
.push("alignstack");
1944 if a
.dialect
== ast
::AsmDialect
::AsmIntel
{
1945 options
.push("intel");
1948 if !options
.is_empty() {
1949 try
!(space(&mut self.s
));
1950 try
!(self.word_space(":"));
1951 try
!(self.commasep(Inconsistent
, &*options
,
1953 try
!(s
.print_string(co
, ast
::CookedStr
));
1958 try
!(self.pclose());
1960 ast
::ExprMac(ref m
) => try
!(self.print_mac(m
, token
::Paren
)),
1961 ast
::ExprParen(ref e
) => {
1963 try
!(self.print_expr(&**e
));
1964 try
!(self.pclose());
1967 try
!(self.ann
.post(self, NodeExpr(expr
)));
1971 pub fn print_local_decl(&mut self, loc
: &ast
::Local
) -> io
::Result
<()> {
1972 try
!(self.print_pat(&*loc
.pat
));
1973 if let Some(ref ty
) = loc
.ty
{
1974 try
!(self.word_space(":"));
1975 try
!(self.print_type(&**ty
));
1980 pub fn print_decl(&mut self, decl
: &ast
::Decl
) -> io
::Result
<()> {
1981 try
!(self.maybe_print_comment(decl
.span
.lo
));
1983 ast
::DeclLocal(ref loc
) => {
1984 try
!(self.space_if_not_bol());
1985 try
!(self.ibox(indent_unit
));
1986 try
!(self.word_nbsp("let"));
1988 try
!(self.ibox(indent_unit
));
1989 try
!(self.print_local_decl(&**loc
));
1991 if let Some(ref init
) = loc
.init
{
1993 try
!(self.word_space("="));
1994 try
!(self.print_expr(&**init
));
1998 ast
::DeclItem(ref item
) => self.print_item(&**item
)
2002 pub fn print_ident(&mut self, ident
: ast
::Ident
) -> io
::Result
<()> {
2003 try
!(word(&mut self.s
, &token
::get_ident(ident
)));
2004 self.ann
.post(self, NodeIdent(&ident
))
2007 pub fn print_usize(&mut self, i
: usize) -> io
::Result
<()> {
2008 word(&mut self.s
, &i
.to_string())
2011 pub fn print_name(&mut self, name
: ast
::Name
) -> io
::Result
<()> {
2012 try
!(word(&mut self.s
, &token
::get_name(name
)));
2013 self.ann
.post(self, NodeName(&name
))
2016 pub fn print_for_decl(&mut self, loc
: &ast
::Local
,
2017 coll
: &ast
::Expr
) -> io
::Result
<()> {
2018 try
!(self.print_local_decl(loc
));
2019 try
!(space(&mut self.s
));
2020 try
!(self.word_space("in"));
2021 self.print_expr(coll
)
2024 fn print_path(&mut self,
2026 colons_before_params
: bool
,
2030 try
!(self.maybe_print_comment(path
.span
.lo
));
2032 let mut first
= !path
.global
;
2033 for segment
in &path
.segments
[..path
.segments
.len()-depth
] {
2037 try
!(word(&mut self.s
, "::"))
2040 try
!(self.print_ident(segment
.identifier
));
2042 try
!(self.print_path_parameters(&segment
.parameters
, colons_before_params
));
2048 fn print_qpath(&mut self,
2051 colons_before_params
: bool
)
2054 try
!(word(&mut self.s
, "<"));
2055 try
!(self.print_type(&qself
.ty
));
2056 if qself
.position
> 0 {
2057 try
!(space(&mut self.s
));
2058 try
!(self.word_space("as"));
2059 let depth
= path
.segments
.len() - qself
.position
;
2060 try
!(self.print_path(&path
, false, depth
));
2062 try
!(word(&mut self.s
, ">"));
2063 try
!(word(&mut self.s
, "::"));
2064 let item_segment
= path
.segments
.last().unwrap();
2065 try
!(self.print_ident(item_segment
.identifier
));
2066 self.print_path_parameters(&item_segment
.parameters
, colons_before_params
)
2069 fn print_path_parameters(&mut self,
2070 parameters
: &ast
::PathParameters
,
2071 colons_before_params
: bool
)
2074 if parameters
.is_empty() {
2078 if colons_before_params
{
2079 try
!(word(&mut self.s
, "::"))
2083 ast
::AngleBracketedParameters(ref data
) => {
2084 try
!(word(&mut self.s
, "<"));
2086 let mut comma
= false;
2087 for lifetime
in &data
.lifetimes
{
2089 try
!(self.word_space(","))
2091 try
!(self.print_lifetime(lifetime
));
2095 if !data
.types
.is_empty() {
2097 try
!(self.word_space(","))
2102 |s
, ty
| s
.print_type(&**ty
)));
2106 for binding
in &*data
.bindings
{
2108 try
!(self.word_space(","))
2110 try
!(self.print_ident(binding
.ident
));
2111 try
!(space(&mut self.s
));
2112 try
!(self.word_space("="));
2113 try
!(self.print_type(&*binding
.ty
));
2117 try
!(word(&mut self.s
, ">"))
2120 ast
::ParenthesizedParameters(ref data
) => {
2121 try
!(word(&mut self.s
, "("));
2125 |s
, ty
| s
.print_type(&**ty
)));
2126 try
!(word(&mut self.s
, ")"));
2131 try
!(self.space_if_not_bol());
2132 try
!(self.word_space("->"));
2133 try
!(self.print_type(&**ty
));
2142 pub fn print_pat(&mut self, pat
: &ast
::Pat
) -> io
::Result
<()> {
2143 try
!(self.maybe_print_comment(pat
.span
.lo
));
2144 try
!(self.ann
.pre(self, NodePat(pat
)));
2145 /* Pat isn't normalized, but the beauty of it
2146 is that it doesn't matter */
2148 ast
::PatWild(ast
::PatWildSingle
) => try
!(word(&mut self.s
, "_")),
2149 ast
::PatWild(ast
::PatWildMulti
) => try
!(word(&mut self.s
, "..")),
2150 ast
::PatIdent(binding_mode
, ref path1
, ref sub
) => {
2151 match binding_mode
{
2152 ast
::BindByRef(mutbl
) => {
2153 try
!(self.word_nbsp("ref"));
2154 try
!(self.print_mutability(mutbl
));
2156 ast
::BindByValue(ast
::MutImmutable
) => {}
2157 ast
::BindByValue(ast
::MutMutable
) => {
2158 try
!(self.word_nbsp("mut"));
2161 try
!(self.print_ident(path1
.node
));
2164 try
!(word(&mut self.s
, "@"));
2165 try
!(self.print_pat(&**p
));
2170 ast
::PatEnum(ref path
, ref args_
) => {
2171 try
!(self.print_path(path
, true, 0));
2173 None
=> try
!(word(&mut self.s
, "(..)")),
2175 if !args
.is_empty() {
2177 try
!(self.commasep(Inconsistent
, &args
[..],
2178 |s
, p
| s
.print_pat(&**p
)));
2179 try
!(self.pclose());
2184 ast
::PatQPath(ref qself
, ref path
) => {
2185 try
!(self.print_qpath(path
, qself
, false));
2187 ast
::PatStruct(ref path
, ref fields
, etc
) => {
2188 try
!(self.print_path(path
, true, 0));
2190 try
!(self.word_space("{"));
2191 try
!(self.commasep_cmnt(
2192 Consistent
, &fields
[..],
2194 try
!(s
.cbox(indent_unit
));
2195 if !f
.node
.is_shorthand
{
2196 try
!(s
.print_ident(f
.node
.ident
));
2197 try
!(s
.word_nbsp(":"));
2199 try
!(s
.print_pat(&*f
.node
.pat
));
2202 |f
| f
.node
.pat
.span
));
2204 if !fields
.is_empty() { try!(self.word_space(",")); }
2205 try
!(word(&mut self.s
, ".."));
2207 try
!(space(&mut self.s
));
2208 try
!(word(&mut self.s
, "}"));
2210 ast
::PatTup(ref elts
) => {
2212 try
!(self.commasep(Inconsistent
,
2214 |s
, p
| s
.print_pat(&**p
)));
2215 if elts
.len() == 1 {
2216 try
!(word(&mut self.s
, ","));
2218 try
!(self.pclose());
2220 ast
::PatBox(ref inner
) => {
2221 try
!(word(&mut self.s
, "box "));
2222 try
!(self.print_pat(&**inner
));
2224 ast
::PatRegion(ref inner
, mutbl
) => {
2225 try
!(word(&mut self.s
, "&"));
2226 if mutbl
== ast
::MutMutable
{
2227 try
!(word(&mut self.s
, "mut "));
2229 try
!(self.print_pat(&**inner
));
2231 ast
::PatLit(ref e
) => try
!(self.print_expr(&**e
)),
2232 ast
::PatRange(ref begin
, ref end
) => {
2233 try
!(self.print_expr(&**begin
));
2234 try
!(space(&mut self.s
));
2235 try
!(word(&mut self.s
, "..."));
2236 try
!(self.print_expr(&**end
));
2238 ast
::PatVec(ref before
, ref slice
, ref after
) => {
2239 try
!(word(&mut self.s
, "["));
2240 try
!(self.commasep(Inconsistent
,
2242 |s
, p
| s
.print_pat(&**p
)));
2243 if let Some(ref p
) = *slice
{
2244 if !before
.is_empty() { try!(self.word_space(",")); }
2245 try
!(self.print_pat(&**p
));
2247 ast
::Pat { node: ast::PatWild(ast::PatWildMulti), .. }
=> {
2248 // this case is handled by print_pat
2250 _
=> try
!(word(&mut self.s
, "..")),
2252 if !after
.is_empty() { try!(self.word_space(",")); }
2254 try
!(self.commasep(Inconsistent
,
2256 |s
, p
| s
.print_pat(&**p
)));
2257 try
!(word(&mut self.s
, "]"));
2259 ast
::PatMac(ref m
) => try
!(self.print_mac(m
, token
::Paren
)),
2261 self.ann
.post(self, NodePat(pat
))
2264 fn print_arm(&mut self, arm
: &ast
::Arm
) -> io
::Result
<()> {
2265 // I have no idea why this check is necessary, but here it
2267 if arm
.attrs
.is_empty() {
2268 try
!(space(&mut self.s
));
2270 try
!(self.cbox(indent_unit
));
2272 try
!(self.print_outer_attributes(&arm
.attrs
));
2273 let mut first
= true;
2274 for p
in &arm
.pats
{
2278 try
!(space(&mut self.s
));
2279 try
!(self.word_space("|"));
2281 try
!(self.print_pat(&**p
));
2283 try
!(space(&mut self.s
));
2284 if let Some(ref e
) = arm
.guard
{
2285 try
!(self.word_space("if"));
2286 try
!(self.print_expr(&**e
));
2287 try
!(space(&mut self.s
));
2289 try
!(self.word_space("=>"));
2291 match arm
.body
.node
{
2292 ast
::ExprBlock(ref blk
) => {
2293 // the block will close the pattern's ibox
2294 try
!(self.print_block_unclosed_indent(&**blk
, indent_unit
));
2296 // If it is a user-provided unsafe block, print a comma after it
2297 if let ast
::UnsafeBlock(ast
::UserProvided
) = blk
.rules
{
2298 try
!(word(&mut self.s
, ","));
2302 try
!(self.end()); // close the ibox for the pattern
2303 try
!(self.print_expr(&*arm
.body
));
2304 try
!(word(&mut self.s
, ","));
2307 self.end() // close enclosing cbox
2310 // Returns whether it printed anything
2311 fn print_explicit_self(&mut self,
2312 explicit_self
: &ast
::ExplicitSelf_
,
2313 mutbl
: ast
::Mutability
) -> io
::Result
<bool
> {
2314 try
!(self.print_mutability(mutbl
));
2315 match *explicit_self
{
2316 ast
::SelfStatic
=> { return Ok(false); }
2317 ast
::SelfValue(_
) => {
2318 try
!(word(&mut self.s
, "self"));
2320 ast
::SelfRegion(ref lt
, m
, _
) => {
2321 try
!(word(&mut self.s
, "&"));
2322 try
!(self.print_opt_lifetime(lt
));
2323 try
!(self.print_mutability(m
));
2324 try
!(word(&mut self.s
, "self"));
2326 ast
::SelfExplicit(ref typ
, _
) => {
2327 try
!(word(&mut self.s
, "self"));
2328 try
!(self.word_space(":"));
2329 try
!(self.print_type(&**typ
));
2335 pub fn print_fn(&mut self,
2337 unsafety
: ast
::Unsafety
,
2339 name
: Option
<ast
::Ident
>,
2340 generics
: &ast
::Generics
,
2341 opt_explicit_self
: Option
<&ast
::ExplicitSelf_
>,
2342 vis
: ast
::Visibility
) -> io
::Result
<()> {
2343 try
!(self.print_fn_header_info(unsafety
, abi
, vis
));
2345 if let Some(name
) = name
{
2347 try
!(self.print_ident(name
));
2349 try
!(self.print_generics(generics
));
2350 try
!(self.print_fn_args_and_ret(decl
, opt_explicit_self
));
2351 self.print_where_clause(&generics
.where_clause
)
2354 pub fn print_fn_args(&mut self, decl
: &ast
::FnDecl
,
2355 opt_explicit_self
: Option
<&ast
::ExplicitSelf_
>)
2357 // It is unfortunate to duplicate the commasep logic, but we want the
2358 // self type and the args all in the same box.
2359 try
!(self.rbox(0, Inconsistent
));
2360 let mut first
= true;
2361 if let Some(explicit_self
) = opt_explicit_self
{
2362 let m
= match explicit_self
{
2363 &ast
::SelfStatic
=> ast
::MutImmutable
,
2364 _
=> match decl
.inputs
[0].pat
.node
{
2365 ast
::PatIdent(ast
::BindByValue(m
), _
, _
) => m
,
2366 _
=> ast
::MutImmutable
2369 first
= !try
!(self.print_explicit_self(explicit_self
, m
));
2372 // HACK(eddyb) ignore the separately printed self argument.
2373 let args
= if first
{
2380 if first { first = false; }
else { try!(self.word_space(",")); }
2381 try
!(self.print_arg(arg
));
2387 pub fn print_fn_args_and_ret(&mut self, decl
: &ast
::FnDecl
,
2388 opt_explicit_self
: Option
<&ast
::ExplicitSelf_
>)
2391 try
!(self.print_fn_args(decl
, opt_explicit_self
));
2393 try
!(word(&mut self.s
, ", ..."));
2395 try
!(self.pclose());
2397 self.print_fn_output(decl
)
2400 pub fn print_fn_block_args(
2404 try
!(word(&mut self.s
, "|"));
2405 try
!(self.print_fn_args(decl
, None
));
2406 try
!(word(&mut self.s
, "|"));
2408 if let ast
::DefaultReturn(..) = decl
.output
{
2412 try
!(self.space_if_not_bol());
2413 try
!(self.word_space("->"));
2415 ast
::Return(ref ty
) => {
2416 try
!(self.print_type(&**ty
));
2417 self.maybe_print_comment(ty
.span
.lo
)
2419 ast
::DefaultReturn(..) => unreachable
!(),
2420 ast
::NoReturn(span
) => {
2421 try
!(self.word_nbsp("!"));
2422 self.maybe_print_comment(span
.lo
)
2427 pub fn print_capture_clause(&mut self, capture_clause
: ast
::CaptureClause
)
2429 match capture_clause
{
2430 ast
::CaptureByValue
=> self.word_space("move"),
2431 ast
::CaptureByRef
=> Ok(()),
2435 pub fn print_bounds(&mut self,
2437 bounds
: &[ast
::TyParamBound
])
2439 if !bounds
.is_empty() {
2440 try
!(word(&mut self.s
, prefix
));
2441 let mut first
= true;
2442 for bound
in bounds
{
2447 try
!(self.word_space("+"));
2451 TraitTyParamBound(ref tref
, TraitBoundModifier
::None
) => {
2452 self.print_poly_trait_ref(tref
)
2454 TraitTyParamBound(ref tref
, TraitBoundModifier
::Maybe
) => {
2455 try
!(word(&mut self.s
, "?"));
2456 self.print_poly_trait_ref(tref
)
2458 RegionTyParamBound(ref lt
) => {
2459 self.print_lifetime(lt
)
2469 pub fn print_lifetime(&mut self,
2470 lifetime
: &ast
::Lifetime
)
2473 self.print_name(lifetime
.name
)
2476 pub fn print_lifetime_def(&mut self,
2477 lifetime
: &ast
::LifetimeDef
)
2480 try
!(self.print_lifetime(&lifetime
.lifetime
));
2482 for v
in &lifetime
.bounds
{
2483 try
!(word(&mut self.s
, sep
));
2484 try
!(self.print_lifetime(v
));
2490 pub fn print_generics(&mut self,
2491 generics
: &ast
::Generics
)
2494 let total
= generics
.lifetimes
.len() + generics
.ty_params
.len();
2499 try
!(word(&mut self.s
, "<"));
2501 let mut ints
= Vec
::new();
2506 try
!(self.commasep(Inconsistent
, &ints
[..], |s
, &idx
| {
2507 if idx
< generics
.lifetimes
.len() {
2508 let lifetime
= &generics
.lifetimes
[idx
];
2509 s
.print_lifetime_def(lifetime
)
2511 let idx
= idx
- generics
.lifetimes
.len();
2512 let param
= &generics
.ty_params
[idx
];
2513 s
.print_ty_param(param
)
2517 try
!(word(&mut self.s
, ">"));
2521 pub fn print_ty_param(&mut self, param
: &ast
::TyParam
) -> io
::Result
<()> {
2522 try
!(self.print_ident(param
.ident
));
2523 try
!(self.print_bounds(":", ¶m
.bounds
));
2524 match param
.default {
2525 Some(ref default) => {
2526 try
!(space(&mut self.s
));
2527 try
!(self.word_space("="));
2528 self.print_type(&**default)
2534 pub fn print_where_clause(&mut self, where_clause
: &ast
::WhereClause
)
2536 if where_clause
.predicates
.is_empty() {
2540 try
!(space(&mut self.s
));
2541 try
!(self.word_space("where"));
2543 for (i
, predicate
) in where_clause
.predicates
.iter().enumerate() {
2545 try
!(self.word_space(","));
2549 &ast
::WherePredicate
::BoundPredicate(ast
::WhereBoundPredicate
{ref bound_lifetimes
,
2553 try
!(self.print_formal_lifetime_list(bound_lifetimes
));
2554 try
!(self.print_type(&**bounded_ty
));
2555 try
!(self.print_bounds(":", bounds
));
2557 &ast
::WherePredicate
::RegionPredicate(ast
::WhereRegionPredicate
{ref lifetime
,
2560 try
!(self.print_lifetime(lifetime
));
2561 try
!(word(&mut self.s
, ":"));
2563 for (i
, bound
) in bounds
.iter().enumerate() {
2564 try
!(self.print_lifetime(bound
));
2567 try
!(word(&mut self.s
, ":"));
2571 &ast
::WherePredicate
::EqPredicate(ast
::WhereEqPredicate{ref path, ref ty, ..}
) => {
2572 try
!(self.print_path(path
, false, 0));
2573 try
!(space(&mut self.s
));
2574 try
!(self.word_space("="));
2575 try
!(self.print_type(&**ty
));
2583 pub fn print_meta_item(&mut self, item
: &ast
::MetaItem
) -> io
::Result
<()> {
2584 try
!(self.ibox(indent_unit
));
2586 ast
::MetaWord(ref name
) => {
2587 try
!(word(&mut self.s
, &name
));
2589 ast
::MetaNameValue(ref name
, ref value
) => {
2590 try
!(self.word_space(&name
[..]));
2591 try
!(self.word_space("="));
2592 try
!(self.print_literal(value
));
2594 ast
::MetaList(ref name
, ref items
) => {
2595 try
!(word(&mut self.s
, &name
));
2597 try
!(self.commasep(Consistent
,
2599 |s
, i
| s
.print_meta_item(&**i
)));
2600 try
!(self.pclose());
2606 pub fn print_view_path(&mut self, vp
: &ast
::ViewPath
) -> io
::Result
<()> {
2608 ast
::ViewPathSimple(ident
, ref path
) => {
2609 try
!(self.print_path(path
, false, 0));
2611 // FIXME(#6993) can't compare identifiers directly here
2612 if path
.segments
.last().unwrap().identifier
.name
!=
2614 try
!(space(&mut self.s
));
2615 try
!(self.word_space("as"));
2616 try
!(self.print_ident(ident
));
2622 ast
::ViewPathGlob(ref path
) => {
2623 try
!(self.print_path(path
, false, 0));
2624 word(&mut self.s
, "::*")
2627 ast
::ViewPathList(ref path
, ref idents
) => {
2628 if path
.segments
.is_empty() {
2629 try
!(word(&mut self.s
, "{"));
2631 try
!(self.print_path(path
, false, 0));
2632 try
!(word(&mut self.s
, "::{"));
2634 try
!(self.commasep(Inconsistent
, &idents
[..], |s
, w
| {
2636 ast
::PathListIdent { name, .. }
=> {
2639 ast
::PathListMod { .. }
=> {
2640 word(&mut s
.s
, "self")
2644 word(&mut self.s
, "}")
2649 pub fn print_mutability(&mut self,
2650 mutbl
: ast
::Mutability
) -> io
::Result
<()> {
2652 ast
::MutMutable
=> self.word_nbsp("mut"),
2653 ast
::MutImmutable
=> Ok(()),
2657 pub fn print_mt(&mut self, mt
: &ast
::MutTy
) -> io
::Result
<()> {
2658 try
!(self.print_mutability(mt
.mutbl
));
2659 self.print_type(&*mt
.ty
)
2662 pub fn print_arg(&mut self, input
: &ast
::Arg
) -> io
::Result
<()> {
2663 try
!(self.ibox(indent_unit
));
2664 match input
.ty
.node
{
2665 ast
::TyInfer
=> try
!(self.print_pat(&*input
.pat
)),
2667 match input
.pat
.node
{
2668 ast
::PatIdent(_
, ref path1
, _
) if
2670 parse
::token
::special_idents
::invalid
.name
=> {
2674 try
!(self.print_pat(&*input
.pat
));
2675 try
!(word(&mut self.s
, ":"));
2676 try
!(space(&mut self.s
));
2679 try
!(self.print_type(&*input
.ty
));
2685 pub fn print_fn_output(&mut self, decl
: &ast
::FnDecl
) -> io
::Result
<()> {
2686 if let ast
::DefaultReturn(..) = decl
.output
{
2690 try
!(self.space_if_not_bol());
2691 try
!(self.ibox(indent_unit
));
2692 try
!(self.word_space("->"));
2695 try
!(self.word_nbsp("!")),
2696 ast
::DefaultReturn(..) => unreachable
!(),
2697 ast
::Return(ref ty
) =>
2698 try
!(self.print_type(&**ty
))
2703 ast
::Return(ref output
) => self.maybe_print_comment(output
.span
.lo
),
2708 pub fn print_ty_fn(&mut self,
2710 unsafety
: ast
::Unsafety
,
2712 name
: Option
<ast
::Ident
>,
2713 generics
: &ast
::Generics
,
2714 opt_explicit_self
: Option
<&ast
::ExplicitSelf_
>)
2716 try
!(self.ibox(indent_unit
));
2717 if !generics
.lifetimes
.is_empty() || !generics
.ty_params
.is_empty() {
2718 try
!(word(&mut self.s
, "for"));
2719 try
!(self.print_generics(generics
));
2721 let generics
= ast
::Generics
{
2722 lifetimes
: Vec
::new(),
2723 ty_params
: OwnedSlice
::empty(),
2724 where_clause
: ast
::WhereClause
{
2725 id
: ast
::DUMMY_NODE_ID
,
2726 predicates
: Vec
::new(),
2729 try
!(self.print_fn(decl
, unsafety
, abi
, name
,
2730 &generics
, opt_explicit_self
,
2735 pub fn maybe_print_trailing_comment(&mut self, span
: codemap
::Span
,
2736 next_pos
: Option
<BytePos
>)
2738 let cm
= match self.cm
{
2742 match self.next_comment() {
2744 if (*cmnt
).style
!= comments
::Trailing { return Ok(()) }
2745 let span_line
= cm
.lookup_char_pos(span
.hi
);
2746 let comment_line
= cm
.lookup_char_pos((*cmnt
).pos
);
2747 let mut next
= (*cmnt
).pos
+ BytePos(1);
2748 match next_pos { None => (), Some(p) => next = p }
2749 if span
.hi
< (*cmnt
).pos
&& (*cmnt
).pos
< next
&&
2750 span_line
.line
== comment_line
.line
{
2751 try
!(self.print_comment(cmnt
));
2752 self.cur_cmnt_and_lit
.cur_cmnt
+= 1;
2760 pub fn print_remaining_comments(&mut self) -> io
::Result
<()> {
2761 // If there aren't any remaining comments, then we need to manually
2762 // make sure there is a line break at the end.
2763 if self.next_comment().is_none() {
2764 try
!(hardbreak(&mut self.s
));
2767 match self.next_comment() {
2769 try
!(self.print_comment(cmnt
));
2770 self.cur_cmnt_and_lit
.cur_cmnt
+= 1;
2778 pub fn print_literal(&mut self, lit
: &ast
::Lit
) -> io
::Result
<()> {
2779 try
!(self.maybe_print_comment(lit
.span
.lo
));
2780 match self.next_lit(lit
.span
.lo
) {
2782 return word(&mut self.s
, &(*ltrl
).lit
);
2787 ast
::LitStr(ref st
, style
) => self.print_string(&st
, style
),
2788 ast
::LitByte(byte
) => {
2789 let mut res
= String
::from("b'");
2790 res
.extend(ascii
::escape_default(byte
).map(|c
| c
as char));
2792 word(&mut self.s
, &res
[..])
2794 ast
::LitChar(ch
) => {
2795 let mut res
= String
::from("'");
2796 res
.extend(ch
.escape_default());
2798 word(&mut self.s
, &res
[..])
2800 ast
::LitInt(i
, t
) => {
2802 ast
::SignedIntLit(st
, ast
::Plus
) => {
2804 &ast_util
::int_ty_to_string(st
, Some(i
as i64)))
2806 ast
::SignedIntLit(st
, ast
::Minus
) => {
2807 let istr
= ast_util
::int_ty_to_string(st
, Some(-(i
as i64)));
2809 &format
!("-{}", istr
))
2811 ast
::UnsignedIntLit(ut
) => {
2812 word(&mut self.s
, &ast_util
::uint_ty_to_string(ut
, Some(i
)))
2814 ast
::UnsuffixedIntLit(ast
::Plus
) => {
2815 word(&mut self.s
, &format
!("{}", i
))
2817 ast
::UnsuffixedIntLit(ast
::Minus
) => {
2818 word(&mut self.s
, &format
!("-{}", i
))
2822 ast
::LitFloat(ref f
, t
) => {
2827 &ast_util
::float_ty_to_string(t
)))
2829 ast
::LitFloatUnsuffixed(ref f
) => word(&mut self.s
, &f
[..]),
2830 ast
::LitBool(val
) => {
2831 if val { word(&mut self.s, "true") }
else { word(&mut self.s, "false") }
2833 ast
::LitBinary(ref v
) => {
2834 let mut escaped
: String
= String
::new();
2836 escaped
.extend(ascii
::escape_default(ch
)
2837 .map(|c
| c
as char));
2839 word(&mut self.s
, &format
!("b\"{}\"", escaped
))
2844 pub fn next_lit(&mut self, pos
: BytePos
) -> Option
<comments
::Literal
> {
2845 match self.literals
{
2847 while self.cur_cmnt_and_lit
.cur_lit
< lits
.len() {
2848 let ltrl
= (*lits
)[self.cur_cmnt_and_lit
.cur_lit
].clone();
2849 if ltrl
.pos
> pos { return None; }
2850 self.cur_cmnt_and_lit
.cur_lit
+= 1;
2851 if ltrl
.pos
== pos { return Some(ltrl); }
2859 pub fn maybe_print_comment(&mut self, pos
: BytePos
) -> io
::Result
<()> {
2861 match self.next_comment() {
2863 if (*cmnt
).pos
< pos
{
2864 try
!(self.print_comment(cmnt
));
2865 self.cur_cmnt_and_lit
.cur_cmnt
+= 1;
2874 pub fn print_comment(&mut self,
2875 cmnt
: &comments
::Comment
) -> io
::Result
<()> {
2877 comments
::Mixed
=> {
2878 assert_eq
!(cmnt
.lines
.len(), 1);
2879 try
!(zerobreak(&mut self.s
));
2880 try
!(word(&mut self.s
, &cmnt
.lines
[0]));
2881 zerobreak(&mut self.s
)
2883 comments
::Isolated
=> {
2884 try
!(self.hardbreak_if_not_bol());
2885 for line
in &cmnt
.lines
{
2886 // Don't print empty lines because they will end up as trailing
2888 if !line
.is_empty() {
2889 try
!(word(&mut self.s
, &line
[..]));
2891 try
!(hardbreak(&mut self.s
));
2895 comments
::Trailing
=> {
2896 try
!(word(&mut self.s
, " "));
2897 if cmnt
.lines
.len() == 1 {
2898 try
!(word(&mut self.s
, &cmnt
.lines
[0]));
2899 hardbreak(&mut self.s
)
2902 for line
in &cmnt
.lines
{
2903 if !line
.is_empty() {
2904 try
!(word(&mut self.s
, &line
[..]));
2906 try
!(hardbreak(&mut self.s
));
2911 comments
::BlankLine
=> {
2912 // We need to do at least one, possibly two hardbreaks.
2913 let is_semi
= match self.s
.last_token() {
2914 pp
::Token
::String(s
, _
) => ";" == s
,
2917 if is_semi
|| self.is_begin() || self.is_end() {
2918 try
!(hardbreak(&mut self.s
));
2920 hardbreak(&mut self.s
)
2925 pub fn print_string(&mut self, st
: &str,
2926 style
: ast
::StrStyle
) -> io
::Result
<()> {
2927 let st
= match style
{
2929 (format
!("\"{}\"", st
.escape_default()))
2932 (format
!("r{delim}\"{string}\"{delim}",
2933 delim
=repeat("#", n
),
2937 word(&mut self.s
, &st
[..])
2940 pub fn next_comment(&mut self) -> Option
<comments
::Comment
> {
2941 match self.comments
{
2942 Some(ref cmnts
) => {
2943 if self.cur_cmnt_and_lit
.cur_cmnt
< cmnts
.len() {
2944 Some(cmnts
[self.cur_cmnt_and_lit
.cur_cmnt
].clone())
2953 pub fn print_opt_abi_and_extern_if_nondefault(&mut self,
2954 opt_abi
: Option
<abi
::Abi
>)
2957 Some(abi
::Rust
) => Ok(()),
2959 try
!(self.word_nbsp("extern"));
2960 self.word_nbsp(&abi
.to_string())
2966 pub fn print_extern_opt_abi(&mut self,
2967 opt_abi
: Option
<abi
::Abi
>) -> io
::Result
<()> {
2970 try
!(self.word_nbsp("extern"));
2971 self.word_nbsp(&abi
.to_string())
2977 pub fn print_fn_header_info(&mut self,
2978 unsafety
: ast
::Unsafety
,
2980 vis
: ast
::Visibility
) -> io
::Result
<()> {
2981 try
!(word(&mut self.s
, &visibility_qualified(vis
, "")));
2982 try
!(self.print_unsafety(unsafety
));
2984 if abi
!= abi
::Rust
{
2985 try
!(self.word_nbsp("extern"));
2986 try
!(self.word_nbsp(&abi
.to_string()));
2989 word(&mut self.s
, "fn")
2992 pub fn print_unsafety(&mut self, s
: ast
::Unsafety
) -> io
::Result
<()> {
2994 ast
::Unsafety
::Normal
=> Ok(()),
2995 ast
::Unsafety
::Unsafe
=> self.word_nbsp("unsafe"),
3000 fn repeat(s
: &str, n
: usize) -> String { iter::repeat(s).take(n).collect() }
3012 fn test_fun_to_string() {
3013 let abba_ident
= token
::str_to_ident("abba");
3015 let decl
= ast
::FnDecl
{
3017 output
: ast
::DefaultReturn(codemap
::DUMMY_SP
),
3020 let generics
= ast_util
::empty_generics();
3021 assert_eq
!(fun_to_string(&decl
, ast
::Unsafety
::Normal
, abba_ident
,
3027 fn test_variant_to_string() {
3028 let ident
= token
::str_to_ident("principal_skinner");
3030 let var
= codemap
::respan(codemap
::DUMMY_SP
, ast
::Variant_
{
3033 // making this up as I go.... ?
3034 kind
: ast
::TupleVariantKind(Vec
::new()),
3040 let varstr
= variant_to_string(&var
);
3041 assert_eq
!(varstr
, "pub principal_skinner");
3045 fn test_signed_int_to_string() {
3046 let pos_int
= ast
::LitInt(42, ast
::SignedIntLit(ast
::TyI32
, ast
::Plus
));
3047 let neg_int
= ast
::LitInt((!42 + 1) as u64, ast
::SignedIntLit(ast
::TyI32
, ast
::Minus
));
3048 assert_eq
!(format
!("-{}", lit_to_string(&codemap
::dummy_spanned(pos_int
))),
3049 lit_to_string(&codemap
::dummy_spanned(neg_int
)));