Merge pull request #2562 from topecongiro/issue-2196
Combine simple heuristics for function calls and array
This commit is contained in:
commit
8dd08ddd92
@ -1688,7 +1688,8 @@ Number of spaces per tab
|
||||
fn lorem() {
|
||||
let ipsum = dolor();
|
||||
let sit = vec![
|
||||
"amet consectetur adipiscing elit amet consectetur adipiscing elit amet consectetur.",
|
||||
"amet consectetur adipiscing elit amet",
|
||||
"consectetur adipiscing elit amet consectetur.",
|
||||
];
|
||||
}
|
||||
```
|
||||
@ -1699,7 +1700,8 @@ fn lorem() {
|
||||
fn lorem() {
|
||||
let ipsum = dolor();
|
||||
let sit = vec![
|
||||
"amet consectetur adipiscing elit amet consectetur adipiscing elit amet consectetur.",
|
||||
"amet consectetur adipiscing elit amet",
|
||||
"consectetur adipiscing elit amet consectetur.",
|
||||
];
|
||||
}
|
||||
```
|
||||
|
@ -127,13 +127,11 @@ fn rewrite_closure_with_block(
|
||||
}
|
||||
|
||||
let block = ast::Block {
|
||||
stmts: vec![
|
||||
ast::Stmt {
|
||||
id: ast::NodeId::new(0),
|
||||
node: ast::StmtKind::Expr(ptr::P(body.clone())),
|
||||
span: body.span,
|
||||
},
|
||||
],
|
||||
stmts: vec![ast::Stmt {
|
||||
id: ast::NodeId::new(0),
|
||||
node: ast::StmtKind::Expr(ptr::P(body.clone())),
|
||||
span: body.span,
|
||||
}],
|
||||
id: ast::NodeId::new(0),
|
||||
rules: ast::BlockCheckMode::Default,
|
||||
span: body.span,
|
||||
@ -300,13 +298,7 @@ pub fn rewrite_last_closure(
|
||||
_ => body,
|
||||
};
|
||||
let (prefix, extra_offset) = rewrite_closure_fn_decl(
|
||||
capture,
|
||||
movability,
|
||||
fn_decl,
|
||||
body,
|
||||
expr.span,
|
||||
context,
|
||||
shape,
|
||||
capture, movability, fn_decl, body, expr.span, context, shape,
|
||||
)?;
|
||||
// If the closure goes multi line before its body, do not overflow the closure.
|
||||
if prefix.contains('\n') {
|
||||
|
168
src/expr.rs
168
src/expr.rs
@ -13,6 +13,7 @@ use std::cmp::min;
|
||||
|
||||
use config::lists::*;
|
||||
use syntax::codemap::{BytePos, CodeMap, Span};
|
||||
use syntax::parse::token::DelimToken;
|
||||
use syntax::{ast, ptr};
|
||||
|
||||
use chains::rewrite_chain;
|
||||
@ -64,14 +65,13 @@ pub fn format_expr(
|
||||
|
||||
let expr_rw = match expr.node {
|
||||
ast::ExprKind::Array(ref expr_vec) => rewrite_array(
|
||||
"",
|
||||
&ptr_vec_to_ref_vec(expr_vec),
|
||||
mk_sp(
|
||||
context.snippet_provider.span_after(expr.span, "["),
|
||||
expr.span.hi(),
|
||||
),
|
||||
expr.span,
|
||||
context,
|
||||
shape,
|
||||
false,
|
||||
None,
|
||||
None,
|
||||
),
|
||||
ast::ExprKind::Lit(ref l) => rewrite_literal(context, l, shape),
|
||||
ast::ExprKind::Call(ref callee, ref args) => {
|
||||
@ -173,13 +173,7 @@ pub fn format_expr(
|
||||
},
|
||||
ast::ExprKind::Closure(capture, movability, ref fn_decl, ref body, _) => {
|
||||
closures::rewrite_closure(
|
||||
capture,
|
||||
movability,
|
||||
fn_decl,
|
||||
body,
|
||||
expr.span,
|
||||
context,
|
||||
shape,
|
||||
capture, movability, fn_decl, body, expr.span, context, shape,
|
||||
)
|
||||
}
|
||||
ast::ExprKind::Try(..)
|
||||
@ -422,147 +416,23 @@ where
|
||||
}
|
||||
|
||||
pub fn rewrite_array<T: Rewrite + Spanned + ToExpr>(
|
||||
name: &str,
|
||||
exprs: &[&T],
|
||||
span: Span,
|
||||
context: &RewriteContext,
|
||||
shape: Shape,
|
||||
trailing_comma: bool,
|
||||
force_separator_tactic: Option<SeparatorTactic>,
|
||||
delim_token: Option<DelimToken>,
|
||||
) -> Option<String> {
|
||||
let bracket_size = if context.config.spaces_within_parens_and_brackets() {
|
||||
2 // "[ "
|
||||
} else {
|
||||
1 // "["
|
||||
};
|
||||
|
||||
let nested_shape = match context.config.indent_style() {
|
||||
IndentStyle::Block => shape
|
||||
.block()
|
||||
.block_indent(context.config.tab_spaces())
|
||||
.with_max_width(context.config)
|
||||
.sub_width(1)?,
|
||||
IndentStyle::Visual => shape
|
||||
.visual_indent(bracket_size)
|
||||
.sub_width(bracket_size * 2)?,
|
||||
};
|
||||
|
||||
let items = itemize_list(
|
||||
context.snippet_provider,
|
||||
exprs.iter(),
|
||||
"]",
|
||||
",",
|
||||
|item| item.span().lo(),
|
||||
|item| item.span().hi(),
|
||||
|item| item.rewrite(context, nested_shape),
|
||||
span.lo(),
|
||||
span.hi(),
|
||||
false,
|
||||
).collect::<Vec<_>>();
|
||||
|
||||
if items.is_empty() {
|
||||
if context.config.spaces_within_parens_and_brackets() {
|
||||
return Some("[ ]".to_string());
|
||||
} else {
|
||||
return Some("[]".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
let tactic = array_tactic(context, shape, nested_shape, exprs, &items, bracket_size);
|
||||
let ends_with_newline = tactic.ends_with_newline(context.config.indent_style());
|
||||
|
||||
let fmt = ListFormatting {
|
||||
tactic,
|
||||
separator: ",",
|
||||
trailing_separator: if trailing_comma {
|
||||
SeparatorTactic::Always
|
||||
} else if context.inside_macro() && !exprs.is_empty() {
|
||||
let ends_with_bracket = context.snippet(span).ends_with(']');
|
||||
let bracket_offset = if ends_with_bracket { 1 } else { 0 };
|
||||
let snippet = context.snippet(mk_sp(span.lo(), span.hi() - BytePos(bracket_offset)));
|
||||
let last_char_index = snippet.rfind(|c: char| !c.is_whitespace())?;
|
||||
if &snippet[last_char_index..last_char_index + 1] == "," {
|
||||
SeparatorTactic::Always
|
||||
} else {
|
||||
SeparatorTactic::Never
|
||||
}
|
||||
} else if context.config.indent_style() == IndentStyle::Visual {
|
||||
SeparatorTactic::Never
|
||||
} else {
|
||||
SeparatorTactic::Vertical
|
||||
},
|
||||
separator_place: SeparatorPlace::Back,
|
||||
shape: nested_shape,
|
||||
ends_with_newline,
|
||||
preserve_newline: false,
|
||||
config: context.config,
|
||||
};
|
||||
let list_str = write_list(&items, &fmt)?;
|
||||
|
||||
let result = if context.config.indent_style() == IndentStyle::Visual
|
||||
|| tactic == DefinitiveListTactic::Horizontal
|
||||
{
|
||||
if context.config.spaces_within_parens_and_brackets() && !list_str.is_empty() {
|
||||
format!("[ {} ]", list_str)
|
||||
} else {
|
||||
format!("[{}]", list_str)
|
||||
}
|
||||
} else {
|
||||
format!(
|
||||
"[{}{}{}]",
|
||||
nested_shape.indent.to_string_with_newline(context.config),
|
||||
list_str,
|
||||
shape.block().indent.to_string_with_newline(context.config)
|
||||
)
|
||||
};
|
||||
|
||||
Some(result)
|
||||
}
|
||||
|
||||
fn array_tactic<T: Rewrite + Spanned + ToExpr>(
|
||||
context: &RewriteContext,
|
||||
shape: Shape,
|
||||
nested_shape: Shape,
|
||||
exprs: &[&T],
|
||||
items: &[ListItem],
|
||||
bracket_size: usize,
|
||||
) -> DefinitiveListTactic {
|
||||
let has_long_item = items
|
||||
.iter()
|
||||
.any(|li| li.item.as_ref().map(|s| s.len() > 10).unwrap_or(false));
|
||||
|
||||
match context.config.indent_style() {
|
||||
IndentStyle::Block => {
|
||||
let tactic = match shape.width.checked_sub(2 * bracket_size) {
|
||||
Some(width) => {
|
||||
let tactic = ListTactic::LimitedHorizontalVertical(
|
||||
context.config.width_heuristics().array_width,
|
||||
);
|
||||
definitive_tactic(items, tactic, Separator::Comma, width)
|
||||
}
|
||||
None => DefinitiveListTactic::Vertical,
|
||||
};
|
||||
if tactic == DefinitiveListTactic::Vertical && !has_long_item
|
||||
&& is_every_expr_simple(exprs)
|
||||
{
|
||||
DefinitiveListTactic::Mixed
|
||||
} else {
|
||||
tactic
|
||||
}
|
||||
}
|
||||
IndentStyle::Visual => {
|
||||
if has_long_item || items.iter().any(ListItem::is_multiline) {
|
||||
definitive_tactic(
|
||||
items,
|
||||
ListTactic::LimitedHorizontalVertical(
|
||||
context.config.width_heuristics().array_width,
|
||||
),
|
||||
Separator::Comma,
|
||||
nested_shape.width,
|
||||
)
|
||||
} else {
|
||||
DefinitiveListTactic::Mixed
|
||||
}
|
||||
}
|
||||
}
|
||||
overflow::rewrite_with_square_brackets(
|
||||
context,
|
||||
name,
|
||||
exprs,
|
||||
shape,
|
||||
span,
|
||||
force_separator_tactic,
|
||||
delim_token,
|
||||
)
|
||||
}
|
||||
|
||||
fn rewrite_empty_block(
|
||||
@ -1489,7 +1359,7 @@ fn is_simple_expr(expr: &ast::Expr) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_every_expr_simple<T: ToExpr>(lists: &[&T]) -> bool {
|
||||
pub fn is_every_expr_simple<T: ToExpr>(lists: &[&T]) -> bool {
|
||||
lists
|
||||
.iter()
|
||||
.all(|arg| arg.to_expr().map_or(false, is_simple_expr))
|
||||
|
@ -261,7 +261,7 @@ fn scan_simple_git_diff() {
|
||||
Range {
|
||||
file: "src/ir/traversal.rs".to_owned(),
|
||||
range: [35, 43],
|
||||
}
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
|
22
src/lists.rs
22
src/lists.rs
@ -101,7 +101,7 @@ impl ListItem {
|
||||
.map_or(false, |s| s.contains('\n'))
|
||||
}
|
||||
|
||||
pub fn has_comment(&self) -> bool {
|
||||
pub fn has_single_line_comment(&self) -> bool {
|
||||
self.pre_comment
|
||||
.as_ref()
|
||||
.map_or(false, |comment| comment.trim_left().starts_with("//"))
|
||||
@ -110,6 +110,10 @@ impl ListItem {
|
||||
.map_or(false, |comment| comment.trim_left().starts_with("//"))
|
||||
}
|
||||
|
||||
pub fn has_comment(&self) -> bool {
|
||||
self.pre_comment.is_some() || self.post_comment.is_some()
|
||||
}
|
||||
|
||||
pub fn from_str<S: Into<String>>(s: S) -> ListItem {
|
||||
ListItem {
|
||||
pre_comment: None,
|
||||
@ -164,7 +168,7 @@ where
|
||||
let pre_line_comments = items
|
||||
.clone()
|
||||
.into_iter()
|
||||
.any(|item| item.as_ref().has_comment());
|
||||
.any(|item| item.as_ref().has_single_line_comment());
|
||||
|
||||
let limit = match tactic {
|
||||
_ if pre_line_comments => return DefinitiveListTactic::Vertical,
|
||||
@ -266,11 +270,15 @@ where
|
||||
result.push_str(indent_str);
|
||||
line_len = 0;
|
||||
if formatting.ends_with_newline {
|
||||
if last {
|
||||
separate = true;
|
||||
} else {
|
||||
trailing_separator = true;
|
||||
}
|
||||
trailing_separator = true;
|
||||
}
|
||||
}
|
||||
|
||||
if last && formatting.ends_with_newline {
|
||||
match formatting.trailing_separator {
|
||||
SeparatorTactic::Always => separate = true,
|
||||
SeparatorTactic::Vertical if result.contains('\n') => separate = true,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,14 +45,6 @@ use utils::{format_visibility, mk_sp, wrap_str};
|
||||
|
||||
const FORCED_BRACKET_MACROS: &[&str] = &["vec!"];
|
||||
|
||||
// FIXME: use the enum from libsyntax?
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
enum MacroStyle {
|
||||
Parens,
|
||||
Brackets,
|
||||
Braces,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum MacroPosition {
|
||||
Item,
|
||||
@ -61,16 +53,6 @@ pub enum MacroPosition {
|
||||
Pat,
|
||||
}
|
||||
|
||||
impl MacroStyle {
|
||||
fn opener(&self) -> &'static str {
|
||||
match *self {
|
||||
MacroStyle::Parens => "(",
|
||||
MacroStyle::Brackets => "[",
|
||||
MacroStyle::Braces => "{",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum MacroArg {
|
||||
Expr(ptr::P<ast::Expr>),
|
||||
@ -177,7 +159,7 @@ pub fn rewrite_macro_inner(
|
||||
let macro_name = rewrite_macro_name(&mac.node.path, extra_ident);
|
||||
|
||||
let style = if FORCED_BRACKET_MACROS.contains(&¯o_name[..]) {
|
||||
MacroStyle::Brackets
|
||||
DelimToken::Bracket
|
||||
} else {
|
||||
original_style
|
||||
};
|
||||
@ -186,12 +168,13 @@ pub fn rewrite_macro_inner(
|
||||
let has_comment = contains_comment(context.snippet(mac.span));
|
||||
if ts.is_empty() && !has_comment {
|
||||
return match style {
|
||||
MacroStyle::Parens if position == MacroPosition::Item => {
|
||||
DelimToken::Paren if position == MacroPosition::Item => {
|
||||
Some(format!("{}();", macro_name))
|
||||
}
|
||||
MacroStyle::Parens => Some(format!("{}()", macro_name)),
|
||||
MacroStyle::Brackets => Some(format!("{}[]", macro_name)),
|
||||
MacroStyle::Braces => Some(format!("{}{{}}", macro_name)),
|
||||
DelimToken::Paren => Some(format!("{}()", macro_name)),
|
||||
DelimToken::Bracket => Some(format!("{}[]", macro_name)),
|
||||
DelimToken::Brace => Some(format!("{}{{}}", macro_name)),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
}
|
||||
// Format well-known macros which cannot be parsed as a valid AST.
|
||||
@ -207,7 +190,7 @@ pub fn rewrite_macro_inner(
|
||||
let mut vec_with_semi = false;
|
||||
let mut trailing_comma = false;
|
||||
|
||||
if MacroStyle::Braces != style {
|
||||
if DelimToken::Brace != style {
|
||||
loop {
|
||||
match parse_macro_arg(&mut parser) {
|
||||
Some(arg) => arg_vec.push(arg),
|
||||
@ -250,7 +233,7 @@ pub fn rewrite_macro_inner(
|
||||
}
|
||||
|
||||
match style {
|
||||
MacroStyle::Parens => {
|
||||
DelimToken::Paren => {
|
||||
// Format macro invocation as function call, preserve the trailing
|
||||
// comma because not all macros support them.
|
||||
overflow::rewrite_with_parens(
|
||||
@ -270,10 +253,10 @@ pub fn rewrite_macro_inner(
|
||||
_ => rw,
|
||||
})
|
||||
}
|
||||
MacroStyle::Brackets => {
|
||||
let mac_shape = shape.offset_left(macro_name.len())?;
|
||||
DelimToken::Bracket => {
|
||||
// Handle special case: `vec![expr; expr]`
|
||||
if vec_with_semi {
|
||||
let mac_shape = shape.offset_left(macro_name.len())?;
|
||||
let (lbr, rbr) = if context.config.spaces_within_parens_and_brackets() {
|
||||
("[ ", " ]")
|
||||
} else {
|
||||
@ -305,31 +288,42 @@ pub fn rewrite_macro_inner(
|
||||
// If we are rewriting `vec!` macro or other special macros,
|
||||
// then we can rewrite this as an usual array literal.
|
||||
// Otherwise, we must preserve the original existence of trailing comma.
|
||||
if FORCED_BRACKET_MACROS.contains(¯o_name.as_str()) {
|
||||
let macro_name = ¯o_name.as_str();
|
||||
let mut force_trailing_comma = if trailing_comma {
|
||||
Some(SeparatorTactic::Always)
|
||||
} else {
|
||||
Some(SeparatorTactic::Never)
|
||||
};
|
||||
if FORCED_BRACKET_MACROS.contains(macro_name) {
|
||||
context.inside_macro.replace(false);
|
||||
trailing_comma = false;
|
||||
if context.use_block_indent() {
|
||||
force_trailing_comma = Some(SeparatorTactic::Vertical);
|
||||
};
|
||||
}
|
||||
// Convert `MacroArg` into `ast::Expr`, as `rewrite_array` only accepts the latter.
|
||||
let sp = mk_sp(
|
||||
context
|
||||
.snippet_provider
|
||||
.span_after(mac.span, original_style.opener()),
|
||||
mac.span.hi() - BytePos(1),
|
||||
);
|
||||
let arg_vec = &arg_vec.iter().map(|e| &*e).collect::<Vec<_>>()[..];
|
||||
let rewrite = rewrite_array(arg_vec, sp, context, mac_shape, trailing_comma)?;
|
||||
let rewrite = rewrite_array(
|
||||
macro_name,
|
||||
arg_vec,
|
||||
mac.span,
|
||||
context,
|
||||
shape,
|
||||
force_trailing_comma,
|
||||
Some(original_style),
|
||||
)?;
|
||||
let comma = match position {
|
||||
MacroPosition::Item => ";",
|
||||
_ => "",
|
||||
};
|
||||
|
||||
Some(format!("{}{}{}", macro_name, rewrite, comma))
|
||||
Some(format!("{}{}", rewrite, comma))
|
||||
}
|
||||
}
|
||||
MacroStyle::Braces => {
|
||||
DelimToken::Brace => {
|
||||
// Skip macro invocations with braces, for now.
|
||||
indent_macro_snippet(context, context.snippet(mac.span), shape.indent)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1010,18 +1004,18 @@ pub fn convert_try_mac(mac: &ast::Mac, context: &RewriteContext) -> Option<ast::
|
||||
}
|
||||
}
|
||||
|
||||
fn macro_style(mac: &ast::Mac, context: &RewriteContext) -> MacroStyle {
|
||||
fn macro_style(mac: &ast::Mac, context: &RewriteContext) -> DelimToken {
|
||||
let snippet = context.snippet(mac.span);
|
||||
let paren_pos = snippet.find_uncommented("(").unwrap_or(usize::max_value());
|
||||
let bracket_pos = snippet.find_uncommented("[").unwrap_or(usize::max_value());
|
||||
let brace_pos = snippet.find_uncommented("{").unwrap_or(usize::max_value());
|
||||
|
||||
if paren_pos < bracket_pos && paren_pos < brace_pos {
|
||||
MacroStyle::Parens
|
||||
DelimToken::Paren
|
||||
} else if bracket_pos < brace_pos {
|
||||
MacroStyle::Brackets
|
||||
DelimToken::Bracket
|
||||
} else {
|
||||
MacroStyle::Braces
|
||||
DelimToken::Brace
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,10 +14,11 @@
|
||||
use config::lists::*;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token::DelimToken;
|
||||
|
||||
use closures;
|
||||
use codemap::SpanUtils;
|
||||
use expr::{is_nested_call, maybe_get_args_offset, ToExpr};
|
||||
use expr::{is_every_expr_simple, is_nested_call, maybe_get_args_offset, ToExpr};
|
||||
use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator};
|
||||
use rewrite::{Rewrite, RewriteContext};
|
||||
use shape::Shape;
|
||||
@ -26,6 +27,8 @@ use utils::{count_newlines, extra_offset, first_line_width, last_line_width, mk_
|
||||
|
||||
use std::cmp::min;
|
||||
|
||||
const SHORT_ITEM_THRESHOLD: usize = 10;
|
||||
|
||||
pub fn rewrite_with_parens<T>(
|
||||
context: &RewriteContext,
|
||||
ident: &str,
|
||||
@ -48,6 +51,7 @@ where
|
||||
")",
|
||||
item_max_width,
|
||||
force_separator_tactic,
|
||||
None,
|
||||
).rewrite(shape)
|
||||
}
|
||||
|
||||
@ -71,6 +75,38 @@ where
|
||||
">",
|
||||
context.config.max_width(),
|
||||
None,
|
||||
None,
|
||||
).rewrite(shape)
|
||||
}
|
||||
|
||||
pub fn rewrite_with_square_brackets<T>(
|
||||
context: &RewriteContext,
|
||||
name: &str,
|
||||
items: &[&T],
|
||||
shape: Shape,
|
||||
span: Span,
|
||||
force_separator_tactic: Option<SeparatorTactic>,
|
||||
delim_token: Option<DelimToken>,
|
||||
) -> Option<String>
|
||||
where
|
||||
T: Rewrite + ToExpr + Spanned,
|
||||
{
|
||||
let (lhs, rhs) = match delim_token {
|
||||
Some(DelimToken::Paren) => ("(", ")"),
|
||||
Some(DelimToken::Brace) => ("{", "}"),
|
||||
_ => ("[", "]"),
|
||||
};
|
||||
Context::new(
|
||||
context,
|
||||
items,
|
||||
name,
|
||||
shape,
|
||||
span,
|
||||
lhs,
|
||||
rhs,
|
||||
context.config.width_heuristics().array_width,
|
||||
force_separator_tactic,
|
||||
Some(("[", "]")),
|
||||
).rewrite(shape)
|
||||
}
|
||||
|
||||
@ -86,6 +122,7 @@ struct Context<'a, T: 'a> {
|
||||
item_max_width: usize,
|
||||
one_line_width: usize,
|
||||
force_separator_tactic: Option<SeparatorTactic>,
|
||||
custom_delims: Option<(&'a str, &'a str)>,
|
||||
}
|
||||
|
||||
impl<'a, T: 'a + Rewrite + ToExpr + Spanned> Context<'a, T> {
|
||||
@ -99,6 +136,7 @@ impl<'a, T: 'a + Rewrite + ToExpr + Spanned> Context<'a, T> {
|
||||
suffix: &'static str,
|
||||
item_max_width: usize,
|
||||
force_separator_tactic: Option<SeparatorTactic>,
|
||||
custom_delims: Option<(&'a str, &'a str)>,
|
||||
) -> Context<'a, T> {
|
||||
// 2 = `( `, 1 = `(`
|
||||
let paren_overhead = if context.config.spaces_within_parens_and_brackets() {
|
||||
@ -135,6 +173,7 @@ impl<'a, T: 'a + Rewrite + ToExpr + Spanned> Context<'a, T> {
|
||||
item_max_width,
|
||||
one_line_width,
|
||||
force_separator_tactic,
|
||||
custom_delims,
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,6 +222,15 @@ impl<'a, T: 'a + Rewrite + ToExpr + Spanned> Context<'a, T> {
|
||||
}
|
||||
}
|
||||
|
||||
fn default_tactic(&self, list_items: &[ListItem]) -> DefinitiveListTactic {
|
||||
definitive_tactic(
|
||||
list_items,
|
||||
ListTactic::LimitedHorizontalVertical(self.item_max_width),
|
||||
Separator::Comma,
|
||||
self.one_line_width,
|
||||
)
|
||||
}
|
||||
|
||||
fn try_overflow_last_item(&self, list_items: &mut Vec<ListItem>) -> DefinitiveListTactic {
|
||||
// 1 = "("
|
||||
let combine_arg_with_callee = self.items.len() == 1 && self.items[0].to_expr().is_some()
|
||||
@ -258,26 +306,16 @@ impl<'a, T: 'a + Rewrite + ToExpr + Spanned> Context<'a, T> {
|
||||
.last()
|
||||
.and_then(|last_item| last_item.rewrite(self.context, self.nested_shape));
|
||||
|
||||
let default_tactic = || {
|
||||
definitive_tactic(
|
||||
&*list_items,
|
||||
ListTactic::LimitedHorizontalVertical(self.item_max_width),
|
||||
Separator::Comma,
|
||||
self.one_line_width,
|
||||
)
|
||||
};
|
||||
|
||||
// Use horizontal layout for a function with a single argument as long as
|
||||
// everything fits in a single line.
|
||||
if self.items.len() == 1
|
||||
&& self.one_line_width != 0 // Vertical layout is forced.
|
||||
&& !list_items[0].has_comment()
|
||||
// `self.one_line_width == 0` means vertical layout is forced.
|
||||
if self.items.len() == 1 && self.one_line_width != 0 && !list_items[0].has_comment()
|
||||
&& !list_items[0].inner_as_ref().contains('\n')
|
||||
&& ::lists::total_item_width(&list_items[0]) <= self.one_line_width
|
||||
{
|
||||
tactic = DefinitiveListTactic::Horizontal;
|
||||
} else {
|
||||
tactic = default_tactic();
|
||||
tactic = self.default_tactic(list_items);
|
||||
|
||||
if tactic == DefinitiveListTactic::Vertical {
|
||||
if let Some((all_simple, num_args_before)) =
|
||||
@ -302,6 +340,8 @@ impl<'a, T: 'a + Rewrite + ToExpr + Spanned> Context<'a, T> {
|
||||
if one_line {
|
||||
tactic = DefinitiveListTactic::SpecialMacro(num_args_before);
|
||||
};
|
||||
} else if is_every_expr_simple(self.items) && no_long_items(list_items) {
|
||||
tactic = DefinitiveListTactic::Mixed;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -340,13 +380,20 @@ impl<'a, T: 'a + Rewrite + ToExpr + Spanned> Context<'a, T> {
|
||||
tactic
|
||||
} else if !self.context.use_block_indent() {
|
||||
SeparatorTactic::Never
|
||||
} else if tactic == DefinitiveListTactic::Mixed {
|
||||
// We are using mixed layout because everything did not fit within a single line.
|
||||
SeparatorTactic::Always
|
||||
} else {
|
||||
self.context.config.trailing_comma()
|
||||
},
|
||||
separator_place: SeparatorPlace::Back,
|
||||
shape: self.nested_shape,
|
||||
ends_with_newline: self.context.use_block_indent()
|
||||
&& tactic == DefinitiveListTactic::Vertical,
|
||||
ends_with_newline: match tactic {
|
||||
DefinitiveListTactic::Vertical | DefinitiveListTactic::Mixed => {
|
||||
self.context.use_block_indent()
|
||||
}
|
||||
_ => false,
|
||||
},
|
||||
preserve_newline: false,
|
||||
config: self.context.config,
|
||||
};
|
||||
@ -364,6 +411,10 @@ impl<'a, T: 'a + Rewrite + ToExpr + Spanned> Context<'a, T> {
|
||||
..shape
|
||||
};
|
||||
|
||||
let (prefix, suffix) = match self.custom_delims {
|
||||
Some((lhs, rhs)) => (lhs, rhs),
|
||||
_ => (self.prefix, self.suffix),
|
||||
};
|
||||
let paren_overhead = paren_overhead(self.context);
|
||||
let fits_one_line = items_str.len() + paren_overhead <= shape.width;
|
||||
let extend_width = if items_str.is_empty() {
|
||||
@ -382,7 +433,7 @@ impl<'a, T: 'a + Rewrite + ToExpr + Spanned> Context<'a, T> {
|
||||
self.ident.len() + items_str.len() + 2 + indent_str.len() + nested_indent_str.len(),
|
||||
);
|
||||
result.push_str(self.ident);
|
||||
result.push_str(self.prefix);
|
||||
result.push_str(prefix);
|
||||
if !self.context.use_block_indent()
|
||||
|| (self.context.inside_macro() && !items_str.contains('\n') && fits_one_line)
|
||||
|| (is_extendable && extend_width <= shape.width)
|
||||
@ -401,7 +452,7 @@ impl<'a, T: 'a + Rewrite + ToExpr + Spanned> Context<'a, T> {
|
||||
}
|
||||
result.push_str(&indent_str);
|
||||
}
|
||||
result.push_str(self.suffix);
|
||||
result.push_str(suffix);
|
||||
result
|
||||
}
|
||||
|
||||
@ -489,3 +540,8 @@ fn shape_from_indent_style(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn no_long_items(list: &[ListItem]) -> bool {
|
||||
list.iter()
|
||||
.all(|item| !item.has_comment() && item.inner_as_ref().len() <= SHORT_ITEM_THRESHOLD)
|
||||
}
|
||||
|
@ -221,18 +221,16 @@ mod test {
|
||||
let diff = make_diff(src, dest, 1);
|
||||
assert_eq!(
|
||||
diff,
|
||||
vec![
|
||||
Mismatch {
|
||||
line_number: 2,
|
||||
line_number_orig: 2,
|
||||
lines: vec![
|
||||
Context("two".to_owned()),
|
||||
Resulting("three".to_owned()),
|
||||
Expected("trois".to_owned()),
|
||||
Context("four".to_owned()),
|
||||
],
|
||||
},
|
||||
]
|
||||
vec![Mismatch {
|
||||
line_number: 2,
|
||||
line_number_orig: 2,
|
||||
lines: vec![
|
||||
Context("two".to_owned()),
|
||||
Resulting("three".to_owned()),
|
||||
Expected("trois".to_owned()),
|
||||
Context("four".to_owned()),
|
||||
],
|
||||
}]
|
||||
);
|
||||
}
|
||||
|
||||
@ -274,13 +272,11 @@ mod test {
|
||||
let diff = make_diff(src, dest, 0);
|
||||
assert_eq!(
|
||||
diff,
|
||||
vec![
|
||||
Mismatch {
|
||||
line_number: 3,
|
||||
line_number_orig: 3,
|
||||
lines: vec![Resulting("three".to_owned()), Expected("trois".to_owned())],
|
||||
},
|
||||
]
|
||||
vec![Mismatch {
|
||||
line_number: 3,
|
||||
line_number_orig: 3,
|
||||
lines: vec![Resulting("three".to_owned()), Expected("trois".to_owned())],
|
||||
}]
|
||||
);
|
||||
}
|
||||
|
||||
@ -291,13 +287,11 @@ mod test {
|
||||
let diff = make_diff(src, dest, 1);
|
||||
assert_eq!(
|
||||
diff,
|
||||
vec![
|
||||
Mismatch {
|
||||
line_number: 5,
|
||||
line_number_orig: 5,
|
||||
lines: vec![Context("five".to_owned()), Expected("".to_owned())],
|
||||
},
|
||||
]
|
||||
vec![Mismatch {
|
||||
line_number: 5,
|
||||
line_number_orig: 5,
|
||||
lines: vec![Context("five".to_owned()), Expected("".to_owned())],
|
||||
}]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
24
tests/lib.rs
24
tests/lib.rs
@ -540,19 +540,17 @@ fn rustfmt_diff_make_diff_tests() {
|
||||
let diff = make_diff("a\nb\nc\nd", "a\ne\nc\nd", 3);
|
||||
assert_eq!(
|
||||
diff,
|
||||
vec![
|
||||
Mismatch {
|
||||
line_number: 1,
|
||||
line_number_orig: 1,
|
||||
lines: vec![
|
||||
DiffLine::Context("a".into()),
|
||||
DiffLine::Resulting("b".into()),
|
||||
DiffLine::Expected("e".into()),
|
||||
DiffLine::Context("c".into()),
|
||||
DiffLine::Context("d".into()),
|
||||
],
|
||||
},
|
||||
]
|
||||
vec![Mismatch {
|
||||
line_number: 1,
|
||||
line_number_orig: 1,
|
||||
lines: vec![
|
||||
DiffLine::Context("a".into()),
|
||||
DiffLine::Resulting("b".into()),
|
||||
DiffLine::Expected("e".into()),
|
||||
DiffLine::Context("c".into()),
|
||||
DiffLine::Context("d".into()),
|
||||
],
|
||||
}]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -233,10 +233,7 @@ impl Foo {
|
||||
if let Some(mi) = attr.meta() {
|
||||
if let Some(value) = mi.value_str() {
|
||||
doc_strings.push(DocFragment::Include(
|
||||
line,
|
||||
attr.span,
|
||||
filename,
|
||||
contents,
|
||||
line, attr.span, filename, contents,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -114,19 +114,7 @@ fn function_calls() {
|
||||
|
||||
fn macros() {
|
||||
baz!(
|
||||
do_not,
|
||||
add,
|
||||
trailing,
|
||||
commas,
|
||||
inside,
|
||||
of,
|
||||
function,
|
||||
like,
|
||||
macros,
|
||||
even,
|
||||
if_they,
|
||||
are,
|
||||
long
|
||||
do_not, add, trailing, commas, inside, of, function, like, macros, even, if_they, are, long
|
||||
);
|
||||
|
||||
baz!(one_item_macro_which_is_also_loooooooooooooooooooooooooooooooooooooooooooooooong);
|
||||
|
@ -218,10 +218,7 @@ fn issue355() {
|
||||
xc => vec![1, 2], // comment
|
||||
yc => vec![3; 4], // comment
|
||||
yd => looooooooooooooooooooooooooooooooooooooooooooooooooooooooong_func(
|
||||
aaaaaaaaaa,
|
||||
bbbbbbbbbb,
|
||||
cccccccccc,
|
||||
dddddddddd,
|
||||
aaaaaaaaaa, bbbbbbbbbb, cccccccccc, dddddddddd,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user