Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 8c73b76

Browse files
committed
Move check_variant() code into a method of ItemNameRepetitions too.
1 parent 2067375 commit 8c73b76

File tree

1 file changed

+72
-67
lines changed

1 file changed

+72
-67
lines changed

clippy_lints/src/item_name_repetitions.rs

Lines changed: 72 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use rustc_data_structures::fx::FxHashSet;
88
use rustc_hir::{EnumDef, FieldDef, Item, ItemKind, OwnerId, Variant, VariantData};
99
use rustc_lint::{LateContext, LateLintPass};
1010
use rustc_session::impl_lint_pass;
11-
use rustc_span::Span;
1211
use rustc_span::symbol::Symbol;
1312

1413
declare_clippy_lint! {
@@ -197,17 +196,86 @@ fn have_no_extra_prefix(prefixes: &[&str]) -> bool {
197196
}
198197

199198
impl ItemNameRepetitions {
199+
/// Lint the names of enum variants against the name of the enum.
200+
fn check_variants(&self, cx: &LateContext<'_>, item: &Item<'_>, def: &EnumDef<'_>) {
201+
if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(item.owner_id.def_id) {
202+
return;
203+
}
204+
205+
if (def.variants.len() as u64) < self.enum_threshold {
206+
return;
207+
}
208+
209+
let item_name = item.ident.name.as_str();
210+
for var in def.variants {
211+
check_enum_start(cx, item_name, var);
212+
check_enum_end(cx, item_name, var);
213+
}
214+
215+
Self::check_enum_common_affix(cx, item, def);
216+
}
217+
200218
/// Lint the names of struct fields against the name of the struct.
201219
fn check_fields(&self, cx: &LateContext<'_>, item: &Item<'_>, fields: &[FieldDef<'_>]) {
202220
if (fields.len() as u64) < self.struct_threshold {
203221
return;
204222
}
205223

206224
self.check_struct_name_repetition(cx, item, fields);
207-
self.check_common_affix(cx, item, fields);
225+
self.check_struct_common_affix(cx, item, fields);
226+
}
227+
228+
fn check_enum_common_affix(cx: &LateContext<'_>, item: &Item<'_>, def: &EnumDef<'_>) {
229+
let first = match def.variants.first() {
230+
Some(variant) => variant.ident.name.as_str(),
231+
None => return,
232+
};
233+
let mut pre = camel_case_split(first);
234+
let mut post = pre.clone();
235+
post.reverse();
236+
for var in def.variants {
237+
let name = var.ident.name.as_str();
238+
239+
let variant_split = camel_case_split(name);
240+
if variant_split.len() == 1 {
241+
return;
242+
}
243+
244+
pre = pre
245+
.iter()
246+
.zip(variant_split.iter())
247+
.take_while(|(a, b)| a == b)
248+
.map(|e| *e.0)
249+
.collect();
250+
post = post
251+
.iter()
252+
.zip(variant_split.iter().rev())
253+
.take_while(|(a, b)| a == b)
254+
.map(|e| *e.0)
255+
.collect();
256+
}
257+
let (what, value) = match (have_no_extra_prefix(&pre), post.is_empty()) {
258+
(true, true) => return,
259+
(false, _) => ("pre", pre.join("")),
260+
(true, false) => {
261+
post.reverse();
262+
("post", post.join(""))
263+
},
264+
};
265+
span_lint_and_help(
266+
cx,
267+
ENUM_VARIANT_NAMES,
268+
item.span,
269+
format!("all variants have the same {what}fix: `{value}`"),
270+
None,
271+
format!(
272+
"remove the {what}fixes and use full paths to \
273+
the variants instead of glob imports"
274+
),
275+
);
208276
}
209277

210-
fn check_common_affix(&self, cx: &LateContext<'_>, item: &Item<'_>, fields: &[FieldDef<'_>]) {
278+
fn check_struct_common_affix(&self, cx: &LateContext<'_>, item: &Item<'_>, fields: &[FieldDef<'_>]) {
211279
// if the SyntaxContext of the identifiers of the fields and struct differ dont lint them.
212280
// this prevents linting in macros in which the location of the field identifier names differ
213281
if !fields.iter().all(|field| item.ident.span.eq_ctxt(field.ident.span)) {
@@ -357,65 +425,6 @@ fn check_enum_end(cx: &LateContext<'_>, item_name: &str, variant: &Variant<'_>)
357425
}
358426
}
359427

360-
fn check_variant(cx: &LateContext<'_>, threshold: u64, def: &EnumDef<'_>, item_name: &str, span: Span) {
361-
if (def.variants.len() as u64) < threshold {
362-
return;
363-
}
364-
365-
for var in def.variants {
366-
check_enum_start(cx, item_name, var);
367-
check_enum_end(cx, item_name, var);
368-
}
369-
370-
let first = match def.variants.first() {
371-
Some(variant) => variant.ident.name.as_str(),
372-
None => return,
373-
};
374-
let mut pre = camel_case_split(first);
375-
let mut post = pre.clone();
376-
post.reverse();
377-
for var in def.variants {
378-
let name = var.ident.name.as_str();
379-
380-
let variant_split = camel_case_split(name);
381-
if variant_split.len() == 1 {
382-
return;
383-
}
384-
385-
pre = pre
386-
.iter()
387-
.zip(variant_split.iter())
388-
.take_while(|(a, b)| a == b)
389-
.map(|e| *e.0)
390-
.collect();
391-
post = post
392-
.iter()
393-
.zip(variant_split.iter().rev())
394-
.take_while(|(a, b)| a == b)
395-
.map(|e| *e.0)
396-
.collect();
397-
}
398-
let (what, value) = match (have_no_extra_prefix(&pre), post.is_empty()) {
399-
(true, true) => return,
400-
(false, _) => ("pre", pre.join("")),
401-
(true, false) => {
402-
post.reverse();
403-
("post", post.join(""))
404-
},
405-
};
406-
span_lint_and_help(
407-
cx,
408-
ENUM_VARIANT_NAMES,
409-
span,
410-
format!("all variants have the same {what}fix: `{value}`"),
411-
None,
412-
format!(
413-
"remove the {what}fixes and use full paths to \
414-
the variants instead of glob imports"
415-
),
416-
);
417-
}
418-
419428
impl LateLintPass<'_> for ItemNameRepetitions {
420429
fn check_item_post(&mut self, _cx: &LateContext<'_>, _item: &Item<'_>) {
421430
let last = self.modules.pop();
@@ -482,11 +491,7 @@ impl LateLintPass<'_> for ItemNameRepetitions {
482491
if span_is_local(item.span) {
483492
match item.kind {
484493
ItemKind::Enum(def, _) => {
485-
if !(self.avoid_breaking_exported_api
486-
&& cx.effective_visibilities.is_exported(item.owner_id.def_id))
487-
{
488-
check_variant(cx, self.enum_threshold, &def, item_name, item.span);
489-
}
494+
self.check_variants(cx, item, &def);
490495
},
491496
ItemKind::Struct(VariantData::Struct { fields, .. }, _) => {
492497
self.check_fields(cx, item, fields);

0 commit comments

Comments
 (0)