From d24bafd353d005edb7bd14e7efd3638cbaef68f4 Mon Sep 17 00:00:00 2001 From: Daniel Patterson Date: Thu, 9 Aug 2012 19:31:47 -0400 Subject: [PATCH] syntax: better formatting of closures in pretty printer and more verbose debugging messages --- src/libsyntax/print/pp.rs | 25 ++++++++----- src/libsyntax/print/pprust.rs | 68 ++++++++++++++++++++++++++++------- 2 files changed, 72 insertions(+), 21 deletions(-) diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index 5bbf5deb4293d..a04b5ebe3c94d 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -254,7 +254,8 @@ impl printer { self.left = 0u; self.right = 0u; } else { self.advance_right(); } - debug!{"pp BEGIN/buffer ~[%u,%u]", self.left, self.right}; + debug!{"pp BEGIN(%d)/buffer ~[%u,%u]", + b.offset, self.left, self.right}; self.token[self.right] = t; self.size[self.right] = -self.right_total; self.scan_push(self.right); @@ -278,7 +279,8 @@ impl printer { self.left = 0u; self.right = 0u; } else { self.advance_right(); } - debug!{"pp BREAK/buffer ~[%u,%u]", self.left, self.right}; + debug!{"pp BREAK(%d)/buffer ~[%u,%u]", + b.offset, self.left, self.right}; self.check_stack(0); self.scan_push(self.right); self.token[self.right] = t; @@ -287,10 +289,12 @@ impl printer { } STRING(s, len) => { if self.scan_stack_empty { - debug!{"pp STRING/print ~[%u,%u]", self.left, self.right}; + debug!{"pp STRING('%s')/print ~[%u,%u]", + *s, self.left, self.right}; self.print(t, len); } else { - debug!{"pp STRING/buffer ~[%u,%u]", self.left, self.right}; + debug!{"pp STRING('%s')/buffer ~[%u,%u]", + *s, self.left, self.right}; self.advance_right(); self.token[self.right] = t; self.size[self.right] = len; @@ -444,22 +448,25 @@ impl printer { let top = self.get_top(); match top.pbreak { fits => { - debug!{"print BREAK in fitting block"}; + debug!{"print BREAK(%d) in fitting block", b.blank_space}; self.space -= b.blank_space; self.indent(b.blank_space); } broken(consistent) => { - debug!{"print BREAK in consistent block"}; + debug!{"print BREAK(%d+%d) in consistent block", + top.offset, b.offset}; self.print_newline(top.offset + b.offset); self.space = self.margin - (top.offset + b.offset); } broken(inconsistent) => { if L > self.space { - debug!{"print BREAK w/ newline in inconsistent"}; + debug!{"print BREAK(%d+%d) w/ newline in inconsistent", + top.offset, b.offset}; self.print_newline(top.offset + b.offset); self.space = self.margin - (top.offset + b.offset); } else { - debug!{"print BREAK w/o newline in inconsistent"}; + debug!{"print BREAK(%d) w/o newline in inconsistent", + b.blank_space}; self.indent(b.blank_space); self.space -= b.blank_space; } @@ -467,7 +474,7 @@ impl printer { } } STRING(s, len) => { - debug!{"print STRING"}; + debug!{"print STRING(%s)", *s}; assert (L == len); // assert L <= space; self.space -= len; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 60c310100a12b..be4786e7b1d0d 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -237,10 +237,16 @@ fn bopen(s: ps) { } fn bclose_(s: ps, span: codemap::span, indented: uint) { + bclose_maybe_open(s, span, indented, true); +} +fn bclose_maybe_open (s: ps, span: codemap::span, indented: uint, + close_box: bool) { maybe_print_comment(s, span.hi); break_offset_if_not_bol(s, 1u, -(indented as int)); word(s.s, ~"}"); - end(s); // close the outer-box + if close_box { + end(s); // close the outer-box + } } fn bclose(s: ps, span: codemap::span) { bclose_(s, span, indent_unit); } @@ -827,8 +833,14 @@ fn print_block(s: ps, blk: ast::blk) { print_possibly_embedded_block(s, blk, block_normal, indent_unit); } +fn print_block_unclosed(s: ps, blk: ast::blk) { + print_possibly_embedded_block_(s, blk, block_normal, indent_unit, ~[], + false); +} + fn print_block_with_attrs(s: ps, blk: ast::blk, attrs: ~[ast::attribute]) { - print_possibly_embedded_block_(s, blk, block_normal, indent_unit, attrs); + print_possibly_embedded_block_(s, blk, block_normal, indent_unit, attrs, + true); } enum embed_type { block_block_fn, block_normal, } @@ -836,11 +848,12 @@ enum embed_type { block_block_fn, block_normal, } fn print_possibly_embedded_block(s: ps, blk: ast::blk, embedded: embed_type, indented: uint) { print_possibly_embedded_block_( - s, blk, embedded, indented, ~[]); + s, blk, embedded, indented, ~[], true); } fn print_possibly_embedded_block_(s: ps, blk: ast::blk, embedded: embed_type, - indented: uint, attrs: ~[ast::attribute]) { + indented: uint, attrs: ~[ast::attribute], + close_box: bool) { match blk.node.rules { ast::unchecked_blk => word(s.s, ~"unchecked"), ast::unsafe_blk => word(s.s, ~"unsafe"), @@ -868,7 +881,7 @@ fn print_possibly_embedded_block_(s: ps, blk: ast::blk, embedded: embed_type, } _ => () } - bclose_(s, blk.span, indented); + bclose_maybe_open(s, blk.span, indented, close_box); s.ann.post(ann_node); } @@ -1060,9 +1073,9 @@ fn print_expr(s: ps, &&expr: @ast::expr) { let blk = if has_block { let blk_arg = vec::pop(base_args); match blk_arg.node { - ast::expr_loop_body(_) => word_nbsp(s, ~"for"), - ast::expr_do_body(_) => word_nbsp(s, ~"do"), - _ => () + ast::expr_loop_body(_) => { head(s, ~"for"); } + ast::expr_do_body(_) => { head(s, ~"do"); } + _ => {} } some(blk_arg) } else { none }; @@ -1074,7 +1087,19 @@ fn print_expr(s: ps, &&expr: @ast::expr) { } if has_block { nbsp(s); - print_expr(s, option::get(blk)); + match blk.get().node { + // need to handle closures specifically + ast::expr_do_body(e) | ast::expr_loop_body(e) => { + end(s); // we close our head box; closure + // will create it's own. + print_expr(s, e); + end(s); // close outer box, as closures don't + } + _ => { + // not sure if this can happen. + print_expr(s, blk.get()); + } + } } } ast::expr_binary(op, lhs, rhs) => { @@ -1174,12 +1199,31 @@ fn print_expr(s: ps, &&expr: @ast::expr) { print_block(s, body); } ast::expr_fn_block(decl, body, cap_clause) => { + // in do/for blocks we don't want to show an empty + // argument list, but at this point we don't know which + // we are inside. + // + // if !decl.inputs.is_empty() { print_fn_block_args(s, decl, *cap_clause); - // The parser always adds an extra implicit block around lambdas + space(s.s); + // } assert body.node.stmts.is_empty(); assert body.node.expr.is_some(); - space(s.s); - print_expr(s, body.node.expr.get()); + // we extract the block, so as not to create another set of boxes + match body.node.expr.get().node { + ast::expr_block(blk) => { + print_block_unclosed(s, blk); + } + _ => { + // this is a bare expression + print_expr(s, body.node.expr.get()); + end(s); // need to close a box + } + } + // a box will be closed by print_expr, but we didn't want an overall + // wrapper so we closed the corresponding opening. so create an + // empty box to satisfy the close. + ibox(s, 0); } ast::expr_loop_body(body) => { print_expr(s, body);