mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-13 04:26:48 +00:00
Fix issue 1124 - detect start of output rather than start of input file when writing output source file (#1133)
* Change required to prevent a trailing space at the end of a separate module being propagated * Detect the start of the output file rather than the start of the input file when deciding whether to output preceding snippets - this stops unnecessary whitespace and blank lines from being inserted when spans and statements are output in an order other than that from the input file. * Add code to prevent space from being added with the prefix snippet if a) the snippet is entirely horizontal whitespace, or b) the snippet contains whitespace followed by a newline. This prevents trailing spaces at the end of a line from being added. * Tests for this issue * Tidy up `match` statements * Add test with blank lines between `use` statements
This commit is contained in:
parent
d022f05f34
commit
61042e6e4d
@ -178,19 +178,26 @@ impl<'a> FmtVisitor<'a> {
|
||||
// Order the imports by view-path & other import path properties
|
||||
ordered_use_items.sort_by(|a, b| compare_use_items(a.0, b.0).unwrap());
|
||||
// First, output the span before the first import
|
||||
let prev_span_str = self.snippet(codemap::mk_sp(self.last_pos, pos_before_first_use_item));
|
||||
// Look for purely trailing space at the start of the prefix snippet before a linefeed, or
|
||||
// a prefix that's entirely horizontal whitespace.
|
||||
let prefix_span_start = match prev_span_str.find('\n') {
|
||||
Some(offset) if prev_span_str[..offset].trim().is_empty() => {
|
||||
self.last_pos + BytePos(offset as u32)
|
||||
}
|
||||
None if prev_span_str.trim().is_empty() => pos_before_first_use_item,
|
||||
_ => self.last_pos,
|
||||
};
|
||||
// Look for indent (the line part preceding the use is all whitespace) and excise that
|
||||
// from the prefix
|
||||
let prev_span_str = self.snippet(codemap::mk_sp(self.last_pos, pos_before_first_use_item));
|
||||
let span_end = match prev_span_str.rfind('\n') {
|
||||
Some(offset) => {
|
||||
if prev_span_str[offset..].trim().is_empty() {
|
||||
self.last_pos + BytePos(offset as u32)
|
||||
} else {
|
||||
pos_before_first_use_item
|
||||
}
|
||||
Some(offset) if prev_span_str[offset..].trim().is_empty() => {
|
||||
self.last_pos + BytePos(offset as u32)
|
||||
}
|
||||
None => pos_before_first_use_item,
|
||||
_ => pos_before_first_use_item,
|
||||
};
|
||||
|
||||
self.last_pos = prefix_span_start;
|
||||
self.format_missing(span_end);
|
||||
for ordered in ordered_use_items {
|
||||
// Fake out the formatter by setting `self.last_pos` to the appropriate location before
|
||||
|
@ -14,6 +14,10 @@ use syntax::codemap::{self, BytePos, Span, Pos};
|
||||
use comment::{CodeCharKind, CommentCodeSlices, rewrite_comment};
|
||||
|
||||
impl<'a> FmtVisitor<'a> {
|
||||
fn output_at_start(&self) -> bool {
|
||||
self.buffer.len == 0
|
||||
}
|
||||
|
||||
// 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) {
|
||||
@ -25,7 +29,7 @@ impl<'a> FmtVisitor<'a> {
|
||||
let config = self.config;
|
||||
self.format_missing_inner(end, |this, last_snippet, snippet| {
|
||||
this.buffer.push_str(last_snippet.trim_right());
|
||||
if last_snippet == snippet {
|
||||
if last_snippet == snippet && !this.output_at_start() {
|
||||
// No new lines in the snippet.
|
||||
this.buffer.push_str("\n");
|
||||
}
|
||||
@ -41,7 +45,7 @@ impl<'a> FmtVisitor<'a> {
|
||||
|
||||
if start == end {
|
||||
// Do nothing if this is the beginning of the file.
|
||||
if start != self.codemap.lookup_char_pos(start).file.start_pos {
|
||||
if !self.output_at_start() {
|
||||
process_last_snippet(self, "", "");
|
||||
}
|
||||
return;
|
||||
|
@ -559,7 +559,7 @@ impl<'a> FmtVisitor<'a> {
|
||||
self.last_pos = filemap.start_pos;
|
||||
self.block_indent = Indent::empty();
|
||||
self.walk_mod_items(m);
|
||||
self.format_missing(filemap.end_pos);
|
||||
self.format_missing_with_indent(filemap.end_pos);
|
||||
}
|
||||
|
||||
pub fn get_context(&self) -> RewriteContext {
|
||||
|
1
tests/config/issue-1124.toml
Normal file
1
tests/config/issue-1124.toml
Normal file
@ -0,0 +1 @@
|
||||
reorder_imports = true
|
13
tests/source/issue-1124.rs
Normal file
13
tests/source/issue-1124.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use d; use c; use b; use a;
|
||||
// The previous line has a space after the `use a;`
|
||||
|
||||
mod a { use d; use c; use b; use a; }
|
||||
|
||||
use z;
|
||||
|
||||
use y;
|
||||
|
||||
|
||||
|
||||
use x;
|
||||
use a;
|
21
tests/target/issue-1124.rs
Normal file
21
tests/target/issue-1124.rs
Normal file
@ -0,0 +1,21 @@
|
||||
use a;
|
||||
use b;
|
||||
use c;
|
||||
use d;
|
||||
// The previous line has a space after the `use a;`
|
||||
|
||||
mod a {
|
||||
use a;
|
||||
use b;
|
||||
use c;
|
||||
use d;
|
||||
}
|
||||
|
||||
use a;
|
||||
|
||||
|
||||
|
||||
use x;
|
||||
|
||||
use y;
|
||||
use z;
|
Loading…
Reference in New Issue
Block a user