Merge pull request #1616 from topecongiro/nested-closure

Use block indent style when visual indent style fails
This commit is contained in:
Nick Cameron 2017-06-01 15:42:16 +12:00 committed by GitHub
commit 535a0160d6
6 changed files with 131 additions and 44 deletions

View file

@ -599,14 +599,17 @@ fn rewrite_closure(capture: ast::CaptureBy,
-> Option<String> { -> Option<String> {
// Start with visual indent, then fall back to block indent if the // Start with visual indent, then fall back to block indent if the
// closure is large. // closure is large.
if let Some(block_str) = block.rewrite(&context, shape) {
let block_threshold = context.config.closure_block_indent_threshold(); let block_threshold = context.config.closure_block_indent_threshold();
if block_threshold < 0 || block_str.matches('\n').count() <= block_threshold as usize { if block_threshold >= 0 {
if let Some(block_str) = block.rewrite(&context, shape) {
if block_str.matches('\n').count() <= block_threshold as usize &&
!need_block_indent(&block_str, shape) {
if let Some(block_str) = block_str.rewrite(context, shape) { if let Some(block_str) = block_str.rewrite(context, shape) {
return Some(format!("{} {}", prefix, block_str)); return Some(format!("{} {}", prefix, block_str));
} }
} }
} }
}
// The body of the closure is big enough to be block indented, that // The body of the closure is big enough to be block indented, that
// means we must re-format. // means we must re-format.
@ -965,13 +968,15 @@ impl<'a> Rewrite for ControlFlow<'a> {
}; };
// for event in event // for event in event
let between_kwd_cond = mk_sp(context.codemap.span_after(self.span, self.keyword.trim()), let between_kwd_cond = mk_sp(
context.codemap.span_after(self.span, self.keyword.trim()),
self.pat self.pat
.map_or(cond_span.lo, |p| if self.matcher.is_empty() { .map_or(cond_span.lo, |p| if self.matcher.is_empty() {
p.span.lo p.span.lo
} else { } else {
context.codemap.span_before(self.span, self.matcher.trim()) context.codemap.span_before(self.span, self.matcher.trim())
})); }),
);
let between_kwd_cond_comment = extract_comment(between_kwd_cond, context, shape); let between_kwd_cond_comment = extract_comment(between_kwd_cond, context, shape);
@ -1676,20 +1681,40 @@ fn rewrite_call_inner(context: &RewriteContext,
.ok_or(Ordering::Greater)?; .ok_or(Ordering::Greater)?;
let span_lo = context.codemap.span_after(span, "("); let span_lo = context.codemap.span_after(span, "(");
let span = mk_sp(span_lo, span.hi); let new_span = mk_sp(span_lo, span.hi);
let (extendable, list_str) = rewrite_call_args(context, let (extendable, list_str) = rewrite_call_args(context,
args, args,
span, new_span,
nested_shape, nested_shape,
one_line_width, one_line_width,
force_trailing_comma) force_trailing_comma)
.ok_or(Ordering::Less)?; .ok_or(Ordering::Less)?;
if !use_block_indent(context) && need_block_indent(&list_str, nested_shape) && !extendable {
println!("here");
let mut new_context = context.clone();
new_context.use_block = true;
return rewrite_call_inner(&new_context,
callee_str,
args,
span,
shape,
force_trailing_comma);
}
Ok(format!("{}{}", Ok(format!("{}{}",
callee_str, callee_str,
wrap_args_with_parens(context, &list_str, extendable, shape, nested_shape))) wrap_args_with_parens(context, &list_str, extendable, shape, nested_shape)))
} }
fn need_block_indent(s: &str, shape: Shape) -> bool {
s.lines().skip(1).any(|s| {
s.find(|c| !char::is_whitespace(c))
.map_or(false, |w| w + 1 < shape.indent.width())
})
}
fn rewrite_call_args(context: &RewriteContext, fn rewrite_call_args(context: &RewriteContext,
args: &[ptr::P<ast::Expr>], args: &[ptr::P<ast::Expr>],
span: Span, span: Span,
@ -1720,8 +1745,7 @@ fn rewrite_call_args(context: &RewriteContext,
// Replace the last item with its first line to see if it fits with // Replace the last item with its first line to see if it fits with
// first arguments. // first arguments.
if overflow_last { if overflow_last {
let arg_shape = if context.config.fn_call_style() == IndentStyle::Block && let arg_shape = if use_block_indent(context) && is_extendable(args) {
is_extendable(args) {
Shape { Shape {
width: context.config.fn_call_width(), width: context.config.fn_call_width(),
indent: shape.block().indent.block_unindent(context.config), indent: shape.block().indent.block_unindent(context.config),
@ -1799,8 +1823,7 @@ fn rewrite_call_args(context: &RewriteContext,
// If arguments do not fit in a single line and do not contain newline, // If arguments do not fit in a single line and do not contain newline,
// try to put it on the next line. Try this only when we are in block mode // try to put it on the next line. Try this only when we are in block mode
// and not rewriting macro. // and not rewriting macro.
Some(ref s) if context.config.fn_call_style() == IndentStyle::Block && Some(ref s) if use_block_indent(context) && !context.inside_macro &&
!context.inside_macro &&
((!can_be_overflowed(context, args) && last_char_is_not_comma && ((!can_be_overflowed(context, args) && last_char_is_not_comma &&
s.contains('\n')) || s.contains('\n')) ||
first_line_width(s) > one_line_budget) => { first_line_width(s) > one_line_budget) => {
@ -1814,23 +1837,25 @@ fn rewrite_call_args(context: &RewriteContext,
} }
} }
fn use_block_indent(context: &RewriteContext) -> bool {
context.config.fn_call_style() == IndentStyle::Block || context.use_block
}
fn can_be_overflowed(context: &RewriteContext, args: &[ptr::P<ast::Expr>]) -> bool { fn can_be_overflowed(context: &RewriteContext, args: &[ptr::P<ast::Expr>]) -> bool {
match args.last().map(|x| &x.node) { match args.last().map(|x| &x.node) {
Some(&ast::ExprKind::Match(..)) => { Some(&ast::ExprKind::Match(..)) => {
(context.config.fn_call_style() == IndentStyle::Block && args.len() == 1) || (use_block_indent(context) && args.len() == 1) ||
(context.config.fn_call_style() == IndentStyle::Visual && args.len() > 1) (context.config.fn_call_style() == IndentStyle::Visual && args.len() > 1)
} }
Some(&ast::ExprKind::Block(..)) | Some(&ast::ExprKind::Block(..)) |
Some(&ast::ExprKind::Closure(..)) => { Some(&ast::ExprKind::Closure(..)) => {
context.config.fn_call_style() == IndentStyle::Block || use_block_indent(context) ||
context.config.fn_call_style() == IndentStyle::Visual && args.len() > 1 context.config.fn_call_style() == IndentStyle::Visual && args.len() > 1
} }
Some(&ast::ExprKind::Call(..)) | Some(&ast::ExprKind::Call(..)) |
Some(&ast::ExprKind::Mac(..)) | Some(&ast::ExprKind::Mac(..)) |
Some(&ast::ExprKind::Struct(..)) => { Some(&ast::ExprKind::Struct(..)) => use_block_indent(context) && args.len() == 1,
context.config.fn_call_style() == IndentStyle::Block && args.len() == 1 Some(&ast::ExprKind::Tup(..)) => use_block_indent(context),
}
Some(&ast::ExprKind::Tup(..)) => context.config.fn_call_style() == IndentStyle::Block,
_ => false, _ => false,
} }
} }
@ -1865,8 +1890,8 @@ fn wrap_args_with_parens(context: &RewriteContext,
shape: Shape, shape: Shape,
nested_shape: Shape) nested_shape: Shape)
-> String { -> String {
if context.config.fn_call_style() == IndentStyle::Visual || if !use_block_indent(context) || (context.inside_macro && !args_str.contains('\n')) ||
(context.inside_macro && !args_str.contains('\n')) || is_extendable { is_extendable {
if context.config.spaces_within_parens() && args_str.len() > 0 { if context.config.spaces_within_parens() && args_str.len() > 0 {
format!("( {} )", args_str) format!("( {} )", args_str)
} else { } else {
@ -2062,9 +2087,10 @@ fn shape_from_fn_call_style(context: &RewriteContext,
overhead: usize, overhead: usize,
offset: usize) offset: usize)
-> Option<Shape> { -> Option<Shape> {
match context.config.fn_call_style() { if use_block_indent(context) {
IndentStyle::Block => Some(shape.block().block_indent(context.config.tab_spaces())), Some(shape.block().block_indent(context.config.tab_spaces()))
IndentStyle::Visual => shape.visual_indent(offset).sub_width(overhead), } else {
shape.visual_indent(offset).sub_width(overhead)
} }
} }

View file

@ -610,7 +610,8 @@ pub fn format_input<T: Write>(input: Input,
let mut report = FormatReport::new(); let mut report = FormatReport::new();
match format_ast(&krate, match format_ast(
&krate,
&parse_session, &parse_session,
&main_file, &main_file,
config, config,
@ -625,7 +626,8 @@ pub fn format_input<T: Write>(input: Input,
return filemap::write_file(file, file_name, out, config); return filemap::write_file(file, file_name, out, config);
} }
Ok(false) Ok(false)
}) { }
) {
Ok((file_map, has_diff)) => { Ok((file_map, has_diff)) => {
if report.has_warnings() { if report.has_warnings() {
summary.add_formatting_error(); summary.add_formatting_error();

View file

@ -205,10 +205,10 @@ pub fn rewrite_macro(mac: &ast::Mac,
context context
.codemap .codemap
.span_after(mac.span, original_style.opener()), .span_after(mac.span, original_style.opener()),
mac.span.hi - BytePos(1) mac.span.hi - BytePos(1),
), ),
context, context,
mac_shape mac_shape,
)); ));
Some(format!("{}{}", macro_name, rewrite)) Some(format!("{}{}", macro_name, rewrite))

View file

@ -27,6 +27,7 @@ pub struct RewriteContext<'a> {
pub codemap: &'a CodeMap, pub codemap: &'a CodeMap,
pub config: &'a Config, pub config: &'a Config,
pub inside_macro: bool, pub inside_macro: bool,
pub use_block: bool,
} }
impl<'a> RewriteContext<'a> { impl<'a> RewriteContext<'a> {

View file

@ -610,6 +610,7 @@ impl<'a> FmtVisitor<'a> {
codemap: self.codemap, codemap: self.codemap,
config: self.config, config: self.config,
inside_macro: false, inside_macro: false,
use_block: false,
} }
} }
} }

View file

@ -0,0 +1,57 @@
fn main() {
// #1078
let items = itemize_list(
context.codemap,
field_iter,
"}",
|item| match *item {
StructLitField::Regular(ref field) => field.span.lo,
StructLitField::Base(ref expr) => {
let last_field_hi = fields.last().map_or(span.lo, |field| field.span.hi);
let snippet = context.snippet(mk_sp(last_field_hi, expr.span.lo));
let pos = snippet.find_uncommented("..").unwrap();
last_field_hi + BytePos(pos as u32)
}
},
|item| match *item {
StructLitField::Regular(ref field) => field.span.hi,
StructLitField::Base(ref expr) => expr.span.hi,
},
|item| {
match *item {
StructLitField::Regular(ref field) => {
rewrite_field(inner_context,
&field,
&Constraints::new(v_budget.checked_sub(1).unwrap_or(0), indent))
}
StructLitField::Base(ref expr) => {
// 2 = ..
expr.rewrite(inner_context,
&Constraints::new(try_opt!(v_budget.checked_sub(2)), indent + 2))
.map(|s| format!("..{}", s))
}
}
},
context.codemap.span_after(span, "{"),
span.hi,
);
// #1580
self.0.pool.execute(move || {
let _timer = segments.0.rotate_timer.time();
if let Err(e) = segments.rotate_async(wal) {
error!("error compacting segment storage WAL", unsafe { error: e.display() });
}
});
// #1581
bootstrap.checks.register(
"PERSISTED_LOCATIONS",
move || if locations2.0.inner_mut.lock().poisoned {
Check::new(State::Error,
"Persisted location storage is poisoned due to a write failure")
} else {
Check::new(State::Healthy, "Persisted location storage is healthy")
}
);
}