Avoid allocating small strings in combine_strs_with_missing_comments

This commit is contained in:
topecongiro 2018-02-18 18:22:06 +09:00
parent 61c6c591e4
commit bd813251f1
2 changed files with 40 additions and 25 deletions

View File

@ -10,7 +10,7 @@
// Formatting and tools for comments.
use std::{self, iter};
use std::{self, iter, borrow::Cow};
use syntax::codemap::Span;
@ -154,6 +154,9 @@ pub fn combine_strs_with_missing_comments(
shape: Shape,
allow_extend: bool,
) -> Option<String> {
let mut result =
String::with_capacity(prev_str.len() + next_str.len() + shape.indent.width() + 128);
result.push_str(prev_str);
let mut allow_one_line = !prev_str.contains('\n') && !next_str.contains('\n');
let first_sep = if prev_str.is_empty() || next_str.is_empty() {
""
@ -163,20 +166,18 @@ pub fn combine_strs_with_missing_comments(
let mut one_line_width =
last_line_width(prev_str) + first_line_width(next_str) + first_sep.len();
let indent_str = shape.indent.to_string(context.config);
let config = context.config;
let indent = shape.indent;
let missing_comment = rewrite_missing_comment(span, shape, context)?;
if missing_comment.is_empty() {
if allow_extend && prev_str.len() + first_sep.len() + next_str.len() <= shape.width {
return Some(format!("{}{}{}", prev_str, first_sep, next_str));
} else {
let sep = if prev_str.is_empty() {
String::new()
} else {
String::from("\n") + &indent_str
};
return Some(format!("{}{}{}", prev_str, sep, next_str));
result.push_str(first_sep);
} else if !prev_str.is_empty() {
result.push_str(&indent.to_string_with_newline(config))
}
result.push_str(next_str);
return Some(result);
}
// We have a missing comment between the first expression and the second expression.
@ -193,32 +194,35 @@ pub fn combine_strs_with_missing_comments(
one_line_width -= first_sep.len();
let first_sep = if prev_str.is_empty() || missing_comment.is_empty() {
String::new()
Cow::from("")
} else {
let one_line_width = last_line_width(prev_str) + first_line_width(&missing_comment) + 1;
if prefer_same_line && one_line_width <= shape.width {
String::from(" ")
Cow::from(" ")
} else {
format!("\n{}", indent_str)
indent.to_string_with_newline(config)
}
};
result.push_str(&first_sep);
result.push_str(&missing_comment);
let second_sep = if missing_comment.is_empty() || next_str.is_empty() {
String::new()
Cow::from("")
} else if missing_comment.starts_with("//") {
format!("\n{}", indent_str)
indent.to_string_with_newline(config)
} else {
one_line_width += missing_comment.len() + first_sep.len() + 1;
allow_one_line &= !missing_comment.starts_with("//") && !missing_comment.contains('\n');
if prefer_same_line && allow_one_line && one_line_width <= shape.width {
String::from(" ")
Cow::from(" ")
} else {
format!("\n{}", indent_str)
indent.to_string_with_newline(config)
}
};
Some(format!(
"{}{}{}{}{}",
prev_str, first_sep, missing_comment, second_sep, next_str,
))
result.push_str(&second_sep);
result.push_str(next_str);
Some(result)
}
pub fn rewrite_doc_comment(orig: &str, shape: Shape, config: &Config) -> Option<String> {

View File

@ -25,7 +25,7 @@ pub struct Indent {
// INDENT_BUFFER.len() = 80
const INDENT_BUFFER_LEN: usize = 80;
const INDENT_BUFFER: &str =
" ";
"\n ";
impl Indent {
pub fn new(block_indent: usize, alignment: usize) -> Indent {
Indent {
@ -74,16 +74,27 @@ pub fn width(&self) -> usize {
}
pub fn to_string(&self, config: &Config) -> Cow<'static, str> {
self.to_string_inner(config, 1)
}
pub fn to_string_with_newline(&self, config: &Config) -> Cow<'static, str> {
self.to_string_inner(config, 0)
}
pub fn to_string_inner(&self, config: &Config, offset: usize) -> Cow<'static, str> {
let (num_tabs, num_spaces) = if config.hard_tabs() {
(self.block_indent / config.tab_spaces(), self.alignment)
} else {
(0, self.width())
};
let num_chars = num_tabs + num_spaces;
if num_tabs == 0 && num_chars <= INDENT_BUFFER_LEN {
Cow::from(&INDENT_BUFFER[0..num_chars])
if num_tabs == 0 && num_chars + offset <= INDENT_BUFFER_LEN {
Cow::from(&INDENT_BUFFER[offset..num_chars + 1])
} else {
let mut indent = String::with_capacity(num_chars);
let mut indent = String::with_capacity(num_chars + if offset == 0 { 1 } else { 0 });
if offset == 0 {
indent.push('\n');
}
for _ in 0..num_tabs {
indent.push('\t')
}