Merge pull request #948 from flutterhash/master

Added option to configure if/else brace style
This commit is contained in:
Marcus Klaas de Vries 2016-04-17 23:15:37 +02:00
commit 68f04cec37
12 changed files with 589 additions and 11 deletions

View File

@ -38,6 +38,22 @@ configuration_option_enum! { BraceStyle:
SameLineWhere,
}
configuration_option_enum! { ControlBraceStyle:
// K&R/Stroustrup style, Rust community default
AlwaysSameLine,
// Allman style
AlwaysNextLine,
}
configuration_option_enum! { ElseIfBraceStyle:
// K&R style, Rust community default
AlwaysSameLine,
// Stroustrup style
ClosingNextLine,
// Allman style
AlwaysNextLine,
}
// How to indent a function's return type.
configuration_option_enum! { ReturnIndent:
// Aligned with the arguments
@ -315,6 +331,10 @@ create_config! {
newline_style: NewlineStyle, NewlineStyle::Unix, "Unix or Windows line endings";
fn_brace_style: BraceStyle, BraceStyle::SameLineWhere, "Brace style for functions";
item_brace_style: BraceStyle, BraceStyle::SameLineWhere, "Brace style for structs and enums";
else_if_brace_style: ElseIfBraceStyle, ElseIfBraceStyle::AlwaysSameLine,
"Brace style for if, else if, and else constructs";
control_brace_style: ControlBraceStyle, ControlBraceStyle::AlwaysSameLine,
"Brace style for match, loop, for, and while constructs";
impl_empty_single_line: bool, true, "Put empty-body implementations on a single line";
fn_empty_single_line: bool, true, "Put empty-body functions on a single line";
fn_single_line: bool, false, "Put single-expression functions on a single line";

View File

@ -23,7 +23,7 @@ use string::{StringFormat, rewrite_string};
use utils::{CodeMapSpanUtils, extra_offset, last_line_width, wrap_str, binary_search,
first_line_width, semicolon_for_stmt, trimmed_last_line_width, left_most_sub_expr};
use visitor::FmtVisitor;
use config::{Config, StructLitStyle, MultilineStyle};
use config::{Config, StructLitStyle, MultilineStyle, ElseIfBraceStyle, ControlBraceStyle};
use comment::{FindUncommented, rewrite_comment, contains_comment, recover_comment_removed};
use types::rewrite_path;
use items::{span_lo_for_arg, span_hi_for_arg};
@ -648,14 +648,20 @@ impl<'a> Rewrite for Loop<'a> {
None => String::new(),
};
let alt_block_sep = String::from("\n") + &context.block_indent.to_string(context.config);
let block_sep = match context.config.control_brace_style {
ControlBraceStyle::AlwaysNextLine => alt_block_sep.as_str(),
ControlBraceStyle::AlwaysSameLine => " ",
};
// FIXME: this drops any comment between "loop" and the block.
self.block
.rewrite(context, width, offset)
.map(|result| {
format!("{}{}{} {}",
format!("{}{}{}{}{}",
label_string,
self.keyword,
pat_expr_string,
block_sep,
result)
})
}
@ -701,12 +707,16 @@ fn rewrite_if_else(context: &RewriteContext,
allow_single_line: bool)
-> Option<String> {
// 3 = "if ", 2 = " {"
let pat_penalty = match context.config.else_if_brace_style {
ElseIfBraceStyle::AlwaysNextLine => 3,
_ => 3 + 2,
};
let pat_expr_string = try_opt!(rewrite_pat_expr(context,
pat,
cond,
"let ",
" =",
try_opt!(width.checked_sub(3 + 2)),
try_opt!(width.checked_sub(pat_penalty)),
offset + 3));
// Try to format if-else on single line.
@ -731,13 +741,19 @@ fn rewrite_if_else(context: &RewriteContext,
offset,
width);
let alt_block_sep = String::from("\n") + &context.block_indent.to_string(context.config);
let after_sep = match context.config.else_if_brace_style {
ElseIfBraceStyle::AlwaysNextLine => alt_block_sep.as_str(),
_ => " ",
};
let mut result = format!("if{}{}{}{}",
between_if_cond_comment.as_ref().map_or(" ", |str| &**str),
pat_expr_string,
after_cond_comment.as_ref().map_or(" ", |str| &**str),
after_cond_comment.as_ref().map_or(after_sep, |str| &**str),
if_block_string);
if let Some(else_block) = else_block_opt {
let mut last_in_chain = false;
let rewrite = match else_block.node {
// If the else expression is another if-else expression, prevent it
// from being formatted on a single line.
@ -763,7 +779,10 @@ fn rewrite_if_else(context: &RewriteContext,
offset,
false)
}
_ => else_block.rewrite(context, width, offset),
_ => {
last_in_chain = true;
else_block.rewrite(context, width, offset)
}
};
let between_if_else_block = mk_sp(if_block.span.hi,
@ -781,10 +800,20 @@ fn rewrite_if_else(context: &RewriteContext,
else_block.span.lo);
let after_else_comment = extract_comment(after_else, &context, offset, width);
let between_sep = match context.config.else_if_brace_style {
ElseIfBraceStyle::AlwaysNextLine |
ElseIfBraceStyle::ClosingNextLine => alt_block_sep.as_str(),
ElseIfBraceStyle::AlwaysSameLine => " ",
};
let after_sep = match context.config.else_if_brace_style {
ElseIfBraceStyle::AlwaysNextLine if last_in_chain => alt_block_sep.as_str(),
_ => " ",
};
try_opt!(write!(&mut result,
"{}else{}",
between_if_else_block_comment.as_ref().map_or(" ", |str| &**str),
after_else_comment.as_ref().map_or(" ", |str| &**str))
between_if_else_block_comment.as_ref()
.map_or(between_sep, |str| &**str),
after_else_comment.as_ref().map_or(after_sep, |str| &**str))
.ok());
result.push_str(&&try_opt!(rewrite));
}
@ -917,7 +946,12 @@ fn rewrite_match(context: &RewriteContext,
// `match `cond` {`
let cond_budget = try_opt!(width.checked_sub(8));
let cond_str = try_opt!(cond.rewrite(context, cond_budget, offset + 6));
let mut result = format!("match {} {{", cond_str);
let alt_block_sep = String::from("\n") + &context.block_indent.to_string(context.config);
let block_sep = match context.config.control_brace_style {
ControlBraceStyle::AlwaysSameLine => " ",
ControlBraceStyle::AlwaysNextLine => alt_block_sep.as_str(),
};
let mut result = format!("match {}{}{{", cond_str, block_sep);
let nested_context = context.nested_context();
let arm_indent = nested_context.block_indent;
@ -1076,6 +1110,7 @@ impl Rewrite for ast::Arm {
};
let comma = arm_comma(&context.config, self, body);
let alt_block_sep = String::from("\n") + &context.block_indent.to_string(context.config);
// Let's try and get the arm body on the same line as the condition.
// 4 = ` => `.len()
@ -1089,12 +1124,17 @@ impl Rewrite for ast::Arm {
false
};
let block_sep = match context.config.control_brace_style {
ControlBraceStyle::AlwaysNextLine if is_block => alt_block_sep.as_str(),
_ => " ",
};
match rewrite {
Some(ref body_str) if !body_str.contains('\n') || !context.config.wrap_match_arms ||
is_block => {
return Some(format!("{}{} => {}{}",
return Some(format!("{}{} =>{}{}{}",
attr_str.trim_left(),
pats_str,
block_sep,
body_str,
comma));
}
@ -1122,10 +1162,14 @@ impl Rewrite for ast::Arm {
("", "")
};
Some(format!("{}{} =>{}\n{}{}\n{}{}",
let block_sep = match context.config.control_brace_style {
ControlBraceStyle::AlwaysNextLine => alt_block_sep,
ControlBraceStyle::AlwaysSameLine => String::from(body_prefix) + "\n",
};
Some(format!("{}{} =>{}{}{}\n{}{}",
attr_str.trim_left(),
pats_str,
body_prefix,
block_sep,
indent_str,
next_line_body,
offset.to_string(context.config),

View File

@ -0,0 +1,44 @@
// rustfmt-control_brace_style: AlwaysNextLine
fn main() {
loop {
();
();
}
'loop_label: loop // loop comment
{
();
}
cond = true;
while cond {
();
}
'while_label: while cond { // while comment
();
}
for obj in iter {
for sub_obj in obj
{
'nested_while_label: while cond {
();
}
}
}
match some_var { // match comment
pattern0 => val0,
pattern1 => val1,
pattern2 | pattern3 => {
do_stuff();
val2
},
};
}

View File

@ -0,0 +1,44 @@
// rustfmt-control_brace_style: AlwaysSameLine
fn main() {
loop {
();
();
}
'loop_label: loop // loop comment
{
();
}
cond = true;
while cond {
();
}
'while_label: while cond { // while comment
();
}
for obj in iter {
for sub_obj in obj
{
'nested_while_label: while cond {
();
}
}
}
match some_var { // match comment
pattern0 => val0,
pattern1 => val1,
pattern2 | pattern3 => {
do_stuff();
val2
},
};
}

View File

@ -0,0 +1,54 @@
// rustfmt-else_if_brace_style: AlwaysNextLine
fn main() {
if false
{
();
();
}
if false // lone if comment
{
();
();
}
let a =
if 0 > 1 {
unreachable!()
}
else
{
0x0
};
if true
{
();
} else if false {
();
();
}
else {
();
();
();
}
if true // else-if-chain if comment
{
();
}
else if false // else-if-chain else-if comment
{
();
();
} else // else-if-chain else comment
{
();
();
();
}
}

View File

@ -0,0 +1,54 @@
// rustfmt-else_if_brace_style: AlwaysSameLine
fn main() {
if false
{
();
();
}
if false // lone if comment
{
();
();
}
let a =
if 0 > 1 {
unreachable!()
}
else
{
0x0
};
if true
{
();
} else if false {
();
();
}
else {
();
();
();
}
if true // else-if-chain if comment
{
();
}
else if false // else-if-chain else-if comment
{
();
();
} else // else-if-chain else comment
{
();
();
();
}
}

View File

@ -0,0 +1,54 @@
// rustfmt-else_if_brace_style: ClosingNextLine
fn main() {
if false
{
();
();
}
if false // lone if comment
{
();
();
}
let a =
if 0 > 1 {
unreachable!()
}
else
{
0x0
};
if true
{
();
} else if false {
();
();
}
else {
();
();
();
}
if true // else-if-chain if comment
{
();
}
else if false // else-if-chain else-if comment
{
();
();
} else // else-if-chain else comment
{
();
();
();
}
}

View File

@ -0,0 +1,52 @@
// rustfmt-control_brace_style: AlwaysNextLine
fn main() {
loop
{
();
();
}
'loop_label: loop
{
();
}
cond = true;
while cond
{
();
}
'while_label: while cond
{
// while comment
();
}
for obj in iter
{
for sub_obj in obj
{
'nested_while_label: while cond
{
();
}
}
}
match some_var
{ // match comment
pattern0 => val0,
pattern1 => val1,
pattern2 | pattern3 =>
{
do_stuff();
val2
}
};
}

View File

@ -0,0 +1,43 @@
// rustfmt-control_brace_style: AlwaysSameLine
fn main() {
loop {
();
();
}
'loop_label: loop {
();
}
cond = true;
while cond {
();
}
'while_label: while cond {
// while comment
();
}
for obj in iter {
for sub_obj in obj {
'nested_while_label: while cond {
();
}
}
}
match some_var { // match comment
pattern0 => val0,
pattern1 => val1,
pattern2 | pattern3 => {
do_stuff();
val2
}
};
}

View File

@ -0,0 +1,62 @@
// rustfmt-else_if_brace_style: AlwaysNextLine
fn main() {
if false
{
();
();
}
if false
// lone if comment
{
();
();
}
let a = if 0 > 1
{
unreachable!()
}
else
{
0x0
};
if true
{
();
}
else if false
{
();
();
}
else
{
();
();
();
}
if true
// else-if-chain if comment
{
();
}
else if false
// else-if-chain else-if comment
{
();
();
}
else
// else-if-chain else comment
{
();
();
();
}
}

View File

@ -0,0 +1,51 @@
// rustfmt-else_if_brace_style: AlwaysSameLine
fn main() {
if false {
();
();
}
if false
// lone if comment
{
();
();
}
let a = if 0 > 1 {
unreachable!()
} else {
0x0
};
if true {
();
} else if false {
();
();
} else {
();
();
();
}
if true
// else-if-chain if comment
{
();
} else if false
// else-if-chain else-if comment
{
();
();
} else
// else-if-chain else comment
{
();
();
();
}
}

View File

@ -0,0 +1,56 @@
// rustfmt-else_if_brace_style: ClosingNextLine
fn main() {
if false {
();
();
}
if false
// lone if comment
{
();
();
}
let a = if 0 > 1 {
unreachable!()
}
else {
0x0
};
if true {
();
}
else if false {
();
();
}
else {
();
();
();
}
if true
// else-if-chain if comment
{
();
}
else if false
// else-if-chain else-if comment
{
();
();
}
else
// else-if-chain else comment
{
();
();
();
}
}