Merge pull request #260 from cburgdorf/struct_lit_force_multiline
Implements struct_lit_force_multiline
This commit is contained in:
commit
db79a5aec5
6 changed files with 320 additions and 8 deletions
|
@ -45,6 +45,26 @@ impl Density {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||||
|
pub enum MultilineStyle {
|
||||||
|
// Use horizontal layout if it fits in one line, fall back to vertical
|
||||||
|
PreferSingle,
|
||||||
|
// Use vertical layout
|
||||||
|
ForceMulti,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl_enum_decodable!(MultilineStyle, PreferSingle, ForceMulti);
|
||||||
|
|
||||||
|
impl MultilineStyle {
|
||||||
|
pub fn to_list_tactic(self) -> ListTactic {
|
||||||
|
match self {
|
||||||
|
MultilineStyle::PreferSingle => ListTactic::HorizontalVertical,
|
||||||
|
MultilineStyle::ForceMulti => ListTactic::Vertical,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! create_config {
|
macro_rules! create_config {
|
||||||
($($i:ident: $ty:ty),+ $(,)*) => (
|
($($i:ident: $ty:ty),+ $(,)*) => (
|
||||||
#[derive(RustcDecodable, Clone)]
|
#[derive(RustcDecodable, Clone)]
|
||||||
|
@ -122,6 +142,7 @@ create_config! {
|
||||||
struct_trailing_comma: SeparatorTactic,
|
struct_trailing_comma: SeparatorTactic,
|
||||||
struct_lit_trailing_comma: SeparatorTactic,
|
struct_lit_trailing_comma: SeparatorTactic,
|
||||||
struct_lit_style: StructLitStyle,
|
struct_lit_style: StructLitStyle,
|
||||||
|
struct_lit_multiline_style: MultilineStyle,
|
||||||
enum_trailing_comma: bool,
|
enum_trailing_comma: bool,
|
||||||
report_todo: ReportTactic,
|
report_todo: ReportTactic,
|
||||||
report_fixme: ReportTactic,
|
report_fixme: ReportTactic,
|
||||||
|
@ -155,6 +176,7 @@ impl Default for Config {
|
||||||
struct_trailing_comma: SeparatorTactic::Vertical,
|
struct_trailing_comma: SeparatorTactic::Vertical,
|
||||||
struct_lit_trailing_comma: SeparatorTactic::Vertical,
|
struct_lit_trailing_comma: SeparatorTactic::Vertical,
|
||||||
struct_lit_style: StructLitStyle::Block,
|
struct_lit_style: StructLitStyle::Block,
|
||||||
|
struct_lit_multiline_style: MultilineStyle::PreferSingle,
|
||||||
enum_trailing_comma: true,
|
enum_trailing_comma: true,
|
||||||
report_todo: ReportTactic::Always,
|
report_todo: ReportTactic::Always,
|
||||||
report_fixme: ReportTactic::Never,
|
report_fixme: ReportTactic::Never,
|
||||||
|
|
23
src/expr.rs
23
src/expr.rs
|
@ -17,7 +17,7 @@ use StructLitStyle;
|
||||||
use utils::{span_after, make_indent, extra_offset, first_line_width, last_line_width, wrap_str,
|
use utils::{span_after, make_indent, extra_offset, first_line_width, last_line_width, wrap_str,
|
||||||
binary_search};
|
binary_search};
|
||||||
use visitor::FmtVisitor;
|
use visitor::FmtVisitor;
|
||||||
use config::BlockIndentStyle;
|
use config::{BlockIndentStyle, MultilineStyle};
|
||||||
use comment::{FindUncommented, rewrite_comment, contains_comment};
|
use comment::{FindUncommented, rewrite_comment, contains_comment};
|
||||||
use types::rewrite_path;
|
use types::rewrite_path;
|
||||||
use items::{span_lo_for_arg, span_hi_for_arg, rewrite_fn_input};
|
use items::{span_lo_for_arg, span_hi_for_arg, rewrite_fn_input};
|
||||||
|
@ -1019,7 +1019,10 @@ fn rewrite_struct_lit<'a>(context: &RewriteContext,
|
||||||
span.hi);
|
span.hi);
|
||||||
|
|
||||||
let fmt = ListFormatting {
|
let fmt = ListFormatting {
|
||||||
tactic: ListTactic::HorizontalVertical,
|
tactic: match (context.config.struct_lit_style, fields.len()) {
|
||||||
|
(StructLitStyle::Visual, 1) => ListTactic::HorizontalVertical,
|
||||||
|
_ => context.config.struct_lit_multiline_style.to_list_tactic(),
|
||||||
|
},
|
||||||
separator: ",",
|
separator: ",",
|
||||||
trailing_separator: if base.is_some() {
|
trailing_separator: if base.is_some() {
|
||||||
SeparatorTactic::Never
|
SeparatorTactic::Never
|
||||||
|
@ -1033,12 +1036,16 @@ fn rewrite_struct_lit<'a>(context: &RewriteContext,
|
||||||
};
|
};
|
||||||
let fields_str = try_opt!(write_list(&items.collect::<Vec<_>>(), &fmt));
|
let fields_str = try_opt!(write_list(&items.collect::<Vec<_>>(), &fmt));
|
||||||
|
|
||||||
match context.config.struct_lit_style {
|
let format_on_newline = || {
|
||||||
StructLitStyle::Block if fields_str.contains('\n') => {
|
let inner_indent = make_indent(context.block_indent +
|
||||||
let inner_indent = make_indent(context.block_indent + context.config.tab_spaces);
|
context.config.tab_spaces);
|
||||||
let outer_indent = make_indent(context.block_indent);
|
let outer_indent = make_indent(context.block_indent);
|
||||||
Some(format!("{} {{\n{}{}\n{}}}", path_str, inner_indent, fields_str, outer_indent))
|
Some(format!("{} {{\n{}{}\n{}}}", path_str, inner_indent, fields_str, outer_indent))
|
||||||
}
|
};
|
||||||
|
|
||||||
|
match (context.config.struct_lit_style, context.config.struct_lit_multiline_style) {
|
||||||
|
(StructLitStyle::Block, _) if fields_str.contains('\n') => format_on_newline(),
|
||||||
|
(StructLitStyle::Block, MultilineStyle::ForceMulti) => format_on_newline(),
|
||||||
_ => Some(format!("{} {{ {} }}", path_str, fields_str)),
|
_ => Some(format!("{} {{ {} }}", path_str, fields_str)),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
72
tests/source/struct_lits_multiline.rs
Normal file
72
tests/source/struct_lits_multiline.rs
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
// rustfmt-struct_lit_multiline_style: ForceMulti
|
||||||
|
|
||||||
|
// Struct literal expressions.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Bar;
|
||||||
|
|
||||||
|
// Comment
|
||||||
|
let y = Foo {a: x };
|
||||||
|
|
||||||
|
Foo { a: foo() /* comment*/, /* comment*/ b: bar(), ..something };
|
||||||
|
|
||||||
|
Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { a: foo(), b: bar(), };
|
||||||
|
|
||||||
|
Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { a: foo(), b: bar(), };
|
||||||
|
|
||||||
|
Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo {
|
||||||
|
// Comment
|
||||||
|
a: foo(), // Comment
|
||||||
|
// Comment
|
||||||
|
b: bar(), // Comment
|
||||||
|
};
|
||||||
|
|
||||||
|
Foo { a:Bar,
|
||||||
|
b:foo() };
|
||||||
|
|
||||||
|
Quux { x: if cond { bar(); }, y: baz() };
|
||||||
|
|
||||||
|
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.
|
||||||
|
first: item(),
|
||||||
|
// Praesent et diam eget libero egestas mattis sit amet vitae augue.
|
||||||
|
// Nam tincidunt congue enim, ut porta lorem lacinia consectetur.
|
||||||
|
second: Item
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(Data::MethodCallData(MethodCallData {
|
||||||
|
span: sub_span.unwrap(),
|
||||||
|
scope: self.enclosing_scope(id),
|
||||||
|
ref_id: def_id,
|
||||||
|
decl_id: Some(decl_id),
|
||||||
|
}));
|
||||||
|
|
||||||
|
Diagram { /* o This graph demonstrates how
|
||||||
|
* / \ significant whitespace is
|
||||||
|
* o o preserved.
|
||||||
|
* /|\ \
|
||||||
|
* o o o o */
|
||||||
|
graph: G, }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn matcher() {
|
||||||
|
TagTerminatedByteMatcher {
|
||||||
|
matcher: ByteMatcher {
|
||||||
|
pattern: b"<HTML",
|
||||||
|
mask: b"\xFF\xDF\xDF\xDF\xDF\xFF",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn issue177() {
|
||||||
|
struct Foo<T> { memb: T }
|
||||||
|
let foo = Foo::<i64> { memb: 10 };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn issue201() {
|
||||||
|
let s = S{a:0, .. b};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn issue201_2() {
|
||||||
|
let s = S{a: S2{ .. c}, .. b};
|
||||||
|
}
|
42
tests/source/struct_lits_visual_multiline.rs
Normal file
42
tests/source/struct_lits_visual_multiline.rs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
// rustfmt-struct_lit_style: Visual
|
||||||
|
// rustfmt-struct_lit_multiline_style: ForceMulti
|
||||||
|
|
||||||
|
// Struct literal expressions.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Bar;
|
||||||
|
|
||||||
|
// Comment
|
||||||
|
let y = Foo {a: x };
|
||||||
|
|
||||||
|
Foo { a: foo() /* comment*/, /* comment*/ b: bar(), ..something };
|
||||||
|
|
||||||
|
Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { a: foo(), b: bar(), };
|
||||||
|
|
||||||
|
Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo {
|
||||||
|
// Comment
|
||||||
|
a: foo(), // Comment
|
||||||
|
// Comment
|
||||||
|
b: bar(), // Comment
|
||||||
|
};
|
||||||
|
|
||||||
|
Foo { a:Bar,
|
||||||
|
b:foo() };
|
||||||
|
|
||||||
|
Quux { x: if cond { bar(); }, y: baz() };
|
||||||
|
|
||||||
|
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.
|
||||||
|
first: item(),
|
||||||
|
// Praesent et diam eget libero egestas mattis sit amet vitae augue.
|
||||||
|
// Nam tincidunt congue enim, ut porta lorem lacinia consectetur.
|
||||||
|
second: Item
|
||||||
|
};
|
||||||
|
|
||||||
|
Diagram { /* o This graph demonstrates how
|
||||||
|
* / \ significant whitespace is
|
||||||
|
* o o preserved.
|
||||||
|
* /|\ \
|
||||||
|
* o o o o */
|
||||||
|
graph: G, }
|
||||||
|
}
|
108
tests/target/struct_lits_multiline.rs
Normal file
108
tests/target/struct_lits_multiline.rs
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
// rustfmt-struct_lit_multiline_style: ForceMulti
|
||||||
|
|
||||||
|
// Struct literal expressions.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Bar;
|
||||||
|
|
||||||
|
// Comment
|
||||||
|
let y = Foo {
|
||||||
|
a: x,
|
||||||
|
};
|
||||||
|
|
||||||
|
Foo {
|
||||||
|
a: foo(), // comment
|
||||||
|
// comment
|
||||||
|
b: bar(),
|
||||||
|
..something
|
||||||
|
};
|
||||||
|
|
||||||
|
Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo {
|
||||||
|
a: foo(),
|
||||||
|
b: bar(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo {
|
||||||
|
a: foo(),
|
||||||
|
b: bar(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo {
|
||||||
|
// Comment
|
||||||
|
a: foo(), // Comment
|
||||||
|
// Comment
|
||||||
|
b: bar(), /* Comment */
|
||||||
|
};
|
||||||
|
|
||||||
|
Foo {
|
||||||
|
a: Bar,
|
||||||
|
b: foo(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Quux {
|
||||||
|
x: if cond {
|
||||||
|
bar();
|
||||||
|
},
|
||||||
|
y: baz(),
|
||||||
|
};
|
||||||
|
|
||||||
|
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.
|
||||||
|
first: item(),
|
||||||
|
// Praesent et diam eget libero egestas mattis sit amet vitae augue.
|
||||||
|
// Nam tincidunt congue enim, ut porta lorem lacinia consectetur.
|
||||||
|
second: Item,
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(Data::MethodCallData(MethodCallData {
|
||||||
|
span: sub_span.unwrap(),
|
||||||
|
scope: self.enclosing_scope(id),
|
||||||
|
ref_id: def_id,
|
||||||
|
decl_id: Some(decl_id),
|
||||||
|
}));
|
||||||
|
|
||||||
|
Diagram {
|
||||||
|
// o This graph demonstrates how
|
||||||
|
// / \ significant whitespace is
|
||||||
|
// o o preserved.
|
||||||
|
// /|\ \
|
||||||
|
// o o o o
|
||||||
|
graph: G,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn matcher() {
|
||||||
|
TagTerminatedByteMatcher {
|
||||||
|
matcher: ByteMatcher {
|
||||||
|
pattern: b"<HTML",
|
||||||
|
mask: b"\xFF\xDF\xDF\xDF\xDF\xFF",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn issue177() {
|
||||||
|
struct Foo<T> {
|
||||||
|
memb: T,
|
||||||
|
}
|
||||||
|
let foo = Foo::<i64> {
|
||||||
|
memb: 10,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn issue201() {
|
||||||
|
let s = S {
|
||||||
|
a: 0,
|
||||||
|
..b
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn issue201_2() {
|
||||||
|
let s = S {
|
||||||
|
a: S2 {
|
||||||
|
..c
|
||||||
|
},
|
||||||
|
..b
|
||||||
|
};
|
||||||
|
}
|
61
tests/target/struct_lits_visual_multiline.rs
Normal file
61
tests/target/struct_lits_visual_multiline.rs
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
// rustfmt-struct_lit_style: Visual
|
||||||
|
// rustfmt-struct_lit_multiline_style: ForceMulti
|
||||||
|
|
||||||
|
// Struct literal expressions.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Bar;
|
||||||
|
|
||||||
|
// Comment
|
||||||
|
let y = Foo { a: x };
|
||||||
|
|
||||||
|
Foo { a: foo(), // comment
|
||||||
|
// comment
|
||||||
|
b: bar(),
|
||||||
|
..something };
|
||||||
|
|
||||||
|
Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { a: foo(),
|
||||||
|
b: bar(), };
|
||||||
|
|
||||||
|
Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { // Commen
|
||||||
|
// t
|
||||||
|
a: foo(), /* C
|
||||||
|
* o
|
||||||
|
* m
|
||||||
|
* m
|
||||||
|
* e
|
||||||
|
* n
|
||||||
|
* t */
|
||||||
|
// Commen
|
||||||
|
// t
|
||||||
|
b: bar(), /* C
|
||||||
|
* o
|
||||||
|
* m
|
||||||
|
* m
|
||||||
|
* e
|
||||||
|
* n
|
||||||
|
* t */ };
|
||||||
|
|
||||||
|
Foo { a: Bar,
|
||||||
|
b: foo(), };
|
||||||
|
|
||||||
|
Quux { x: if cond {
|
||||||
|
bar();
|
||||||
|
},
|
||||||
|
y: baz(), };
|
||||||
|
|
||||||
|
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.
|
||||||
|
first: item(),
|
||||||
|
// Praesent et diam eget libero egestas mattis sit amet vitae augue.
|
||||||
|
// Nam tincidunt congue enim, ut porta lorem lacinia consectetur.
|
||||||
|
second: Item, };
|
||||||
|
|
||||||
|
Diagram { // o This graph demonstrates how
|
||||||
|
// / \ significant whitespace is
|
||||||
|
// o o preserved.
|
||||||
|
// /|\ \
|
||||||
|
// o o o o
|
||||||
|
graph: G, }
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue