From fa0df69a979e490b639a9f502f95060649ba5fb9 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sat, 6 Aug 2016 20:59:27 +0200 Subject: [PATCH] Add a configurable threshold for enum variants before name lints trigger (fixes #1138) --- clippy_lints/src/enum_variants.rs | 19 ++++++++++++------ clippy_lints/src/lib.rs | 2 +- clippy_lints/src/utils/conf.rs | 2 ++ tests/compile-fail/enum_variants.rs | 30 +++++++++++++++++++---------- 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/clippy_lints/src/enum_variants.rs b/clippy_lints/src/enum_variants.rs index 8278780d9b4..03bd49b09b6 100644 --- a/clippy_lints/src/enum_variants.rs +++ b/clippy_lints/src/enum_variants.rs @@ -44,9 +44,15 @@ declare_lint! { "finds type names prefixed/postfixed with their containing module's name" } -#[derive(Default)] pub struct EnumVariantNames { modules: Vec, + threshold: u64, +} + +impl EnumVariantNames { + pub fn new(threshold: u64) -> EnumVariantNames { + EnumVariantNames { modules: Vec::new(), threshold: threshold } + } } impl LintPass for EnumVariantNames { @@ -75,7 +81,11 @@ fn partial_rmatch(post: &str, name: &str) -> usize { // FIXME: #600 #[allow(while_let_on_iterator)] -fn check_variant(cx: &EarlyContext, def: &EnumDef, item_name: &str, item_name_chars: usize, span: Span) { +fn check_variant(cx: &EarlyContext, threshold: u64, def: &EnumDef, item_name: &str, + item_name_chars: usize, span: Span) { + if (def.variants.len() as u64) < threshold { + return; + } for var in &def.variants { let name = var2str(var); if partial_match(item_name, &name) == item_name_chars { @@ -85,9 +95,6 @@ fn check_variant(cx: &EarlyContext, def: &EnumDef, item_name: &str, item_name_ch span_lint(cx, ENUM_VARIANT_NAMES, var.span, "Variant name ends with the enum's name"); } } - if def.variants.len() < 2 { - return; - } let first = var2str(&def.variants[0]); let mut pre = &first[..camel_case_until(&*first)]; let mut post = &first[camel_case_from(&*first)..]; @@ -177,7 +184,7 @@ impl EarlyLintPass for EnumVariantNames { } } if let ItemKind::Enum(ref def, _) = item.node { - check_variant(cx, def, &item_name, item_name_chars, item.span); + check_variant(cx, self.threshold, def, &item_name, item_name_chars, item.span); } self.modules.push(item_camel); } diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 7308a656590..f110bb8f329 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -175,7 +175,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { reg.register_late_lint_pass(box misc::TopLevelRefPass); reg.register_late_lint_pass(box misc::CmpNan); reg.register_late_lint_pass(box eq_op::EqOp); - reg.register_early_lint_pass(box enum_variants::EnumVariantNames::default()); + reg.register_early_lint_pass(box enum_variants::EnumVariantNames::new(conf.enum_variant_name_threshold)); reg.register_late_lint_pass(box enum_glob_use::EnumGlobUse); reg.register_late_lint_pass(box enum_clike::UnportableVariant); reg.register_late_lint_pass(box bit_mask::BitMask); diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs index edb18478c3f..07be9f7f5bc 100644 --- a/clippy_lints/src/utils/conf.rs +++ b/clippy_lints/src/utils/conf.rs @@ -160,6 +160,8 @@ define_Conf! { ("single-char-binding-names-threshold", max_single_char_names, 5 => u64), /// Lint: BOXED_LOCAL. The maximum size of objects (in bytes) that will be linted. Larger objects are ok on the heap ("too-large-for-stack", too_large_for_stack, 200 => u64), + /// Lint: ENUM_VARIANT_NAMES. The minimum number of enum variants for the lints about variant names to trigger + ("enum-variant-name-threshold", enum_variant_name_threshold, 3 => u64), } /// Read the `toml` configuration file. The function will ignore “File not found” errors iif diff --git a/tests/compile-fail/enum_variants.rs b/tests/compile-fail/enum_variants.rs index ed7f7823f8f..f0fda37f7f8 100644 --- a/tests/compile-fail/enum_variants.rs +++ b/tests/compile-fail/enum_variants.rs @@ -13,6 +13,22 @@ enum FakeCallType2 { enum Foo { cFoo, //~ ERROR: Variant name ends with the enum's name cBar, + cBaz, +} + +enum Fooo { + cFoo, // no error, threshold is 3 variants by default + cBar, +} + +enum Food { //~ ERROR: All variants have the same prefix: `Food` + FoodGood, //~ ERROR: Variant name starts with the enum's name + FoodMiddle, //~ ERROR: Variant name starts with the enum's name + FoodBad, //~ ERROR: Variant name starts with the enum's name +} + +enum Stuff { + StuffBad, // no error } enum BadCallType { //~ ERROR: All variants have the same prefix: `CallType` @@ -21,7 +37,7 @@ enum BadCallType { //~ ERROR: All variants have the same prefix: `CallType` CallTypeDestroy, } -enum TwoCallType { //~ ERROR: All variants have the same prefix: `CallType` +enum TwoCallType { // no error CallTypeCall, CallTypeCreate, } @@ -32,7 +48,7 @@ enum Consts { //~ ERROR: All variants have the same prefix: `Constant` ConstantLie, } -enum Two { //~ ERROR: All variants have the same prefix: `Constant` +enum Two { // no error here ConstantInt, ConstantInfer, } @@ -61,20 +77,14 @@ enum Sealll { enum Seallll { //~ ERROR: All variants have the same prefix: `With` WithOutCake, + WithOutTea, WithOut, } enum NonCaps { //~ ERROR: All variants have the same prefix: `Prefix` Prefix的, + PrefixTea, PrefixCake, } -enum Stuff { - BadStuff, //~ ERROR: Variant name ends with the enum's name -} - -enum Food { - FoodGood, //~ ERROR: Variant name starts with the enum's name -} - fn main() {}