Share codes when rewriting generics

This commit is contained in:
topecongiro 2017-06-10 18:24:23 +09:00
parent c879d5ebd7
commit 9eefc6fc8d
5 changed files with 72 additions and 42 deletions

View file

@ -16,7 +16,7 @@ use utils::{format_mutability, format_visibility, contains_skip, end_typaram, wr
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,
DefinitiveListTactic, ListTactic, definitive_tactic, format_item_list};
DefinitiveListTactic, ListTactic, definitive_tactic};
use expr::{is_empty_block, is_simple_block_stmt, rewrite_assign_rhs};
use comment::{FindUncommented, contains_comment, rewrite_comment, recover_comment_removed};
use visitor::FmtVisitor;
@ -2111,21 +2111,13 @@ fn rewrite_generics(context: &RewriteContext,
return Some(String::new());
}
let offset = match context.config.generics_indent() {
IndentStyle::Block => shape.indent.block_only().block_indent(context.config),
// 1 = <
IndentStyle::Visual => shape.indent + 1,
};
let h_budget = try_opt!(shape.width.checked_sub(2));
// FIXME: might need to insert a newline if the generics are really long.
let generics_shape = generics_shape_from_config(context.config, shape, 0);
// Strings for the generics.
let lt_strs = lifetimes
.iter()
.map(|lt| lt.rewrite(context, Shape::legacy(h_budget, offset)));
.map(|lt| lt.rewrite(context, generics_shape));
let ty_strs = tys.iter()
.map(|ty_param| ty_param.rewrite(context, Shape::legacy(h_budget, offset)));
.map(|ty_param| ty_param.rewrite(context, generics_shape));
// Extract comments between generics.
let lt_spans = lifetimes.iter().map(|l| {
@ -2147,21 +2139,64 @@ fn rewrite_generics(context: &RewriteContext,
|&(_, ref str)| str.clone(),
context.codemap.span_after(span, "<"),
span.hi);
let list_str =
try_opt!(format_item_list(items, Shape::legacy(h_budget, offset), context.config));
format_generics_item_list(context, items, generics_shape, generics_shape.width)
}
let result = if context.config.generics_indent() != IndentStyle::Visual &&
list_str.contains('\n') {
pub fn generics_shape_from_config(config: &Config, shape: Shape, offset: usize) -> Shape {
Shape {
// 2 = `<>`
width: shape.width.checked_sub(offset + 2).unwrap_or(0),
..match config.generics_indent() {
IndentStyle::Visual => shape.visual_indent(1 + offset),
IndentStyle::Block => shape.block().block_indent(config.tab_spaces()),
}
}
}
pub fn format_generics_item_list<I>(context: &RewriteContext,
items: I,
shape: Shape,
one_line_budget: usize)
-> Option<String>
where I: Iterator<Item = ListItem>
{
let item_vec = items.collect::<Vec<_>>();
let fmt = ListFormatting {
tactic: definitive_tactic(&item_vec, ListTactic::HorizontalVertical, one_line_budget),
separator: ",",
trailing_separator: if context.config.generics_indent() == IndentStyle::Visual {
SeparatorTactic::Never
} else {
context.config.trailing_comma()
},
shape: shape,
ends_with_newline: false,
config: context.config,
};
let list_str = try_opt!(write_list(&item_vec, &fmt));
Some(wrap_generics_with_angle_brackets(context, &list_str, shape.indent))
}
pub fn wrap_generics_with_angle_brackets(context: &RewriteContext,
list_str: &str,
list_offset: Indent)
-> String {
if context.config.generics_indent() == IndentStyle::Block &&
(list_str.contains('\n') || list_str.ends_with(',')) {
format!("<\n{}{}\n{}>",
offset.to_string(context.config),
list_offset.to_string(context.config),
list_str,
shape.indent.block_only().to_string(context.config))
list_offset
.block_unindent(context.config)
.to_string(context.config))
} else if context.config.spaces_within_angle_brackets() {
format!("< {} >", list_str)
} else {
format!("<{}>", list_str)
};
Some(result)
}
}
fn rewrite_trait_bounds(context: &RewriteContext,

View file

@ -19,7 +19,8 @@ use syntax::symbol::keywords;
use {Shape, Spanned};
use codemap::SpanUtils;
use lists::{format_item_list, itemize_list, format_fn_args};
use items::{format_generics_item_list, generics_shape_from_config};
use lists::{itemize_list, format_fn_args};
use rewrite::{Rewrite, RewriteContext};
use utils::{extra_offset, format_mutability, colon_spaces, wrap_str, mk_sp};
use expr::{rewrite_unary_prefix, rewrite_pair, rewrite_tuple_type};
@ -213,31 +214,25 @@ fn rewrite_segment(path_context: PathContext,
""
};
// 1 for <
let extra_offset = 1 + separator.len();
// 1 for >
// TODO bad visual indent
let list_shape = try_opt!(try_opt!(shape.shrink_left(extra_offset)).sub_width(1))
.visual_indent(0);
let generics_shape =
generics_shape_from_config(context.config, shape, separator.len());
let items = itemize_list(context.codemap,
param_list.into_iter(),
">",
|param| param.get_span().lo,
|param| param.get_span().hi,
|seg| seg.rewrite(context, list_shape),
|seg| seg.rewrite(context, generics_shape),
list_lo,
span_hi);
let list_str = try_opt!(format_item_list(items, list_shape, context.config));
let generics_str = try_opt!(format_generics_item_list(context,
items,
generics_shape,
generics_shape.width));
// Update position of last bracket.
*span_lo = next_span_lo;
if context.config.spaces_within_angle_brackets() && list_str.len() > 0 {
format!("{}< {} >", separator, list_str)
} else {
format!("{}<{}>", separator, list_str)
}
format!("{}{}", separator, generics_str)
}
ast::PathParameters::Parenthesized(ref data) => {
let output = match data.output {

View file

@ -8,7 +8,7 @@ fn lorem<
Amet: Eq = usize,
Adipiscing: Eq = usize,
Consectetur: Eq = usize,
Elit: Eq = usize
Elit: Eq = usize,
>(ipsum: Ipsum,
dolor: Dolor,
sit: Sit,

View file

@ -16,7 +16,7 @@ fn foo(
fn bar<
'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb,
TTTTTTTTTTTTT,
UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW
UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW,
>(
a: Aaaaaaaaaaaaaaa,
) {
@ -51,7 +51,7 @@ impl Foo {
fn bar<
'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb,
TTTTTTTTTTTTT,
UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW
UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW,
>(
a: Aaaaaaaaaaaaaaa,
) {
@ -69,7 +69,7 @@ struct Foo<
TTTTTTTTTTTTTTTTTTTTTTTTTTTT,
UUUUUUUUUUUUUUUUUUUUUU,
VVVVVVVVVVVVVVVVVVVVVVVVVVV,
WWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWW,
> {
foo: Foo,
}

View file

@ -16,7 +16,7 @@ fn foo(
fn bar<
'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb,
TTTTTTTTTTTTT,
UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW
UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW,
>(
a: Aaaaaaaaaaaaaaa,
) {
@ -53,7 +53,7 @@ impl Foo {
fn bar<
'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb,
TTTTTTTTTTTTT,
UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW
UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW,
>(
a: Aaaaaaaaaaaaaaa,
) {
@ -65,7 +65,7 @@ struct Foo<
TTTTTTTTTTTTTTTTTTTTTTTTTTTT,
UUUUUUUUUUUUUUUUUUUUUU,
VVVVVVVVVVVVVVVVVVVVVVVVVVV,
WWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWW,
> {
foo: Foo,
}