From b161815fe0aace4baa7007386b783a88547d7548 Mon Sep 17 00:00:00 2001 From: Marcus Klaas Date: Sun, 19 Jul 2015 23:42:54 +0200 Subject: [PATCH] Format if-else expressions --- src/comment.rs | 8 +++--- src/expr.rs | 40 ++++++++++++++++++++++++++++-- src/imports.rs | 12 +++++++-- src/issues.rs | 8 ++++-- src/items.rs | 18 +++++++++++--- src/utils.rs | 8 ++++-- tests/source/expr.rs | 13 +++++++++- tests/source/struct_lits_visual.rs | 2 ++ tests/target/expr.rs | 19 +++++++++++++- tests/target/struct_lits_visual.rs | 5 ++++ 10 files changed, 117 insertions(+), 16 deletions(-) diff --git a/src/comment.rs b/src/comment.rs index 7e4119880c3..6d453bd5c88 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -17,9 +17,11 @@ pub fn rewrite_comment(orig: &str, block_style: bool, width: usize, offset: usiz let s = orig.trim(); // Edge case: block comments. Let's not trim their lines (for now). - let opener = if block_style { "/* " } else { "// " }; - let closer = if block_style { " */" } else { "" }; - let line_start = if block_style { " * " } else { "// " }; + let (opener, closer, line_start) = if block_style { + ("/* ", " */", " * ") + } else { + ("// ", "", "// ") + }; let max_chars = width.checked_sub(closer.len()).unwrap_or(1) .checked_sub(opener.len()).unwrap_or(1); diff --git a/src/expr.rs b/src/expr.rs index e0a76308b44..89846527cff 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -76,6 +76,17 @@ impl Rewrite for ast::Expr { format!("{}loop {}", rewrite_label(label), result) }) } + ast::Expr_::ExprBlock(ref block) => { + block.rewrite(context, width, offset) + } + ast::Expr_::ExprIf(ref cond, ref if_block, ref else_block) => { + rewrite_if_else(context, + cond, + if_block, + else_block.as_ref().map(|e| &**e), + width, + offset) + } _ => context.codemap.span_to_snippet(self.span).ok() } } @@ -108,6 +119,29 @@ fn rewrite_label(label: Option) -> String { } } +fn rewrite_if_else(context: &RewriteContext, + cond: &ast::Expr, + if_block: &ast::Block, + else_block: Option<&ast::Expr>, + width: usize, + offset: usize) + -> Option { + // FIXME: missing comments between control statements and blocks + let cond_string = try_opt!(cond.rewrite(context, width - 3 - 2, offset + 3)); + let if_block_string = try_opt!(if_block.rewrite(context, width, offset)); + + match else_block { + Some(else_block) => { + else_block.rewrite(context, width, offset).map(|else_block_string| { + format!("if {} {} else {}", cond_string, if_block_string, else_block_string) + }) + } + None => { + Some(format!("if {} {}", cond_string, if_block_string)) + } + } +} + fn rewrite_string_lit(context: &RewriteContext, s: &str, span: Span, @@ -229,6 +263,8 @@ fn rewrite_struct_lit<'a>(context: &RewriteContext, let field_iter = fields.into_iter().map(StructLitField::Regular) .chain(base.into_iter().map(StructLitField::Base)); + let inner_context = &RewriteContext { block_indent: indent, ..*context }; + let items = itemize_list(context.codemap, Vec::new(), field_iter, @@ -250,13 +286,13 @@ fn rewrite_struct_lit<'a>(context: &RewriteContext, |item| { match *item { StructLitField::Regular(ref field) => { - rewrite_field(context, &field, h_budget, indent) + rewrite_field(inner_context, &field, h_budget, indent) .unwrap_or(context.codemap.span_to_snippet(field.span) .unwrap()) }, StructLitField::Base(ref expr) => { // 2 = .. - expr.rewrite(context, h_budget - 2, indent + 2) + expr.rewrite(inner_context, h_budget - 2, indent + 2) .map(|s| format!("..{}", s)) .unwrap_or(context.codemap.span_to_snippet(expr.span) .unwrap()) diff --git a/src/imports.rs b/src/imports.rs index 1973115cd43..66bf26b041d 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -60,7 +60,11 @@ impl<'a> FmtVisitor<'a> { } // 2 = :: - let path_separation_w = if path_str.len() > 0 { 2 } else { 0 }; + let path_separation_w = if path_str.len() > 0 { + 2 + } else { + 0 + }; // 5 = "use " + { let indent = path_str.len() + 5 + path_separation_w + vis.len(); @@ -106,7 +110,11 @@ impl<'a> FmtVisitor<'a> { // FIXME: Make more efficient by using a linked list? That would // require changes to the signatures of itemize_list and write_list. let has_self = move_self_to_front(&mut items); - let first_index = if has_self { 0 } else { 1 }; + let first_index = if has_self { + 0 + } else { + 1 + }; if self.config.reorder_imports { items[1..].sort_by(|a, b| a.item.cmp(&b.item)); diff --git a/src/issues.rs b/src/issues.rs index 31f544605b5..34d5b8ab2c4 100644 --- a/src/issues.rs +++ b/src/issues.rs @@ -70,7 +70,11 @@ impl fmt::Display for Issue { IssueType::Todo => "TODO", IssueType::Fixme => "FIXME", }; - let details = if self.missing_number { " without issue number" } else { "" }; + let details = if self.missing_number { + " without issue number" + } else { + "" + }; write!(fmt, "{}{}", msg, details) } @@ -177,7 +181,7 @@ impl BadIssueSeeker { issue: Issue, mut part: NumberPart) -> IssueClassification { - if ! issue.missing_number || c == '\n' { + if !issue.missing_number || c == '\n' { return IssueClassification::Bad(issue); } else if c == ')' { return if let NumberPart::CloseParen = part { diff --git a/src/items.rs b/src/items.rs index b3f4a0a63a4..3c35b20fb3f 100644 --- a/src/items.rs +++ b/src/items.rs @@ -446,7 +446,11 @@ impl<'a> FmtVisitor<'a> { + field.node.name.to_string().len() + 1; // Open paren - let comma_cost = if self.config.enum_trailing_comma { 1 } else { 0 }; + let comma_cost = if self.config.enum_trailing_comma { + 1 + } else { + 0 + }; let budget = self.config.ideal_width - indent - comma_cost - 1; // 1 = ) let fmt = ListFormatting { @@ -520,7 +524,11 @@ impl<'a> FmtVisitor<'a> { ast::StructFieldKind::UnnamedField(..) => true }; - let (opener, terminator) = if is_tuple { ("(", ")") } else { (" {", "}") }; + let (opener, terminator) = if is_tuple { + ("(", ")") + } else { + (" {", "}") + }; let generics_str = match generics { Some(g) => self.format_generics(g, @@ -565,7 +573,11 @@ impl<'a> FmtVisitor<'a> { result.push_str(&indentation); } - let tactic = if break_line { ListTactic::Vertical } else { ListTactic::Horizontal }; + let tactic = if break_line { + ListTactic::Vertical + } else { + ListTactic::Horizontal + }; // 1 = , let budget = self.config.ideal_width - offset + self.config.tab_spaces - 1; diff --git a/src/utils.rs b/src/utils.rs index 47203a0754f..246f7cb2dc3 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -24,7 +24,9 @@ pub fn span_after(original: Span, needle: &str, codemap: &CodeMap) -> BytePos { #[inline] pub fn prev_char(s: &str, mut i: usize) -> usize { - if i == 0 { return 0; } + if i == 0 { + return 0; + } i -= 1; while !s.is_char_boundary(i) { @@ -35,7 +37,9 @@ pub fn prev_char(s: &str, mut i: usize) -> usize { #[inline] pub fn next_char(s: &str, mut i: usize) -> usize { - if i >= s.len() { return s.len(); } + if i >= s.len() { + return s.len(); + } while !s.is_char_boundary(i) { i += 1; diff --git a/tests/source/expr.rs b/tests/source/expr.rs index 373e42d67c5..d26c57ebbd0 100644 --- a/tests/source/expr.rs +++ b/tests/source/expr.rs @@ -12,5 +12,16 @@ some_ridiculously_loooooooooooooooooooooong_function(10000 * 30000000000 + 40000 - 50000 * sqrt(-1), trivial_value); (((((((((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + a + - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaa))))))))) + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaa))))))))); + + if 1 + 2 > 0 { let result = 5; result } else { 4}; + + if cond() { + something(); + } else if different_cond() { + something_else(); + } else { + // Check subformatting + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + } } diff --git a/tests/source/struct_lits_visual.rs b/tests/source/struct_lits_visual.rs index b629ffa1263..f14a56397ec 100644 --- a/tests/source/struct_lits_visual.rs +++ b/tests/source/struct_lits_visual.rs @@ -22,6 +22,8 @@ fn main() { Foo { a:Bar, b:foo() }; + Quux { x: if cond { bar(); }, y: baz() }; + A { // Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. first: item(), diff --git a/tests/target/expr.rs b/tests/target/expr.rs index 25c84511c41..3a8605b7c42 100644 --- a/tests/target/expr.rs +++ b/tests/target/expr.rs @@ -13,5 +13,22 @@ fn foo() -> bool { trivial_value); (((((((((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + a + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + - aaaaa))))))))) + aaaaa))))))))); + + if 1 + 2 > 0 { + let result = 5; + result + } else { + 4 + }; + + if cond() { + something(); + } else if different_cond() { + something_else(); + } else { + // Check subformatting + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + } } diff --git a/tests/target/struct_lits_visual.rs b/tests/target/struct_lits_visual.rs index 651cd2b883b..248839cb869 100644 --- a/tests/target/struct_lits_visual.rs +++ b/tests/target/struct_lits_visual.rs @@ -35,6 +35,11 @@ fn main() { Foo { a: Bar, b: foo() }; + Quux { x: if cond { + bar(); + }, + y: baz(), }; + A { // Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit // amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante // hendrerit. Donec et mollis dolor.