Skip to content

Commit 59750dc

Browse files
committed
upper_case_acronyms: add optional aggressive mode and relax default
Moves the lint back from pedantic to style group. The lint default now only warns on names that are completely capitalized, like "WORD" and only if the name is longer than 2 chars (so that names where each of the letter represents a word are still distinguishable). For example: FP (false positive) would still be "valid" and not warned about (but EOF would warn). A "upper_case_acronyms_aggressive: true/false" config option was added that restores the original lint behaviour to warn on any kind of camel case name that had more than one capital letter following another capital letter.
1 parent 4545150 commit 59750dc

File tree

3 files changed

+37
-10
lines changed

3 files changed

+37
-10
lines changed

clippy_lints/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,7 +1216,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
12161216
let enum_variant_name_threshold = conf.enum_variant_name_threshold;
12171217
store.register_early_pass(move || box enum_variants::EnumVariantNames::new(enum_variant_name_threshold));
12181218
store.register_early_pass(|| box tabs_in_doc_comments::TabsInDocComments);
1219-
store.register_early_pass(|| box upper_case_acronyms::UpperCaseAcronyms);
1219+
let upper_case_acronyms_aggressive = conf.upper_case_acronyms_aggressive;
1220+
store.register_early_pass(move || box upper_case_acronyms::UpperCaseAcronyms::new(upper_case_acronyms_aggressive));
12201221
store.register_late_pass(|| box default::Default::default());
12211222
store.register_late_pass(|| box unused_self::UnusedSelf);
12221223
store.register_late_pass(|| box mutable_debug_assertion::DebugAssertWithMutCall);
@@ -1416,7 +1417,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
14161417
LintId::of(&unnecessary_wraps::UNNECESSARY_WRAPS),
14171418
LintId::of(&unnested_or_patterns::UNNESTED_OR_PATTERNS),
14181419
LintId::of(&unused_self::UNUSED_SELF),
1419-
LintId::of(&upper_case_acronyms::UPPER_CASE_ACRONYMS),
14201420
LintId::of(&wildcard_imports::ENUM_GLOB_USE),
14211421
LintId::of(&wildcard_imports::WILDCARD_IMPORTS),
14221422
LintId::of(&zero_sized_map_values::ZERO_SIZED_MAP_VALUES),
@@ -1835,6 +1835,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
18351835
LintId::of(&types::FN_TO_NUMERIC_CAST_WITH_TRUNCATION),
18361836
LintId::of(&unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME),
18371837
LintId::of(&unused_unit::UNUSED_UNIT),
1838+
LintId::of(&upper_case_acronyms::UPPER_CASE_ACRONYMS),
18381839
LintId::of(&write::PRINTLN_EMPTY_STRING),
18391840
LintId::of(&write::PRINT_LITERAL),
18401841
LintId::of(&write::PRINT_WITH_NEWLINE),

clippy_lints/src/upper_case_acronyms.rs

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,20 @@ use rustc_ast::ast::{Item, ItemKind, Variant};
55
use rustc_errors::Applicability;
66
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
77
use rustc_middle::lint::in_external_macro;
8-
use rustc_session::{declare_lint_pass, declare_tool_lint};
8+
use rustc_session::{declare_tool_lint, impl_lint_pass};
99
use rustc_span::symbol::Ident;
1010

1111
declare_clippy_lint! {
12-
/// **What it does:** Checks for camel case name containing a capitalized acronym.
12+
/// **What it does:** Checks for fully capitalized names and optionally names containing a capitalized acronym.
1313
///
1414
/// **Why is this bad?** In CamelCase, acronyms count as one word.
1515
/// See [naming conventions](https://rust-lang.github.io/api-guidelines/naming.html#casing-conforms-to-rfc-430-c-case)
1616
/// for more.
1717
///
18+
/// By default, the lint only triggers on fully-capitalized names.
19+
/// You can use the `upper_case_acronyms_aggressive: true` config option to enable linting
20+
/// on all camel case names
21+
///
1822
/// **Known problems:** When two acronyms are contiguous, the lint can't tell where
1923
/// the first acronym ends and the second starts, so it suggests to lowercase all of
2024
/// the letters in the second acronym.
@@ -29,11 +33,24 @@ declare_clippy_lint! {
2933
/// struct HttpResponse;
3034
/// ```
3135
pub UPPER_CASE_ACRONYMS,
32-
pedantic,
36+
style,
3337
"capitalized acronyms are against the naming convention"
3438
}
3539

36-
declare_lint_pass!(UpperCaseAcronyms => [UPPER_CASE_ACRONYMS]);
40+
#[derive(Default)]
41+
pub struct UpperCaseAcronyms {
42+
upper_case_acronyms_aggressive: bool,
43+
}
44+
45+
impl UpperCaseAcronyms {
46+
pub fn new(aggressive: bool) -> Self {
47+
Self {
48+
upper_case_acronyms_aggressive: aggressive,
49+
}
50+
}
51+
}
52+
53+
impl_lint_pass!(UpperCaseAcronyms => [UPPER_CASE_ACRONYMS]);
3754

3855
fn correct_ident(ident: &str) -> String {
3956
let ident = ident.chars().rev().collect::<String>();
@@ -56,11 +73,18 @@ fn correct_ident(ident: &str) -> String {
5673
ident
5774
}
5875

59-
fn check_ident(cx: &EarlyContext<'_>, ident: &Ident) {
76+
fn check_ident(cx: &EarlyContext<'_>, ident: &Ident, be_aggressive: bool) {
6077
let span = ident.span;
6178
let ident = &ident.as_str();
6279
let corrected = correct_ident(ident);
63-
if ident != &corrected {
80+
// warn if we have pure-uppercase idents
81+
// assume that two-letter words are some kind of valid abbreviation like FP for false positive
82+
// (and don't warn)
83+
if (ident.chars().all(|c| c.is_ascii_uppercase()) && ident.len() > 2)
84+
// otherwise, warn if we have SOmeTHING lIKE THIs but only warn with the aggressive
85+
// upper_case_acronyms_aggressive config option enabled
86+
|| (be_aggressive && ident != &corrected)
87+
{
6488
span_lint_and_sugg(
6589
cx,
6690
UPPER_CASE_ACRONYMS,
@@ -82,12 +106,12 @@ impl EarlyLintPass for UpperCaseAcronyms {
82106
ItemKind::TyAlias(..) | ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Trait(..)
83107
);
84108
then {
85-
check_ident(cx, &it.ident);
109+
check_ident(cx, &it.ident, self.upper_case_acronyms_aggressive);
86110
}
87111
}
88112
}
89113

90114
fn check_variant(&mut self, cx: &EarlyContext<'_>, v: &Variant) {
91-
check_ident(cx, &v.ident);
115+
check_ident(cx, &v.ident, self.upper_case_acronyms_aggressive);
92116
}
93117
}

clippy_lints/src/utils/conf.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ define_Conf! {
173173
(disallowed_methods, "disallowed_methods": Vec<String>, Vec::<String>::new()),
174174
/// Lint: UNREADABLE_LITERAL. Should the fraction of a decimal be linted to include separators.
175175
(unreadable_literal_lint_fractions, "unreadable_literal_lint_fractions": bool, true),
176+
/// Lint: UPPER_CASE_ACRONYMS. Enabler verbose mode triggers if there is more than one uppercase char next to each other
177+
(upper_case_acronyms_aggressive, "upper_case_acronyms_aggressive": bool, false),
176178
/// Lint: _CARGO_COMMON_METADATA. For internal testing only, ignores the current `publish` settings in the Cargo manifest.
177179
(cargo_ignore_publish, "cargo_ignore_publish": bool, false),
178180
}

0 commit comments

Comments
 (0)