Use Indent::to_string_with_newline to avoid unnecessary allocation

This commit is contained in:
topecongiro 2018-02-19 12:47:54 +09:00
parent 9d47e7370e
commit 125e7124e7
8 changed files with 109 additions and 117 deletions

View File

@ -67,8 +67,10 @@ use shape::Shape;
use utils::{first_line_width, last_line_extendable, last_line_width, mk_sp,
trimmed_last_line_width, wrap_str};
use std::borrow::Cow;
use std::cmp::min;
use std::iter;
use syntax::{ast, ptr};
use syntax::codemap::Span;
@ -246,13 +248,13 @@ pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) -
let connector = if fits_single_line && !parent_rewrite_contains_newline {
// Yay, we can put everything on one line.
String::new()
Cow::from("")
} else {
// Use new lines.
if context.force_one_line_chain {
return None;
}
format!("\n{}", nested_shape.indent.to_string(context.config))
nested_shape.indent.to_string_with_newline(context.config)
};
let first_connector = if is_small_parent || fits_single_line
@ -261,7 +263,7 @@ pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) -
{
""
} else {
connector.as_str()
&connector
};
let result = if is_small_parent && rewrites.len() > 1 {

View File

@ -319,7 +319,7 @@ fn rewrite_comment_inner(
.width
.checked_sub(closer.len() + opener.len())
.unwrap_or(1);
let indent_str = shape.indent.to_string(config);
let indent_str = shape.indent.to_string_with_newline(config);
let fmt_indent = shape.indent + (opener.len() - line_start.len());
let mut fmt = StringFormat {
opener: "",
@ -360,7 +360,7 @@ fn rewrite_comment_inner(
let mut code_block_buffer = String::with_capacity(128);
let mut is_prev_line_multi_line = false;
let mut inside_code_block = false;
let comment_line_separator = format!("\n{}{}", indent_str, line_start);
let comment_line_separator = format!("{}{}", indent_str, line_start);
let join_code_block_with_comment_line_separator = |s: &str| {
let mut result = String::with_capacity(s.len() + 128);
let mut iter = s.lines().peekable();
@ -408,7 +408,6 @@ fn rewrite_comment_inner(
} else if is_prev_line_multi_line && !line.is_empty() {
result.push(' ')
} else if is_last && !closer.is_empty() && line.is_empty() {
result.push('\n');
result.push_str(&indent_str);
} else {
result.push_str(&comment_line_separator);
@ -520,9 +519,9 @@ pub fn recover_missing_comment_in_span(
let force_new_line_before_comment =
missing_snippet[..pos].contains('\n') || total_width > context.config.max_width();
let sep = if force_new_line_before_comment {
format!("\n{}", shape.indent.to_string(context.config))
shape.indent.to_string_with_newline(context.config)
} else {
String::from(" ")
Cow::from(" ")
};
Some(format!("{}{}", sep, missing_comment))
}
@ -705,12 +704,6 @@ impl RichChar for (usize, char) {
}
}
impl RichChar for (char, usize) {
fn get_char(&self) -> char {
self.0
}
}
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
enum CharClassesStatus {
Normal,

View File

@ -392,10 +392,10 @@ where
rhs_shape = rhs_shape.offset_left(infix.len())?;
}
let rhs_result = rhs.rewrite(context, rhs_shape)?;
let indent_str = rhs_shape.indent.to_string(context.config);
let indent_str = rhs_shape.indent.to_string_with_newline(context.config);
let infix_with_sep = match separator_place {
SeparatorPlace::Back => format!("{}\n{}", infix, indent_str),
SeparatorPlace::Front => format!("\n{}{}", indent_str, infix),
SeparatorPlace::Back => format!("{}{}", infix, indent_str),
SeparatorPlace::Front => format!("{}{}", indent_str, infix),
};
Some(format!(
"{}{}{}{}",
@ -489,10 +489,10 @@ pub fn rewrite_array<T: Rewrite + Spanned + ToExpr>(
}
} else {
format!(
"[\n{}{}\n{}]",
nested_shape.indent.to_string(context.config),
"[{}{}{}]",
nested_shape.indent.to_string_with_newline(context.config),
list_str,
shape.block().indent.to_string(context.config)
shape.block().indent.to_string_with_newline(context.config)
)
};
@ -1065,7 +1065,7 @@ impl<'a> Rewrite for ControlFlow<'a> {
fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
debug!("ControlFlow::rewrite {:?} {:?}", self, shape);
let alt_block_sep = String::from("\n") + &shape.indent.to_string(context.config);
let alt_block_sep = &shape.indent.to_string_with_newline(context.config);
let (cond_str, used_width) = self.rewrite_cond(context, shape, &alt_block_sep)?;
// If `used_width` is 0, it indicates that whole control flow is written in a single line.
if used_width == 0 {
@ -1185,9 +1185,9 @@ fn rewrite_label(opt_label: Option<ast::Label>) -> Cow<'static, str> {
fn extract_comment(span: Span, context: &RewriteContext, shape: Shape) -> Option<String> {
match rewrite_missing_comment(span, shape, context) {
Some(ref comment) if !comment.is_empty() => Some(format!(
"\n{indent}{}\n{indent}",
"{indent}{}{indent}",
comment,
indent = shape.indent.to_string(context.config)
indent = shape.indent.to_string_with_newline(context.config)
)),
_ => None,
}
@ -1271,7 +1271,7 @@ fn rewrite_match(
IndentStyle::Block => cond_shape.offset_left(6)?,
};
let cond_str = cond.rewrite(context, cond_shape)?;
let alt_block_sep = String::from("\n") + &shape.indent.to_string(context.config);
let alt_block_sep = &shape.indent.to_string_with_newline(context.config);
let block_sep = match context.config.control_brace_style() {
ControlBraceStyle::AlwaysNextLine => &alt_block_sep,
_ if last_line_extendable(&cond_str) => " ",
@ -1562,8 +1562,7 @@ fn rewrite_match_body(
};
let comma = arm_comma(context.config, body, is_last);
let alt_block_sep = String::from("\n") + &shape.indent.to_string(context.config);
let alt_block_sep = alt_block_sep.as_str();
let alt_block_sep = &shape.indent.to_string_with_newline(context.config);
let combine_orig_body = |body_str: &str| {
let block_sep = match context.config.control_brace_style() {
@ -1583,31 +1582,31 @@ fn rewrite_match_body(
let combine_next_line_body = |body_str: &str| {
if is_block {
return Some(format!(
"{} =>\n{}{}",
"{} =>{}{}",
pats_str,
next_line_indent.to_string(context.config),
next_line_indent.to_string_with_newline(context.config),
body_str
));
}
let indent_str = shape.indent.to_string(context.config);
let nested_indent_str = next_line_indent.to_string(context.config);
let indent_str = shape.indent.to_string_with_newline(context.config);
let nested_indent_str = next_line_indent.to_string_with_newline(context.config);
let (body_prefix, body_suffix) = if context.config.match_arm_blocks() {
let comma = if context.config.match_block_trailing_comma() {
","
} else {
""
};
("{", format!("\n{}}}{}", indent_str, comma))
("{", format!("{}}}{}", indent_str, comma))
} else {
("", String::from(","))
};
let block_sep = match context.config.control_brace_style() {
ControlBraceStyle::AlwaysNextLine => format!("{}{}\n", alt_block_sep, body_prefix),
_ if body_prefix.is_empty() => "\n".to_owned(),
_ if forbid_same_line => format!("{}{}\n", alt_block_sep, body_prefix),
_ => format!(" {}\n", body_prefix),
ControlBraceStyle::AlwaysNextLine => format!("{}{}", alt_block_sep, body_prefix),
_ if body_prefix.is_empty() => "".to_owned(),
_ if forbid_same_line => format!("{}{}", alt_block_sep, body_prefix),
_ => format!(" {}", body_prefix),
} + &nested_indent_str;
Some(format!(
@ -1697,8 +1696,8 @@ fn rewrite_guard(
if let Some(cond_shape) = cond_shape {
if let Some(cond_str) = guard.rewrite(context, cond_shape) {
return Some(format!(
"\n{}if {}",
cond_shape.indent.to_string(context.config),
"{}if {}",
cond_shape.indent.to_string_with_newline(context.config),
cond_str
));
}
@ -1749,9 +1748,9 @@ fn rewrite_pat_expr(
let nested_shape = shape
.block_indent(context.config.tab_spaces())
.with_max_width(context.config);
let nested_indent_str = nested_shape.indent.to_string(context.config);
let nested_indent_str = nested_shape.indent.to_string_with_newline(context.config);
expr.rewrite(context, nested_shape)
.map(|expr_rw| format!("\n{}{}", nested_indent_str, expr_rw))
.map(|expr_rw| format!("{}{}", nested_indent_str, expr_rw))
}
fn can_extend_match_arm_body(body: &ast::Expr) -> bool {
@ -2322,18 +2321,28 @@ pub fn wrap_args_with_parens(
|| (context.inside_macro && !args_str.contains('\n')
&& args_str.len() + paren_overhead(context) <= shape.width) || is_extendable
{
let mut result = String::with_capacity(args_str.len() + 4);
if context.config.spaces_within_parens_and_brackets() && !args_str.is_empty() {
format!("( {} )", args_str)
result.push_str("( ");
result.push_str(args_str);
result.push_str(" )");
} else {
format!("({})", args_str)
result.push_str("(");
result.push_str(args_str);
result.push_str(")");
}
result
} else {
format!(
"(\n{}{}\n{})",
nested_shape.indent.to_string(context.config),
args_str,
shape.block().indent.to_string(context.config)
)
let nested_indent_str = nested_shape.indent.to_string_with_newline(context.config);
let indent_str = shape.block().indent.to_string_with_newline(context.config);
let mut result =
String::with_capacity(args_str.len() + 2 + indent_str.len() + nested_indent_str.len());
result.push_str("(");
result.push_str(&nested_indent_str);
result.push_str(args_str);
result.push_str(&indent_str);
result.push_str(")");
result
}
}
@ -2425,17 +2434,17 @@ fn rewrite_index(
let new_index_rw = index.rewrite(context, index_shape);
match (orig_index_rw, new_index_rw) {
(_, Some(ref new_index_str)) if !new_index_str.contains('\n') => Some(format!(
"{}\n{}{}{}{}",
"{}{}{}{}{}",
expr_str,
indent.to_string(context.config),
indent.to_string_with_newline(context.config),
lbr,
new_index_str,
rbr
)),
(None, Some(ref new_index_str)) => Some(format!(
"{}\n{}{}{}{}",
"{}{}{}{}{}",
expr_str,
indent.to_string(context.config),
indent.to_string_with_newline(context.config),
lbr,
new_index_str,
rbr
@ -2562,10 +2571,10 @@ pub fn wrap_struct_field(
|| fields_str.len() > one_line_width)
{
format!(
"\n{}{}\n{}",
nested_shape.indent.to_string(context.config),
"{}{}{}",
nested_shape.indent.to_string_with_newline(context.config),
fields_str,
shape.indent.to_string(context.config)
shape.indent.to_string_with_newline(context.config)
)
} else {
// One liner or visual indent.
@ -2588,7 +2597,7 @@ pub fn rewrite_field(
}
let mut attrs_str = field.attrs.rewrite(context, shape)?;
if !attrs_str.is_empty() {
attrs_str.push_str(&format!("\n{}", shape.indent.to_string(context.config)));
attrs_str.push_str(&shape.indent.to_string_with_newline(context.config));
};
let name = field.ident.node.to_string();
if field.is_shorthand {
@ -2847,7 +2856,7 @@ pub fn choose_rhs<R: Rewrite>(
Shape::indented(shape.indent.block_indent(context.config), context.config)
.sub_width(shape.rhs_overhead(context.config))?;
let new_rhs = expr.rewrite(context, new_shape);
let new_indent_str = &new_shape.indent.to_string(context.config);
let new_indent_str = &new_shape.indent.to_string_with_newline(context.config);
match (orig_rhs, new_rhs) {
(Some(ref orig_rhs), Some(ref new_rhs))
@ -2857,9 +2866,9 @@ pub fn choose_rhs<R: Rewrite>(
Some(format!(" {}", orig_rhs))
}
(Some(ref orig_rhs), Some(ref new_rhs)) if prefer_next_line(orig_rhs, new_rhs) => {
Some(format!("\n{}{}", new_indent_str, new_rhs))
Some(format!("{}{}", new_indent_str, new_rhs))
}
(None, Some(ref new_rhs)) => Some(format!("\n{}{}", new_indent_str, new_rhs)),
(None, Some(ref new_rhs)) => Some(format!("{}{}", new_indent_str, new_rhs)),
(None, None) => None,
(Some(ref orig_rhs), _) => Some(format!(" {}", orig_rhs)),
}

View File

@ -318,8 +318,7 @@ impl<'a> FmtVisitor<'a> {
// start of the body, but we need more spans from the compiler to solve
// this.
if newline_brace {
result.push('\n');
result.push_str(&indent.to_string(self.config));
result.push_str(&indent.to_string_with_newline(self.config));
} else {
result.push(' ');
}
@ -471,8 +470,7 @@ impl<'a> FmtVisitor<'a> {
return None;
}
let mut result = String::with_capacity(1024);
result.push('\n');
let indentation = self.block_indent.to_string(self.config);
let indentation = self.block_indent.to_string_with_newline(self.config);
result.push_str(&indentation);
let itemize_list_with = |one_line_width: usize| {
@ -571,8 +569,7 @@ pub fn format_impl(
if let ast::ItemKind::Impl(_, _, _, ref generics, _, ref self_ty, ref items) = item.node {
let mut result = String::with_capacity(128);
let ref_and_type = format_impl_ref_and_type(context, item, offset)?;
let indent_str = offset.to_string(context.config);
let sep = format!("\n{}", &indent_str);
let sep = offset.to_string_with_newline(context.config);
result.push_str(&ref_and_type);
let where_budget = if result.contains('\n') {
@ -623,10 +620,9 @@ pub fn format_impl(
}
if !where_clause_str.is_empty() && !where_clause_str.contains('\n') {
result.push('\n');
let width = offset.block_indent + context.config.tab_spaces() - 1;
let where_indent = Indent::new(0, width);
result.push_str(&where_indent.to_string(context.config));
result.push_str(&where_indent.to_string_with_newline(context.config));
}
result.push_str(&where_clause_str);
@ -662,13 +658,11 @@ pub fn format_impl(
visitor.format_missing(item.span.hi() - BytePos(1));
let inner_indent_str = visitor.block_indent.to_string(context.config);
let outer_indent_str = offset.block_only().to_string(context.config);
let inner_indent_str = visitor.block_indent.to_string_with_newline(context.config);
let outer_indent_str = offset.block_only().to_string_with_newline(context.config);
result.push('\n');
result.push_str(&inner_indent_str);
result.push_str(visitor.buffer.to_string().trim());
result.push('\n');
result.push_str(&outer_indent_str);
}
@ -957,9 +951,8 @@ pub fn format_trait(context: &RewriteContext, item: &ast::Item, offset: Indent)
if offset.width() + last_line_width(&result) + trait_bound_str.len()
> context.config.comment_width()
{
result.push('\n');
let trait_indent = offset.block_only().block_indent(context.config);
result.push_str(&trait_indent.to_string(context.config));
result.push_str(&trait_indent.to_string_with_newline(context.config));
}
result.push_str(&trait_bound_str);
@ -995,10 +988,9 @@ pub fn format_trait(context: &RewriteContext, item: &ast::Item, offset: Indent)
&& last_line_width(&result) + where_clause_str.len() + offset.width()
> context.config.comment_width()
{
result.push('\n');
let width = offset.block_indent + context.config.tab_spaces() - 1;
let where_indent = Indent::new(0, width);
result.push_str(&where_indent.to_string(context.config));
result.push_str(&where_indent.to_string_with_newline(context.config));
}
result.push_str(&where_clause_str);
@ -1026,20 +1018,17 @@ pub fn format_trait(context: &RewriteContext, item: &ast::Item, offset: Indent)
match context.config.brace_style() {
_ if last_line_contains_single_line_comment(&result) => {
result.push('\n');
result.push_str(&offset.to_string(context.config));
result.push_str(&offset.to_string_with_newline(context.config));
}
BraceStyle::AlwaysNextLine => {
result.push('\n');
result.push_str(&offset.to_string(context.config));
result.push_str(&offset.to_string_with_newline(context.config));
}
BraceStyle::PreferSameLine => result.push(' '),
BraceStyle::SameLineWhere => {
if !where_clause_str.is_empty()
&& (!trait_items.is_empty() || result.contains('\n'))
{
result.push('\n');
result.push_str(&offset.to_string(context.config));
result.push_str(&offset.to_string_with_newline(context.config));
} else {
result.push(' ');
}
@ -1061,13 +1050,11 @@ pub fn format_trait(context: &RewriteContext, item: &ast::Item, offset: Indent)
visitor.format_missing(item.span.hi() - BytePos(1));
let inner_indent_str = visitor.block_indent.to_string(context.config);
let outer_indent_str = offset.block_only().to_string(context.config);
let inner_indent_str = visitor.block_indent.to_string_with_newline(context.config);
let outer_indent_str = offset.block_only().to_string_with_newline(context.config);
result.push('\n');
result.push_str(&inner_indent_str);
result.push_str(visitor.buffer.to_string().trim());
result.push('\n');
result.push_str(&outer_indent_str);
} else if result.contains('\n') {
result.push('\n');
@ -1395,7 +1382,10 @@ pub fn rewrite_type_alias(
if where_clause_str.is_empty() {
result.push_str(" =");
} else {
result.push_str(&format!("\n{}=", indent.to_string(context.config)));
result.push_str(&format!(
"{}=",
indent.to_string_with_newline(context.config)
));
}
// 1 = ";"
@ -1589,7 +1579,11 @@ fn rewrite_static(
let nested_indent = offset.block_indent(context.config);
let nested_shape = Shape::indented(nested_indent, context.config);
let ty_str = static_parts.ty.rewrite(context, nested_shape)?;
format!("\n{}{}", nested_indent.to_string(context.config), ty_str)
format!(
"{}{}",
nested_indent.to_string_with_newline(context.config),
ty_str
)
}
};
@ -1866,8 +1860,7 @@ fn rewrite_fn_base(
} else {
result.push_str("(");
if context.config.indent_style() == IndentStyle::Visual {
result.push('\n');
result.push_str(&arg_indent.to_string(context.config));
result.push_str(&arg_indent.to_string_with_newline(context.config));
}
}
} else {
@ -1923,11 +1916,9 @@ fn rewrite_fn_base(
let mut args_last_line_contains_comment = false;
if put_args_in_block {
arg_indent = indent.block_indent(context.config);
result.push('\n');
result.push_str(&arg_indent.to_string(context.config));
result.push_str(&arg_indent.to_string_with_newline(context.config));
result.push_str(&arg_str);
result.push('\n');
result.push_str(&indent.to_string(context.config));
result.push_str(&indent.to_string_with_newline(context.config));
result.push(')');
} else {
result.push_str(&arg_str);
@ -1948,8 +1939,7 @@ fn rewrite_fn_base(
.map_or(false, |last_line| last_line.contains("//"))
{
args_last_line_contains_comment = true;
result.push('\n');
result.push_str(&arg_indent.to_string(context.config));
result.push_str(&arg_indent.to_string_with_newline(context.config));
}
result.push(')');
}
@ -1988,8 +1978,7 @@ fn rewrite_fn_base(
arg_indent
};
result.push('\n');
result.push_str(&indent.to_string(context.config));
result.push_str(&indent.to_string_with_newline(context.config));
indent
} else {
result.push(' ');
@ -2488,9 +2477,9 @@ fn rewrite_where_clause_rfc_style(
rewrite_comments_before_after_where(context, span_before, span_after, shape)?;
let starting_newline = if where_clause_option.snuggle && comment_before.is_empty() {
" ".to_owned()
Cow::from(" ")
} else {
"\n".to_owned() + &block_shape.indent.to_string(context.config)
block_shape.indent.to_string_with_newline(context.config)
};
let clause_shape = block_shape.block_left(context.config.tab_spaces())?;
@ -2544,9 +2533,9 @@ fn rewrite_where_clause_rfc_style(
let comment_separator = |comment: &str, shape: Shape| {
if comment.is_empty() {
String::new()
Cow::from("")
} else {
format!("\n{}", shape.indent.to_string(context.config))
shape.indent.to_string_with_newline(context.config)
}
};
let newline_before_where = comment_separator(&comment_before, shape);
@ -2557,9 +2546,9 @@ fn rewrite_where_clause_rfc_style(
&& comment_after.is_empty() && !preds_str.contains('\n')
&& 6 + preds_str.len() <= shape.width || where_single_line
{
String::from(" ")
Cow::from(" ")
} else {
format!("\n{}", clause_shape.indent.to_string(context.config))
clause_shape.indent.to_string_with_newline(context.config)
};
Some(format!(
"{}{}{}where{}{}{}{}",
@ -2817,10 +2806,10 @@ impl Rewrite for ast::ForeignItem {
ty.rewrite(context, shape).map(|ty_str| {
// 1 = space between prefix and type.
let sep = if prefix.len() + ty_str.len() + 1 <= shape.width {
String::from(" ")
Cow::from(" ")
} else {
let nested_indent = shape.indent.block_indent(context.config);
format!("\n{}", nested_indent.to_string(context.config))
nested_indent.to_string_with_newline(context.config)
};
format!("{}{}{};", prefix, sep, ty_str)
})

View File

@ -250,14 +250,14 @@ pub fn rewrite_macro(
Some(format!("{}{}{}; {}{}", macro_name, lbr, lhs, rhs, rbr))
} else {
Some(format!(
"{}{}\n{}{};\n{}{}\n{}{}",
"{}{}{}{};{}{}{}{}",
macro_name,
lbr,
nested_shape.indent.to_string(context.config),
nested_shape.indent.to_string_with_newline(context.config),
lhs,
nested_shape.indent.to_string(context.config),
nested_shape.indent.to_string_with_newline(context.config),
rhs,
shape.indent.to_string(context.config),
shape.indent.to_string_with_newline(context.config),
rbr
))
}
@ -350,15 +350,14 @@ pub fn rewrite_macro_def(
};
if multi_branch_style {
result += " {\n";
result += &arm_shape.indent.to_string(context.config);
result += " {";
result += &arm_shape.indent.to_string_with_newline(context.config);
}
result += write_list(&branch_items, &fmt)?.as_str();
if multi_branch_style {
result += "\n";
result += &indent.to_string(context.config);
result += &indent.to_string_with_newline(context.config);
result += "}";
}

View File

@ -55,7 +55,7 @@ pub fn rewrite_string<'a>(
let graphemes = UnicodeSegmentation::graphemes(&*stripped_str, false).collect::<Vec<&str>>();
let shape = fmt.shape;
let indent = shape.indent.to_string(fmt.config);
let indent = shape.indent.to_string_with_newline(fmt.config);
let punctuation = ":,;.";
// `cur_start` is the position in `orig` of the start of the current line.
@ -133,7 +133,6 @@ pub fn rewrite_string<'a>(
result.push_str(line);
result.push_str(fmt.line_end);
result.push('\n');
result.push_str(&indent);
result.push_str(fmt.line_start);

View File

@ -784,7 +784,7 @@ pub fn join_bounds(context: &RewriteContext, shape: Shape, type_strs: &[String])
let result = type_strs.join(joiner);
if result.contains('\n') || result.len() > shape.width {
let joiner_indent = shape.indent.block_indent(context.config);
let joiner = format!("\n{}+ ", joiner_indent.to_string(context.config));
let joiner = format!("{}+ ", joiner_indent.to_string_with_newline(context.config));
type_strs.join(&joiner)
} else {
result

View File

@ -674,8 +674,9 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
if is_internal {
match self.config.brace_style() {
BraceStyle::AlwaysNextLine => {
let sep_str = format!("\n{}{{", self.block_indent.to_string(self.config));
self.push_str(&sep_str);
let indent_str = self.block_indent.to_string_with_newline(self.config);
self.push_str(&indent_str);
self.push_str("{");
}
_ => self.push_str(" {"),
}