diff --git a/ci/base-tests.sh b/ci/base-tests.sh index 13b652c0f7d..f7c3342fe38 100755 --- a/ci/base-tests.sh +++ b/ci/base-tests.sh @@ -7,6 +7,7 @@ remark -f *.md > /dev/null # build clippy in debug mode and run tests cargo build --features debugging cargo test --features debugging +cd clippy_lints && cargo test && cd .. mkdir -p ~/rust/cargo/bin cp target/debug/cargo-clippy ~/rust/cargo/bin/cargo-clippy cp target/debug/clippy-driver ~/rust/cargo/bin/clippy-driver diff --git a/clippy_lints/src/consts.rs b/clippy_lints/src/consts.rs index ff189d6e893..cf3ea0414da 100644 --- a/clippy_lints/src/consts.rs +++ b/clippy_lints/src/consts.rs @@ -16,22 +16,6 @@ use syntax::ast::{FloatTy, LitKind}; use syntax::ptr::P; use crate::utils::{sext, unsext, clip}; -#[derive(Debug, Copy, Clone)] -pub enum FloatWidth { - F32, - F64, - Any, -} - -impl From for FloatWidth { - fn from(ty: FloatTy) -> Self { - match ty { - FloatTy::F32 => FloatWidth::F32, - FloatTy::F64 => FloatWidth::F64, - } - } -} - /// A `LitKind`-like enum to fold constant `Expr`s into. #[derive(Debug, Clone)] pub enum Constant { diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 7d429ce4923..8c03689df43 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -48,9 +48,9 @@ macro_rules! declare_clippy_lint { }; } -pub mod consts; +mod consts; #[macro_use] -pub mod utils; +mod utils; // begin lints modules, do not remove this comment, it’s used in `update_lints` pub mod approx_const; diff --git a/clippy_lints/src/utils/camel_case.rs b/clippy_lints/src/utils/camel_case.rs new file mode 100644 index 00000000000..e8a8d510fe5 --- /dev/null +++ b/clippy_lints/src/utils/camel_case.rs @@ -0,0 +1,114 @@ +/// Return the index of the character after the first camel-case component of +/// `s`. +pub fn camel_case_until(s: &str) -> usize { + let mut iter = s.char_indices(); + if let Some((_, first)) = iter.next() { + if !first.is_uppercase() { + return 0; + } + } else { + return 0; + } + let mut up = true; + let mut last_i = 0; + for (i, c) in iter { + if up { + if c.is_lowercase() { + up = false; + } else { + return last_i; + } + } else if c.is_uppercase() { + up = true; + last_i = i; + } else if !c.is_lowercase() { + return i; + } + } + if up { + last_i + } else { + s.len() + } +} + +/// Return index of the last camel-case component of `s`. +pub fn camel_case_from(s: &str) -> usize { + let mut iter = s.char_indices().rev(); + if let Some((_, first)) = iter.next() { + if !first.is_lowercase() { + return s.len(); + } + } else { + return s.len(); + } + let mut down = true; + let mut last_i = s.len(); + for (i, c) in iter { + if down { + if c.is_uppercase() { + down = false; + last_i = i; + } else if !c.is_lowercase() { + return last_i; + } + } else if c.is_lowercase() { + down = true; + } else { + return last_i; + } + } + last_i +} + +#[cfg(test)] +mod test { + use super::{camel_case_from, camel_case_until}; + + #[test] + fn from_full() { + assert_eq!(camel_case_from("AbcDef"), 0); + assert_eq!(camel_case_from("Abc"), 0); + } + + #[test] + fn from_partial() { + assert_eq!(camel_case_from("abcDef"), 3); + assert_eq!(camel_case_from("aDbc"), 1); + } + + #[test] + fn from_not() { + assert_eq!(camel_case_from("AbcDef_"), 7); + assert_eq!(camel_case_from("AbcDD"), 5); + } + + #[test] + fn from_caps() { + assert_eq!(camel_case_from("ABCD"), 4); + } + + #[test] + fn until_full() { + assert_eq!(camel_case_until("AbcDef"), 6); + assert_eq!(camel_case_until("Abc"), 3); + } + + #[test] + fn until_not() { + assert_eq!(camel_case_until("abcDef"), 0); + assert_eq!(camel_case_until("aDbc"), 0); + } + + #[test] + fn until_partial() { + assert_eq!(camel_case_until("AbcDef_"), 6); + assert_eq!(camel_case_until("CallTypeC"), 8); + assert_eq!(camel_case_until("AbcDD"), 3); + } + + #[test] + fn until_caps() { + assert_eq!(camel_case_until("ABCD"), 0); + } +} \ No newline at end of file diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs index 1567bd9ffb6..f910080c229 100644 --- a/clippy_lints/src/utils/conf.rs +++ b/clippy_lints/src/utils/conf.rs @@ -38,17 +38,6 @@ pub enum Error { Io(io::Error), /// Not valid toml or doesn't fit the expected conf format Toml(String), - /// Type error. - Type( - /// The name of the key. - &'static str, - /// The expected type. - &'static str, - /// The type we got instead. - &'static str, - ), - /// There is an unknown key is the file. - UnknownKey(String), } impl fmt::Display for Error { @@ -56,10 +45,6 @@ impl fmt::Display for Error { match *self { Error::Io(ref err) => err.fmt(f), Error::Toml(ref err) => err.fmt(f), - Error::Type(key, expected, got) => { - write!(f, "`{}` is expected to be a `{}` but is a `{}`", key, expected, got) - }, - Error::UnknownKey(ref key) => write!(f, "unknown key `{}`", key), } } } diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 976161a40a9..650ea373d97 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -21,9 +21,11 @@ use syntax::ast::{self, LitKind}; use syntax::attr; use syntax::source_map::{Span, DUMMY_SP}; use syntax::errors::DiagnosticBuilder; -use syntax::ptr::P; use syntax::symbol::keywords; +mod camel_case; +pub use self::camel_case::{camel_case_from, camel_case_until}; + pub mod comparisons; pub mod conf; pub mod constants; @@ -37,8 +39,6 @@ pub mod ptr; pub mod usage; pub use self::hir_utils::{SpanlessEq, SpanlessHash}; -pub type MethodArgs = HirVec>; - pub mod higher; /// Returns true if the two spans come from differing expansions (i.e. one is @@ -106,17 +106,6 @@ pub fn match_type(cx: &LateContext<'_, '_>, ty: Ty<'_>, path: &[&str]) -> bool { } } -/// Check if the method call given in `expr` belongs to given type. -pub fn match_impl_method(cx: &LateContext<'_, '_>, expr: &Expr, path: &[&str]) -> bool { - let method_call = cx.tables.type_dependent_defs()[expr.hir_id]; - let trt_id = cx.tcx.impl_of_method(method_call.def_id()); - if let Some(trt_id) = trt_id { - match_def_path(cx.tcx, trt_id, path) - } else { - false - } -} - /// Check if the method call given in `expr` belongs to given trait. pub fn match_trait_method(cx: &LateContext<'_, '_>, expr: &Expr, path: &[&str]) -> bool { let method_call = cx.tables.type_dependent_defs()[expr.hir_id]; @@ -755,69 +744,6 @@ pub fn is_direct_expn_of(span: Span, name: &str) -> Option { } } -/// Return the index of the character after the first camel-case component of -/// `s`. -pub fn camel_case_until(s: &str) -> usize { - let mut iter = s.char_indices(); - if let Some((_, first)) = iter.next() { - if !first.is_uppercase() { - return 0; - } - } else { - return 0; - } - let mut up = true; - let mut last_i = 0; - for (i, c) in iter { - if up { - if c.is_lowercase() { - up = false; - } else { - return last_i; - } - } else if c.is_uppercase() { - up = true; - last_i = i; - } else if !c.is_lowercase() { - return i; - } - } - if up { - last_i - } else { - s.len() - } -} - -/// Return index of the last camel-case component of `s`. -pub fn camel_case_from(s: &str) -> usize { - let mut iter = s.char_indices().rev(); - if let Some((_, first)) = iter.next() { - if !first.is_lowercase() { - return s.len(); - } - } else { - return s.len(); - } - let mut down = true; - let mut last_i = s.len(); - for (i, c) in iter { - if down { - if c.is_uppercase() { - down = false; - last_i = i; - } else if !c.is_lowercase() { - return last_i; - } - } else if c.is_lowercase() { - down = true; - } else { - return last_i; - } - } - last_i -} - /// Convenience function to get the return type of a function pub fn return_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, fn_item: NodeId) -> Ty<'tcx> { let fn_def_id = cx.tcx.hir.local_def_id(fn_item); @@ -1109,3 +1035,84 @@ pub fn any_parent_is_automatically_derived(tcx: TyCtxt<'_, '_, '_>, node: NodeId } false } + +#[cfg(test)] +mod test { + use super::{trim_multiline, without_block_comments}; + + #[test] + fn test_trim_multiline_single_line() { + assert_eq!("", trim_multiline("".into(), false)); + assert_eq!("...", trim_multiline("...".into(), false)); + assert_eq!("...", trim_multiline(" ...".into(), false)); + assert_eq!("...", trim_multiline("\t...".into(), false)); + assert_eq!("...", trim_multiline("\t\t...".into(), false)); + } + + #[test] + #[rustfmt::skip] + fn test_trim_multiline_block() { + assert_eq!("\ + if x { + y + } else { + z + }", trim_multiline(" if x { + y + } else { + z + }".into(), false)); + assert_eq!("\ + if x { + \ty + } else { + \tz + }", trim_multiline(" if x { + \ty + } else { + \tz + }".into(), false)); + } + + #[test] + #[rustfmt::skip] + fn test_trim_multiline_empty_line() { + assert_eq!("\ + if x { + y + + } else { + z + }", trim_multiline(" if x { + y + + } else { + z + }".into(), false)); + } + + #[test] + fn test_without_block_comments_lines_without_block_comments() { + let result = without_block_comments(vec!["/*", "", "*/"]); + println!("result: {:?}", result); + assert!(result.is_empty()); + + let result = without_block_comments(vec!["", "/*", "", "*/", "#[crate_type = \"lib\"]", "/*", "", "*/", ""]); + assert_eq!(result, vec!["", "#[crate_type = \"lib\"]", ""]); + + let result = without_block_comments(vec!["/* rust", "", "*/"]); + assert!(result.is_empty()); + + let result = without_block_comments(vec!["/* one-line comment */"]); + assert!(result.is_empty()); + + let result = without_block_comments(vec!["/* nested", "/* multi-line", "comment", "*/", "test", "*/"]); + assert!(result.is_empty()); + + let result = without_block_comments(vec!["/* nested /* inline /* comment */ test */ */"]); + assert!(result.is_empty()); + + let result = without_block_comments(vec!["foo", "bar", "baz"]); + assert_eq!(result, vec!["foo", "bar", "baz"]); + } +} \ No newline at end of file diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs index 4d89f8ddffb..3c03645cc1b 100644 --- a/clippy_lints/src/utils/paths.rs +++ b/clippy_lints/src/utils/paths.rs @@ -9,8 +9,6 @@ pub const BEGIN_PANIC: [&str; 3] = ["std", "panicking", "begin_panic"]; pub const BEGIN_PANIC_FMT: [&str; 3] = ["std", "panicking", "begin_panic_fmt"]; pub const BINARY_HEAP: [&str; 4] = ["alloc", "collections", "binary_heap", "BinaryHeap"]; pub const BORROW_TRAIT: [&str; 3] = ["core", "borrow", "Borrow"]; -pub const BOX: [&str; 3] = ["std", "boxed", "Box"]; -pub const BOX_NEW: [&str; 4] = ["std", "boxed", "Box", "new"]; pub const BTREEMAP: [&str; 5] = ["alloc", "collections", "btree", "map", "BTreeMap"]; pub const BTREEMAP_ENTRY: [&str; 5] = ["alloc", "collections", "btree", "map", "Entry"]; pub const BTREESET: [&str; 5] = ["alloc", "collections", "btree", "set", "BTreeSet"]; @@ -22,16 +20,13 @@ pub const COW: [&str; 3] = ["alloc", "borrow", "Cow"]; pub const CSTRING_NEW: [&str; 5] = ["std", "ffi", "c_str", "CString", "new"]; pub const C_VOID: [&str; 4] = ["std", "os", "raw", "c_void"]; pub const C_VOID_LIBC: [&str; 2] = ["libc", "c_void"]; -pub const DEBUG_FMT_METHOD: [&str; 4] = ["core", "fmt", "Debug", "fmt"]; pub const DEFAULT_TRAIT: [&str; 3] = ["core", "default", "Default"]; pub const DEFAULT_TRAIT_METHOD: [&str; 4] = ["core", "default", "Default", "default"]; pub const DISPLAY_FMT_METHOD: [&str; 4] = ["core", "fmt", "Display", "fmt"]; pub const DOUBLE_ENDED_ITERATOR: [&str; 4] = ["core", "iter", "traits", "DoubleEndedIterator"]; pub const DROP: [&str; 3] = ["core", "mem", "drop"]; pub const DURATION: [&str; 3] = ["core", "time", "Duration"]; -pub const FMT_ARGUMENTS_NEWV1: [&str; 4] = ["core", "fmt", "Arguments", "new_v1"]; pub const FMT_ARGUMENTS_NEWV1FORMATTED: [&str; 4] = ["core", "fmt", "Arguments", "new_v1_formatted"]; -pub const FMT_ARGUMENTV1_NEW: [&str; 4] = ["core", "fmt", "ArgumentV1", "new"]; pub const FROM_FROM: [&str; 4] = ["core", "convert", "From", "from"]; pub const FROM_TRAIT: [&str; 3] = ["core", "convert", "From"]; pub const HASH: [&str; 2] = ["hash", "Hash"]; @@ -43,7 +38,6 @@ pub const INDEX_MUT: [&str; 3] = ["core", "ops", "IndexMut"]; pub const INIT: [&str; 4] = ["core", "intrinsics", "", "init"]; pub const INTO: [&str; 3] = ["core", "convert", "Into"]; pub const INTO_ITERATOR: [&str; 4] = ["core", "iter", "traits", "IntoIterator"]; -pub const IO_PRINT: [&str; 4] = ["std", "io", "stdio", "_print"]; pub const IO_READ: [&str; 3] = ["std", "io", "Read"]; pub const IO_WRITE: [&str; 3] = ["std", "io", "Write"]; pub const ITERATOR: [&str; 4] = ["core", "iter", "iterator", "Iterator"]; @@ -69,9 +63,7 @@ pub const RANGE_FROM: [&str; 3] = ["core", "ops", "RangeFrom"]; pub const RANGE_FROM_STD: [&str; 3] = ["std", "ops", "RangeFrom"]; pub const RANGE_FULL: [&str; 3] = ["core", "ops", "RangeFull"]; pub const RANGE_FULL_STD: [&str; 3] = ["std", "ops", "RangeFull"]; -pub const RANGE_INCLUSIVE: [&str; 3] = ["core", "ops", "RangeInclusive"]; pub const RANGE_INCLUSIVE_NEW: [&str; 4] = ["core", "ops", "RangeInclusive", "new"]; -pub const RANGE_INCLUSIVE_STD: [&str; 3] = ["std", "ops", "RangeInclusive"]; pub const RANGE_INCLUSIVE_STD_NEW: [&str; 4] = ["std", "ops", "RangeInclusive", "new"]; pub const RANGE_STD: [&str; 3] = ["std", "ops", "Range"]; pub const RANGE_TO: [&str; 3] = ["core", "ops", "RangeTo"]; @@ -81,7 +73,6 @@ pub const RANGE_TO_STD: [&str; 3] = ["std", "ops", "RangeTo"]; pub const RC: [&str; 3] = ["alloc", "rc", "Rc"]; pub const REGEX: [&str; 3] = ["regex", "re_unicode", "Regex"]; pub const REGEX_BUILDER_NEW: [&str; 5] = ["regex", "re_builder", "unicode", "RegexBuilder", "new"]; -pub const REGEX_BYTES: [&str; 3] = ["regex", "re_bytes", "Regex"]; pub const REGEX_BYTES_BUILDER_NEW: [&str; 5] = ["regex", "re_builder", "bytes", "RegexBuilder", "new"]; pub const REGEX_BYTES_NEW: [&str; 4] = ["regex", "re_bytes", "Regex", "new"]; pub const REGEX_BYTES_SET_NEW: [&str; 5] = ["regex", "re_set", "bytes", "RegexSet", "new"]; diff --git a/clippy_lints/src/utils/sugg.rs b/clippy_lints/src/utils/sugg.rs index 3d587a72eec..8b1b8a31ac2 100644 --- a/clippy_lints/src/utils/sugg.rs +++ b/clippy_lints/src/utils/sugg.rs @@ -177,6 +177,7 @@ impl<'a> Sugg<'a> { /// Convenience method to create the `..` or `...` /// suggestion. + #[allow(dead_code)] pub fn range(self, end: &Self, limit: ast::RangeLimits) -> Sugg<'static> { match limit { ast::RangeLimits::HalfOpen => make_assoc(AssocOp::DotDot, &self, end), diff --git a/tests/camel_case.rs b/tests/camel_case.rs deleted file mode 100644 index b7efbde6596..00000000000 --- a/tests/camel_case.rs +++ /dev/null @@ -1,50 +0,0 @@ -extern crate clippy_lints; - -use clippy_lints::utils::{camel_case_from, camel_case_until}; - -#[test] -fn from_full() { - assert_eq!(camel_case_from("AbcDef"), 0); - assert_eq!(camel_case_from("Abc"), 0); -} - -#[test] -fn from_partial() { - assert_eq!(camel_case_from("abcDef"), 3); - assert_eq!(camel_case_from("aDbc"), 1); -} - -#[test] -fn from_not() { - assert_eq!(camel_case_from("AbcDef_"), 7); - assert_eq!(camel_case_from("AbcDD"), 5); -} - -#[test] -fn from_caps() { - assert_eq!(camel_case_from("ABCD"), 4); -} - -#[test] -fn until_full() { - assert_eq!(camel_case_until("AbcDef"), 6); - assert_eq!(camel_case_until("Abc"), 3); -} - -#[test] -fn until_not() { - assert_eq!(camel_case_until("abcDef"), 0); - assert_eq!(camel_case_until("aDbc"), 0); -} - -#[test] -fn until_partial() { - assert_eq!(camel_case_until("AbcDef_"), 6); - assert_eq!(camel_case_until("CallTypeC"), 8); - assert_eq!(camel_case_until("AbcDD"), 3); -} - -#[test] -fn until_caps() { - assert_eq!(camel_case_until("ABCD"), 0); -} diff --git a/tests/trim_multiline.rs b/tests/trim_multiline.rs deleted file mode 100644 index a0db2e59a29..00000000000 --- a/tests/trim_multiline.rs +++ /dev/null @@ -1,57 +0,0 @@ - - -/// test the multiline-trim function -extern crate clippy_lints; - -use clippy_lints::utils::trim_multiline; - -#[test] -fn test_single_line() { - assert_eq!("", trim_multiline("".into(), false)); - assert_eq!("...", trim_multiline("...".into(), false)); - assert_eq!("...", trim_multiline(" ...".into(), false)); - assert_eq!("...", trim_multiline("\t...".into(), false)); - assert_eq!("...", trim_multiline("\t\t...".into(), false)); -} - -#[test] -#[rustfmt::skip] -fn test_block() { - assert_eq!("\ -if x { - y -} else { - z -}", trim_multiline(" if x { - y - } else { - z - }".into(), false)); - assert_eq!("\ -if x { -\ty -} else { -\tz -}", trim_multiline(" if x { - \ty - } else { - \tz - }".into(), false)); -} - -#[test] -#[rustfmt::skip] -fn test_empty_line() { - assert_eq!("\ -if x { - y - -} else { - z -}", trim_multiline(" if x { - y - - } else { - z - }".into(), false)); -} diff --git a/tests/without_block_comments.rs b/tests/without_block_comments.rs deleted file mode 100644 index 730c5cb128f..00000000000 --- a/tests/without_block_comments.rs +++ /dev/null @@ -1,27 +0,0 @@ -extern crate clippy_lints; -use clippy_lints::utils::without_block_comments; - -#[test] -fn test_lines_without_block_comments() { - let result = without_block_comments(vec!["/*", "", "*/"]); - println!("result: {:?}", result); - assert!(result.is_empty()); - - let result = without_block_comments(vec!["", "/*", "", "*/", "#[crate_type = \"lib\"]", "/*", "", "*/", ""]); - assert_eq!(result, vec!["", "#[crate_type = \"lib\"]", ""]); - - let result = without_block_comments(vec!["/* rust", "", "*/"]); - assert!(result.is_empty()); - - let result = without_block_comments(vec!["/* one-line comment */"]); - assert!(result.is_empty()); - - let result = without_block_comments(vec!["/* nested", "/* multi-line", "comment", "*/", "test", "*/"]); - assert!(result.is_empty()); - - let result = without_block_comments(vec!["/* nested /* inline /* comment */ test */ */"]); - assert!(result.is_empty()); - - let result = without_block_comments(vec!["foo", "bar", "baz"]); - assert_eq!(result, vec!["foo", "bar", "baz"]); -}