Merge pull request #1510 from fintelia/better-filelines

Better file_lines
This commit is contained in:
Nick Cameron 2017-05-15 09:19:18 +12:00 committed by GitHub
commit d1682b3473
9 changed files with 145 additions and 40 deletions

View File

@ -115,34 +115,41 @@ impl FileLines {
Files(self.0.as_ref().map(MultiMap::keys))
}
/// Returns true if `range` is fully contained in `self`.
pub fn contains(&self, range: &LineRange) -> bool {
/// Returns true if `self` includes all lines in all files. Otherwise runs `f` on all ranges in
/// the designated file (if any) and returns true if `f` ever does.
fn file_range_matches<F>(&self, file_name: &str, f: F) -> bool
where F: FnMut(&Range) -> bool
{
let map = match self.0 {
// `None` means "all lines in all files".
None => return true,
Some(ref map) => map,
};
match canonicalize_path_string(range.file_name())
.and_then(|canonical| map.get_vec(&canonical).ok_or(())) {
Ok(ranges) => ranges.iter().any(|r| r.contains(Range::from(range))),
match canonicalize_path_string(file_name).and_then(|file| map.get_vec(&file).ok_or(())) {
Ok(ranges) => ranges.iter().any(f),
Err(_) => false,
}
}
/// Returns true if `range` is fully contained in `self`.
pub fn contains(&self, range: &LineRange) -> bool {
self.file_range_matches(range.file_name(), |r| r.contains(Range::from(range)))
}
/// Returns true if any lines in `range` are in `self`.
pub fn intersects(&self, range: &LineRange) -> bool {
let map = match self.0 {
// `None` means "all lines in all files".
None => return true,
Some(ref map) => map,
};
self.file_range_matches(range.file_name(), |r| r.intersects(Range::from(range)))
}
match canonicalize_path_string(range.file_name())
.and_then(|canonical| map.get_vec(&canonical).ok_or(())) {
Ok(ranges) => ranges.iter().any(|r| r.intersects(Range::from(range))),
Err(_) => false,
}
/// Returns true if `line` from `file_name` is in `self`.
pub fn contains_line(&self, file_name: &str, line: usize) -> bool {
self.file_range_matches(file_name, |r| r.lo <= line && r.hi >= line)
}
/// Returns true if any of the lines between `lo` and `hi` from `file_name` are in `self`.
pub fn intersects_range(&self, file_name: &str, lo: usize, hi: usize) -> bool {
self.file_range_matches(file_name, |r| r.intersects(Range::new(lo, hi)))
}
}

View File

@ -480,27 +480,35 @@ fn format_lines(text: &mut StringBuffer, name: &str, config: &Config, report: &m
continue;
}
// Add warnings for bad todos/ fixmes
if let Some(issue) = issue_seeker.inspect(c) {
errors.push(FormattingError {
line: cur_line,
kind: ErrorKind::BadIssue(issue),
});
let format_line = config.file_lines.contains_line(name, cur_line as usize);
if format_line {
// Add warnings for bad todos/ fixmes
if let Some(issue) = issue_seeker.inspect(c) {
errors.push(FormattingError {
line: cur_line,
kind: ErrorKind::BadIssue(issue),
});
}
}
if c == '\n' {
// Check for (and record) trailing whitespace.
if let Some(lw) = last_wspace {
trims.push((cur_line, lw, b));
line_len -= 1;
}
// Check for any line width errors we couldn't correct.
if config.error_on_line_overflow && line_len > config.max_width {
errors.push(FormattingError {
line: cur_line,
kind: ErrorKind::LineOverflow(line_len, config.max_width),
});
if format_line {
// Check for (and record) trailing whitespace.
if let Some(lw) = last_wspace {
trims.push((cur_line, lw, b));
line_len -= 1;
}
// Check for any line width errors we couldn't correct.
if config.error_on_line_overflow && line_len > config.max_width {
errors.push(FormattingError {
line: cur_line,
kind: ErrorKind::LineOverflow(line_len, config.max_width),
});
}
}
line_len = 0;
cur_line += 1;
newline_count += 1;

View File

@ -83,17 +83,18 @@ impl<'a> FmtVisitor<'a> {
let big_snippet = &local_begin.fm.src.as_ref().unwrap()[start_index..end_index];
let big_diff = (span.lo - big_span_lo).to_usize();
let snippet = self.snippet(span);
let snippet = self.snippet(span.clone());
debug!("write_snippet `{}`", snippet);
self.write_snippet_inner(big_snippet, big_diff, &snippet, process_last_snippet);
self.write_snippet_inner(big_snippet, big_diff, &snippet, span, process_last_snippet);
}
fn write_snippet_inner<F>(&mut self,
big_snippet: &str,
big_diff: usize,
old_snippet: &str,
span: Span,
process_last_snippet: F)
where F: Fn(&mut FmtVisitor, &str, &str)
{
@ -104,6 +105,10 @@ impl<'a> FmtVisitor<'a> {
let mut last_wspace = None;
let mut rewrite_next_comment = true;
let char_pos = self.codemap.lookup_char_pos(span.lo);
let file_name = &char_pos.file.name;
let mut cur_line = char_pos.line;
fn replace_chars(string: &str) -> String {
string
.chars()
@ -129,6 +134,15 @@ impl<'a> FmtVisitor<'a> {
let fix_indent = last_char.map_or(true, |rev_c| ['{', '\n'].contains(&rev_c));
let subslice_num_lines = subslice.chars().filter(|c| *c == '\n').count();
if rewrite_next_comment &&
!self.config
.file_lines
.intersects_range(file_name, cur_line, cur_line + subslice_num_lines) {
rewrite_next_comment = false;
}
if rewrite_next_comment {
if fix_indent {
if let Some('{') = last_char {
@ -172,6 +186,7 @@ impl<'a> FmtVisitor<'a> {
}
}
cur_line += subslice_num_lines;
continue;
} else {
rewrite_next_comment = false;
@ -182,6 +197,10 @@ impl<'a> FmtVisitor<'a> {
i += offset;
if c == '\n' {
if !self.config.file_lines.contains_line(file_name, cur_line) {
last_wspace = None;
}
if let Some(lw) = last_wspace {
self.buffer.push_str(&snippet[line_start..lw]);
self.buffer.push_str("\n");
@ -189,6 +208,7 @@ impl<'a> FmtVisitor<'a> {
self.buffer.push_str(&snippet[line_start..i + 1]);
}
cur_line += 1;
line_start = i + 1;
last_wspace = None;
rewrite_next_comment = rewrite_next_comment || kind == CodeCharKind::Normal;

View File

@ -11,10 +11,10 @@ fn floaters() {
let y = if cond {
val1
} else {
val2
val2
}
.method_call();
// aaaaaaaaaaaaa
{
match x {
PushParam => {
@ -24,6 +24,6 @@ fn floaters() {
}]
.clone());
}
}
}
}
}

View File

@ -0,0 +1,17 @@
// rustfmt-file_lines: [{"file":"tests/source/file-lines-5.rs","range":[3,5]}]
struct A {
t: i64,
}
mod foo {
fn bar() {
// test
let i = 12;
// test
}
// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
fn baz() {
let j = 15;
}
}

View File

@ -0,0 +1,18 @@
// rustfmt-file_lines: [{"file":"tests/source/file-lines-6.rs","range":[9,10]}]
struct A {
t: i64,
}
mod foo {
fn bar() {
// test
let i = 12;
// test
}
fn baz() {
///
let j = 15;
}
}

View File

@ -11,10 +11,10 @@ fn floaters() {
let y = if cond {
val1
} else {
val2
val2
}
.method_call();
// aaaaaaaaaaaaa
{
match x {
PushParam => {
@ -24,6 +24,6 @@ fn floaters() {
}]
.clone());
}
}
}
}
}

View File

@ -0,0 +1,17 @@
// rustfmt-file_lines: [{"file":"tests/source/file-lines-5.rs","range":[3,5]}]
struct A {
t: i64,
}
mod foo {
fn bar() {
// test
let i = 12;
// test
}
// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
fn baz() {
let j = 15;
}
}

View File

@ -0,0 +1,18 @@
// rustfmt-file_lines: [{"file":"tests/source/file-lines-6.rs","range":[9,10]}]
struct A {
t: i64,
}
mod foo {
fn bar() {
// test
let i = 12;
// test
}
fn baz() {
///
let j = 15;
}
}