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
::*;
14 use ast
::{self, TokenTree, BlockCheckMode, PatKind}
;
15 use ast
::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}
;
17 use attr
::ThinAttributesExt
;
18 use util
::parser
::AssocOp
;
20 use attr
::{AttrMetaMethods, AttributeMethods}
;
21 use codemap
::{self, CodeMap, BytePos}
;
23 use parse
::token
::{self, BinOpToken, Token, InternedString}
;
24 use parse
::lexer
::comments
;
26 use print
::pp
::{self, break_offset, word, space, zerobreak, hardbreak}
;
27 use print
::pp
::{Breaks, eof}
;
28 use print
::pp
::Breaks
::{Consistent, Inconsistent}
;
33 use std
::io
::{self, Write, Read}
;
36 pub enum AnnNode
<'a
> {
37 NodeIdent(&'a ast
::Ident
),
38 NodeName(&'a ast
::Name
),
39 NodeBlock(&'a ast
::Block
),
40 NodeItem(&'a ast
::Item
),
41 NodeSubItem(ast
::NodeId
),
42 NodeExpr(&'a ast
::Expr
),
43 NodePat(&'a ast
::Pat
),
47 fn pre(&self, _state
: &mut State
, _node
: AnnNode
) -> io
::Result
<()> { Ok(()) }
48 fn post(&self, _state
: &mut State
, _node
: AnnNode
) -> io
::Result
<()> { Ok(()) }
51 #[derive(Copy, Clone)]
54 impl PpAnn
for NoAnn {}
56 #[derive(Copy, Clone)]
57 pub struct CurrentCommentAndLiteral
{
62 pub struct State
<'a
> {
63 pub s
: pp
::Printer
<'a
>,
64 cm
: Option
<&'a CodeMap
>,
65 comments
: Option
<Vec
<comments
::Comment
> >,
66 literals
: Option
<Vec
<comments
::Literal
> >,
67 cur_cmnt_and_lit
: CurrentCommentAndLiteral
,
68 boxes
: Vec
<pp
::Breaks
>,
72 pub fn rust_printer
<'a
>(writer
: Box
<Write
+'a
>) -> State
<'a
> {
73 static NO_ANN
: NoAnn
= NoAnn
;
74 rust_printer_annotated(writer
, &NO_ANN
)
77 pub fn rust_printer_annotated
<'a
>(writer
: Box
<Write
+'a
>,
78 ann
: &'a PpAnn
) -> State
<'a
> {
80 s
: pp
::mk_printer(writer
, DEFAULT_COLUMNS
),
84 cur_cmnt_and_lit
: CurrentCommentAndLiteral
{
93 pub const INDENT_UNIT
: usize = 4;
95 pub const DEFAULT_COLUMNS
: usize = 78;
97 /// Requires you to pass an input filename and reader so that
98 /// it can scan the input text for comments and literals to
100 pub fn print_crate
<'a
>(cm
: &'a CodeMap
,
101 span_diagnostic
: &errors
::Handler
,
107 is_expanded
: bool
) -> io
::Result
<()> {
108 let mut s
= State
::new_from_input(cm
,
115 if is_expanded
&& !std_inject
::no_std(krate
) {
116 // We need to print `#![no_std]` (and its feature gate) so that
117 // compiling pretty-printed source won't inject libstd again.
118 // However we don't want these attributes in the AST because
119 // of the feature gate, so we fake them up here.
121 // #![feature(prelude_import)]
122 let prelude_import_meta
= attr
::mk_word_item(InternedString
::new("prelude_import"));
123 let list
= attr
::mk_list_item(InternedString
::new("feature"),
124 vec
![prelude_import_meta
]);
125 let fake_attr
= attr
::mk_attr_inner(attr
::mk_attr_id(), list
);
126 s
.print_attribute(&fake_attr
)?
;
129 let no_std_meta
= attr
::mk_word_item(InternedString
::new("no_std"));
130 let fake_attr
= attr
::mk_attr_inner(attr
::mk_attr_id(), no_std_meta
);
131 s
.print_attribute(&fake_attr
)?
;
134 s
.print_mod(&krate
.module
, &krate
.attrs
)?
;
135 s
.print_remaining_comments()?
;
140 pub fn new_from_input(cm
: &'a CodeMap
,
141 span_diagnostic
: &errors
::Handler
,
146 is_expanded
: bool
) -> State
<'a
> {
147 let (cmnts
, lits
) = comments
::gather_comments_and_literals(
157 // If the code is post expansion, don't use the table of
158 // literals, since it doesn't correspond with the literals
159 // in the AST anymore.
160 if is_expanded { None }
else { Some(lits) }
)
163 pub fn new(cm
: &'a CodeMap
,
166 comments
: Option
<Vec
<comments
::Comment
>>,
167 literals
: Option
<Vec
<comments
::Literal
>>) -> State
<'a
> {
169 s
: pp
::mk_printer(out
, DEFAULT_COLUMNS
),
173 cur_cmnt_and_lit
: CurrentCommentAndLiteral
{
183 pub fn to_string
<F
>(f
: F
) -> String
where
184 F
: FnOnce(&mut State
) -> io
::Result
<()>,
186 let mut wr
= Vec
::new();
188 let mut printer
= rust_printer(Box
::new(&mut wr
));
189 f(&mut printer
).unwrap();
190 eof(&mut printer
.s
).unwrap();
192 String
::from_utf8(wr
).unwrap()
195 pub fn binop_to_string(op
: BinOpToken
) -> &'
static str {
201 token
::Percent
=> "%",
210 pub fn token_to_string(tok
: &Token
) -> String
{
212 token
::Eq
=> "=".to_string(),
213 token
::Lt
=> "<".to_string(),
214 token
::Le
=> "<=".to_string(),
215 token
::EqEq
=> "==".to_string(),
216 token
::Ne
=> "!=".to_string(),
217 token
::Ge
=> ">=".to_string(),
218 token
::Gt
=> ">".to_string(),
219 token
::Not
=> "!".to_string(),
220 token
::Tilde
=> "~".to_string(),
221 token
::OrOr
=> "||".to_string(),
222 token
::AndAnd
=> "&&".to_string(),
223 token
::BinOp(op
) => binop_to_string(op
).to_string(),
224 token
::BinOpEq(op
) => format
!("{}=", binop_to_string(op
)),
226 /* Structural symbols */
227 token
::At
=> "@".to_string(),
228 token
::Dot
=> ".".to_string(),
229 token
::DotDot
=> "..".to_string(),
230 token
::DotDotDot
=> "...".to_string(),
231 token
::Comma
=> ",".to_string(),
232 token
::Semi
=> ";".to_string(),
233 token
::Colon
=> ":".to_string(),
234 token
::ModSep
=> "::".to_string(),
235 token
::RArrow
=> "->".to_string(),
236 token
::LArrow
=> "<-".to_string(),
237 token
::FatArrow
=> "=>".to_string(),
238 token
::OpenDelim(token
::Paren
) => "(".to_string(),
239 token
::CloseDelim(token
::Paren
) => ")".to_string(),
240 token
::OpenDelim(token
::Bracket
) => "[".to_string(),
241 token
::CloseDelim(token
::Bracket
) => "]".to_string(),
242 token
::OpenDelim(token
::Brace
) => "{".to_string(),
243 token
::CloseDelim(token
::Brace
) => "}".to_string(),
244 token
::Pound
=> "#".to_string(),
245 token
::Dollar
=> "$".to_string(),
246 token
::Question
=> "?".to_string(),
249 token
::Literal(lit
, suf
) => {
250 let mut out
= match lit
{
251 token
::Byte(b
) => format
!("b'{}'", b
),
252 token
::Char(c
) => format
!("'{}'", c
),
253 token
::Float(c
) => c
.to_string(),
254 token
::Integer(c
) => c
.to_string(),
255 token
::Str_(s
) => format
!("\"{}\"", s
),
256 token
::StrRaw(s
, n
) => format
!("r{delim}\"{string}\"{delim}",
257 delim
=repeat("#", n
),
259 token
::ByteStr(v
) => format
!("b\"{}\"", v
),
260 token
::ByteStrRaw(s
, n
) => format
!("br{delim}\"{string}\"{delim}",
261 delim
=repeat("#", n
),
265 if let Some(s
) = suf
{
266 out
.push_str(&s
.as_str())
272 /* Name components */
273 token
::Ident(s
, _
) => s
.to_string(),
274 token
::Lifetime(s
) => s
.to_string(),
275 token
::Underscore
=> "_".to_string(),
278 token
::DocComment(s
) => s
.to_string(),
279 token
::SubstNt(s
, _
) => format
!("${}", s
),
280 token
::MatchNt(s
, t
, _
, _
) => format
!("${}:{}", s
, t
),
281 token
::Eof
=> "<eof>".to_string(),
282 token
::Whitespace
=> " ".to_string(),
283 token
::Comment
=> "/* */".to_string(),
284 token
::Shebang(s
) => format
!("/* shebang: {}*/", s
),
286 token
::SpecialVarNt(var
) => format
!("${}", var
.as_str()),
288 token
::Interpolated(ref nt
) => match *nt
{
289 token
::NtExpr(ref e
) => expr_to_string(&e
),
290 token
::NtMeta(ref e
) => meta_item_to_string(&e
),
291 token
::NtTy(ref e
) => ty_to_string(&e
),
292 token
::NtPath(ref e
) => path_to_string(&e
),
293 token
::NtItem(ref e
) => item_to_string(&e
),
294 token
::NtBlock(ref e
) => block_to_string(&e
),
295 token
::NtStmt(ref e
) => stmt_to_string(&e
),
296 token
::NtPat(ref e
) => pat_to_string(&e
),
297 token
::NtIdent(ref e
, _
) => ident_to_string(e
.node
),
298 token
::NtTT(ref e
) => tt_to_string(&e
),
299 token
::NtArm(ref e
) => arm_to_string(&e
),
300 token
::NtImplItem(ref e
) => impl_item_to_string(&e
),
301 token
::NtTraitItem(ref e
) => trait_item_to_string(&e
),
302 token
::NtGenerics(ref e
) => generics_to_string(&e
),
303 token
::NtWhereClause(ref e
) => where_clause_to_string(&e
),
304 token
::NtArg(ref e
) => arg_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
,
382 unsafety
: ast
::Unsafety
,
383 constness
: ast
::Constness
,
385 opt_explicit_self
: Option
<&ast
::SelfKind
>,
386 generics
: &ast
::Generics
)
390 s
.print_fn(decl
, unsafety
, constness
, Abi
::Rust
, Some(name
),
391 generics
, opt_explicit_self
, &ast
::Visibility
::Inherited
)?
;
392 s
.end()?
; // Close the head box
393 s
.end() // Close the outer box
397 pub fn block_to_string(blk
: &ast
::Block
) -> String
{
399 // containing cbox, will be closed by print-block at }
400 s
.cbox(INDENT_UNIT
)?
;
401 // head-ibox, will be closed by print-block after {
407 pub fn meta_item_to_string(mi
: &ast
::MetaItem
) -> String
{
408 to_string(|s
| s
.print_meta_item(mi
))
411 pub fn attribute_to_string(attr
: &ast
::Attribute
) -> String
{
412 to_string(|s
| s
.print_attribute(attr
))
415 pub fn lit_to_string(l
: &ast
::Lit
) -> String
{
416 to_string(|s
| s
.print_literal(l
))
419 pub fn explicit_self_to_string(explicit_self
: &ast
::SelfKind
) -> String
{
420 to_string(|s
| s
.print_explicit_self(explicit_self
, ast
::Mutability
::Immutable
).map(|_
| {}
))
423 pub fn variant_to_string(var
: &ast
::Variant
) -> String
{
424 to_string(|s
| s
.print_variant(var
))
427 pub fn arg_to_string(arg
: &ast
::Arg
) -> String
{
428 to_string(|s
| s
.print_arg(arg
, false))
431 pub fn mac_to_string(arg
: &ast
::Mac
) -> String
{
432 to_string(|s
| s
.print_mac(arg
, ::parse
::token
::Paren
))
435 pub fn visibility_qualified(vis
: &ast
::Visibility
, s
: &str) -> String
{
437 ast
::Visibility
::Public
=> format
!("pub {}", s
),
438 ast
::Visibility
::Crate
=> format
!("pub(crate) {}", s
),
439 ast
::Visibility
::Restricted { ref path, .. }
=> format
!("pub({}) {}", path
, s
),
440 ast
::Visibility
::Inherited
=> s
.to_string()
444 fn needs_parentheses(expr
: &ast
::Expr
) -> bool
{
446 ast
::ExprKind
::Assign(..) | ast
::ExprKind
::Binary(..) |
447 ast
::ExprKind
::Closure(..) |
448 ast
::ExprKind
::AssignOp(..) | ast
::ExprKind
::Cast(..) |
449 ast
::ExprKind
::InPlace(..) | ast
::ExprKind
::Type(..) => true,
454 pub trait PrintState
<'a
> {
455 fn writer(&mut self) -> &mut pp
::Printer
<'a
>;
456 fn boxes(&mut self) -> &mut Vec
<pp
::Breaks
>;
457 fn comments(&mut self) -> &mut Option
<Vec
<comments
::Comment
>>;
458 fn cur_cmnt_and_lit(&mut self) -> &mut CurrentCommentAndLiteral
;
459 fn literals(&self) -> &Option
<Vec
<comments
::Literal
>>;
461 fn word_space(&mut self, w
: &str) -> io
::Result
<()> {
462 word(self.writer(), w
)?
;
466 fn popen(&mut self) -> io
::Result
<()> { word(self.writer(), "(") }
468 fn pclose(&mut self) -> io
::Result
<()> { word(self.writer(), ")") }
470 fn is_begin(&mut self) -> bool
{
471 match self.writer().last_token() {
472 pp
::Token
::Begin(_
) => true,
477 fn is_end(&mut self) -> bool
{
478 match self.writer().last_token() {
479 pp
::Token
::End
=> true,
484 // is this the beginning of a line?
485 fn is_bol(&mut self) -> bool
{
486 self.writer().last_token().is_eof() || self.writer().last_token().is_hardbreak_tok()
489 fn hardbreak_if_not_bol(&mut self) -> io
::Result
<()> {
491 hardbreak(self.writer())?
497 fn rbox(&mut self, u
: usize, b
: pp
::Breaks
) -> io
::Result
<()> {
498 self.boxes().push(b
);
499 pp
::rbox(self.writer(), u
, b
)
502 fn ibox(&mut self, u
: usize) -> io
::Result
<()> {
503 self.boxes().push(pp
::Breaks
::Inconsistent
);
504 pp
::ibox(self.writer(), u
)
507 fn end(&mut self) -> io
::Result
<()> {
508 self.boxes().pop().unwrap();
509 pp
::end(self.writer())
512 fn commasep
<T
, F
>(&mut self, b
: Breaks
, elts
: &[T
], mut op
: F
) -> io
::Result
<()>
513 where F
: FnMut(&mut Self, &T
) -> io
::Result
<()>,
516 let mut first
= true;
518 if first { first = false; }
else { self.word_space(",")?; }
524 fn next_lit(&mut self, pos
: BytePos
) -> Option
<comments
::Literal
> {
525 let mut cur_lit
= self.cur_cmnt_and_lit().cur_lit
;
527 let mut result
= None
;
529 if let &Some(ref lits
) = self.literals()
531 while cur_lit
< lits
.len() {
532 let ltrl
= (*lits
)[cur_lit
].clone();
533 if ltrl
.pos
> pos { break; }
542 self.cur_cmnt_and_lit().cur_lit
= cur_lit
;
546 fn maybe_print_comment(&mut self, pos
: BytePos
) -> io
::Result
<()> {
548 match self.next_comment() {
550 if (*cmnt
).pos
< pos
{
551 self.print_comment(cmnt
)?
;
552 self.cur_cmnt_and_lit().cur_cmnt
+= 1;
561 fn print_comment(&mut self,
562 cmnt
: &comments
::Comment
) -> io
::Result
<()> {
565 assert_eq
!(cmnt
.lines
.len(), 1);
566 zerobreak(self.writer())?
;
567 word(self.writer(), &cmnt
.lines
[0])?
;
568 zerobreak(self.writer())
570 comments
::Isolated
=> {
571 self.hardbreak_if_not_bol()?
;
572 for line
in &cmnt
.lines
{
573 // Don't print empty lines because they will end up as trailing
575 if !line
.is_empty() {
576 word(self.writer(), &line
[..])?
;
578 hardbreak(self.writer())?
;
582 comments
::Trailing
=> {
583 word(self.writer(), " ")?
;
584 if cmnt
.lines
.len() == 1 {
585 word(self.writer(), &cmnt
.lines
[0])?
;
586 hardbreak(self.writer())
589 for line
in &cmnt
.lines
{
590 if !line
.is_empty() {
591 word(self.writer(), &line
[..])?
;
593 hardbreak(self.writer())?
;
598 comments
::BlankLine
=> {
599 // We need to do at least one, possibly two hardbreaks.
600 let is_semi
= match self.writer().last_token() {
601 pp
::Token
::String(s
, _
) => ";" == s
,
604 if is_semi
|| self.is_begin() || self.is_end() {
605 hardbreak(self.writer())?
;
607 hardbreak(self.writer())
612 fn next_comment(&mut self) -> Option
<comments
::Comment
> {
613 let cur_cmnt
= self.cur_cmnt_and_lit().cur_cmnt
;
614 match *self.comments() {
616 if cur_cmnt
< cmnts
.len() {
617 Some(cmnts
[cur_cmnt
].clone())
626 fn print_literal(&mut self, lit
: &ast
::Lit
) -> io
::Result
<()> {
627 self.maybe_print_comment(lit
.span
.lo
)?
;
628 match self.next_lit(lit
.span
.lo
) {
630 return word(self.writer(), &(*ltrl
).lit
);
635 ast
::LitKind
::Str(ref st
, style
) => self.print_string(&st
, style
),
636 ast
::LitKind
::Byte(byte
) => {
637 let mut res
= String
::from("b'");
638 res
.extend(ascii
::escape_default(byte
).map(|c
| c
as char));
640 word(self.writer(), &res
[..])
642 ast
::LitKind
::Char(ch
) => {
643 let mut res
= String
::from("'");
644 res
.extend(ch
.escape_default());
646 word(self.writer(), &res
[..])
648 ast
::LitKind
::Int(i
, t
) => {
650 ast
::LitIntType
::Signed(st
) => {
652 &st
.val_to_string(i
as i64))
654 ast
::LitIntType
::Unsigned(ut
) => {
655 word(self.writer(), &ut
.val_to_string(i
))
657 ast
::LitIntType
::Unsuffixed
=> {
658 word(self.writer(), &format
!("{}", i
))
662 ast
::LitKind
::Float(ref f
, t
) => {
669 ast
::LitKind
::FloatUnsuffixed(ref f
) => word(self.writer(), &f
[..]),
670 ast
::LitKind
::Bool(val
) => {
671 if val { word(self.writer(), "true") }
else { word(self.writer(), "false") }
673 ast
::LitKind
::ByteStr(ref v
) => {
674 let mut escaped
: String
= String
::new();
675 for &ch
in v
.iter() {
676 escaped
.extend(ascii
::escape_default(ch
)
677 .map(|c
| c
as char));
679 word(self.writer(), &format
!("b\"{}\"", escaped
))
684 fn print_string(&mut self, st
: &str,
685 style
: ast
::StrStyle
) -> io
::Result
<()> {
686 let st
= match style
{
687 ast
::StrStyle
::Cooked
=> {
688 (format
!("\"{}\"", st
.escape_default()))
690 ast
::StrStyle
::Raw(n
) => {
691 (format
!("r{delim}\"{string}\"{delim}",
692 delim
=repeat("#", n
),
696 word(self.writer(), &st
[..])
699 fn print_inner_attributes(&mut self,
700 attrs
: &[ast
::Attribute
]) -> io
::Result
<()> {
701 self.print_either_attributes(attrs
, ast
::AttrStyle
::Inner
, false, true)
704 fn print_inner_attributes_no_trailing_hardbreak(&mut self,
705 attrs
: &[ast
::Attribute
])
707 self.print_either_attributes(attrs
, ast
::AttrStyle
::Inner
, false, false)
710 fn print_outer_attributes(&mut self,
711 attrs
: &[ast
::Attribute
]) -> io
::Result
<()> {
712 self.print_either_attributes(attrs
, ast
::AttrStyle
::Outer
, false, true)
715 fn print_inner_attributes_inline(&mut self,
716 attrs
: &[ast
::Attribute
]) -> io
::Result
<()> {
717 self.print_either_attributes(attrs
, ast
::AttrStyle
::Inner
, true, true)
720 fn print_outer_attributes_inline(&mut self,
721 attrs
: &[ast
::Attribute
]) -> io
::Result
<()> {
722 self.print_either_attributes(attrs
, ast
::AttrStyle
::Outer
, true, true)
725 fn print_either_attributes(&mut self,
726 attrs
: &[ast
::Attribute
],
727 kind
: ast
::AttrStyle
,
729 trailing_hardbreak
: bool
) -> io
::Result
<()> {
732 if attr
.node
.style
== kind
{
733 self.print_attribute_inline(attr
, is_inline
)?
;
740 if count
> 0 && trailing_hardbreak
&& !is_inline
{
741 self.hardbreak_if_not_bol()?
;
746 fn print_attribute(&mut self, attr
: &ast
::Attribute
) -> io
::Result
<()> {
747 self.print_attribute_inline(attr
, false)
750 fn print_attribute_inline(&mut self, attr
: &ast
::Attribute
,
751 is_inline
: bool
) -> io
::Result
<()> {
753 self.hardbreak_if_not_bol()?
;
755 self.maybe_print_comment(attr
.span
.lo
)?
;
756 if attr
.node
.is_sugared_doc
{
757 word(self.writer(), &attr
.value_str().unwrap())?
;
758 hardbreak(self.writer())
760 match attr
.node
.style
{
761 ast
::AttrStyle
::Inner
=> word(self.writer(), "#![")?
,
762 ast
::AttrStyle
::Outer
=> word(self.writer(), "#[")?
,
764 self.print_meta_item(&attr
.meta())?
;
765 word(self.writer(), "]")
769 fn print_meta_item(&mut self, item
: &ast
::MetaItem
) -> io
::Result
<()> {
770 self.ibox(INDENT_UNIT
)?
;
772 ast
::MetaItemKind
::Word(ref name
) => {
773 word(self.writer(), &name
)?
;
775 ast
::MetaItemKind
::NameValue(ref name
, ref value
) => {
776 self.word_space(&name
[..])?
;
777 self.word_space("=")?
;
778 self.print_literal(value
)?
;
780 ast
::MetaItemKind
::List(ref name
, ref items
) => {
781 word(self.writer(), &name
)?
;
783 self.commasep(Consistent
,
785 |s
, i
| s
.print_meta_item(&i
))?
;
792 fn space_if_not_bol(&mut self) -> io
::Result
<()> {
793 if !self.is_bol() { space(self.writer())?; }
797 fn nbsp(&mut self) -> io
::Result
<()> { word(self.writer(), " ") }
800 impl<'a
> PrintState
<'a
> for State
<'a
> {
801 fn writer(&mut self) -> &mut pp
::Printer
<'a
> {
805 fn boxes(&mut self) -> &mut Vec
<pp
::Breaks
> {
809 fn comments(&mut self) -> &mut Option
<Vec
<comments
::Comment
>> {
813 fn cur_cmnt_and_lit(&mut self) -> &mut CurrentCommentAndLiteral
{
814 &mut self.cur_cmnt_and_lit
817 fn literals(&self) -> &Option
<Vec
<comments
::Literal
>> {
823 pub fn cbox(&mut self, u
: usize) -> io
::Result
<()> {
824 self.boxes
.push(pp
::Breaks
::Consistent
);
825 pp
::cbox(&mut self.s
, u
)
828 pub fn word_nbsp(&mut self, w
: &str) -> io
::Result
<()> {
829 word(&mut self.s
, w
)?
;
833 pub fn head(&mut self, w
: &str) -> io
::Result
<()> {
834 // outer-box is consistent
835 self.cbox(INDENT_UNIT
)?
;
836 // head-box is inconsistent
837 self.ibox(w
.len() + 1)?
;
838 // keyword that starts the head
845 pub fn bopen(&mut self) -> io
::Result
<()> {
846 word(&mut self.s
, "{")?
;
847 self.end() // close the head-box
850 pub fn bclose_(&mut self, span
: codemap
::Span
,
851 indented
: usize) -> io
::Result
<()> {
852 self.bclose_maybe_open(span
, indented
, true)
854 pub fn bclose_maybe_open(&mut self, span
: codemap
::Span
,
855 indented
: usize, close_box
: bool
) -> io
::Result
<()> {
856 self.maybe_print_comment(span
.hi
)?
;
857 self.break_offset_if_not_bol(1, -(indented
as isize))?
;
858 word(&mut self.s
, "}")?
;
860 self.end()?
; // close the outer-box
864 pub fn bclose(&mut self, span
: codemap
::Span
) -> io
::Result
<()> {
865 self.bclose_(span
, INDENT_UNIT
)
868 pub fn in_cbox(&self) -> bool
{
869 match self.boxes
.last() {
870 Some(&last_box
) => last_box
== pp
::Breaks
::Consistent
,
875 pub fn break_offset_if_not_bol(&mut self, n
: usize,
876 off
: isize) -> io
::Result
<()> {
878 break_offset(&mut self.s
, n
, off
)
880 if off
!= 0 && self.s
.last_token().is_hardbreak_tok() {
881 // We do something pretty sketchy here: tuck the nonzero
882 // offset-adjustment we were going to deposit along with the
883 // break into the previous hardbreak.
884 self.s
.replace_last_token(pp
::hardbreak_tok_offset(off
));
890 // Synthesizes a comment that was not textually present in the original source
892 pub fn synth_comment(&mut self, text
: String
) -> io
::Result
<()> {
893 word(&mut self.s
, "/*")?
;
895 word(&mut self.s
, &text
[..])?
;
897 word(&mut self.s
, "*/")
902 pub fn commasep_cmnt
<T
, F
, G
>(&mut self,
906 mut get_span
: G
) -> io
::Result
<()> where
907 F
: FnMut(&mut State
, &T
) -> io
::Result
<()>,
908 G
: FnMut(&T
) -> codemap
::Span
,
911 let len
= elts
.len();
914 self.maybe_print_comment(get_span(elt
).hi
)?
;
918 word(&mut self.s
, ",")?
;
919 self.maybe_print_trailing_comment(get_span(elt
),
920 Some(get_span(&elts
[i
]).hi
))?
;
921 self.space_if_not_bol()?
;
927 pub fn commasep_exprs(&mut self, b
: Breaks
,
928 exprs
: &[P
<ast
::Expr
>]) -> io
::Result
<()> {
929 self.commasep_cmnt(b
, exprs
, |s
, e
| s
.print_expr(&e
), |e
| e
.span
)
932 pub fn print_mod(&mut self, _mod
: &ast
::Mod
,
933 attrs
: &[ast
::Attribute
]) -> io
::Result
<()> {
934 self.print_inner_attributes(attrs
)?
;
935 for item
in &_mod
.items
{
936 self.print_item(&item
)?
;
941 pub fn print_foreign_mod(&mut self, nmod
: &ast
::ForeignMod
,
942 attrs
: &[ast
::Attribute
]) -> io
::Result
<()> {
943 self.print_inner_attributes(attrs
)?
;
944 for item
in &nmod
.items
{
945 self.print_foreign_item(item
)?
;
950 pub fn print_opt_lifetime(&mut self,
951 lifetime
: &Option
<ast
::Lifetime
>) -> io
::Result
<()> {
952 if let Some(l
) = *lifetime
{
953 self.print_lifetime(&l
)?
;
959 pub fn print_type(&mut self, ty
: &ast
::Ty
) -> io
::Result
<()> {
960 self.maybe_print_comment(ty
.span
.lo
)?
;
963 ast
::TyKind
::Vec(ref ty
) => {
964 word(&mut self.s
, "[")?
;
965 self.print_type(&ty
)?
;
966 word(&mut self.s
, "]")?
;
968 ast
::TyKind
::Ptr(ref mt
) => {
969 word(&mut self.s
, "*")?
;
971 ast
::Mutability
::Mutable
=> self.word_nbsp("mut")?
,
972 ast
::Mutability
::Immutable
=> self.word_nbsp("const")?
,
974 self.print_type(&mt
.ty
)?
;
976 ast
::TyKind
::Rptr(ref lifetime
, ref mt
) => {
977 word(&mut self.s
, "&")?
;
978 self.print_opt_lifetime(lifetime
)?
;
981 ast
::TyKind
::Tup(ref elts
) => {
983 self.commasep(Inconsistent
, &elts
[..],
984 |s
, ty
| s
.print_type(&ty
))?
;
986 word(&mut self.s
, ",")?
;
990 ast
::TyKind
::Paren(ref typ
) => {
992 self.print_type(&typ
)?
;
995 ast
::TyKind
::BareFn(ref f
) => {
996 let generics
= ast
::Generics
{
997 lifetimes
: f
.lifetimes
.clone(),
998 ty_params
: P
::empty(),
999 where_clause
: ast
::WhereClause
{
1000 id
: ast
::DUMMY_NODE_ID
,
1001 predicates
: Vec
::new(),
1004 self.print_ty_fn(f
.abi
,
1011 ast
::TyKind
::Path(None
, ref path
) => {
1012 self.print_path(path
, false, 0)?
;
1014 ast
::TyKind
::Path(Some(ref qself
), ref path
) => {
1015 self.print_qpath(path
, qself
, false)?
1017 ast
::TyKind
::ObjectSum(ref ty
, ref bounds
) => {
1018 self.print_type(&ty
)?
;
1019 self.print_bounds("+", &bounds
[..])?
;
1021 ast
::TyKind
::PolyTraitRef(ref bounds
) => {
1022 self.print_bounds("", &bounds
[..])?
;
1024 ast
::TyKind
::FixedLengthVec(ref ty
, ref v
) => {
1025 word(&mut self.s
, "[")?
;
1026 self.print_type(&ty
)?
;
1027 word(&mut self.s
, "; ")?
;
1028 self.print_expr(&v
)?
;
1029 word(&mut self.s
, "]")?
;
1031 ast
::TyKind
::Typeof(ref e
) => {
1032 word(&mut self.s
, "typeof(")?
;
1033 self.print_expr(&e
)?
;
1034 word(&mut self.s
, ")")?
;
1036 ast
::TyKind
::Infer
=> {
1037 word(&mut self.s
, "_")?
;
1039 ast
::TyKind
::Mac(ref m
) => {
1040 self.print_mac(m
, token
::Paren
)?
;
1046 pub fn print_foreign_item(&mut self,
1047 item
: &ast
::ForeignItem
) -> io
::Result
<()> {
1048 self.hardbreak_if_not_bol()?
;
1049 self.maybe_print_comment(item
.span
.lo
)?
;
1050 self.print_outer_attributes(&item
.attrs
)?
;
1052 ast
::ForeignItemKind
::Fn(ref decl
, ref generics
) => {
1054 self.print_fn(decl
, ast
::Unsafety
::Normal
,
1055 ast
::Constness
::NotConst
,
1056 Abi
::Rust
, Some(item
.ident
),
1057 generics
, None
, &item
.vis
)?
;
1058 self.end()?
; // end head-ibox
1059 word(&mut self.s
, ";")?
;
1060 self.end() // end the outer fn box
1062 ast
::ForeignItemKind
::Static(ref t
, m
) => {
1063 self.head(&visibility_qualified(&item
.vis
, "static"))?
;
1065 self.word_space("mut")?
;
1067 self.print_ident(item
.ident
)?
;
1068 self.word_space(":")?
;
1069 self.print_type(&t
)?
;
1070 word(&mut self.s
, ";")?
;
1071 self.end()?
; // end the head-ibox
1072 self.end() // end the outer cbox
1077 fn print_associated_const(&mut self,
1080 default: Option
<&ast
::Expr
>,
1081 vis
: &ast
::Visibility
)
1084 word(&mut self.s
, &visibility_qualified(vis
, ""))?
;
1085 self.word_space("const")?
;
1086 self.print_ident(ident
)?
;
1087 self.word_space(":")?
;
1088 self.print_type(ty
)?
;
1089 if let Some(expr
) = default {
1090 space(&mut self.s
)?
;
1091 self.word_space("=")?
;
1092 self.print_expr(expr
)?
;
1094 word(&mut self.s
, ";")
1097 fn print_associated_type(&mut self,
1099 bounds
: Option
<&ast
::TyParamBounds
>,
1100 ty
: Option
<&ast
::Ty
>)
1102 self.word_space("type")?
;
1103 self.print_ident(ident
)?
;
1104 if let Some(bounds
) = bounds
{
1105 self.print_bounds(":", bounds
)?
;
1107 if let Some(ty
) = ty
{
1108 space(&mut self.s
)?
;
1109 self.word_space("=")?
;
1110 self.print_type(ty
)?
;
1112 word(&mut self.s
, ";")
1115 /// Pretty-print an item
1116 pub fn print_item(&mut self, item
: &ast
::Item
) -> io
::Result
<()> {
1117 self.hardbreak_if_not_bol()?
;
1118 self.maybe_print_comment(item
.span
.lo
)?
;
1119 self.print_outer_attributes(&item
.attrs
)?
;
1120 self.ann
.pre(self, NodeItem(item
))?
;
1122 ast
::ItemKind
::ExternCrate(ref optional_path
) => {
1123 self.head(&visibility_qualified(&item
.vis
, "extern crate"))?
;
1124 if let Some(p
) = *optional_path
{
1125 let val
= p
.as_str();
1126 if val
.contains("-") {
1127 self.print_string(&val
, ast
::StrStyle
::Cooked
)?
;
1129 self.print_name(p
)?
;
1131 space(&mut self.s
)?
;
1132 word(&mut self.s
, "as")?
;
1133 space(&mut self.s
)?
;
1135 self.print_ident(item
.ident
)?
;
1136 word(&mut self.s
, ";")?
;
1137 self.end()?
; // end inner head-block
1138 self.end()?
; // end outer head-block
1140 ast
::ItemKind
::Use(ref vp
) => {
1141 self.head(&visibility_qualified(&item
.vis
, "use"))?
;
1142 self.print_view_path(&vp
)?
;
1143 word(&mut self.s
, ";")?
;
1144 self.end()?
; // end inner head-block
1145 self.end()?
; // end outer head-block
1147 ast
::ItemKind
::Static(ref ty
, m
, ref expr
) => {
1148 self.head(&visibility_qualified(&item
.vis
, "static"))?
;
1149 if m
== ast
::Mutability
::Mutable
{
1150 self.word_space("mut")?
;
1152 self.print_ident(item
.ident
)?
;
1153 self.word_space(":")?
;
1154 self.print_type(&ty
)?
;
1155 space(&mut self.s
)?
;
1156 self.end()?
; // end the head-ibox
1158 self.word_space("=")?
;
1159 self.print_expr(&expr
)?
;
1160 word(&mut self.s
, ";")?
;
1161 self.end()?
; // end the outer cbox
1163 ast
::ItemKind
::Const(ref ty
, ref expr
) => {
1164 self.head(&visibility_qualified(&item
.vis
, "const"))?
;
1165 self.print_ident(item
.ident
)?
;
1166 self.word_space(":")?
;
1167 self.print_type(&ty
)?
;
1168 space(&mut self.s
)?
;
1169 self.end()?
; // end the head-ibox
1171 self.word_space("=")?
;
1172 self.print_expr(&expr
)?
;
1173 word(&mut self.s
, ";")?
;
1174 self.end()?
; // end the outer cbox
1176 ast
::ItemKind
::Fn(ref decl
, unsafety
, constness
, abi
, ref typarams
, ref body
) => {
1188 word(&mut self.s
, " ")?
;
1189 self.print_block_with_attrs(&body
, &item
.attrs
)?
;
1191 ast
::ItemKind
::Mod(ref _mod
) => {
1192 self.head(&visibility_qualified(&item
.vis
, "mod"))?
;
1193 self.print_ident(item
.ident
)?
;
1196 self.print_mod(_mod
, &item
.attrs
)?
;
1197 self.bclose(item
.span
)?
;
1199 ast
::ItemKind
::ForeignMod(ref nmod
) => {
1200 self.head("extern")?
;
1201 self.word_nbsp(&nmod
.abi
.to_string())?
;
1203 self.print_foreign_mod(nmod
, &item
.attrs
)?
;
1204 self.bclose(item
.span
)?
;
1206 ast
::ItemKind
::Ty(ref ty
, ref params
) => {
1207 self.ibox(INDENT_UNIT
)?
;
1209 self.word_nbsp(&visibility_qualified(&item
.vis
, "type"))?
;
1210 self.print_ident(item
.ident
)?
;
1211 self.print_generics(params
)?
;
1212 self.end()?
; // end the inner ibox
1214 self.print_where_clause(¶ms
.where_clause
)?
;
1215 space(&mut self.s
)?
;
1216 self.word_space("=")?
;
1217 self.print_type(&ty
)?
;
1218 word(&mut self.s
, ";")?
;
1219 self.end()?
; // end the outer ibox
1221 ast
::ItemKind
::Enum(ref enum_definition
, ref params
) => {
1222 self.print_enum_def(
1230 ast
::ItemKind
::Struct(ref struct_def
, ref generics
) => {
1231 self.head(&visibility_qualified(&item
.vis
, "struct"))?
;
1232 self.print_struct(&struct_def
, generics
, item
.ident
, item
.span
, true)?
;
1235 ast
::ItemKind
::DefaultImpl(unsafety
, ref trait_ref
) => {
1237 self.print_visibility(&item
.vis
)?
;
1238 self.print_unsafety(unsafety
)?
;
1239 self.word_nbsp("impl")?
;
1240 self.print_trait_ref(trait_ref
)?
;
1241 space(&mut self.s
)?
;
1242 self.word_space("for")?
;
1243 self.word_space("..")?
;
1245 self.bclose(item
.span
)?
;
1247 ast
::ItemKind
::Impl(unsafety
,
1252 ref impl_items
) => {
1254 self.print_visibility(&item
.vis
)?
;
1255 self.print_unsafety(unsafety
)?
;
1256 self.word_nbsp("impl")?
;
1258 if generics
.is_parameterized() {
1259 self.print_generics(generics
)?
;
1260 space(&mut self.s
)?
;
1264 ast
::ImplPolarity
::Negative
=> {
1265 word(&mut self.s
, "!")?
;
1272 self.print_trait_ref(t
)?
;
1273 space(&mut self.s
)?
;
1274 self.word_space("for")?
;
1279 self.print_type(&ty
)?
;
1280 self.print_where_clause(&generics
.where_clause
)?
;
1282 space(&mut self.s
)?
;
1284 self.print_inner_attributes(&item
.attrs
)?
;
1285 for impl_item
in impl_items
{
1286 self.print_impl_item(impl_item
)?
;
1288 self.bclose(item
.span
)?
;
1290 ast
::ItemKind
::Trait(unsafety
, ref generics
, ref bounds
, ref trait_items
) => {
1292 self.print_visibility(&item
.vis
)?
;
1293 self.print_unsafety(unsafety
)?
;
1294 self.word_nbsp("trait")?
;
1295 self.print_ident(item
.ident
)?
;
1296 self.print_generics(generics
)?
;
1297 let mut real_bounds
= Vec
::with_capacity(bounds
.len());
1298 for b
in bounds
.iter() {
1299 if let TraitTyParamBound(ref ptr
, ast
::TraitBoundModifier
::Maybe
) = *b
{
1300 space(&mut self.s
)?
;
1301 self.word_space("for ?")?
;
1302 self.print_trait_ref(&ptr
.trait_ref
)?
;
1304 real_bounds
.push(b
.clone());
1307 self.print_bounds(":", &real_bounds
[..])?
;
1308 self.print_where_clause(&generics
.where_clause
)?
;
1309 word(&mut self.s
, " ")?
;
1311 for trait_item
in trait_items
{
1312 self.print_trait_item(trait_item
)?
;
1314 self.bclose(item
.span
)?
;
1316 ast
::ItemKind
::Mac(codemap
::Spanned { ref node, .. }
) => {
1317 self.print_visibility(&item
.vis
)?
;
1318 self.print_path(&node
.path
, false, 0)?
;
1319 word(&mut self.s
, "! ")?
;
1320 self.print_ident(item
.ident
)?
;
1321 self.cbox(INDENT_UNIT
)?
;
1323 self.print_tts(&node
.tts
[..])?
;
1325 word(&mut self.s
, ";")?
;
1329 self.ann
.post(self, NodeItem(item
))
1332 fn print_trait_ref(&mut self, t
: &ast
::TraitRef
) -> io
::Result
<()> {
1333 self.print_path(&t
.path
, false, 0)
1336 fn print_formal_lifetime_list(&mut self, lifetimes
: &[ast
::LifetimeDef
]) -> io
::Result
<()> {
1337 if !lifetimes
.is_empty() {
1338 word(&mut self.s
, "for<")?
;
1339 let mut comma
= false;
1340 for lifetime_def
in lifetimes
{
1342 self.word_space(",")?
1344 self.print_lifetime_def(lifetime_def
)?
;
1347 word(&mut self.s
, ">")?
;
1352 fn print_poly_trait_ref(&mut self, t
: &ast
::PolyTraitRef
) -> io
::Result
<()> {
1353 self.print_formal_lifetime_list(&t
.bound_lifetimes
)?
;
1354 self.print_trait_ref(&t
.trait_ref
)
1357 pub fn print_enum_def(&mut self, enum_definition
: &ast
::EnumDef
,
1358 generics
: &ast
::Generics
, ident
: ast
::Ident
,
1359 span
: codemap
::Span
,
1360 visibility
: &ast
::Visibility
) -> io
::Result
<()> {
1361 self.head(&visibility_qualified(visibility
, "enum"))?
;
1362 self.print_ident(ident
)?
;
1363 self.print_generics(generics
)?
;
1364 self.print_where_clause(&generics
.where_clause
)?
;
1365 space(&mut self.s
)?
;
1366 self.print_variants(&enum_definition
.variants
, span
)
1369 pub fn print_variants(&mut self,
1370 variants
: &[ast
::Variant
],
1371 span
: codemap
::Span
) -> io
::Result
<()> {
1374 self.space_if_not_bol()?
;
1375 self.maybe_print_comment(v
.span
.lo
)?
;
1376 self.print_outer_attributes(&v
.node
.attrs
)?
;
1377 self.ibox(INDENT_UNIT
)?
;
1378 self.print_variant(v
)?
;
1379 word(&mut self.s
, ",")?
;
1381 self.maybe_print_trailing_comment(v
.span
, None
)?
;
1386 pub fn print_visibility(&mut self, vis
: &ast
::Visibility
) -> io
::Result
<()> {
1388 ast
::Visibility
::Public
=> self.word_nbsp("pub"),
1389 ast
::Visibility
::Crate
=> self.word_nbsp("pub(crate)"),
1390 ast
::Visibility
::Restricted { ref path, .. }
=>
1391 self.word_nbsp(&format
!("pub({})", path
)),
1392 ast
::Visibility
::Inherited
=> Ok(())
1396 pub fn print_struct(&mut self,
1397 struct_def
: &ast
::VariantData
,
1398 generics
: &ast
::Generics
,
1400 span
: codemap
::Span
,
1401 print_finalizer
: bool
) -> io
::Result
<()> {
1402 self.print_ident(ident
)?
;
1403 self.print_generics(generics
)?
;
1404 if !struct_def
.is_struct() {
1405 if struct_def
.is_tuple() {
1408 Inconsistent
, struct_def
.fields(),
1410 s
.print_visibility(&field
.vis
)?
;
1411 s
.maybe_print_comment(field
.span
.lo
)?
;
1412 s
.print_type(&field
.ty
)
1417 self.print_where_clause(&generics
.where_clause
)?
;
1418 if print_finalizer
{
1419 word(&mut self.s
, ";")?
;
1422 self.end() // close the outer-box
1424 self.print_where_clause(&generics
.where_clause
)?
;
1427 self.hardbreak_if_not_bol()?
;
1429 for field
in struct_def
.fields() {
1430 self.hardbreak_if_not_bol()?
;
1431 self.maybe_print_comment(field
.span
.lo
)?
;
1432 self.print_outer_attributes(&field
.attrs
)?
;
1433 self.print_visibility(&field
.vis
)?
;
1434 self.print_ident(field
.ident
.unwrap())?
;
1435 self.word_nbsp(":")?
;
1436 self.print_type(&field
.ty
)?
;
1437 word(&mut self.s
, ",")?
;
1444 /// This doesn't deserve to be called "pretty" printing, but it should be
1445 /// meaning-preserving. A quick hack that might help would be to look at the
1446 /// spans embedded in the TTs to decide where to put spaces and newlines.
1447 /// But it'd be better to parse these according to the grammar of the
1448 /// appropriate macro, transcribe back into the grammar we just parsed from,
1449 /// and then pretty-print the resulting AST nodes (so, e.g., we print
1450 /// expression arguments as expressions). It can be done! I think.
1451 pub fn print_tt(&mut self, tt
: &ast
::TokenTree
) -> io
::Result
<()> {
1453 TokenTree
::Token(_
, ref tk
) => {
1454 word(&mut self.s
, &token_to_string(tk
))?
;
1456 parse
::token
::DocComment(..) => {
1457 hardbreak(&mut self.s
)
1462 TokenTree
::Delimited(_
, ref delimed
) => {
1463 word(&mut self.s
, &token_to_string(&delimed
.open_token()))?
;
1464 space(&mut self.s
)?
;
1465 self.print_tts(&delimed
.tts
)?
;
1466 space(&mut self.s
)?
;
1467 word(&mut self.s
, &token_to_string(&delimed
.close_token()))
1469 TokenTree
::Sequence(_
, ref seq
) => {
1470 word(&mut self.s
, "$(")?
;
1471 for tt_elt
in &seq
.tts
{
1472 self.print_tt(tt_elt
)?
;
1474 word(&mut self.s
, ")")?
;
1475 match seq
.separator
{
1477 word(&mut self.s
, &token_to_string(tk
))?
;
1482 ast
::KleeneOp
::ZeroOrMore
=> word(&mut self.s
, "*"),
1483 ast
::KleeneOp
::OneOrMore
=> word(&mut self.s
, "+"),
1489 pub fn print_tts(&mut self, tts
: &[ast
::TokenTree
]) -> io
::Result
<()> {
1491 let mut suppress_space
= false;
1492 for (i
, tt
) in tts
.iter().enumerate() {
1493 if i
!= 0 && !suppress_space
{
1494 space(&mut self.s
)?
;
1497 // There should be no space between the module name and the following `::` in paths,
1498 // otherwise imported macros get re-parsed from crate metadata incorrectly (#20701)
1499 suppress_space
= match *tt
{
1500 TokenTree
::Token(_
, token
::Ident(_
, token
::ModName
)) |
1501 TokenTree
::Token(_
, token
::MatchNt(_
, _
, _
, token
::ModName
)) |
1502 TokenTree
::Token(_
, token
::SubstNt(_
, token
::ModName
)) => true,
1509 pub fn print_variant(&mut self, v
: &ast
::Variant
) -> io
::Result
<()> {
1511 let generics
= ast
::Generics
::default();
1512 self.print_struct(&v
.node
.data
, &generics
, v
.node
.name
, v
.span
, false)?
;
1513 match v
.node
.disr_expr
{
1515 space(&mut self.s
)?
;
1516 self.word_space("=")?
;
1523 pub fn print_method_sig(&mut self,
1526 vis
: &ast
::Visibility
)
1528 self.print_fn(&m
.decl
,
1534 Some(&m
.explicit_self
.node
),
1538 pub fn print_trait_item(&mut self, ti
: &ast
::TraitItem
)
1540 self.ann
.pre(self, NodeSubItem(ti
.id
))?
;
1541 self.hardbreak_if_not_bol()?
;
1542 self.maybe_print_comment(ti
.span
.lo
)?
;
1543 self.print_outer_attributes(&ti
.attrs
)?
;
1545 ast
::TraitItemKind
::Const(ref ty
, ref default) => {
1546 self.print_associated_const(ti
.ident
, &ty
,
1547 default.as_ref().map(|expr
| &**expr
),
1548 &ast
::Visibility
::Inherited
)?
;
1550 ast
::TraitItemKind
::Method(ref sig
, ref body
) => {
1554 self.print_method_sig(ti
.ident
, sig
, &ast
::Visibility
::Inherited
)?
;
1555 if let Some(ref body
) = *body
{
1557 self.print_block_with_attrs(body
, &ti
.attrs
)?
;
1559 word(&mut self.s
, ";")?
;
1562 ast
::TraitItemKind
::Type(ref bounds
, ref default) => {
1563 self.print_associated_type(ti
.ident
, Some(bounds
),
1564 default.as_ref().map(|ty
| &**ty
))?
;
1567 self.ann
.post(self, NodeSubItem(ti
.id
))
1570 pub fn print_impl_item(&mut self, ii
: &ast
::ImplItem
) -> io
::Result
<()> {
1571 self.ann
.pre(self, NodeSubItem(ii
.id
))?
;
1572 self.hardbreak_if_not_bol()?
;
1573 self.maybe_print_comment(ii
.span
.lo
)?
;
1574 self.print_outer_attributes(&ii
.attrs
)?
;
1575 if let ast
::Defaultness
::Default
= ii
.defaultness
{
1576 self.word_nbsp("default")?
;
1579 ast
::ImplItemKind
::Const(ref ty
, ref expr
) => {
1580 self.print_associated_const(ii
.ident
, &ty
, Some(&expr
), &ii
.vis
)?
;
1582 ast
::ImplItemKind
::Method(ref sig
, ref body
) => {
1584 self.print_method_sig(ii
.ident
, sig
, &ii
.vis
)?
;
1586 self.print_block_with_attrs(body
, &ii
.attrs
)?
;
1588 ast
::ImplItemKind
::Type(ref ty
) => {
1589 self.print_associated_type(ii
.ident
, None
, Some(ty
))?
;
1591 ast
::ImplItemKind
::Macro(codemap
::Spanned { ref node, .. }
) => {
1592 // code copied from ItemKind::Mac:
1593 self.print_path(&node
.path
, false, 0)?
;
1594 word(&mut self.s
, "! ")?
;
1595 self.cbox(INDENT_UNIT
)?
;
1597 self.print_tts(&node
.tts
[..])?
;
1599 word(&mut self.s
, ";")?
;
1603 self.ann
.post(self, NodeSubItem(ii
.id
))
1606 pub fn print_stmt(&mut self, st
: &ast
::Stmt
) -> io
::Result
<()> {
1607 self.maybe_print_comment(st
.span
.lo
)?
;
1609 ast
::StmtKind
::Decl(ref decl
, _
) => {
1610 self.print_decl(&decl
)?
;
1612 ast
::StmtKind
::Expr(ref expr
, _
) => {
1613 self.space_if_not_bol()?
;
1614 self.print_expr_outer_attr_style(&expr
, false)?
;
1616 ast
::StmtKind
::Semi(ref expr
, _
) => {
1617 self.space_if_not_bol()?
;
1618 self.print_expr_outer_attr_style(&expr
, false)?
;
1619 word(&mut self.s
, ";")?
;
1621 ast
::StmtKind
::Mac(ref mac
, style
, ref attrs
) => {
1622 self.space_if_not_bol()?
;
1623 self.print_outer_attributes(attrs
.as_attr_slice())?
;
1624 let delim
= match style
{
1625 ast
::MacStmtStyle
::Braces
=> token
::Brace
,
1628 self.print_mac(&mac
, delim
)?
;
1630 ast
::MacStmtStyle
::Braces
=> {}
1631 _
=> word(&mut self.s
, ";")?
,
1635 if parse
::classify
::stmt_ends_with_semi(&st
.node
) {
1636 word(&mut self.s
, ";")?
;
1638 self.maybe_print_trailing_comment(st
.span
, None
)
1641 pub fn print_block(&mut self, blk
: &ast
::Block
) -> io
::Result
<()> {
1642 self.print_block_with_attrs(blk
, &[])
1645 pub fn print_block_unclosed(&mut self, blk
: &ast
::Block
) -> io
::Result
<()> {
1646 self.print_block_unclosed_indent(blk
, INDENT_UNIT
)
1649 pub fn print_block_unclosed_with_attrs(&mut self, blk
: &ast
::Block
,
1650 attrs
: &[ast
::Attribute
])
1652 self.print_block_maybe_unclosed(blk
, INDENT_UNIT
, attrs
, false)
1655 pub fn print_block_unclosed_indent(&mut self, blk
: &ast
::Block
,
1656 indented
: usize) -> io
::Result
<()> {
1657 self.print_block_maybe_unclosed(blk
, indented
, &[], false)
1660 pub fn print_block_with_attrs(&mut self,
1662 attrs
: &[ast
::Attribute
]) -> io
::Result
<()> {
1663 self.print_block_maybe_unclosed(blk
, INDENT_UNIT
, attrs
, true)
1666 pub fn print_block_maybe_unclosed(&mut self,
1669 attrs
: &[ast
::Attribute
],
1670 close_box
: bool
) -> io
::Result
<()> {
1672 BlockCheckMode
::Unsafe(..) => self.word_space("unsafe")?
,
1673 BlockCheckMode
::Default
=> ()
1675 self.maybe_print_comment(blk
.span
.lo
)?
;
1676 self.ann
.pre(self, NodeBlock(blk
))?
;
1679 self.print_inner_attributes(attrs
)?
;
1681 for st
in &blk
.stmts
{
1682 self.print_stmt(st
)?
;
1686 self.space_if_not_bol()?
;
1687 self.print_expr_outer_attr_style(&expr
, false)?
;
1688 self.maybe_print_trailing_comment(expr
.span
, Some(blk
.span
.hi
))?
;
1692 self.bclose_maybe_open(blk
.span
, indented
, close_box
)?
;
1693 self.ann
.post(self, NodeBlock(blk
))
1696 fn print_else(&mut self, els
: Option
<&ast
::Expr
>) -> io
::Result
<()> {
1700 // "another else-if"
1701 ast
::ExprKind
::If(ref i
, ref then
, ref e
) => {
1702 self.cbox(INDENT_UNIT
- 1)?
;
1704 word(&mut self.s
, " else if ")?
;
1705 self.print_expr(&i
)?
;
1706 space(&mut self.s
)?
;
1707 self.print_block(&then
)?
;
1708 self.print_else(e
.as_ref().map(|e
| &**e
))
1710 // "another else-if-let"
1711 ast
::ExprKind
::IfLet(ref pat
, ref expr
, ref then
, ref e
) => {
1712 self.cbox(INDENT_UNIT
- 1)?
;
1714 word(&mut self.s
, " else if let ")?
;
1715 self.print_pat(&pat
)?
;
1716 space(&mut self.s
)?
;
1717 self.word_space("=")?
;
1718 self.print_expr(&expr
)?
;
1719 space(&mut self.s
)?
;
1720 self.print_block(&then
)?
;
1721 self.print_else(e
.as_ref().map(|e
| &**e
))
1724 ast
::ExprKind
::Block(ref b
) => {
1725 self.cbox(INDENT_UNIT
- 1)?
;
1727 word(&mut self.s
, " else ")?
;
1728 self.print_block(&b
)
1730 // BLEAH, constraints would be great here
1732 panic
!("print_if saw if with weird alternative");
1740 pub fn print_if(&mut self, test
: &ast
::Expr
, blk
: &ast
::Block
,
1741 elseopt
: Option
<&ast
::Expr
>) -> io
::Result
<()> {
1743 self.print_expr(test
)?
;
1744 space(&mut self.s
)?
;
1745 self.print_block(blk
)?
;
1746 self.print_else(elseopt
)
1749 pub fn print_if_let(&mut self, pat
: &ast
::Pat
, expr
: &ast
::Expr
, blk
: &ast
::Block
,
1750 elseopt
: Option
<&ast
::Expr
>) -> io
::Result
<()> {
1751 self.head("if let")?
;
1752 self.print_pat(pat
)?
;
1753 space(&mut self.s
)?
;
1754 self.word_space("=")?
;
1755 self.print_expr(expr
)?
;
1756 space(&mut self.s
)?
;
1757 self.print_block(blk
)?
;
1758 self.print_else(elseopt
)
1761 pub fn print_mac(&mut self, m
: &ast
::Mac
, delim
: token
::DelimToken
)
1763 self.print_path(&m
.node
.path
, false, 0)?
;
1764 word(&mut self.s
, "!")?
;
1766 token
::Paren
=> self.popen()?
,
1767 token
::Bracket
=> word(&mut self.s
, "[")?
,
1773 self.print_tts(&m
.node
.tts
)?
;
1775 token
::Paren
=> self.pclose(),
1776 token
::Bracket
=> word(&mut self.s
, "]"),
1777 token
::Brace
=> self.bclose(m
.span
),
1782 fn print_call_post(&mut self, args
: &[P
<ast
::Expr
>]) -> io
::Result
<()> {
1784 self.commasep_exprs(Inconsistent
, args
)?
;
1788 pub fn check_expr_bin_needs_paren(&mut self, sub_expr
: &ast
::Expr
,
1789 binop
: ast
::BinOp
) -> bool
{
1790 match sub_expr
.node
{
1791 ast
::ExprKind
::Binary(ref sub_op
, _
, _
) => {
1792 if AssocOp
::from_ast_binop(sub_op
.node
).precedence() <
1793 AssocOp
::from_ast_binop(binop
.node
).precedence() {
1803 pub fn print_expr_maybe_paren(&mut self, expr
: &ast
::Expr
) -> io
::Result
<()> {
1804 let needs_par
= needs_parentheses(expr
);
1808 self.print_expr(expr
)?
;
1815 fn print_expr_in_place(&mut self,
1817 expr
: &ast
::Expr
) -> io
::Result
<()> {
1818 self.print_expr_maybe_paren(place
)?
;
1819 space(&mut self.s
)?
;
1820 self.word_space("<-")?
;
1821 self.print_expr_maybe_paren(expr
)
1824 fn print_expr_vec(&mut self, exprs
: &[P
<ast
::Expr
>],
1825 attrs
: &[Attribute
]) -> io
::Result
<()> {
1826 self.ibox(INDENT_UNIT
)?
;
1827 word(&mut self.s
, "[")?
;
1828 self.print_inner_attributes_inline(attrs
)?
;
1829 self.commasep_exprs(Inconsistent
, &exprs
[..])?
;
1830 word(&mut self.s
, "]")?
;
1834 fn print_expr_repeat(&mut self,
1835 element
: &ast
::Expr
,
1837 attrs
: &[Attribute
]) -> io
::Result
<()> {
1838 self.ibox(INDENT_UNIT
)?
;
1839 word(&mut self.s
, "[")?
;
1840 self.print_inner_attributes_inline(attrs
)?
;
1841 self.print_expr(element
)?
;
1842 self.word_space(";")?
;
1843 self.print_expr(count
)?
;
1844 word(&mut self.s
, "]")?
;
1848 fn print_expr_struct(&mut self,
1850 fields
: &[ast
::Field
],
1851 wth
: &Option
<P
<ast
::Expr
>>,
1852 attrs
: &[Attribute
]) -> io
::Result
<()> {
1853 self.print_path(path
, true, 0)?
;
1854 word(&mut self.s
, "{")?
;
1855 self.print_inner_attributes_inline(attrs
)?
;
1860 s
.ibox(INDENT_UNIT
)?
;
1861 s
.print_ident(field
.ident
.node
)?
;
1863 s
.print_expr(&field
.expr
)?
;
1869 self.ibox(INDENT_UNIT
)?
;
1870 if !fields
.is_empty() {
1871 word(&mut self.s
, ",")?
;
1872 space(&mut self.s
)?
;
1874 word(&mut self.s
, "..")?
;
1875 self.print_expr(&expr
)?
;
1878 _
=> if !fields
.is_empty() {
1879 word(&mut self.s
, ",")?
1882 word(&mut self.s
, "}")?
;
1886 fn print_expr_tup(&mut self, exprs
: &[P
<ast
::Expr
>],
1887 attrs
: &[Attribute
]) -> io
::Result
<()> {
1889 self.print_inner_attributes_inline(attrs
)?
;
1890 self.commasep_exprs(Inconsistent
, &exprs
[..])?
;
1891 if exprs
.len() == 1 {
1892 word(&mut self.s
, ",")?
;
1897 fn print_expr_call(&mut self,
1899 args
: &[P
<ast
::Expr
>]) -> io
::Result
<()> {
1900 self.print_expr_maybe_paren(func
)?
;
1901 self.print_call_post(args
)
1904 fn print_expr_method_call(&mut self,
1905 ident
: ast
::SpannedIdent
,
1907 args
: &[P
<ast
::Expr
>]) -> io
::Result
<()> {
1908 let base_args
= &args
[1..];
1909 self.print_expr(&args
[0])?
;
1910 word(&mut self.s
, ".")?
;
1911 self.print_ident(ident
.node
)?
;
1912 if !tys
.is_empty() {
1913 word(&mut self.s
, "::<")?
;
1914 self.commasep(Inconsistent
, tys
,
1915 |s
, ty
| s
.print_type(&ty
))?
;
1916 word(&mut self.s
, ">")?
;
1918 self.print_call_post(base_args
)
1921 fn print_expr_binary(&mut self,
1924 rhs
: &ast
::Expr
) -> io
::Result
<()> {
1925 if self.check_expr_bin_needs_paren(lhs
, op
) {
1926 self.print_expr_maybe_paren(lhs
)?
;
1928 self.print_expr(lhs
)?
;
1930 space(&mut self.s
)?
;
1931 self.word_space(op
.node
.to_string())?
;
1932 if self.check_expr_bin_needs_paren(rhs
, op
) {
1933 self.print_expr_maybe_paren(rhs
)
1935 self.print_expr(rhs
)
1939 fn print_expr_unary(&mut self,
1941 expr
: &ast
::Expr
) -> io
::Result
<()> {
1942 word(&mut self.s
, ast
::UnOp
::to_string(op
))?
;
1943 self.print_expr_maybe_paren(expr
)
1946 fn print_expr_addr_of(&mut self,
1947 mutability
: ast
::Mutability
,
1948 expr
: &ast
::Expr
) -> io
::Result
<()> {
1949 word(&mut self.s
, "&")?
;
1950 self.print_mutability(mutability
)?
;
1951 self.print_expr_maybe_paren(expr
)
1954 pub fn print_expr(&mut self, expr
: &ast
::Expr
) -> io
::Result
<()> {
1955 self.print_expr_outer_attr_style(expr
, true)
1958 fn print_expr_outer_attr_style(&mut self,
1960 is_inline
: bool
) -> io
::Result
<()> {
1961 self.maybe_print_comment(expr
.span
.lo
)?
;
1963 let attrs
= expr
.attrs
.as_attr_slice();
1965 self.print_outer_attributes_inline(attrs
)?
;
1967 self.print_outer_attributes(attrs
)?
;
1970 self.ibox(INDENT_UNIT
)?
;
1971 self.ann
.pre(self, NodeExpr(expr
))?
;
1973 ast
::ExprKind
::Box(ref expr
) => {
1974 self.word_space("box")?
;
1975 self.print_expr(expr
)?
;
1977 ast
::ExprKind
::InPlace(ref place
, ref expr
) => {
1978 self.print_expr_in_place(place
, expr
)?
;
1980 ast
::ExprKind
::Vec(ref exprs
) => {
1981 self.print_expr_vec(&exprs
[..], attrs
)?
;
1983 ast
::ExprKind
::Repeat(ref element
, ref count
) => {
1984 self.print_expr_repeat(&element
, &count
, attrs
)?
;
1986 ast
::ExprKind
::Struct(ref path
, ref fields
, ref wth
) => {
1987 self.print_expr_struct(path
, &fields
[..], wth
, attrs
)?
;
1989 ast
::ExprKind
::Tup(ref exprs
) => {
1990 self.print_expr_tup(&exprs
[..], attrs
)?
;
1992 ast
::ExprKind
::Call(ref func
, ref args
) => {
1993 self.print_expr_call(&func
, &args
[..])?
;
1995 ast
::ExprKind
::MethodCall(ident
, ref tys
, ref args
) => {
1996 self.print_expr_method_call(ident
, &tys
[..], &args
[..])?
;
1998 ast
::ExprKind
::Binary(op
, ref lhs
, ref rhs
) => {
1999 self.print_expr_binary(op
, &lhs
, &rhs
)?
;
2001 ast
::ExprKind
::Unary(op
, ref expr
) => {
2002 self.print_expr_unary(op
, &expr
)?
;
2004 ast
::ExprKind
::AddrOf(m
, ref expr
) => {
2005 self.print_expr_addr_of(m
, &expr
)?
;
2007 ast
::ExprKind
::Lit(ref lit
) => {
2008 self.print_literal(&lit
)?
;
2010 ast
::ExprKind
::Cast(ref expr
, ref ty
) => {
2011 if let ast
::ExprKind
::Cast(..) = expr
.node
{
2012 self.print_expr(&expr
)?
;
2014 self.print_expr_maybe_paren(&expr
)?
;
2016 space(&mut self.s
)?
;
2017 self.word_space("as")?
;
2018 self.print_type(&ty
)?
;
2020 ast
::ExprKind
::Type(ref expr
, ref ty
) => {
2021 self.print_expr(&expr
)?
;
2022 self.word_space(":")?
;
2023 self.print_type(&ty
)?
;
2025 ast
::ExprKind
::If(ref test
, ref blk
, ref elseopt
) => {
2026 self.print_if(&test
, &blk
, elseopt
.as_ref().map(|e
| &**e
))?
;
2028 ast
::ExprKind
::IfLet(ref pat
, ref expr
, ref blk
, ref elseopt
) => {
2029 self.print_if_let(&pat
, &expr
, &blk
, elseopt
.as_ref().map(|e
| &**e
))?
;
2031 ast
::ExprKind
::While(ref test
, ref blk
, opt_ident
) => {
2032 if let Some(ident
) = opt_ident
{
2033 self.print_ident(ident
)?
;
2034 self.word_space(":")?
;
2036 self.head("while")?
;
2037 self.print_expr(&test
)?
;
2038 space(&mut self.s
)?
;
2039 self.print_block_with_attrs(&blk
, attrs
)?
;
2041 ast
::ExprKind
::WhileLet(ref pat
, ref expr
, ref blk
, opt_ident
) => {
2042 if let Some(ident
) = opt_ident
{
2043 self.print_ident(ident
)?
;
2044 self.word_space(":")?
;
2046 self.head("while let")?
;
2047 self.print_pat(&pat
)?
;
2048 space(&mut self.s
)?
;
2049 self.word_space("=")?
;
2050 self.print_expr(&expr
)?
;
2051 space(&mut self.s
)?
;
2052 self.print_block_with_attrs(&blk
, attrs
)?
;
2054 ast
::ExprKind
::ForLoop(ref pat
, ref iter
, ref blk
, opt_ident
) => {
2055 if let Some(ident
) = opt_ident
{
2056 self.print_ident(ident
)?
;
2057 self.word_space(":")?
;
2060 self.print_pat(&pat
)?
;
2061 space(&mut self.s
)?
;
2062 self.word_space("in")?
;
2063 self.print_expr(&iter
)?
;
2064 space(&mut self.s
)?
;
2065 self.print_block_with_attrs(&blk
, attrs
)?
;
2067 ast
::ExprKind
::Loop(ref blk
, opt_ident
) => {
2068 if let Some(ident
) = opt_ident
{
2069 self.print_ident(ident
)?
;
2070 self.word_space(":")?
;
2073 space(&mut self.s
)?
;
2074 self.print_block_with_attrs(&blk
, attrs
)?
;
2076 ast
::ExprKind
::Match(ref expr
, ref arms
) => {
2077 self.cbox(INDENT_UNIT
)?
;
2079 self.word_nbsp("match")?
;
2080 self.print_expr(&expr
)?
;
2081 space(&mut self.s
)?
;
2083 self.print_inner_attributes_no_trailing_hardbreak(attrs
)?
;
2085 self.print_arm(arm
)?
;
2087 self.bclose_(expr
.span
, INDENT_UNIT
)?
;
2089 ast
::ExprKind
::Closure(capture_clause
, ref decl
, ref body
) => {
2090 self.print_capture_clause(capture_clause
)?
;
2092 self.print_fn_block_args(&decl
)?
;
2093 space(&mut self.s
)?
;
2095 let default_return
= match decl
.output
{
2096 ast
::FunctionRetTy
::Default(..) => true,
2100 if !default_return
|| !body
.stmts
.is_empty() || body
.expr
.is_none() {
2101 self.print_block_unclosed(&body
)?
;
2103 // we extract the block, so as not to create another set of boxes
2104 let i_expr
= body
.expr
.as_ref().unwrap();
2106 ast
::ExprKind
::Block(ref blk
) => {
2107 self.print_block_unclosed_with_attrs(
2109 i_expr
.attrs
.as_attr_slice())?
;
2112 // this is a bare expression
2113 self.print_expr(&i_expr
)?
;
2114 self.end()?
; // need to close a box
2118 // a box will be closed by print_expr, but we didn't want an overall
2119 // wrapper so we closed the corresponding opening. so create an
2120 // empty box to satisfy the close.
2123 ast
::ExprKind
::Block(ref blk
) => {
2124 // containing cbox, will be closed by print-block at }
2125 self.cbox(INDENT_UNIT
)?
;
2126 // head-box, will be closed by print-block after {
2128 self.print_block_with_attrs(&blk
, attrs
)?
;
2130 ast
::ExprKind
::Assign(ref lhs
, ref rhs
) => {
2131 self.print_expr(&lhs
)?
;
2132 space(&mut self.s
)?
;
2133 self.word_space("=")?
;
2134 self.print_expr(&rhs
)?
;
2136 ast
::ExprKind
::AssignOp(op
, ref lhs
, ref rhs
) => {
2137 self.print_expr(&lhs
)?
;
2138 space(&mut self.s
)?
;
2139 word(&mut self.s
, op
.node
.to_string())?
;
2140 self.word_space("=")?
;
2141 self.print_expr(&rhs
)?
;
2143 ast
::ExprKind
::Field(ref expr
, id
) => {
2144 self.print_expr(&expr
)?
;
2145 word(&mut self.s
, ".")?
;
2146 self.print_ident(id
.node
)?
;
2148 ast
::ExprKind
::TupField(ref expr
, id
) => {
2149 self.print_expr(&expr
)?
;
2150 word(&mut self.s
, ".")?
;
2151 self.print_usize(id
.node
)?
;
2153 ast
::ExprKind
::Index(ref expr
, ref index
) => {
2154 self.print_expr(&expr
)?
;
2155 word(&mut self.s
, "[")?
;
2156 self.print_expr(&index
)?
;
2157 word(&mut self.s
, "]")?
;
2159 ast
::ExprKind
::Range(ref start
, ref end
, limits
) => {
2160 if let &Some(ref e
) = start
{
2161 self.print_expr(&e
)?
;
2163 if limits
== ast
::RangeLimits
::HalfOpen
{
2164 word(&mut self.s
, "..")?
;
2166 word(&mut self.s
, "...")?
;
2168 if let &Some(ref e
) = end
{
2169 self.print_expr(&e
)?
;
2172 ast
::ExprKind
::Path(None
, ref path
) => {
2173 self.print_path(path
, true, 0)?
2175 ast
::ExprKind
::Path(Some(ref qself
), ref path
) => {
2176 self.print_qpath(path
, qself
, true)?
2178 ast
::ExprKind
::Break(opt_ident
) => {
2179 word(&mut self.s
, "break")?
;
2180 space(&mut self.s
)?
;
2181 if let Some(ident
) = opt_ident
{
2182 self.print_ident(ident
.node
)?
;
2183 space(&mut self.s
)?
;
2186 ast
::ExprKind
::Again(opt_ident
) => {
2187 word(&mut self.s
, "continue")?
;
2188 space(&mut self.s
)?
;
2189 if let Some(ident
) = opt_ident
{
2190 self.print_ident(ident
.node
)?
;
2194 ast
::ExprKind
::Ret(ref result
) => {
2195 word(&mut self.s
, "return")?
;
2198 word(&mut self.s
, " ")?
;
2199 self.print_expr(&expr
)?
;
2204 ast
::ExprKind
::InlineAsm(ref a
) => {
2205 word(&mut self.s
, "asm!")?
;
2207 self.print_string(&a
.asm
, a
.asm_str_style
)?
;
2208 self.word_space(":")?
;
2210 self.commasep(Inconsistent
, &a
.outputs
,
2212 let mut ch
= out
.constraint
.chars();
2214 Some('
='
) if out
.is_rw
=> {
2215 s
.print_string(&format
!("+{}", ch
.as_str()),
2216 ast
::StrStyle
::Cooked
)?
2218 _
=> s
.print_string(&out
.constraint
,
2219 ast
::StrStyle
::Cooked
)?
2222 s
.print_expr(&out
.expr
)?
;
2226 space(&mut self.s
)?
;
2227 self.word_space(":")?
;
2229 self.commasep(Inconsistent
, &a
.inputs
,
2230 |s
, &(ref co
, ref o
)| {
2231 s
.print_string(&co
, ast
::StrStyle
::Cooked
)?
;
2237 space(&mut self.s
)?
;
2238 self.word_space(":")?
;
2240 self.commasep(Inconsistent
, &a
.clobbers
,
2242 s
.print_string(&co
, ast
::StrStyle
::Cooked
)?
;
2246 let mut options
= vec
!();
2248 options
.push("volatile");
2251 options
.push("alignstack");
2253 if a
.dialect
== ast
::AsmDialect
::Intel
{
2254 options
.push("intel");
2257 if !options
.is_empty() {
2258 space(&mut self.s
)?
;
2259 self.word_space(":")?
;
2260 self.commasep(Inconsistent
, &options
,
2262 s
.print_string(co
, ast
::StrStyle
::Cooked
)?
;
2269 ast
::ExprKind
::Mac(ref m
) => self.print_mac(m
, token
::Paren
)?
,
2270 ast
::ExprKind
::Paren(ref e
) => {
2272 self.print_inner_attributes_inline(attrs
)?
;
2273 self.print_expr(&e
)?
;
2276 ast
::ExprKind
::Try(ref e
) => {
2277 self.print_expr(e
)?
;
2278 word(&mut self.s
, "?")?
2281 self.ann
.post(self, NodeExpr(expr
))?
;
2285 pub fn print_local_decl(&mut self, loc
: &ast
::Local
) -> io
::Result
<()> {
2286 self.print_pat(&loc
.pat
)?
;
2287 if let Some(ref ty
) = loc
.ty
{
2288 self.word_space(":")?
;
2289 self.print_type(&ty
)?
;
2294 pub fn print_decl(&mut self, decl
: &ast
::Decl
) -> io
::Result
<()> {
2295 self.maybe_print_comment(decl
.span
.lo
)?
;
2297 ast
::DeclKind
::Local(ref loc
) => {
2298 self.print_outer_attributes(loc
.attrs
.as_attr_slice())?
;
2299 self.space_if_not_bol()?
;
2300 self.ibox(INDENT_UNIT
)?
;
2301 self.word_nbsp("let")?
;
2303 self.ibox(INDENT_UNIT
)?
;
2304 self.print_local_decl(&loc
)?
;
2306 if let Some(ref init
) = loc
.init
{
2308 self.word_space("=")?
;
2309 self.print_expr(&init
)?
;
2313 ast
::DeclKind
::Item(ref item
) => self.print_item(&item
)
2317 pub fn print_ident(&mut self, ident
: ast
::Ident
) -> io
::Result
<()> {
2318 word(&mut self.s
, &ident
.name
.as_str())?
;
2319 self.ann
.post(self, NodeIdent(&ident
))
2322 pub fn print_usize(&mut self, i
: usize) -> io
::Result
<()> {
2323 word(&mut self.s
, &i
.to_string())
2326 pub fn print_name(&mut self, name
: ast
::Name
) -> io
::Result
<()> {
2327 word(&mut self.s
, &name
.as_str())?
;
2328 self.ann
.post(self, NodeName(&name
))
2331 pub fn print_for_decl(&mut self, loc
: &ast
::Local
,
2332 coll
: &ast
::Expr
) -> io
::Result
<()> {
2333 self.print_local_decl(loc
)?
;
2334 space(&mut self.s
)?
;
2335 self.word_space("in")?
;
2336 self.print_expr(coll
)
2339 fn print_path(&mut self,
2341 colons_before_params
: bool
,
2345 self.maybe_print_comment(path
.span
.lo
)?
;
2347 let mut first
= !path
.global
;
2348 for segment
in &path
.segments
[..path
.segments
.len()-depth
] {
2352 word(&mut self.s
, "::")?
2355 self.print_ident(segment
.identifier
)?
;
2357 self.print_path_parameters(&segment
.parameters
, colons_before_params
)?
;
2363 fn print_qpath(&mut self,
2366 colons_before_params
: bool
)
2369 word(&mut self.s
, "<")?
;
2370 self.print_type(&qself
.ty
)?
;
2371 if qself
.position
> 0 {
2372 space(&mut self.s
)?
;
2373 self.word_space("as")?
;
2374 let depth
= path
.segments
.len() - qself
.position
;
2375 self.print_path(&path
, false, depth
)?
;
2377 word(&mut self.s
, ">")?
;
2378 word(&mut self.s
, "::")?
;
2379 let item_segment
= path
.segments
.last().unwrap();
2380 self.print_ident(item_segment
.identifier
)?
;
2381 self.print_path_parameters(&item_segment
.parameters
, colons_before_params
)
2384 fn print_path_parameters(&mut self,
2385 parameters
: &ast
::PathParameters
,
2386 colons_before_params
: bool
)
2389 if parameters
.is_empty() {
2393 if colons_before_params
{
2394 word(&mut self.s
, "::")?
2398 ast
::PathParameters
::AngleBracketed(ref data
) => {
2399 word(&mut self.s
, "<")?
;
2401 let mut comma
= false;
2402 for lifetime
in &data
.lifetimes
{
2404 self.word_space(",")?
2406 self.print_lifetime(lifetime
)?
;
2410 if !data
.types
.is_empty() {
2412 self.word_space(",")?
2417 |s
, ty
| s
.print_type(&ty
))?
;
2421 for binding
in data
.bindings
.iter() {
2423 self.word_space(",")?
2425 self.print_ident(binding
.ident
)?
;
2426 space(&mut self.s
)?
;
2427 self.word_space("=")?
;
2428 self.print_type(&binding
.ty
)?
;
2432 word(&mut self.s
, ">")?
2435 ast
::PathParameters
::Parenthesized(ref data
) => {
2436 word(&mut self.s
, "(")?
;
2440 |s
, ty
| s
.print_type(&ty
))?
;
2441 word(&mut self.s
, ")")?
;
2446 self.space_if_not_bol()?
;
2447 self.word_space("->")?
;
2448 self.print_type(&ty
)?
;
2457 pub fn print_pat(&mut self, pat
: &ast
::Pat
) -> io
::Result
<()> {
2458 self.maybe_print_comment(pat
.span
.lo
)?
;
2459 self.ann
.pre(self, NodePat(pat
))?
;
2460 /* Pat isn't normalized, but the beauty of it
2461 is that it doesn't matter */
2463 PatKind
::Wild
=> word(&mut self.s
, "_")?
,
2464 PatKind
::Ident(binding_mode
, ref path1
, ref sub
) => {
2465 match binding_mode
{
2466 ast
::BindingMode
::ByRef(mutbl
) => {
2467 self.word_nbsp("ref")?
;
2468 self.print_mutability(mutbl
)?
;
2470 ast
::BindingMode
::ByValue(ast
::Mutability
::Immutable
) => {}
2471 ast
::BindingMode
::ByValue(ast
::Mutability
::Mutable
) => {
2472 self.word_nbsp("mut")?
;
2475 self.print_ident(path1
.node
)?
;
2478 word(&mut self.s
, "@")?
;
2479 self.print_pat(&p
)?
;
2484 PatKind
::TupleStruct(ref path
, ref args_
) => {
2485 self.print_path(path
, true, 0)?
;
2487 None
=> word(&mut self.s
, "(..)")?
,
2490 self.commasep(Inconsistent
, &args
[..],
2491 |s
, p
| s
.print_pat(&p
))?
;
2496 PatKind
::Path(ref path
) => {
2497 self.print_path(path
, true, 0)?
;
2499 PatKind
::QPath(ref qself
, ref path
) => {
2500 self.print_qpath(path
, qself
, false)?
;
2502 PatKind
::Struct(ref path
, ref fields
, etc
) => {
2503 self.print_path(path
, true, 0)?
;
2505 self.word_space("{")?
;
2507 Consistent
, &fields
[..],
2509 s
.cbox(INDENT_UNIT
)?
;
2510 if !f
.node
.is_shorthand
{
2511 s
.print_ident(f
.node
.ident
)?
;
2514 s
.print_pat(&f
.node
.pat
)?
;
2517 |f
| f
.node
.pat
.span
)?
;
2519 if !fields
.is_empty() { self.word_space(",")?; }
2520 word(&mut self.s
, "..")?
;
2522 space(&mut self.s
)?
;
2523 word(&mut self.s
, "}")?
;
2525 PatKind
::Tup(ref elts
) => {
2527 self.commasep(Inconsistent
,
2529 |s
, p
| s
.print_pat(&p
))?
;
2530 if elts
.len() == 1 {
2531 word(&mut self.s
, ",")?
;
2535 PatKind
::Box(ref inner
) => {
2536 word(&mut self.s
, "box ")?
;
2537 self.print_pat(&inner
)?
;
2539 PatKind
::Ref(ref inner
, mutbl
) => {
2540 word(&mut self.s
, "&")?
;
2541 if mutbl
== ast
::Mutability
::Mutable
{
2542 word(&mut self.s
, "mut ")?
;
2544 self.print_pat(&inner
)?
;
2546 PatKind
::Lit(ref e
) => self.print_expr(&**e
)?
,
2547 PatKind
::Range(ref begin
, ref end
) => {
2548 self.print_expr(&begin
)?
;
2549 space(&mut self.s
)?
;
2550 word(&mut self.s
, "...")?
;
2551 self.print_expr(&end
)?
;
2553 PatKind
::Vec(ref before
, ref slice
, ref after
) => {
2554 word(&mut self.s
, "[")?
;
2555 self.commasep(Inconsistent
,
2557 |s
, p
| s
.print_pat(&p
))?
;
2558 if let Some(ref p
) = *slice
{
2559 if !before
.is_empty() { self.word_space(",")?; }
2560 if p
.node
!= PatKind
::Wild
{
2561 self.print_pat(&p
)?
;
2563 word(&mut self.s
, "..")?
;
2564 if !after
.is_empty() { self.word_space(",")?; }
2566 self.commasep(Inconsistent
,
2568 |s
, p
| s
.print_pat(&p
))?
;
2569 word(&mut self.s
, "]")?
;
2571 PatKind
::Mac(ref m
) => self.print_mac(m
, token
::Paren
)?
,
2573 self.ann
.post(self, NodePat(pat
))
2576 fn print_arm(&mut self, arm
: &ast
::Arm
) -> io
::Result
<()> {
2577 // I have no idea why this check is necessary, but here it
2579 if arm
.attrs
.is_empty() {
2580 space(&mut self.s
)?
;
2582 self.cbox(INDENT_UNIT
)?
;
2584 self.print_outer_attributes(&arm
.attrs
)?
;
2585 let mut first
= true;
2586 for p
in &arm
.pats
{
2590 space(&mut self.s
)?
;
2591 self.word_space("|")?
;
2593 self.print_pat(&p
)?
;
2595 space(&mut self.s
)?
;
2596 if let Some(ref e
) = arm
.guard
{
2597 self.word_space("if")?
;
2598 self.print_expr(&e
)?
;
2599 space(&mut self.s
)?
;
2601 self.word_space("=>")?
;
2603 match arm
.body
.node
{
2604 ast
::ExprKind
::Block(ref blk
) => {
2605 // the block will close the pattern's ibox
2606 self.print_block_unclosed_indent(&blk
, INDENT_UNIT
)?
;
2608 // If it is a user-provided unsafe block, print a comma after it
2609 if let BlockCheckMode
::Unsafe(ast
::UserProvided
) = blk
.rules
{
2610 word(&mut self.s
, ",")?
;
2614 self.end()?
; // close the ibox for the pattern
2615 self.print_expr(&arm
.body
)?
;
2616 word(&mut self.s
, ",")?
;
2619 self.end() // close enclosing cbox
2622 // Returns whether it printed anything
2623 fn print_explicit_self(&mut self,
2624 explicit_self
: &ast
::SelfKind
,
2625 mutbl
: ast
::Mutability
) -> io
::Result
<bool
> {
2626 self.print_mutability(mutbl
)?
;
2627 match *explicit_self
{
2628 ast
::SelfKind
::Static
=> { return Ok(false); }
2629 ast
::SelfKind
::Value(_
) => {
2630 word(&mut self.s
, "self")?
;
2632 ast
::SelfKind
::Region(ref lt
, m
, _
) => {
2633 word(&mut self.s
, "&")?
;
2634 self.print_opt_lifetime(lt
)?
;
2635 self.print_mutability(m
)?
;
2636 word(&mut self.s
, "self")?
;
2638 ast
::SelfKind
::Explicit(ref typ
, _
) => {
2639 word(&mut self.s
, "self")?
;
2640 self.word_space(":")?
;
2641 self.print_type(&typ
)?
;
2647 pub fn print_fn(&mut self,
2649 unsafety
: ast
::Unsafety
,
2650 constness
: ast
::Constness
,
2652 name
: Option
<ast
::Ident
>,
2653 generics
: &ast
::Generics
,
2654 opt_explicit_self
: Option
<&ast
::SelfKind
>,
2655 vis
: &ast
::Visibility
) -> io
::Result
<()> {
2656 self.print_fn_header_info(unsafety
, constness
, abi
, vis
)?
;
2658 if let Some(name
) = name
{
2660 self.print_ident(name
)?
;
2662 self.print_generics(generics
)?
;
2663 self.print_fn_args_and_ret(decl
, opt_explicit_self
)?
;
2664 self.print_where_clause(&generics
.where_clause
)
2667 pub fn print_fn_args(&mut self, decl
: &ast
::FnDecl
,
2668 opt_explicit_self
: Option
<&ast
::SelfKind
>,
2669 is_closure
: bool
) -> io
::Result
<()> {
2670 // It is unfortunate to duplicate the commasep logic, but we want the
2671 // self type and the args all in the same box.
2672 self.rbox(0, Inconsistent
)?
;
2673 let mut first
= true;
2674 if let Some(explicit_self
) = opt_explicit_self
{
2675 let m
= match *explicit_self
{
2676 ast
::SelfKind
::Static
=> ast
::Mutability
::Immutable
,
2677 _
=> match decl
.inputs
[0].pat
.node
{
2678 PatKind
::Ident(ast
::BindingMode
::ByValue(m
), _
, _
) => m
,
2679 _
=> ast
::Mutability
::Immutable
2682 first
= !self.print_explicit_self(explicit_self
, m
)?
;
2685 // HACK(eddyb) ignore the separately printed self argument.
2686 let args
= if first
{
2693 if first { first = false; }
else { self.word_space(",")?; }
2694 self.print_arg(arg
, is_closure
)?
;
2700 pub fn print_fn_args_and_ret(&mut self, decl
: &ast
::FnDecl
,
2701 opt_explicit_self
: Option
<&ast
::SelfKind
>)
2704 self.print_fn_args(decl
, opt_explicit_self
, false)?
;
2706 word(&mut self.s
, ", ...")?
;
2710 self.print_fn_output(decl
)
2713 pub fn print_fn_block_args(
2717 word(&mut self.s
, "|")?
;
2718 self.print_fn_args(decl
, None
, true)?
;
2719 word(&mut self.s
, "|")?
;
2721 if let ast
::FunctionRetTy
::Default(..) = decl
.output
{
2725 self.space_if_not_bol()?
;
2726 self.word_space("->")?
;
2728 ast
::FunctionRetTy
::Ty(ref ty
) => {
2729 self.print_type(&ty
)?
;
2730 self.maybe_print_comment(ty
.span
.lo
)
2732 ast
::FunctionRetTy
::Default(..) => unreachable
!(),
2733 ast
::FunctionRetTy
::None(span
) => {
2734 self.word_nbsp("!")?
;
2735 self.maybe_print_comment(span
.lo
)
2740 pub fn print_capture_clause(&mut self, capture_clause
: ast
::CaptureBy
)
2742 match capture_clause
{
2743 ast
::CaptureBy
::Value
=> self.word_space("move"),
2744 ast
::CaptureBy
::Ref
=> Ok(()),
2748 pub fn print_bounds(&mut self,
2750 bounds
: &[ast
::TyParamBound
])
2752 if !bounds
.is_empty() {
2753 word(&mut self.s
, prefix
)?
;
2754 let mut first
= true;
2755 for bound
in bounds
{
2760 self.word_space("+")?
;
2764 TraitTyParamBound(ref tref
, TraitBoundModifier
::None
) => {
2765 self.print_poly_trait_ref(tref
)
2767 TraitTyParamBound(ref tref
, TraitBoundModifier
::Maybe
) => {
2768 word(&mut self.s
, "?")?
;
2769 self.print_poly_trait_ref(tref
)
2771 RegionTyParamBound(ref lt
) => {
2772 self.print_lifetime(lt
)
2782 pub fn print_lifetime(&mut self,
2783 lifetime
: &ast
::Lifetime
)
2786 self.print_name(lifetime
.name
)
2789 pub fn print_lifetime_def(&mut self,
2790 lifetime
: &ast
::LifetimeDef
)
2793 self.print_lifetime(&lifetime
.lifetime
)?
;
2795 for v
in &lifetime
.bounds
{
2796 word(&mut self.s
, sep
)?
;
2797 self.print_lifetime(v
)?
;
2803 pub fn print_generics(&mut self,
2804 generics
: &ast
::Generics
)
2807 let total
= generics
.lifetimes
.len() + generics
.ty_params
.len();
2812 word(&mut self.s
, "<")?
;
2814 let mut ints
= Vec
::new();
2819 self.commasep(Inconsistent
, &ints
[..], |s
, &idx
| {
2820 if idx
< generics
.lifetimes
.len() {
2821 let lifetime
= &generics
.lifetimes
[idx
];
2822 s
.print_lifetime_def(lifetime
)
2824 let idx
= idx
- generics
.lifetimes
.len();
2825 let param
= &generics
.ty_params
[idx
];
2826 s
.print_ty_param(param
)
2830 word(&mut self.s
, ">")?
;
2834 pub fn print_ty_param(&mut self, param
: &ast
::TyParam
) -> io
::Result
<()> {
2835 self.print_ident(param
.ident
)?
;
2836 self.print_bounds(":", ¶m
.bounds
)?
;
2837 match param
.default {
2838 Some(ref default) => {
2839 space(&mut self.s
)?
;
2840 self.word_space("=")?
;
2841 self.print_type(&default)
2847 pub fn print_where_clause(&mut self, where_clause
: &ast
::WhereClause
)
2849 if where_clause
.predicates
.is_empty() {
2853 space(&mut self.s
)?
;
2854 self.word_space("where")?
;
2856 for (i
, predicate
) in where_clause
.predicates
.iter().enumerate() {
2858 self.word_space(",")?
;
2862 ast
::WherePredicate
::BoundPredicate(ast
::WhereBoundPredicate
{ref bound_lifetimes
,
2866 self.print_formal_lifetime_list(bound_lifetimes
)?
;
2867 self.print_type(&bounded_ty
)?
;
2868 self.print_bounds(":", bounds
)?
;
2870 ast
::WherePredicate
::RegionPredicate(ast
::WhereRegionPredicate
{ref lifetime
,
2873 self.print_lifetime(lifetime
)?
;
2874 word(&mut self.s
, ":")?
;
2876 for (i
, bound
) in bounds
.iter().enumerate() {
2877 self.print_lifetime(bound
)?
;
2880 word(&mut self.s
, ":")?
;
2884 ast
::WherePredicate
::EqPredicate(ast
::WhereEqPredicate{ref path, ref ty, ..}
) => {
2885 self.print_path(path
, false, 0)?
;
2886 space(&mut self.s
)?
;
2887 self.word_space("=")?
;
2888 self.print_type(&ty
)?
;
2896 pub fn print_view_path(&mut self, vp
: &ast
::ViewPath
) -> io
::Result
<()> {
2898 ast
::ViewPathSimple(ident
, ref path
) => {
2899 self.print_path(path
, false, 0)?
;
2901 if path
.segments
.last().unwrap().identifier
.name
!=
2903 space(&mut self.s
)?
;
2904 self.word_space("as")?
;
2905 self.print_ident(ident
)?
;
2911 ast
::ViewPathGlob(ref path
) => {
2912 self.print_path(path
, false, 0)?
;
2913 word(&mut self.s
, "::*")
2916 ast
::ViewPathList(ref path
, ref idents
) => {
2917 if path
.segments
.is_empty() {
2918 word(&mut self.s
, "{")?
;
2920 self.print_path(path
, false, 0)?
;
2921 word(&mut self.s
, "::{")?
;
2923 self.commasep(Inconsistent
, &idents
[..], |s
, w
| {
2925 ast
::PathListItemKind
::Ident { name, rename, .. }
=> {
2926 s
.print_ident(name
)?
;
2927 if let Some(ident
) = rename
{
2929 s
.word_space("as")?
;
2930 s
.print_ident(ident
)?
;
2934 ast
::PathListItemKind
::Mod { rename, .. }
=> {
2935 word(&mut s
.s
, "self")?
;
2936 if let Some(ident
) = rename
{
2938 s
.word_space("as")?
;
2939 s
.print_ident(ident
)?
;
2945 word(&mut self.s
, "}")
2950 pub fn print_mutability(&mut self,
2951 mutbl
: ast
::Mutability
) -> io
::Result
<()> {
2953 ast
::Mutability
::Mutable
=> self.word_nbsp("mut"),
2954 ast
::Mutability
::Immutable
=> Ok(()),
2958 pub fn print_mt(&mut self, mt
: &ast
::MutTy
) -> io
::Result
<()> {
2959 self.print_mutability(mt
.mutbl
)?
;
2960 self.print_type(&mt
.ty
)
2963 pub fn print_arg(&mut self, input
: &ast
::Arg
, is_closure
: bool
) -> io
::Result
<()> {
2964 self.ibox(INDENT_UNIT
)?
;
2965 match input
.ty
.node
{
2966 ast
::TyKind
::Infer
if is_closure
=> self.print_pat(&input
.pat
)?
,
2968 match input
.pat
.node
{
2969 PatKind
::Ident(_
, ref path1
, _
) if
2971 parse
::token
::special_idents
::invalid
.name
=> {
2975 self.print_pat(&input
.pat
)?
;
2976 word(&mut self.s
, ":")?
;
2977 space(&mut self.s
)?
;
2980 self.print_type(&input
.ty
)?
;
2986 pub fn print_fn_output(&mut self, decl
: &ast
::FnDecl
) -> io
::Result
<()> {
2987 if let ast
::FunctionRetTy
::Default(..) = decl
.output
{
2991 self.space_if_not_bol()?
;
2992 self.ibox(INDENT_UNIT
)?
;
2993 self.word_space("->")?
;
2995 ast
::FunctionRetTy
::None(_
) =>
2996 self.word_nbsp("!")?
,
2997 ast
::FunctionRetTy
::Default(..) => unreachable
!(),
2998 ast
::FunctionRetTy
::Ty(ref ty
) =>
2999 self.print_type(&ty
)?
3004 ast
::FunctionRetTy
::Ty(ref output
) => self.maybe_print_comment(output
.span
.lo
),
3009 pub fn print_ty_fn(&mut self,
3011 unsafety
: ast
::Unsafety
,
3013 name
: Option
<ast
::Ident
>,
3014 generics
: &ast
::Generics
,
3015 opt_explicit_self
: Option
<&ast
::SelfKind
>)
3017 self.ibox(INDENT_UNIT
)?
;
3018 if !generics
.lifetimes
.is_empty() || !generics
.ty_params
.is_empty() {
3019 word(&mut self.s
, "for")?
;
3020 self.print_generics(generics
)?
;
3022 let generics
= ast
::Generics
{
3023 lifetimes
: Vec
::new(),
3024 ty_params
: P
::empty(),
3025 where_clause
: ast
::WhereClause
{
3026 id
: ast
::DUMMY_NODE_ID
,
3027 predicates
: Vec
::new(),
3032 ast
::Constness
::NotConst
,
3037 &ast
::Visibility
::Inherited
)?
;
3041 pub fn maybe_print_trailing_comment(&mut self, span
: codemap
::Span
,
3042 next_pos
: Option
<BytePos
>)
3044 let cm
= match self.cm
{
3048 match self.next_comment() {
3050 if (*cmnt
).style
!= comments
::Trailing { return Ok(()) }
3051 let span_line
= cm
.lookup_char_pos(span
.hi
);
3052 let comment_line
= cm
.lookup_char_pos((*cmnt
).pos
);
3053 let mut next
= (*cmnt
).pos
+ BytePos(1);
3054 match next_pos { None => (), Some(p) => next = p }
3055 if span
.hi
< (*cmnt
).pos
&& (*cmnt
).pos
< next
&&
3056 span_line
.line
== comment_line
.line
{
3057 self.print_comment(cmnt
)?
;
3058 self.cur_cmnt_and_lit
.cur_cmnt
+= 1;
3066 pub fn print_remaining_comments(&mut self) -> io
::Result
<()> {
3067 // If there aren't any remaining comments, then we need to manually
3068 // make sure there is a line break at the end.
3069 if self.next_comment().is_none() {
3070 hardbreak(&mut self.s
)?
;
3073 match self.next_comment() {
3075 self.print_comment(cmnt
)?
;
3076 self.cur_cmnt_and_lit
.cur_cmnt
+= 1;
3084 pub fn print_opt_abi_and_extern_if_nondefault(&mut self,
3085 opt_abi
: Option
<Abi
>)
3088 Some(Abi
::Rust
) => Ok(()),
3090 self.word_nbsp("extern")?
;
3091 self.word_nbsp(&abi
.to_string())
3097 pub fn print_extern_opt_abi(&mut self,
3098 opt_abi
: Option
<Abi
>) -> io
::Result
<()> {
3101 self.word_nbsp("extern")?
;
3102 self.word_nbsp(&abi
.to_string())
3108 pub fn print_fn_header_info(&mut self,
3109 unsafety
: ast
::Unsafety
,
3110 constness
: ast
::Constness
,
3112 vis
: &ast
::Visibility
) -> io
::Result
<()> {
3113 word(&mut self.s
, &visibility_qualified(vis
, ""))?
;
3116 ast
::Constness
::NotConst
=> {}
3117 ast
::Constness
::Const
=> self.word_nbsp("const")?
3120 self.print_unsafety(unsafety
)?
;
3122 if abi
!= Abi
::Rust
{
3123 self.word_nbsp("extern")?
;
3124 self.word_nbsp(&abi
.to_string())?
;
3127 word(&mut self.s
, "fn")
3130 pub fn print_unsafety(&mut self, s
: ast
::Unsafety
) -> io
::Result
<()> {
3132 ast
::Unsafety
::Normal
=> Ok(()),
3133 ast
::Unsafety
::Unsafe
=> self.word_nbsp("unsafe"),
3138 fn repeat(s
: &str, n
: usize) -> String { iter::repeat(s).take(n).collect() }
3149 fn test_fun_to_string() {
3150 let abba_ident
= token
::str_to_ident("abba");
3152 let decl
= ast
::FnDecl
{
3154 output
: ast
::FunctionRetTy
::Default(codemap
::DUMMY_SP
),
3157 let generics
= ast
::Generics
::default();
3158 assert_eq
!(fun_to_string(&decl
, ast
::Unsafety
::Normal
,
3159 ast
::Constness
::NotConst
,
3166 fn test_variant_to_string() {
3167 let ident
= token
::str_to_ident("principal_skinner");
3169 let var
= codemap
::respan(codemap
::DUMMY_SP
, ast
::Variant_
{
3172 // making this up as I go.... ?
3173 data
: ast
::VariantData
::Unit(ast
::DUMMY_NODE_ID
),
3177 let varstr
= variant_to_string(&var
);
3178 assert_eq
!(varstr
, "principal_skinner");