diff --git a/clippy_lints/src/needless_continue.rs b/clippy_lints/src/needless_continue.rs index 9b248b894a0..1e7120951ca 100644 --- a/clippy_lints/src/needless_continue.rs +++ b/clippy_lints/src/needless_continue.rs @@ -32,8 +32,7 @@ use syntax::ast; use syntax::codemap::{original_sp,DUMMY_SP}; use std::borrow::Cow; -use utils::{in_macro, span_help_and_lint, snippet_block, snippet, trim_multiline, - left_pad_lines_with_spaces, align_snippets}; +use utils::{in_macro, span_help_and_lint, snippet_block, snippet, trim_multiline}; /// **What it does:** The lint checks for `if`-statements appearing in loops /// that contain a `continue` statement in either their main blocks or their @@ -312,7 +311,6 @@ fn suggestion_snippet_for_continue_inside_else<'a>(ctx: &EarlyContext, let block_code = &snippet(ctx, data.if_block.span, "..").into_owned(); let block_code = erode_block(block_code); let block_code = trim_multiline(Cow::from(block_code), false); - let block_code = left_pad_lines_with_spaces(&block_code, 4_usize); if_code.push_str(&block_code); @@ -329,9 +327,10 @@ fn suggestion_snippet_for_continue_inside_else<'a>(ctx: &EarlyContext, .collect::>().join("\n"); let mut ret = String::from(header); - ret.push_str(&align_snippets(&[&if_code, - "\n// Merged code follows...", - &to_annex])); + + ret.push_str(&if_code); + ret.push_str("\n// Merged code follows..."); + ret.push_str(&to_annex); ret.push_str("\n}\n"); ret } diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 5782d3ef3a8..40dab908614 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -22,7 +22,6 @@ use syntax::codemap::{ExpnFormat, ExpnInfo, MultiSpan, Span, DUMMY_SP}; use syntax::errors::DiagnosticBuilder; use syntax::ptr::P; use syntax::symbol::keywords; -use std::iter; pub mod comparisons; pub mod conf; @@ -980,191 +979,3 @@ pub fn type_size<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: ty::Ty<'tcx>) -> Opti .enter(|infcx| ty.layout(&infcx).ok().map(|lay| lay.size(&TargetDataLayout::parse(cx.sess())).bytes())) } -/// Add `n` spaces to the left of `s`. -pub fn left_pad_with_spaces(s: &str, n: usize) -> String { - let mut new_s = iter::repeat(' ').take(n).collect::(); - new_s.push_str(s); - new_s -} - -/// Add `n` spaces to the left of each line in `s` and return the result -/// in a new String. -/// e.g., when n = 2, the string -/// -/// " fn foo() { -/// bar() -/// }" -/// -/// becomes -/// -/// " fn foo() { -/// bar() -/// }" -/// -/// # Example -/// -/// ``` -/// use clippy_lints::utils::left_pad_with_spaces; -/// -/// let input = "\ -/// fn main() { -/// println!("hello world!"); -/// }"; -/// -/// let expected = -/// " fn main() { -/// println!("hello world!"); -/// }"; -/// -/// assert_eq!(expected, input); -/// ``` -pub fn left_pad_lines_with_spaces(s: &str, n: usize) -> String { - s.lines() - .map(|line| left_pad_with_spaces(line, n)) - .collect::>() - .join("\n") -} - -/// Remove upto `n` whitespace characters from the beginning of `s`. -/// -/// # Examples -/// -/// ``` -/// let s = " foobar "; -/// assert_eq!("foobar ", remove_whitespace_from_left(s, 100)); -/// assert_eq!(" foobar ", remove_whitespace_from_left(s, 2)); -/// assert_eq("", remove_whitespace_from_left(" ", 50)); -/// ``` -pub fn remove_whitespace_from_left(s: &str, n: usize) -> String { - s.chars() - .enumerate() - .skip_while(|&(i, c)| i < n && c.is_whitespace()) - .map(|(_, c)| c) - .collect::() -} - -/// Aligns two snippets such that the indentation level of the last non-empty, -/// non-space line of the first snippet matches the first non-empty, non-space -/// line of the second. -pub fn align_two_snippets(s: &str, t: &str) -> String { - // indent level of the last nonempty, non-whitespace line of s. - let target_ilevel = s.lines() - .rev() - .skip_while(|line| line.is_empty() || is_all_whitespace(line)) - .next() - .map_or(0_usize, indent_level); - - // We want to align the first nonempty, non-all-whitespace line of t to - // have the same indent level as target_ilevel - let level = t.lines() - .skip_while(|line| line.is_empty() || is_all_whitespace(line)) - .next() - .map_or(0_usize, indent_level); - - // When add_spaces=true, we add spaces, otherwise eat. - let add_spaces = target_ilevel > level; - - let delta = if add_spaces { - target_ilevel - level - } else { - level - target_ilevel - }; - - let new_t = t.lines() - .map(|line| { - if is_null(line) { - // leave empty lines alone - String::from(line) - } else if add_spaces { - left_pad_with_spaces(line, delta) - } else { - remove_whitespace_from_left(line, delta) - } - }) - .collect::>().join("\n"); - - format!("{}\n{}", s, new_t) -} - -/// Aligns strings in `xs` pairwise from the start, such that for any pair of -/// strings, the first string's last line is aligned with the first line of -/// the second string. See `align_two_snippets`. Use this to merge code regions -/// into a reasonably aligned chunk of code. -/// -/// For example, consider -/// -/// ``` -/// let s1 = "\ -/// if (condition()) { -/// do_something()"; -/// -/// let s2 = "\ -/// code_from_somewhere_else();" -/// -/// let s3 = "\ -/// another_piece_of_code(); -/// indented_here();"; -/// ``` -/// -/// -/// -/// Now calling `align_snippets(&[s1, s2, s3])` will yield the following: -/// -/// ``` -/// if (condition()) { -/// do_something(); -/// code_from_somewhere_else(); -/// another_piece_of_code(); -/// indented_here(); -/// ``` -pub fn align_snippets(xs: &[&str]) -> String { - if xs.is_empty() { - String::from("") - } else { - let mut ret = xs[0].to_string(); - for x in xs.iter().skip(1_usize) { - ret = align_two_snippets(&ret, x); - } - ret - } -} - - -/// # Examples -/// ``` -/// use clippy_lints::utils::is_all_whitespace; -/// -/// assert_eq!(true, " \n\t "); -/// assert_eq!(false, ""); -/// assert_eq!(false, "hello world!\n"); -/// ``` -pub fn is_all_whitespace(s: &str) -> bool { - s.chars().all(|c| c.is_whitespace()) -} - -/// Returns true if a string is empty or just spaces. -pub fn is_null(s: &str) -> bool { - s.is_empty() || is_all_whitespace(s) -} - -/// Returns the indentation level of a string. It just returns the count of -/// whitespace characters in the string before a non-whitespace character -/// is encountered. -/// -/// # Examples -/// -/// ``` -/// use clippy_lints::utils::indent_level; -/// -/// let s = " fn foo() { "; -/// assert_eq!(4, indent_level(s)); -/// -/// let s = "fn foo() { "; -/// assert_eq!(0, indent_level(s)); -/// ``` -pub fn indent_level(s: &str) -> usize { - s.chars() - .enumerate() - .find(|&(_, c)| !c.is_whitespace()) - .map_or(0_usize, |(i, _)| i) -} diff --git a/tests/test_align_snippets.rs b/tests/test_align_snippets.rs deleted file mode 100644 index f6a80036b35..00000000000 --- a/tests/test_align_snippets.rs +++ /dev/null @@ -1,74 +0,0 @@ -extern crate clippy_lints; - -use clippy_lints::utils::align_snippets; - -#[test] -fn test_align_snippets_single_line() { - assert_eq!("", align_snippets(&[""])); - assert_eq!("...", align_snippets(&["..."])); -} - -#[test] -#[cfg_attr(rustfmt, rustfmt_skip)] -fn test_align_snippets_multiline() { - let expected = "\ -if condition() { - do_something(); - do_another_thing(); - yet_another_thing(); - { - and_then_an_indented_block(); - } - and_then_something_the_user_indented();"; // expected - - let input = &[ -"\ -if condition() { - do_something();", -" do_another_thing();", -" yet_another_thing(); - { - and_then_an_indented_block(); - } - and_then_something_the_user_indented();", - ]; // input - - let got = align_snippets(input); - assert_eq!(expected, got); - -} - -#[test] -#[cfg_attr(rustfmt, rustfmt_skip)] -fn test_align_snippets_multiline_with_empty_lines() { - let expected = "\ -if condition() { - do_something(); - do_another_thing(); - yet_another_thing(); - { - - and_then_an_indented_block(); - } - - and_then_something_the_user_indented();"; // expected - - let input = &[ -"\ -if condition() { - do_something();", -" do_another_thing();", -" yet_another_thing(); - { - - and_then_an_indented_block(); - } - - and_then_something_the_user_indented();", - ]; // input - - let got = align_snippets(input); - println!("Input: {}\nExpected: {}\nGot: {}", input.join("\n"), &expected, &got); - assert_eq!(expected, got); -} - diff --git a/tests/ui/needless_continue.stderr b/tests/ui/needless_continue.stderr index e8433ef9f74..5a4447aa694 100644 --- a/tests/ui/needless_continue.stderr +++ b/tests/ui/needless_continue.stderr @@ -15,29 +15,27 @@ note: lint level defined here | ^^^^^^^^^^^^^^^^^ = help: Consider dropping the else clause and merging the code that follows (in the loop) with the if block, like so: if i % 2 == 0 && i % 3 == 0 { - println!("{}", i); - println!("{}", i+1); - if i % 5 == 0 { - println!("{}", i+2); - } - let i = 0; - println!("bar {} ", i); - - // Merged code follows... - println!("bleh"); - { - println!("blah"); - } - if !(!(i == 2) || !(i == 5)) { - println!("lama"); - } - if (zero!(i % 2) || nonzero!(i % 5)) && i % 3 != 0 { - continue; - } else { - println!("Blabber"); - println!("Jabber"); - } - println!("bleh"); + println!("{}", i); + println!("{}", i+1); + if i % 5 == 0 { + println!("{}", i+2); + } + let i = 0; + println!("bar {} ", i); + // Merged code follows...println!("bleh"); + { + println!("blah"); + } + if !(!(i == 2) || !(i == 5)) { + println!("lama"); + } + if (zero!(i % 2) || nonzero!(i % 5)) && i % 3 != 0 { + continue; + } else { + println!("Blabber"); + println!("Jabber"); + } + println!("bleh"); }