Merge pull request #1746 from topecongiro/struct-tuple

RFC: Use block indent style for struct tuple
This commit is contained in:
Nick Cameron 2017-07-06 08:16:10 +12:00 committed by GitHub
commit 6b0035327c
14 changed files with 193 additions and 173 deletions

View File

@ -16,12 +16,12 @@ use {Indent, Shape, Spanned};
use codemap::SpanUtils;
use rewrite::{Rewrite, RewriteContext};
use lists::{write_list, itemize_list, ListFormatting, SeparatorTactic, ListTactic,
DefinitiveListTactic, definitive_tactic, ListItem, format_item_list, struct_lit_shape,
DefinitiveListTactic, definitive_tactic, ListItem, struct_lit_shape,
struct_lit_tactic, shape_for_tactic, struct_lit_formatting};
use string::{StringFormat, rewrite_string};
use utils::{extra_offset, last_line_width, wrap_str, binary_search, first_line_width,
semicolon_for_stmt, trimmed_last_line_width, left_most_sub_expr, stmt_expr,
colon_spaces, contains_skip, mk_sp, last_line_extendable};
colon_spaces, contains_skip, mk_sp, last_line_extendable, paren_overhead};
use visitor::FmtVisitor;
use config::{Config, IndentStyle, MultilineStyle, ControlBraceStyle, Style};
use comment::{FindUncommented, rewrite_comment, contains_comment, recover_comment_removed};
@ -2217,7 +2217,7 @@ where
context.config.trailing_comma()
},
shape: shape,
ends_with_newline: false,
ends_with_newline: context.use_block_indent() && tactic == DefinitiveListTactic::Vertical,
config: context.config,
};
@ -2436,14 +2436,6 @@ pub fn can_be_overflowed_expr(context: &RewriteContext, expr: &ast::Expr, args_l
}
}
fn paren_overhead(context: &RewriteContext) -> usize {
if context.config.spaces_within_parens() {
4
} else {
2
}
}
pub fn wrap_args_with_parens(
context: &RewriteContext,
args_str: &str,
@ -2813,7 +2805,21 @@ where
list_lo,
span.hi - BytePos(1),
);
let list_str = try_opt!(format_item_list(items, nested_shape, context.config));
let item_vec: Vec<_> = items.collect();
let tactic = definitive_tactic(
&item_vec,
ListTactic::HorizontalVertical,
nested_shape.width,
);
let fmt = ListFormatting {
tactic: tactic,
separator: ",",
trailing_separator: SeparatorTactic::Never,
shape: shape,
ends_with_newline: false,
config: context.config,
};
let list_str = try_opt!(write_list(&item_vec, &fmt));
if context.config.spaces_within_parens() && list_str.len() > 0 {
Some(format!("( {} )", list_str))
@ -3023,3 +3029,13 @@ impl<'a> ToExpr for TuplePatField<'a> {
can_be_overflowed_pat(context, self, len)
}
}
impl<'a> ToExpr for ast::StructField {
fn to_expr(&self) -> Option<&ast::Expr> {
None
}
fn can_be_overflowed(&self, _: &RewriteContext, _: usize) -> bool {
false
}
}

View File

@ -167,7 +167,9 @@ impl FileLines {
}
/// FileLines files iterator.
pub struct Files<'a>(Option<::std::collections::hash_map::Keys<'a, String, Vec<Range>>>);
pub struct Files<'a>(
Option<::std::collections::hash_map::Keys<'a, String, Vec<Range>>>,
);
impl<'a> iter::Iterator for Files<'a> {
type Item = &'a String;

View File

@ -15,9 +15,10 @@ use codemap::SpanUtils;
use utils::{format_mutability, format_visibility, contains_skip, end_typaram, wrap_str,
last_line_width, format_unsafety, trim_newlines, stmt_expr, semicolon_for_expr,
trimmed_last_line_width, colon_spaces, mk_sp};
use lists::{write_list, itemize_list, ListItem, ListFormatting, SeparatorTactic, list_helper,
use lists::{write_list, itemize_list, ListItem, ListFormatting, SeparatorTactic,
DefinitiveListTactic, ListTactic, definitive_tactic};
use expr::{format_expr, is_empty_block, is_simple_block_stmt, rewrite_assign_rhs, ExprType};
use expr::{format_expr, is_empty_block, is_simple_block_stmt, rewrite_assign_rhs,
rewrite_call_inner, ExprType};
use comment::{FindUncommented, contains_comment, rewrite_comment, recover_comment_removed};
use visitor::FmtVisitor;
use rewrite::{Rewrite, RewriteContext};
@ -392,7 +393,8 @@ impl<'a> FmtVisitor<'a> {
generics: &ast::Generics,
span: Span,
) {
self.buffer.push_str(&format_header("enum ", ident, vis));
let enum_header = format_header("enum ", ident, vis);
self.buffer.push_str(&enum_header);
let enum_snippet = self.snippet(span);
let brace_pos = enum_snippet.find_uncommented("{").unwrap();
@ -406,6 +408,7 @@ impl<'a> FmtVisitor<'a> {
enum_def.variants.is_empty(),
self.block_indent,
mk_sp(span.lo, body_start),
last_line_width(&enum_header),
).unwrap();
self.buffer.push_str(&generics_str);
@ -1071,11 +1074,19 @@ fn format_struct_struct(
fields.is_empty(),
offset,
mk_sp(span.lo, body_lo),
last_line_width(&result),
))
}
None => {
if context.config.item_brace_style() == BraceStyle::AlwaysNextLine &&
!fields.is_empty()
// 3 = ` {}`, 2 = ` {`.
let overhead = if fields.is_empty() { 3 } else { 2 };
if (context.config.item_brace_style() == BraceStyle::AlwaysNextLine &&
!fields.is_empty()) ||
context
.config
.max_width()
.checked_sub(result.len())
.unwrap_or(0) < overhead
{
format!("\n{}{{", offset.block_only().to_string(context.config))
} else {
@ -1083,7 +1094,18 @@ fn format_struct_struct(
}
}
};
result.push_str(&generics_str);
// 1 = `}`
let overhead = if fields.is_empty() { 1 } else { 0 };
let max_len = context.config.max_width() - offset.width();
if !generics_str.contains('\n') && result.len() + generics_str.len() + overhead > max_len {
result.push('\n');
result.push_str(&offset
.block_indent(context.config)
.to_string(context.config));
result.push_str(&generics_str.trim_left());
} else {
result.push_str(&generics_str);
}
if fields.is_empty() {
let snippet = context.snippet(mk_sp(body_lo, span.hi - BytePos(1)));
@ -1147,17 +1169,13 @@ fn format_tuple_struct(
let where_clause_str = match generics {
Some(generics) => {
let shape = Shape::indented(offset + last_line_width(&header_str), context.config);
let budget = context.budget(last_line_width(&header_str));
let shape = Shape::legacy(budget, offset);
let g_span = mk_sp(span.lo, body_lo);
let generics_str = try_opt!(rewrite_generics(context, generics, shape, g_span));
result.push_str(&generics_str);
let where_budget = try_opt!(
context
.config
.max_width()
.checked_sub(last_line_width(&result))
);
let where_budget = context.budget(last_line_width(&result));
try_opt!(rewrite_where_clause(
context,
&generics.where_clause,
@ -1174,6 +1192,18 @@ fn format_tuple_struct(
};
if fields.is_empty() {
// 3 = `();`
let used_width = if result.contains('\n') {
last_line_width(&result) + 3
} else {
offset.width() + result.len() + 3
};
if used_width > context.config.max_width() {
result.push('\n');
result.push_str(&offset
.block_indent(context.config)
.to_string(context.config))
}
result.push('(');
let snippet = context.snippet(mk_sp(body_lo, context.codemap.span_before(span, ")")));
if snippet.is_empty() {
@ -1187,82 +1217,19 @@ fn format_tuple_struct(
}
result.push(')');
} else {
let (tactic, item_indent) = match context.config.fn_args_layout() {
IndentStyle::Visual => {
// 1 = `(`
(
ListTactic::HorizontalVertical,
offset.block_only() + result.len() + 1,
)
}
IndentStyle::Block => {
(
ListTactic::HorizontalVertical,
offset.block_only().block_indent(&context.config),
)
}
};
// 3 = `();`
let item_budget = try_opt!(
context
.config
.max_width()
.checked_sub(item_indent.width() + 3)
let body = try_opt!(
rewrite_call_inner(
context,
"",
&fields.iter().map(|field| field).collect::<Vec<_>>()[..],
span,
Shape::legacy(context.budget(last_line_width(&result) + 3), offset),
context.config.fn_call_width(),
false,
).ok()
);
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| {
rewrite_struct_field(context, field, Shape::legacy(item_budget, item_indent), 0)
},
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,
));
if context.config.fn_args_layout() == IndentStyle::Visual || !body.contains('\n') {
result.push('(');
if context.config.spaces_within_parens() && body.len() > 0 {
result.push(' ');
}
result.push_str(&body);
if context.config.spaces_within_parens() && body.len() > 0 {
result.push(' ');
}
result.push(')');
} else {
result.push_str("(\n");
result.push_str(&item_indent.to_string(&context.config));
result.push_str(&body);
result.push('\n');
result.push_str(&offset.block_only().to_string(&context.config));
result.push(')');
}
result.push_str(&body);
}
if !where_clause_str.is_empty() && !where_clause_str.contains('\n') &&
@ -1452,6 +1419,11 @@ fn rewrite_struct_field_type(
.map(|ty| format!("{}{}", spacing, ty))
}
impl Rewrite for ast::StructField {
fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
rewrite_struct_field(context, self, shape, 0)
}
}
pub fn rewrite_struct_field(
context: &RewriteContext,
@ -2384,7 +2356,7 @@ fn rewrite_generics(
span: Span,
) -> Option<String> {
let g_shape = try_opt!(generics_shape_from_config(context.config, shape, 0));
let one_line_width = try_opt!(shape.width.checked_sub(2));
let one_line_width = shape.width.checked_sub(2).unwrap_or(0);
rewrite_generics_inner(context, generics, g_shape, one_line_width, span).or_else(|| {
rewrite_generics_inner(context, generics, g_shape, 0, span)
})
@ -2459,8 +2431,11 @@ where
{
let item_vec = items.collect::<Vec<_>>();
let tactic = definitive_tactic(&item_vec, ListTactic::HorizontalVertical, one_line_budget);
let ends_with_newline = context.config.generics_indent() == IndentStyle::Block &&
tactic == DefinitiveListTactic::Vertical;
let fmt = ListFormatting {
tactic: definitive_tactic(&item_vec, ListTactic::HorizontalVertical, one_line_budget),
tactic: tactic,
separator: ",",
trailing_separator: if context.config.generics_indent() == IndentStyle::Visual {
SeparatorTactic::Never
@ -2468,7 +2443,7 @@ where
context.config.trailing_comma()
},
shape: shape,
ends_with_newline: false,
ends_with_newline: ends_with_newline,
config: context.config,
};
@ -2697,8 +2672,9 @@ fn format_generics(
force_same_line_brace: bool,
offset: Indent,
span: Span,
used_width: usize,
) -> Option<String> {
let shape = Shape::indented(offset, context.config);
let shape = Shape::legacy(context.budget(used_width + offset.width()), offset);
let mut result = try_opt!(rewrite_generics(context, generics, shape, span));
if !generics.where_clause.predicates.is_empty() || result.contains('\n') {

View File

@ -14,7 +14,7 @@ use std::iter::Peekable;
use syntax::codemap::{CodeMap, BytePos};
use {Indent, Shape};
use comment::{FindUncommented, rewrite_comment, find_comment_end};
use comment::{find_comment_end, rewrite_comment, FindUncommented};
use config::{Config, IndentStyle};
use rewrite::RewriteContext;
use utils::mk_sp;
@ -68,31 +68,6 @@ pub struct ListFormatting<'a> {
pub config: &'a Config,
}
pub fn format_item_list<I>(items: I, shape: Shape, config: &Config) -> Option<String>
where
I: Iterator<Item = ListItem>,
{
list_helper(items, shape, config, ListTactic::HorizontalVertical)
}
pub fn list_helper<I>(items: I, shape: Shape, config: &Config, tactic: ListTactic) -> Option<String>
where
I: Iterator<Item = ListItem>,
{
let item_vec: Vec<_> = items.collect();
let tactic = definitive_tactic(&item_vec, tactic, shape.width);
let fmt = ListFormatting {
tactic: tactic,
separator: ",",
trailing_separator: SeparatorTactic::Never,
shape: shape,
ends_with_newline: false,
config: config,
};
write_list(&item_vec, &fmt)
}
impl AsRef<ListItem> for ListItem {
fn as_ref(&self) -> &ListItem {
self
@ -118,10 +93,13 @@ impl ListItem {
.map_or(false, |s| s.contains('\n'))
}
pub fn has_line_pre_comment(&self) -> bool {
pub fn has_comment(&self) -> bool {
self.pre_comment
.as_ref()
.map_or(false, |comment| comment.starts_with("//"))
.map_or(false, |comment| comment.starts_with("//")) ||
self.post_comment
.as_ref()
.map_or(false, |comment| comment.starts_with("//"))
}
pub fn from_str<S: Into<String>>(s: S) -> ListItem {
@ -150,7 +128,7 @@ where
let pre_line_comments = items
.clone()
.into_iter()
.any(|item| item.as_ref().has_line_pre_comment());
.any(|item| item.as_ref().has_comment());
let limit = match tactic {
_ if pre_line_comments => return DefinitiveListTactic::Vertical,

View File

@ -45,4 +45,8 @@ impl<'a> RewriteContext<'a> {
pub fn use_block_indent(&self) -> bool {
self.config.fn_call_style() == IndentStyle::Block || self.use_block
}
pub fn budget(&self, used_width: usize) -> usize {
self.config.max_width().checked_sub(used_width).unwrap_or(0)
}
}

View File

@ -393,6 +393,15 @@ pub fn colon_spaces(before: bool, after: bool) -> &'static str {
}
}
#[inline]
pub fn paren_overhead(context: &RewriteContext) -> usize {
if context.config.spaces_within_parens() {
4
} else {
2
}
}
#[test]
fn bin_search_test() {
let closure = |i| match i {

View File

@ -73,14 +73,19 @@ struct Bar;
struct NewType(Type, OtherType);
struct NewInt<T: Copy>(pub i32, SomeType /* inline comment */, T /* sup */);
struct NewInt<T: Copy>(
pub i32,
SomeType, // inline comment
T, // sup
);
struct Qux<'a,
N: Clone + 'a,
E: Clone + 'a,
G: Labeller<'a, N, E> + GraphWalk<'a, N, E>,
W: Write + Copy>
(
struct Qux<
'a,
N: Clone + 'a,
E: Clone + 'a,
G: Labeller<'a, N, E> + GraphWalk<'a, N, E>,
W: Write + Copy,
>(
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, // Comment
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB,
#[AnAttr]
@ -94,7 +99,7 @@ struct Tuple(
// Comment 1
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA,
// Comment 2
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB,
);
// With a where clause and generics.
@ -139,7 +144,10 @@ struct Baz {
}
// Will this be a one-liner?
struct Tuple(A /* Comment */, B);
struct Tuple(
A, // Comment
B,
);
pub struct State<F: FnMut() -> time::Timespec> {
now: F,
@ -186,19 +194,27 @@ struct Foo<T>(
TTTTTTTTTTTTTTTTT,
UUUUUUUUUUUUUUUUUUUUUUUU,
TTTTTTTTTTTTTTTTTTT,
UUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUU,
);
struct Foo<T>(TTTTTTTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUUUUUU, TTTTTTTTTTTTTTTTTTT)
struct Foo<T>(
TTTTTTTTTTTTTTTTTT,
UUUUUUUUUUUUUUUUUUUUUUUU,
TTTTTTTTTTTTTTTTTTT,
)
where
T: PartialEq;
struct Foo<T>(TTTTTTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUUUUUU, TTTTTTTTTTTTTTTTTTTTT)
struct Foo<T>(
TTTTTTTTTTTTTTTTT,
UUUUUUUUUUUUUUUUUUUUUUUU,
TTTTTTTTTTTTTTTTTTTTT,
)
where
T: PartialEq;
struct Foo<T>(
TTTTTTTTTTTTTTTTT,
UUUUUUUUUUUUUUUUUUUUUUUU,
TTTTTTTTTTTTTTTTTTT,
UUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUU,
)
where
T: PartialEq;
@ -208,7 +224,7 @@ struct Foo<T>(
// Baz
TTTTTTTTTTTTTTTTTTT,
// Qux (FIXME #572 - doc comment)
UUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUU,
);
mod m {
@ -223,7 +239,7 @@ mod m {
struct Foo<T>(
TTTTTTTTTTTTTTTTTTT,
/// Qux
UUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUU,
);
struct Issue677 {

View File

@ -32,7 +32,7 @@ enum Bar {
enum LongVariants {
First(
LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONG, // comment
VARIANT
VARIANT,
),
// This is the second variant
Second,
@ -53,7 +53,7 @@ enum X {
CreateWebGLPaintTask(
Size2D<i32>,
GLContextAttributes,
IpcSender<Result<(IpcSender<CanvasMsg>, usize), String>>
IpcSender<Result<(IpcSender<CanvasMsg>, usize), String>>,
), // This is a post comment
}
@ -120,7 +120,7 @@ fn nested_enum_test() {
usize,
usize,
usize,
usize
usize,
), /* AAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAA
* AAAAAAAAAAAAAAAAAAAAAA */
Two, /* AAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
@ -155,6 +155,6 @@ pub enum CoreResourceMsg {
#[serde(deserialize_with = "::hyper_serde::deserialize",
serialize_with = "::hyper_serde::serialize")]
Cookie,
CookieSource
CookieSource,
),
}

View File

@ -29,7 +29,7 @@ fn main() {
kaas!(
// comments
a, // post macro
b /* another */
b // another
);
trailingcomma!(a, b, c,);

View File

@ -40,7 +40,7 @@ where
fn baz<
'a: 'b, // comment on 'a
T: SomsssssssssssssssssssssssssssssssssssssssssssssssssssssseType, /* comment on T */
T: SomsssssssssssssssssssssssssssssssssssssssssssssssssssssseType, // comment on T
>(
a: A,
b: B, // comment on b

View File

@ -14,7 +14,10 @@ fn main() {
supports_clipboard,
);
Quux::<ParamOne /* Comment 1 */, ParamTwo /* Comment 2 */>::some_func();
Quux::<
ParamOne, // Comment 1
ParamTwo, // Comment 2
>::some_func();
<*mut JSObject>::relocate(entry);

View File

@ -10,7 +10,7 @@ fn foo() {
// Comment
foo(), // Comment
// Comment
bar(), /* Comment */
bar(), // Comment
);
Foo(Bar, f());
@ -24,7 +24,7 @@ fn foo() {
Baz(
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,
zzzzz, /* test */
zzzzz, // test
);
A(

View File

@ -41,14 +41,19 @@ struct Bar;
struct NewType(Type, OtherType);
struct NewInt<T: Copy>(pub i32, SomeType /* inline comment */, T /* sup */);
struct NewInt<T: Copy>(
pub i32,
SomeType, // inline comment
T, // sup
);
struct Qux<'a,
N: Clone + 'a,
E: Clone + 'a,
G: Labeller<'a, N, E> + GraphWalk<'a, N, E>,
W: Write + Copy>
(
struct Qux<
'a,
N: Clone + 'a,
E: Clone + 'a,
G: Labeller<'a, N, E> + GraphWalk<'a, N, E>,
W: Write + Copy,
>(
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, // Comment
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB,
#[AnAttr]
@ -62,7 +67,7 @@ struct Tuple(
// Comment 1
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA,
// Comment 2
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB,
);
// With a where clause and generics.
@ -107,7 +112,10 @@ struct Baz {
}
// Will this be a one-liner?
struct Tuple(A /* Comment */, B);
struct Tuple(
A, // Comment
B,
);
pub struct State<F: FnMut() -> time::Timespec> {
now: F,
@ -154,19 +162,27 @@ struct Foo<T>(
TTTTTTTTTTTTTTTTT,
UUUUUUUUUUUUUUUUUUUUUUUU,
TTTTTTTTTTTTTTTTTTT,
UUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUU,
);
struct Foo<T>(TTTTTTTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUUUUUU, TTTTTTTTTTTTTTTTTTT)
struct Foo<T>(
TTTTTTTTTTTTTTTTTT,
UUUUUUUUUUUUUUUUUUUUUUUU,
TTTTTTTTTTTTTTTTTTT,
)
where
T: PartialEq;
struct Foo<T>(TTTTTTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUUUUUU, TTTTTTTTTTTTTTTTTTTTT)
struct Foo<T>(
TTTTTTTTTTTTTTTTT,
UUUUUUUUUUUUUUUUUUUUUUUU,
TTTTTTTTTTTTTTTTTTTTT,
)
where
T: PartialEq;
struct Foo<T>(
TTTTTTTTTTTTTTTTT,
UUUUUUUUUUUUUUUUUUUUUUUU,
TTTTTTTTTTTTTTTTTTT,
UUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUU,
)
where
T: PartialEq;
@ -176,7 +192,7 @@ struct Foo<T>(
// Baz
TTTTTTTTTTTTTTTTTTT,
// Qux (FIXME #572 - doc comment)
UUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUU,
);
mod m {
@ -191,7 +207,7 @@ mod m {
struct Foo<T>(
TTTTTTTTTTTTTTTTTTT,
/// Qux
UUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUU,
);
struct Issue677 {

View File

@ -48,7 +48,7 @@ struct Pair<
struct TupPair<
S, T,
>(S, T)
>(S, T,)
where
T: P,
S: P + Q;