From 9eefc6fc8d113e80f92de53ae756cb5203e173b1 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Sat, 10 Jun 2017 18:24:23 +0900 Subject: [PATCH] Share codes when rewriting generics --- src/items.rs | 75 ++++++++++++++----- src/types.rs | 25 +++---- tests/target/configs-generics_indent-block.rs | 2 +- tests/target/fn-custom-2.rs | 6 +- tests/target/fn-custom-3.rs | 6 +- 5 files changed, 72 insertions(+), 42 deletions(-) diff --git a/src/items.rs b/src/items.rs index bbbe75ddf780..03ca6f608325 100644 --- a/src/items.rs +++ b/src/items.rs @@ -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(context: &RewriteContext, + items: I, + shape: Shape, + one_line_budget: usize) + -> Option + where I: Iterator +{ + let item_vec = items.collect::>(); + + 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, diff --git a/src/types.rs b/src/types.rs index 7dfc43371789..4e74ea8213f1 100644 --- a/src/types.rs +++ b/src/types.rs @@ -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 { diff --git a/tests/target/configs-generics_indent-block.rs b/tests/target/configs-generics_indent-block.rs index 789243c02c30..848e59c7c0ae 100644 --- a/tests/target/configs-generics_indent-block.rs +++ b/tests/target/configs-generics_indent-block.rs @@ -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, diff --git a/tests/target/fn-custom-2.rs b/tests/target/fn-custom-2.rs index e9ba39f666cb..f0923bd1a853 100644 --- a/tests/target/fn-custom-2.rs +++ b/tests/target/fn-custom-2.rs @@ -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, } diff --git a/tests/target/fn-custom-3.rs b/tests/target/fn-custom-3.rs index a29aac411ba9..4d26c9b69519 100644 --- a/tests/target/fn-custom-3.rs +++ b/tests/target/fn-custom-3.rs @@ -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, }