Skip to content

Commit e34ef64

Browse files
committed
Add lint long_variable_names
The lint is configurable by using `max-variable-name-length` and it is set to 100 by default.
1 parent 40bead0 commit e34ef64

File tree

10 files changed

+132
-0
lines changed

10 files changed

+132
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5938,6 +5938,7 @@ Released 2018-09-13
59385938
[`literal_string_with_formatting_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#literal_string_with_formatting_args
59395939
[`little_endian_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#little_endian_bytes
59405940
[`logic_bug`]: https://rust-lang.github.io/rust-clippy/master/index.html#logic_bug
5941+
[`long_variable_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#long_variable_names
59415942
[`lossy_float_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#lossy_float_literal
59425943
[`macro_metavars_in_unsafe`]: https://rust-lang.github.io/rust-clippy/master/index.html#macro_metavars_in_unsafe
59435944
[`macro_use_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#macro_use_imports
@@ -6535,6 +6536,7 @@ Released 2018-09-13
65356536
[`max-struct-bools`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-struct-bools
65366537
[`max-suggested-slice-pattern-length`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-suggested-slice-pattern-length
65376538
[`max-trait-bounds`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-trait-bounds
6539+
[`max-variable-name-length`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-variable-name-length
65386540
[`min-ident-chars-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#min-ident-chars-threshold
65396541
[`missing-docs-allow-unused`]: https://doc.rust-lang.org/clippy/lint_configuration.html#missing-docs-allow-unused
65406542
[`missing-docs-in-crate-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#missing-docs-in-crate-items

book/src/lint_configuration.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,16 @@ The maximum number of bounds a trait can have to be linted
734734
* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds)
735735

736736

737+
## `max-variable-name-length`
738+
The maximum length of a variable
739+
740+
**Default Value:** `100`
741+
742+
---
743+
**Affected lints:**
744+
* [`long_variable_names`](https://rust-lang.github.io/rust-clippy/master/index.html#long_variable_names)
745+
746+
737747
## `min-ident-chars-threshold`
738748
Minimum chars an ident can have, anything below or equal to this will be linted.
739749

clippy_config/src/conf.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,9 @@ define_Conf! {
675675
/// The maximum number of bounds a trait can have to be linted
676676
#[lints(type_repetition_in_bounds)]
677677
max_trait_bounds: u64 = 3,
678+
/// The maximum length of a variable
679+
#[lints(long_variable_names)]
680+
max_variable_name_length: u32 = 100,
678681
/// Minimum chars an ident can have, anything below or equal to this will be linted.
679682
#[lints(min_ident_chars)]
680683
min_ident_chars_threshold: u64 = 1,

clippy_lints/src/declared_lints.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
260260
crate::literal_representation::UNREADABLE_LITERAL_INFO,
261261
crate::literal_representation::UNUSUAL_BYTE_GROUPINGS_INFO,
262262
crate::literal_string_with_formatting_args::LITERAL_STRING_WITH_FORMATTING_ARGS_INFO,
263+
crate::long_variable_names::LONG_VARIABLE_NAMES_INFO,
263264
crate::loops::CHAR_INDICES_AS_BYTE_INDICES_INFO,
264265
crate::loops::EMPTY_LOOP_INFO,
265266
crate::loops::EXPLICIT_COUNTER_LOOP_INFO,

clippy_lints/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ mod lifetimes;
199199
mod lines_filter_map_ok;
200200
mod literal_representation;
201201
mod literal_string_with_formatting_args;
202+
mod long_variable_names;
202203
mod loops;
203204
mod macro_metavars_in_unsafe;
204205
mod macro_use;
@@ -944,5 +945,6 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
944945
store.register_late_pass(|_| Box::new(single_option_map::SingleOptionMap));
945946
store.register_late_pass(move |_| Box::new(redundant_test_prefix::RedundantTestPrefix));
946947
store.register_late_pass(|_| Box::new(cloned_ref_to_slice_refs::ClonedRefToSliceRefs::new(conf)));
948+
store.register_late_pass(move |_| Box::new(long_variable_names::LongVariableNames::new(conf)));
947949
// add lints here, do not remove this comment, it's used in `new_lint`
948950
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
use crate::rustc_span::Pos;
2+
use clippy_config::Conf;
3+
use clippy_utils::diagnostics::span_lint_and_help;
4+
use rustc_hir::{Pat, PatKind};
5+
use rustc_lint::{LateContext, LateLintPass};
6+
use rustc_session::impl_lint_pass;
7+
8+
declare_clippy_lint! {
9+
/// ### What it does
10+
/// Checks for variable that exceeds a configurable number characters.
11+
///
12+
/// ### Why is this bad?
13+
/// Long variable names can make code harder to read and thus to maintain.
14+
///
15+
/// ### Example
16+
/// ```no_run
17+
/// let ferris_fixes_more_bugs_than_your_entire_devops_team_does = "content of a string";
18+
/// ```
19+
/// Use instead:
20+
/// ```no_run
21+
/// let ferris_fixes_more_bugs = "content of a string";
22+
/// ```
23+
#[clippy::version = "1.88.0"]
24+
pub LONG_VARIABLE_NAMES,
25+
style,
26+
"usage of a long variable"
27+
}
28+
pub struct LongVariableNames {
29+
pub max_variable_name_length: u32,
30+
}
31+
32+
impl LongVariableNames {
33+
pub fn new(conf: &'static Conf) -> Self {
34+
Self {
35+
max_variable_name_length: conf.max_variable_name_length,
36+
}
37+
}
38+
}
39+
40+
impl_lint_pass!(LongVariableNames => [LONG_VARIABLE_NAMES]);
41+
42+
impl<'tcx> LateLintPass<'tcx> for LongVariableNames {
43+
fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
44+
if let PatKind::Binding(.., ident, _) = pat.kind {
45+
let length_bytes = if ident.span.from_expansion() {
46+
// since the span can't be calculated, we can't lint this
47+
// so we just return
48+
return;
49+
} else {
50+
(ident.span.hi() - ident.span.lo()).to_u32() + 1
51+
};
52+
if length_bytes > self.max_variable_name_length {
53+
let variable_name_length = u32::try_from(ident.name.to_ident_string().chars().count())
54+
.expect("the variable name length exceeds u32::MAX");
55+
if variable_name_length > self.max_variable_name_length {
56+
let length_diff = variable_name_length - self.max_variable_name_length;
57+
58+
span_lint_and_help(
59+
cx,
60+
LONG_VARIABLE_NAMES,
61+
ident.span,
62+
format!(
63+
"variable name is longer than the configured `max-variable-name-length` of ({} characters)",
64+
self.max_variable_name_length
65+
),
66+
None,
67+
format!("reduce the length of the variable name with at least {length_diff} characters"),
68+
);
69+
}
70+
}
71+
}
72+
}
73+
}

tests/clippy.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
# default config for tests, overrides clippy.toml at the project root
22
lint-commented-code = false
3+
4+
# override the default length of variables to test the configuration
5+
max-variable-name-length = 50

tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
5757
max-struct-bools
5858
max-suggested-slice-pattern-length
5959
max-trait-bounds
60+
max-variable-name-length
6061
min-ident-chars-threshold
6162
missing-docs-allow-unused
6263
missing-docs-in-crate-items
@@ -151,6 +152,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
151152
max-struct-bools
152153
max-suggested-slice-pattern-length
153154
max-trait-bounds
155+
max-variable-name-length
154156
min-ident-chars-threshold
155157
missing-docs-allow-unused
156158
missing-docs-in-crate-items
@@ -245,6 +247,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni
245247
max-struct-bools
246248
max-suggested-slice-pattern-length
247249
max-trait-bounds
250+
max-variable-name-length
248251
min-ident-chars-threshold
249252
missing-docs-allow-unused
250253
missing-docs-in-crate-items

tests/ui/long_variable_names.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![warn(clippy::long_variable_names)]
2+
3+
fn a_function(ferris_singlehandedly_refactored_the_monolith_while_juggling_crates_and_lifetimes: &str) {
4+
//~^ long_variable_names
5+
}
6+
7+
fn another_function(just_a_short_name: &str) {
8+
// should not cause a problem
9+
}
10+
11+
fn main() {
12+
// `ferris_singlehandedly_refactored_the_monolith_while_juggling_crates_and_lifetimes` is too long
13+
let ferris_singlehandedly_refactored_the_monolith_while_juggling_crates_and_lifetimes = "very long indeed";
14+
//~^ long_variable_names
15+
}

tests/ui/long_variable_names.stderr

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: variable name is longer than the configured `max-variable-name-length` of (50 characters)
2+
--> tests/ui/long_variable_names.rs:3:15
3+
|
4+
LL | fn a_function(ferris_singlehandedly_refactored_the_monolith_while_juggling_crates_and_lifetimes: &str) {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= help: reduce the length of the variable name with at least 31 characters
8+
= note: `-D clippy::long-variable-names` implied by `-D warnings`
9+
= help: to override `-D warnings` add `#[allow(clippy::long_variable_names)]`
10+
11+
error: variable name is longer than the configured `max-variable-name-length` of (50 characters)
12+
--> tests/ui/long_variable_names.rs:13:9
13+
|
14+
LL | let ferris_singlehandedly_refactored_the_monolith_while_juggling_crates_and_lifetimes = "very long indeed";
15+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
16+
|
17+
= help: reduce the length of the variable name with at least 31 characters
18+
19+
error: aborting due to 2 previous errors
20+

0 commit comments

Comments
 (0)