Refactor compute_budgets_for_args()
This commit is contained in:
parent
c67f729205
commit
ec6c2d6e99
1 changed files with 55 additions and 49 deletions
104
src/items.rs
104
src/items.rs
|
@ -1835,21 +1835,15 @@ fn rewrite_fn_base(
|
||||||
let ret_str_len = if multi_line_ret_str { 0 } else { ret_str.len() };
|
let ret_str_len = if multi_line_ret_str { 0 } else { ret_str.len() };
|
||||||
|
|
||||||
// Args.
|
// Args.
|
||||||
let (mut one_line_budget, mut multi_line_budget, mut arg_indent) =
|
let (one_line_budget, multi_line_budget, mut arg_indent) = try_opt!(compute_budgets_for_args(
|
||||||
try_opt!(compute_budgets_for_args(
|
context,
|
||||||
context,
|
&result,
|
||||||
&result,
|
indent,
|
||||||
indent,
|
ret_str_len,
|
||||||
ret_str_len,
|
newline_brace,
|
||||||
newline_brace,
|
has_braces,
|
||||||
has_braces,
|
multi_line_ret_str,
|
||||||
));
|
));
|
||||||
|
|
||||||
if context.config.fn_args_layout() == IndentStyle::Block {
|
|
||||||
arg_indent = indent.block_indent(context.config);
|
|
||||||
// 1 = ","
|
|
||||||
multi_line_budget = context.config.max_width() - (arg_indent.width() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"rewrite_fn_base: one_line_budget: {}, multi_line_budget: {}, arg_indent: {:?}",
|
"rewrite_fn_base: one_line_budget: {}, multi_line_budget: {}, arg_indent: {:?}",
|
||||||
|
@ -1885,10 +1879,6 @@ fn rewrite_fn_base(
|
||||||
result.push(' ')
|
result.push(' ')
|
||||||
}
|
}
|
||||||
|
|
||||||
if multi_line_ret_str {
|
|
||||||
one_line_budget = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A conservative estimation, to goal is to be over all parens in generics
|
// A conservative estimation, to goal is to be over all parens in generics
|
||||||
let args_start = generics
|
let args_start = generics
|
||||||
.ty_params
|
.ty_params
|
||||||
|
@ -1917,11 +1907,8 @@ fn rewrite_fn_base(
|
||||||
generics_str.contains('\n'),
|
generics_str.contains('\n'),
|
||||||
));
|
));
|
||||||
|
|
||||||
let multi_line_arg_str =
|
|
||||||
arg_str.contains('\n') || arg_str.chars().last().map_or(false, |c| c == ',');
|
|
||||||
|
|
||||||
let put_args_in_block = match context.config.fn_args_layout() {
|
let put_args_in_block = match context.config.fn_args_layout() {
|
||||||
IndentStyle::Block => multi_line_arg_str || generics_str.contains('\n'),
|
IndentStyle::Block => arg_str.contains('\n') || arg_str.len() > one_line_budget,
|
||||||
_ => false,
|
_ => false,
|
||||||
} && !fd.inputs.is_empty();
|
} && !fd.inputs.is_empty();
|
||||||
|
|
||||||
|
@ -1936,6 +1923,12 @@ fn rewrite_fn_base(
|
||||||
result.push(')');
|
result.push(')');
|
||||||
} else {
|
} else {
|
||||||
result.push_str(&arg_str);
|
result.push_str(&arg_str);
|
||||||
|
let used_width = last_line_used_width(&result, indent.width()) + first_line_width(&ret_str);
|
||||||
|
// Put the closing brace on the next line if it overflows the max width.
|
||||||
|
// 1 = `)`
|
||||||
|
if fd.inputs.len() == 0 && used_width + 1 > context.config.max_width() {
|
||||||
|
result.push('\n');
|
||||||
|
}
|
||||||
if context.config.spaces_within_parens() && fd.inputs.len() > 0 {
|
if context.config.spaces_within_parens() && fd.inputs.len() > 0 {
|
||||||
result.push(' ')
|
result.push(' ')
|
||||||
}
|
}
|
||||||
|
@ -1954,15 +1947,16 @@ fn rewrite_fn_base(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return type.
|
// Return type.
|
||||||
if !ret_str.is_empty() {
|
if let ast::FunctionRetTy::Ty(..) = fd.output {
|
||||||
let ret_should_indent = match context.config.fn_args_layout() {
|
let ret_should_indent = match context.config.fn_args_layout() {
|
||||||
// If our args are block layout then we surely must have space.
|
// If our args are block layout then we surely must have space.
|
||||||
IndentStyle::Block if put_args_in_block => false,
|
IndentStyle::Block if put_args_in_block || fd.inputs.len() == 0 => false,
|
||||||
|
_ if args_last_line_contains_comment => false,
|
||||||
|
_ if result.contains('\n') || multi_line_ret_str => true,
|
||||||
_ => {
|
_ => {
|
||||||
// If we've already gone multi-line, or the return type would push over the max
|
// If the return type would push over the max width, then put the return type on
|
||||||
// width, then put the return type on a new line. With the +1 for the signature
|
// a new line. With the +1 for the signature length an additional space between
|
||||||
// length an additional space between the closing parenthesis of the argument and
|
// the closing parenthesis of the argument and the arrow '->' is considered.
|
||||||
// the arrow '->' is considered.
|
|
||||||
let mut sig_length = result.len() + indent.width() + ret_str_len + 1;
|
let mut sig_length = result.len() + indent.width() + ret_str_len + 1;
|
||||||
|
|
||||||
// If there is no where clause, take into account the space after the return type
|
// If there is no where clause, take into account the space after the return type
|
||||||
|
@ -1971,10 +1965,7 @@ fn rewrite_fn_base(
|
||||||
sig_length += 2;
|
sig_length += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
let overlong_sig = sig_length > context.config.max_width();
|
sig_length > context.config.max_width()
|
||||||
|
|
||||||
(!args_last_line_contains_comment) &&
|
|
||||||
(result.contains('\n') || multi_line_ret_str || overlong_sig)
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let ret_indent = if ret_should_indent {
|
let ret_indent = if ret_should_indent {
|
||||||
|
@ -2276,6 +2267,7 @@ fn compute_budgets_for_args(
|
||||||
ret_str_len: usize,
|
ret_str_len: usize,
|
||||||
newline_brace: bool,
|
newline_brace: bool,
|
||||||
has_braces: bool,
|
has_braces: bool,
|
||||||
|
force_vertical_layout: bool,
|
||||||
) -> Option<((usize, usize, Indent))> {
|
) -> Option<((usize, usize, Indent))> {
|
||||||
debug!(
|
debug!(
|
||||||
"compute_budgets_for_args {} {:?}, {}, {}",
|
"compute_budgets_for_args {} {:?}, {}, {}",
|
||||||
|
@ -2285,7 +2277,7 @@ fn compute_budgets_for_args(
|
||||||
newline_brace
|
newline_brace
|
||||||
);
|
);
|
||||||
// Try keeping everything on the same line.
|
// Try keeping everything on the same line.
|
||||||
if !result.contains('\n') {
|
if !result.contains('\n') && !force_vertical_layout {
|
||||||
// 2 = `()`, 3 = `() `, space is before ret_string.
|
// 2 = `()`, 3 = `() `, space is before ret_string.
|
||||||
let overhead = if ret_str_len == 0 { 2 } else { 3 };
|
let overhead = if ret_str_len == 0 { 2 } else { 3 };
|
||||||
let mut used_space = indent.width() + result.len() + ret_str_len + overhead;
|
let mut used_space = indent.width() + result.len() + ret_str_len + overhead;
|
||||||
|
@ -2306,31 +2298,45 @@ fn compute_budgets_for_args(
|
||||||
|
|
||||||
if one_line_budget > 0 {
|
if one_line_budget > 0 {
|
||||||
// 4 = "() {".len()
|
// 4 = "() {".len()
|
||||||
let multi_line_overhead =
|
let (indent, multi_line_budget) = match context.config.fn_args_layout() {
|
||||||
indent.width() + result.len() + if newline_brace { 2 } else { 4 };
|
IndentStyle::Block => {
|
||||||
let multi_line_budget =
|
let indent = indent.block_indent(context.config);
|
||||||
try_opt!(context.config.max_width().checked_sub(multi_line_overhead));
|
let budget =
|
||||||
|
try_opt!(context.config.max_width().checked_sub(indent.width() + 1));
|
||||||
|
(indent, budget)
|
||||||
|
}
|
||||||
|
IndentStyle::Visual => {
|
||||||
|
let indent = indent + result.len() + 1;
|
||||||
|
let multi_line_overhead =
|
||||||
|
indent.width() + result.len() + if newline_brace { 2 } else { 4 };
|
||||||
|
let budget =
|
||||||
|
try_opt!(context.config.max_width().checked_sub(multi_line_overhead));
|
||||||
|
(indent, budget)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return Some((
|
return Some((one_line_budget, multi_line_budget, indent));
|
||||||
one_line_budget,
|
|
||||||
multi_line_budget,
|
|
||||||
indent + result.len() + 1,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Didn't work. we must force vertical layout and put args on a newline.
|
// Didn't work. we must force vertical layout and put args on a newline.
|
||||||
let new_indent = indent.block_indent(context.config);
|
let new_indent = indent.block_indent(context.config);
|
||||||
// Account for `)` and possibly ` {`.
|
let used_space = match context.config.fn_args_layout() {
|
||||||
let used_space = new_indent.width() + if ret_str_len == 0 { 1 } else { 3 };
|
// 1 = `,`
|
||||||
|
IndentStyle::Block => new_indent.width() + 1,
|
||||||
|
// Account for `)` and possibly ` {`.
|
||||||
|
IndentStyle::Visual => new_indent.width() + if ret_str_len == 0 { 1 } else { 3 },
|
||||||
|
};
|
||||||
let max_space = try_opt!(context.config.max_width().checked_sub(used_space));
|
let max_space = try_opt!(context.config.max_width().checked_sub(used_space));
|
||||||
Some((0, max_space, new_indent))
|
Some((0, max_space, new_indent))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn newline_for_brace(config: &Config, where_clause: &ast::WhereClause) -> bool {
|
fn newline_for_brace(config: &Config, where_clause: &ast::WhereClause, has_body: bool) -> bool {
|
||||||
match config.fn_brace_style() {
|
match (config.fn_brace_style(), config.where_density()) {
|
||||||
BraceStyle::AlwaysNextLine => true,
|
(BraceStyle::AlwaysNextLine, _) => true,
|
||||||
BraceStyle::SameLineWhere if !where_clause.predicates.is_empty() => true,
|
(_, Density::Compressed) if where_clause.predicates.len() == 1 => false,
|
||||||
|
(_, Density::CompressedIfEmpty) if where_clause.predicates.len() == 1 && !has_body => false,
|
||||||
|
(BraceStyle::SameLineWhere, _) if !where_clause.predicates.is_empty() => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue