needless_continue: Remove indentation of suggestion code.
As per a suggestion by Oliver on the PR thread, maintaining indentation in the suggested code is futile because of the changes in the compiler and the messiness of real-world code. rustfmt will do the indentation if required, so we don't need to do it.
This commit is contained in:
@@ -32,8 +32,7 @@ use syntax::ast;
|
|||||||
use syntax::codemap::{original_sp,DUMMY_SP};
|
use syntax::codemap::{original_sp,DUMMY_SP};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use utils::{in_macro, span_help_and_lint, snippet_block, snippet, trim_multiline,
|
use utils::{in_macro, span_help_and_lint, snippet_block, snippet, trim_multiline};
|
||||||
left_pad_lines_with_spaces, align_snippets};
|
|
||||||
|
|
||||||
/// **What it does:** The lint checks for `if`-statements appearing in loops
|
/// **What it does:** The lint checks for `if`-statements appearing in loops
|
||||||
/// that contain a `continue` statement in either their main blocks or their
|
/// 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 = &snippet(ctx, data.if_block.span, "..").into_owned();
|
||||||
let block_code = erode_block(block_code);
|
let block_code = erode_block(block_code);
|
||||||
let block_code = trim_multiline(Cow::from(block_code), false);
|
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);
|
if_code.push_str(&block_code);
|
||||||
|
|
||||||
@@ -329,9 +327,10 @@ fn suggestion_snippet_for_continue_inside_else<'a>(ctx: &EarlyContext,
|
|||||||
.collect::<Vec<_>>().join("\n");
|
.collect::<Vec<_>>().join("\n");
|
||||||
|
|
||||||
let mut ret = String::from(header);
|
let mut ret = String::from(header);
|
||||||
ret.push_str(&align_snippets(&[&if_code,
|
|
||||||
"\n// Merged code follows...",
|
ret.push_str(&if_code);
|
||||||
&to_annex]));
|
ret.push_str("\n// Merged code follows...");
|
||||||
|
ret.push_str(&to_annex);
|
||||||
ret.push_str("\n}\n");
|
ret.push_str("\n}\n");
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ use syntax::codemap::{ExpnFormat, ExpnInfo, MultiSpan, Span, DUMMY_SP};
|
|||||||
use syntax::errors::DiagnosticBuilder;
|
use syntax::errors::DiagnosticBuilder;
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
use syntax::symbol::keywords;
|
use syntax::symbol::keywords;
|
||||||
use std::iter;
|
|
||||||
|
|
||||||
pub mod comparisons;
|
pub mod comparisons;
|
||||||
pub mod conf;
|
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()))
|
.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::<String>();
|
|
||||||
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::<Vec<_>>()
|
|
||||||
.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::<String>()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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::<Vec<_>>().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)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -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:
|
= 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 {
|
if i % 2 == 0 && i % 3 == 0 {
|
||||||
println!("{}", i);
|
println!("{}", i);
|
||||||
println!("{}", i+1);
|
println!("{}", i+1);
|
||||||
if i % 5 == 0 {
|
if i % 5 == 0 {
|
||||||
println!("{}", i+2);
|
println!("{}", i+2);
|
||||||
}
|
}
|
||||||
let i = 0;
|
let i = 0;
|
||||||
println!("bar {} ", i);
|
println!("bar {} ", i);
|
||||||
|
// Merged code follows...println!("bleh");
|
||||||
// Merged code follows...
|
{
|
||||||
println!("bleh");
|
println!("blah");
|
||||||
{
|
}
|
||||||
println!("blah");
|
if !(!(i == 2) || !(i == 5)) {
|
||||||
}
|
println!("lama");
|
||||||
if !(!(i == 2) || !(i == 5)) {
|
}
|
||||||
println!("lama");
|
if (zero!(i % 2) || nonzero!(i % 5)) && i % 3 != 0 {
|
||||||
}
|
continue;
|
||||||
if (zero!(i % 2) || nonzero!(i % 5)) && i % 3 != 0 {
|
} else {
|
||||||
continue;
|
println!("Blabber");
|
||||||
} else {
|
println!("Jabber");
|
||||||
println!("Blabber");
|
}
|
||||||
println!("Jabber");
|
println!("bleh");
|
||||||
}
|
|
||||||
println!("bleh");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user