@@ -8,7 +8,6 @@ use rustc_data_structures::fx::FxHashSet;
8
8
use rustc_hir:: { EnumDef , FieldDef , Item , ItemKind , OwnerId , Variant , VariantData } ;
9
9
use rustc_lint:: { LateContext , LateLintPass } ;
10
10
use rustc_session:: impl_lint_pass;
11
- use rustc_span:: Span ;
12
11
use rustc_span:: symbol:: Symbol ;
13
12
14
13
declare_clippy_lint ! {
@@ -197,17 +196,86 @@ fn have_no_extra_prefix(prefixes: &[&str]) -> bool {
197
196
}
198
197
199
198
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
+
200
218
/// Lint the names of struct fields against the name of the struct.
201
219
fn check_fields ( & self , cx : & LateContext < ' _ > , item : & Item < ' _ > , fields : & [ FieldDef < ' _ > ] ) {
202
220
if ( fields. len ( ) as u64 ) < self . struct_threshold {
203
221
return ;
204
222
}
205
223
206
224
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
+ ) ;
208
276
}
209
277
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 < ' _ > ] ) {
211
279
// if the SyntaxContext of the identifiers of the fields and struct differ dont lint them.
212
280
// this prevents linting in macros in which the location of the field identifier names differ
213
281
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<'_>)
357
425
}
358
426
}
359
427
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
-
419
428
impl LateLintPass < ' _ > for ItemNameRepetitions {
420
429
fn check_item_post ( & mut self , _cx : & LateContext < ' _ > , _item : & Item < ' _ > ) {
421
430
let last = self . modules . pop ( ) ;
@@ -482,11 +491,7 @@ impl LateLintPass<'_> for ItemNameRepetitions {
482
491
if span_is_local ( item. span ) {
483
492
match item. kind {
484
493
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) ;
490
495
} ,
491
496
ItemKind :: Struct ( VariantData :: Struct { fields, .. } , _) => {
492
497
self . check_fields ( cx, item, fields) ;
0 commit comments