Merge pull request #1486 from topecongiro/refactoring

Refactor source codes
This commit is contained in:
Nick Cameron 2017-05-02 10:30:11 +12:00 committed by GitHub
commit 2223b64f86
5 changed files with 152 additions and 125 deletions

View File

@ -104,11 +104,16 @@ pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) -
parent_shape = chain_indent(context, shape);
}
let parent_rewrite = try_opt!(parent.rewrite(context, parent_shape));
let parent_rewrite_contains_newline = parent_rewrite.contains('\n');
// Decide how to layout the rest of the chain. `extend` is true if we can
// put the first non-parent item on the same line as the parent.
let (nested_shape, extend) = if !parent_rewrite.contains('\n') && is_continuable(&parent) {
let nested_shape = if let ast::ExprKind::Try(..) = subexpr_list.last().unwrap().node {
let first_subexpr_is_try = match subexpr_list.last().unwrap().node {
ast::ExprKind::Try(..) => true,
_ => false,
};
let (nested_shape, extend) = if !parent_rewrite_contains_newline && is_continuable(&parent) {
let nested_shape = if first_subexpr_is_try {
parent_shape.block_indent(context.config.tab_spaces)
} else {
chain_indent(context, shape.add_offset(parent_rewrite.len()))
@ -120,7 +125,7 @@ pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) -
// The parent is a block, so align the rest of the chain with the closing
// brace.
(parent_shape, false)
} else if parent_rewrite.contains('\n') {
} else if parent_rewrite_contains_newline {
(chain_indent(context,
parent_shape.block_indent(context.config.tab_spaces)),
false)
@ -137,9 +142,9 @@ pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) -
..nested_shape
};
let first_child_shape = if extend {
let mut shape = try_opt!(parent_shape.shrink_left(last_line_width(&parent_rewrite)));
let mut shape = try_opt!(parent_shape.offset_left(last_line_width(&parent_rewrite)));
match context.config.chain_indent {
IndentStyle::Visual => other_child_shape,
IndentStyle::Visual => shape,
IndentStyle::Block => {
shape.offset = shape
.offset
@ -207,7 +212,7 @@ pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) -
}
}
let connector = if fits_single_line && !parent_rewrite.contains('\n') {
let connector = if fits_single_line && !parent_rewrite_contains_newline {
// Yay, we can put everything on one line.
String::new()
} else {
@ -215,9 +220,7 @@ pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) -
format!("\n{}", nested_shape.indent.to_string(context.config))
};
let first_connector = if extend || subexpr_list.is_empty() {
""
} else if let ast::ExprKind::Try(_) = subexpr_list.last().unwrap().node {
let first_connector = if extend || subexpr_list.is_empty() || first_subexpr_is_try {
""
} else {
&*connector
@ -375,33 +378,19 @@ fn rewrite_chain_subexpr(expr: &ast::Expr,
context: &RewriteContext,
shape: Shape)
-> Option<String> {
let rewrite_element = |expr_str: String| if expr_str.len() <= shape.width {
Some(expr_str)
} else {
None
};
match expr.node {
ast::ExprKind::MethodCall(ref method_name, ref types, ref expressions) => {
rewrite_method_call(method_name.node, types, expressions, span, context, shape)
}
ast::ExprKind::Field(_, ref field) => {
let s = format!(".{}", field.node);
if s.len() <= shape.width {
Some(s)
} else {
None
}
}
ast::ExprKind::TupField(_, ref field) => {
let s = format!(".{}", field.node);
if s.len() <= shape.width {
Some(s)
} else {
None
}
}
ast::ExprKind::Try(_) => {
if shape.width >= 1 {
Some("?".into())
} else {
None
}
}
ast::ExprKind::Field(_, ref field) => rewrite_element(format!(".{}", field.node)),
ast::ExprKind::TupField(_, ref field) => rewrite_element(format!(".{}", field.node)),
ast::ExprKind::Try(_) => rewrite_element(String::from("?")),
_ => unreachable!(),
}
}

View File

@ -38,7 +38,8 @@ impl Rewrite for ast::Local {
shape.indent);
let mut result = "let ".to_owned();
let pat_shape = try_opt!(shape.offset_left(result.len()));
// 4 = "let ".len()
let pat_shape = try_opt!(shape.offset_left(4));
// 1 = ;
let pat_shape = try_opt!(pat_shape.sub_width(1));
let pat_str = try_opt!(self.pat.rewrite(&context, pat_shape));
@ -70,7 +71,6 @@ impl Rewrite for ast::Local {
if let Some(ref ex) = self.init {
// 1 = trailing semicolon;
//let budget = try_opt!(shape.width.checked_sub(shape.indent.block_only().width() + 1));
let nested_shape = try_opt!(shape.sub_width(1));
result = try_opt!(rewrite_assign_rhs(&context, result, ex, nested_shape));
@ -380,7 +380,6 @@ impl<'a> FmtVisitor<'a> {
self.config.item_brace_style,
enum_def.variants.is_empty(),
self.block_indent,
self.block_indent.block_indent(self.config),
mk_sp(span.lo, body_start))
.unwrap();
self.buffer.push_str(&generics_str);
@ -644,12 +643,9 @@ fn format_impl_ref_and_type(context: &RewriteContext,
Some(ref tr) => tr.path.span.lo,
None => self_ty.span.lo,
};
let generics_str = try_opt!(rewrite_generics(context,
generics,
Shape::legacy(context.config.max_width,
offset),
offset + result.len(),
mk_sp(lo, hi)));
let generics_indent = offset + last_line_width(&result);
let shape = try_opt!(generics_shape(context.config, generics_indent));
let generics_str = try_opt!(rewrite_generics(context, generics, shape, mk_sp(lo, hi)));
result.push_str(&generics_str);
if polarity == ast::ImplPolarity::Negative {
@ -759,12 +755,10 @@ pub fn format_trait(context: &RewriteContext, item: &ast::Item, offset: Indent)
let body_lo = context.codemap.span_after(item.span, "{");
let generics_str = try_opt!(rewrite_generics(context,
generics,
Shape::legacy(context.config.max_width,
offset),
offset + result.len(),
mk_sp(item.span.lo, body_lo)));
let generics_indent = offset + last_line_width(&result);
let shape = try_opt!(generics_shape(context.config, generics_indent));
let generics_str =
try_opt!(rewrite_generics(context, generics, shape, mk_sp(item.span.lo, body_lo)));
result.push_str(&generics_str);
let trait_bound_str =
@ -902,7 +896,6 @@ fn format_struct_struct(context: &RewriteContext,
context.config.item_brace_style,
fields.is_empty(),
offset,
offset + header_str.len(),
mk_sp(span.lo, body_lo)))
}
None => {
@ -1011,12 +1004,10 @@ fn format_tuple_struct(context: &RewriteContext,
let where_clause_str = match generics {
Some(generics) => {
let generics_str = try_opt!(rewrite_generics(context,
generics,
Shape::legacy(context.config.max_width,
offset),
offset + header_str.len(),
mk_sp(span.lo, body_lo)));
let generics_indent = offset + last_line_width(&header_str);
let shape = try_opt!(generics_shape(context.config, generics_indent));
let generics_str =
try_opt!(rewrite_generics(context, generics, shape, mk_sp(span.lo, body_lo)));
result.push_str(&generics_str);
let where_budget = try_opt!(context
@ -1050,33 +1041,24 @@ fn format_tuple_struct(context: &RewriteContext,
.config
.max_width
.checked_sub(item_indent.width() + 3));
let shape = Shape::legacy(item_budget, item_indent);
let items =
itemize_list(context.codemap,
fields.iter(),
")",
|field| {
// Include attributes and doc comments, if present
if !field.attrs.is_empty() {
field.attrs[0].span.lo
} else {
field.span.lo
}
},
|field| field.ty.span.hi,
|field| field.rewrite(context, Shape::legacy(item_budget, item_indent)),
context.codemap.span_after(span, "("),
span.hi);
let body_budget = try_opt!(context
.config
.max_width
.checked_sub(offset.block_only().width() + result.len() +
3));
let body = try_opt!(list_helper(items,
// TODO budget is wrong in block case
Shape::legacy(body_budget, item_indent),
context.config,
tactic));
let items = itemize_list(context.codemap,
fields.iter(),
")",
|field| {
// Include attributes and doc comments, if present
if !field.attrs.is_empty() {
field.attrs[0].span.lo
} else {
field.span.lo
}
},
|field| field.ty.span.hi,
|field| field.rewrite(context, shape),
context.codemap.span_after(span, "("),
span.hi);
let body = try_opt!(list_helper(items, shape, context.config, tactic));
if context.config.fn_args_layout == IndentStyle::Visual || !body.contains('\n') {
result.push('(');
@ -1130,12 +1112,9 @@ pub fn rewrite_type_alias(context: &RewriteContext,
let generics_indent = indent + result.len();
let generics_span = mk_sp(context.codemap.span_after(span, "type"), ty.span.lo);
let generics_width = context.config.max_width - " =".len();
let generics_str = try_opt!(rewrite_generics(context,
generics,
Shape::legacy(generics_width, indent),
generics_indent,
generics_span));
let shape = try_opt!(try_opt!(generics_shape(context.config, generics_indent))
.sub_width(" =".len()));
let generics_str = try_opt!(rewrite_generics(context, generics, shape, generics_span));
result.push_str(&generics_str);
@ -1551,13 +1530,10 @@ fn rewrite_fn_base(context: &RewriteContext,
result.push_str(&ident.to_string());
// Generics.
let generics_indent = indent + result.len();
let generics_indent = indent + last_line_width(&result);
let generics_span = mk_sp(span.lo, span_for_return(&fd.output).lo);
let generics_str = try_opt!(rewrite_generics(context,
generics,
Shape::legacy(context.config.max_width, indent),
generics_indent,
generics_span));
let shape = try_opt!(generics_shape(context.config, generics_indent));
let generics_str = try_opt!(rewrite_generics(context, generics, shape, generics_span));
result.push_str(&generics_str);
let snuggle_angle_bracket = last_line_width(&generics_str) == 1;
@ -1964,8 +1940,6 @@ fn newline_for_brace(config: &Config, where_clause: &ast::WhereClause) -> bool {
fn rewrite_generics(context: &RewriteContext,
generics: &ast::Generics,
shape: Shape,
// TODO shouldn't need this
generics_offset: Indent,
span: Span)
-> Option<String> {
// FIXME: convert bounds to where clauses where they get too big or if
@ -1977,12 +1951,12 @@ fn rewrite_generics(context: &RewriteContext,
}
let offset = match context.config.generics_indent {
IndentStyle::Block => shape.indent.block_indent(context.config),
IndentStyle::Block => shape.indent.block_only().block_indent(context.config),
// 1 = <
IndentStyle::Visual => generics_offset + 1,
IndentStyle::Visual => shape.indent + 1,
};
let h_budget = try_opt!(shape.width.checked_sub(generics_offset.width() + 2));
let h_budget = try_opt!(shape.width.checked_sub(2));
// FIXME: might need to insert a newline if the generics are really long.
// Strings for the generics.
@ -2022,7 +1996,7 @@ fn rewrite_generics(context: &RewriteContext,
format!("<\n{}{}\n{}>",
offset.to_string(context.config),
list_str,
shape.indent.to_string(context.config))
shape.indent.block_only().to_string(context.config))
} else if context.config.spaces_within_angle_brackets {
format!("< {} >", list_str)
} else {
@ -2224,14 +2198,10 @@ fn format_generics(context: &RewriteContext,
brace_style: BraceStyle,
force_same_line_brace: bool,
offset: Indent,
generics_offset: Indent,
span: Span)
-> Option<String> {
let mut result = try_opt!(rewrite_generics(context,
generics,
Shape::legacy(context.config.max_width, offset),
generics_offset,
span));
let shape = try_opt!(generics_shape(context.config, offset));
let mut result = try_opt!(rewrite_generics(context, generics, shape, span));
if !generics.where_clause.predicates.is_empty() || result.contains('\n') {
let budget = try_opt!(context
@ -2273,3 +2243,8 @@ fn format_generics(context: &RewriteContext,
Some(result)
}
fn generics_shape(config: &Config, indent: Indent) -> Option<Shape> {
Some(Shape::legacy(try_opt!(config.max_width.checked_sub(indent.width())),
indent))
}

View File

@ -158,7 +158,7 @@ impl Indent {
let (num_tabs, num_spaces) = if config.hard_tabs {
(self.block_indent / config.tab_spaces, self.alignment)
} else {
(0, self.block_indent + self.alignment)
(0, self.width())
};
let num_chars = num_tabs + num_spaces;
let mut indent = String::with_capacity(num_chars);
@ -262,10 +262,7 @@ impl Shape {
let alignment = self.offset + extra_width;
Shape {
width: self.width,
indent: Indent {
block_indent: self.indent.block_indent,
alignment: alignment,
},
indent: Indent::new(self.indent.block_indent, alignment),
offset: alignment,
}
}
@ -274,19 +271,13 @@ impl Shape {
if self.indent.alignment == 0 {
Shape {
width: self.width,
indent: Indent {
block_indent: self.indent.block_indent + extra_width,
alignment: 0,
},
indent: Indent::new(self.indent.block_indent + extra_width, 0),
offset: 0,
}
} else {
Shape {
width: self.width,
indent: Indent {
block_indent: self.indent.block_indent,
alignment: self.indent.alignment + extra_width,
},
indent: self.indent + extra_width,
offset: self.indent.alignment + extra_width,
}
}
@ -295,10 +286,7 @@ impl Shape {
pub fn add_offset(&self, extra_width: usize) -> Shape {
Shape {
width: self.width,
indent: Indent {
block_indent: self.indent.block_indent,
alignment: self.indent.alignment,
},
indent: self.indent,
offset: self.offset + extra_width,
}
}
@ -306,10 +294,7 @@ impl Shape {
pub fn block(&self) -> Shape {
Shape {
width: self.width,
indent: Indent {
block_indent: self.indent.block_indent,
alignment: 0,
},
indent: self.indent.block_only(),
offset: self.offset,
}
}

View File

@ -0,0 +1,39 @@
// rustfmt-normalize_comments: true
// rustfmt-wrap_comments: true
// rustfmt-error_on_line_overflow: false
// rustfmt-struct_lit_style: Visual
fn foo() {
Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo(f(), b());
Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo(// Comment
foo(), /* Comment */
// Comment
bar() /* Comment */);
Foo(Bar, f());
Quux(if cond {
bar();
},
baz());
Baz(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,
zzzzz /* test */);
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.
item(),
// Praesent et diam eget libero egestas mattis sit amet vitae augue.
// Nam tincidunt congue enim, ut porta lorem lacinia consectetur.
Item);
Diagram(// o This graph demonstrates how
// / \ significant whitespace is
// o o preserved.
// /|\ \
// o o o o
G)
}

View File

@ -0,0 +1,39 @@
// rustfmt-normalize_comments: true
// rustfmt-wrap_comments: true
// rustfmt-error_on_line_overflow: false
// rustfmt-struct_lit_style: Visual
fn foo() {
Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo(f(), b());
Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo(// Comment
foo(), /* Comment */
// Comment
bar() /* Comment */);
Foo(Bar, f());
Quux(if cond {
bar();
},
baz());
Baz(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,
zzzzz /* test */);
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.
item(),
// Praesent et diam eget libero egestas mattis sit amet vitae augue.
// Nam tincidunt congue enim, ut porta lorem lacinia consectetur.
Item);
Diagram(// o This graph demonstrates how
// / \ significant whitespace is
// o o preserved.
// /|\ \
// o o o o
G)
}