Keep track of line number in visitor

This commit is contained in:
topecongiro 2017-12-08 16:59:04 +09:00
parent 97fd517593
commit 5e6bb3edb0
5 changed files with 57 additions and 46 deletions

View File

@ -285,7 +285,7 @@ impl<'a> FmtVisitor<'a> {
}
Some(ref s) => {
self.format_missing_with_indent(source!(self, span).lo());
self.buffer.push_str(s);
self.push_str(s);
self.last_pos = source!(self, span).hi();
}
None => {

View File

@ -240,12 +240,12 @@ impl<'a> FnSig<'a> {
impl<'a> FmtVisitor<'a> {
fn format_item(&mut self, item: Item) {
self.buffer.push_str(&item.abi);
self.push_str(&item.abi);
let snippet = self.snippet(item.span);
let brace_pos = snippet.find_uncommented("{").unwrap();
self.buffer.push_str("{");
self.push_str("{");
if !item.body.is_empty() || contains_comment(&snippet[brace_pos..]) {
// FIXME: this skips comments between the extern keyword and the opening
// brace.
@ -255,9 +255,8 @@ impl<'a> FmtVisitor<'a> {
if item.body.is_empty() {
self.format_missing_no_indent(item.span.hi() - BytePos(1));
self.block_indent = self.block_indent.block_unindent(self.config);
self.buffer
.push_str(&self.block_indent.to_string(self.config));
let indent_str = self.block_indent.to_string(self.config);
self.push_str(&indent_str);
} else {
for item in &item.body {
self.format_body_element(item);
@ -268,7 +267,7 @@ impl<'a> FmtVisitor<'a> {
}
}
self.buffer.push_str("}");
self.push_str("}");
self.last_pos = item.span.hi();
}
@ -423,7 +422,7 @@ impl<'a> FmtVisitor<'a> {
span: Span,
) {
let enum_header = format_header("enum ", ident, vis);
self.buffer.push_str(&enum_header);
self.push_str(&enum_header);
let enum_snippet = self.snippet(span);
let brace_pos = enum_snippet.find_uncommented("{").unwrap();
@ -441,23 +440,23 @@ impl<'a> FmtVisitor<'a> {
mk_sp(span.lo(), body_start),
last_line_width(&enum_header),
).unwrap();
self.buffer.push_str(&generics_str);
self.push_str(&generics_str);
self.last_pos = body_start;
self.block_indent = self.block_indent.block_indent(self.config);
let variant_list = self.format_variant_list(enum_def, body_start, span.hi() - BytePos(1));
match variant_list {
Some(ref body_str) => self.buffer.push_str(body_str),
Some(ref body_str) => self.push_str(body_str),
None => self.format_missing_no_indent(span.hi() - BytePos(1)),
}
self.block_indent = self.block_indent.block_unindent(self.config);
if variant_list.is_some() || contains_comment(&enum_snippet[brace_pos..]) {
self.buffer
.push_str(&self.block_indent.to_string(self.config));
let indent_str = self.block_indent.to_string(self.config);
self.push_str(&indent_str);
}
self.buffer.push_str("}");
self.push_str("}");
self.last_pos = span.hi();
}

View File

@ -338,6 +338,11 @@ where
visitor.format_separate_mod(module, &*filemap);
};
assert_eq!(
visitor.line_number,
::utils::count_newlines(&format!("{}", visitor.buffer))
);
has_diff |= match after_file(path_str, &mut visitor.buffer) {
Ok(result) => result,
Err(e) => {

View File

@ -28,27 +28,25 @@ impl<'a> FmtVisitor<'a> {
// TODO these format_missing methods are ugly. Refactor and add unit tests
// for the central whitespace stripping loop.
pub fn format_missing(&mut self, end: BytePos) {
self.format_missing_inner(end, |this, last_snippet, _| {
this.buffer.push_str(last_snippet)
})
self.format_missing_inner(end, |this, last_snippet, _| this.push_str(last_snippet))
}
pub fn format_missing_with_indent(&mut self, end: BytePos) {
let config = self.config;
self.format_missing_inner(end, |this, last_snippet, snippet| {
this.buffer.push_str(last_snippet.trim_right());
this.push_str(last_snippet.trim_right());
if last_snippet == snippet && !this.output_at_start() {
// No new lines in the snippet.
this.buffer.push_str("\n");
this.push_str("\n");
}
let indent = this.block_indent.to_string(config);
this.buffer.push_str(&indent);
this.push_str(&indent);
})
}
pub fn format_missing_no_indent(&mut self, end: BytePos) {
self.format_missing_inner(end, |this, last_snippet, _| {
this.buffer.push_str(last_snippet.trim_right());
this.push_str(last_snippet.trim_right());
})
}
@ -97,7 +95,7 @@ impl<'a> FmtVisitor<'a> {
newline_count = newline_lower_bound;
}
let blank_lines: String = repeat('\n').take(newline_count).collect();
self.buffer.push_str(&blank_lines);
self.push_str(&blank_lines);
}
fn write_snippet<F>(&mut self, span: Span, process_last_snippet: F)
@ -154,12 +152,12 @@ impl<'a> FmtVisitor<'a> {
if status.rewrite_next_comment {
if fix_indent {
if let Some('{') = last_char {
self.buffer.push_str("\n");
self.push_str("\n");
}
self.buffer
.push_str(&self.block_indent.to_string(self.config));
let indent_str = self.block_indent.to_string(self.config);
self.push_str(&indent_str);
} else {
self.buffer.push_str(" ");
self.push_str(" ");
}
let comment_width = ::std::cmp::min(
@ -170,7 +168,7 @@ impl<'a> FmtVisitor<'a> {
let comment_shape = Shape::legacy(comment_width, comment_indent);
let comment_str = rewrite_comment(subslice, false, comment_shape, self.config)
.unwrap_or_else(|| String::from(subslice));
self.buffer.push_str(&comment_str);
self.push_str(&comment_str);
status.last_wspace = None;
status.line_start = offset + subslice.len();
@ -183,13 +181,13 @@ impl<'a> FmtVisitor<'a> {
.any(|s| s.len() >= 2 && &s[0..2] == "/*")
{
// Add a newline after line comments
self.buffer.push_str("\n");
self.push_str("\n");
}
} else if status.line_start <= snippet.len() {
// For other comments add a newline if there isn't one at the end already
match snippet[status.line_start..].chars().next() {
Some('\n') | Some('\r') => (),
_ => self.buffer.push_str("\n"),
_ => self.push_str("\n"),
}
}
@ -277,10 +275,10 @@ impl<'a> FmtVisitor<'a> {
}
if let Some(lw) = status.last_wspace {
self.buffer.push_str(&snippet[status.line_start..lw]);
self.buffer.push_str("\n");
self.push_str(&snippet[status.line_start..lw]);
self.push_str("\n");
} else {
self.buffer.push_str(&snippet[status.line_start..i + 1]);
self.push_str(&snippet[status.line_start..i + 1]);
}
status.cur_line += 1;
@ -306,7 +304,7 @@ impl<'a> FmtVisitor<'a> {
let remaining = snippet[status.line_start..subslice.len() + offset].trim();
if !remaining.is_empty() {
self.buffer.push_str(remaining);
self.push_str(remaining);
status.line_start = subslice.len() + offset;
status.rewrite_next_comment = true;
}

View File

@ -81,6 +81,7 @@ pub struct FmtVisitor<'a> {
pub config: &'a Config,
pub is_if_else_block: bool,
pub snippet_provider: &'a SnippetProvider<'a>,
pub line_number: usize,
}
impl<'b, 'a: 'b> FmtVisitor<'a> {
@ -132,7 +133,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
self.last_pos = self.last_pos + brace_compensation;
self.block_indent = self.block_indent.block_indent(self.config);
self.buffer.push_str("{");
self.push_str("{");
if self.config.remove_blank_lines_at_start_or_end_of_block() {
if let Some(first_stmt) = b.stmts.first() {
@ -195,7 +196,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
if !b.stmts.is_empty() {
if let Some(expr) = utils::stmt_expr(&b.stmts[b.stmts.len() - 1]) {
if utils::semicolon_for_expr(&self.get_context(), expr) {
self.buffer.push_str(";");
self.push_str(";");
}
}
}
@ -255,7 +256,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
self.config.tab_spaces()
};
self.buffer.truncate(total_len - chars_too_many);
self.buffer.push_str("}");
self.push_str("}");
self.block_indent = self.block_indent.block_unindent(self.config);
}
@ -288,7 +289,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
if let Some(fn_str) = rewrite {
self.format_missing_with_indent(source!(self, s).lo());
self.buffer.push_str(&fn_str);
self.push_str(&fn_str);
if let Some(c) = fn_str.chars().last() {
if c == '}' {
self.last_pos = source!(self, block.span).hi();
@ -519,13 +520,18 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
self.push_rewrite(mac.span, rewrite);
}
pub fn push_str(&mut self, s: &str) {
self.line_number += count_newlines(s);
self.buffer.push_str(s);
}
pub fn push_rewrite(&mut self, span: Span, rewrite: Option<String>) {
self.format_missing_with_indent(source!(self, span).lo());
if let Some(ref s) = rewrite {
self.buffer.push_str(s);
self.push_str(s);
} else {
let snippet = self.snippet(span);
self.buffer.push_str(snippet);
self.push_str(snippet);
}
self.last_pos = source!(self, span).hi();
}
@ -548,6 +554,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
config: config,
is_if_else_block: false,
snippet_provider: snippet_provider,
line_number: 0,
}
}
@ -692,15 +699,17 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
let is_internal = !(inner_span.lo().0 == 0 && inner_span.hi().0 == 0)
&& local_file_name == self.codemap.span_to_filename(inner_span);
self.buffer.push_str(&*utils::format_visibility(vis));
self.buffer.push_str("mod ");
self.buffer.push_str(&ident.to_string());
self.push_str(&*utils::format_visibility(vis));
self.push_str("mod ");
self.push_str(&ident.to_string());
if is_internal {
match self.config.brace_style() {
BraceStyle::AlwaysNextLine => self.buffer
.push_str(&format!("\n{}{{", self.block_indent.to_string(self.config))),
_ => self.buffer.push_str(" {"),
BraceStyle::AlwaysNextLine => {
let sep_str = format!("\n{}{{", self.block_indent.to_string(self.config));
self.push_str(&sep_str);
}
_ => self.push_str(" {"),
}
// Hackery to account for the closing }.
let mod_lo = self.codemap.span_after(source!(self, s), "{");
@ -708,7 +717,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
self.snippet(mk_sp(mod_lo, source!(self, m.inner).hi() - BytePos(1)));
let body_snippet = body_snippet.trim();
if body_snippet.is_empty() {
self.buffer.push_str("}");
self.push_str("}");
} else {
self.last_pos = mod_lo;
self.block_indent = self.block_indent.block_indent(self.config);
@ -719,7 +728,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
}
self.last_pos = source!(self, m.inner).hi();
} else {
self.buffer.push_str(";");
self.push_str(";");
self.last_pos = source!(self, s).hi();
}
}