33use clippy_utils:: camel_case;
44use clippy_utils:: diagnostics:: { span_lint, span_lint_and_help} ;
55use clippy_utils:: source:: is_present_in_source;
6- use rustc_ast :: ast :: { EnumDef , Item , ItemKind , VisibilityKind } ;
7- use rustc_lint:: { EarlyContext , EarlyLintPass , Lint } ;
6+ use rustc_hir :: { EnumDef , Item , ItemKind } ;
7+ use rustc_lint:: { LateContext , LateLintPass } ;
88use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
99use rustc_span:: source_map:: Span ;
1010use rustc_span:: symbol:: Symbol ;
@@ -39,36 +39,6 @@ declare_clippy_lint! {
3939 "enums where all variants share a prefix/postfix"
4040}
4141
42- declare_clippy_lint ! {
43- /// **What it does:** Detects public enumeration variants that are
44- /// prefixed or suffixed by the same characters.
45- ///
46- /// **Why is this bad?** Public enumeration variant names should specify their variant,
47- /// not repeat the enumeration name.
48- ///
49- /// **Known problems:** None.
50- ///
51- /// **Example:**
52- /// ```rust
53- /// pub enum Cake {
54- /// BlackForestCake,
55- /// HummingbirdCake,
56- /// BattenbergCake,
57- /// }
58- /// ```
59- /// Could be written as:
60- /// ```rust
61- /// pub enum Cake {
62- /// BlackForest,
63- /// Hummingbird,
64- /// Battenberg,
65- /// }
66- /// ```
67- pub PUB_ENUM_VARIANT_NAMES ,
68- pedantic,
69- "public enums where all variants share a prefix/postfix"
70- }
71-
7242declare_clippy_lint ! {
7343 /// **What it does:** Detects type names that are prefixed or suffixed by the
7444 /// containing module's name.
@@ -127,21 +97,22 @@ declare_clippy_lint! {
12797pub struct EnumVariantNames {
12898 modules : Vec < ( Symbol , String ) > ,
12999 threshold : u64 ,
100+ avoid_breaking_exported_api : bool ,
130101}
131102
132103impl EnumVariantNames {
133104 #[ must_use]
134- pub fn new ( threshold : u64 ) -> Self {
105+ pub fn new ( threshold : u64 , avoid_breaking_exported_api : bool ) -> Self {
135106 Self {
136107 modules : Vec :: new ( ) ,
137108 threshold,
109+ avoid_breaking_exported_api,
138110 }
139111 }
140112}
141113
142114impl_lint_pass ! ( EnumVariantNames => [
143115 ENUM_VARIANT_NAMES ,
144- PUB_ENUM_VARIANT_NAMES ,
145116 MODULE_NAME_REPETITIONS ,
146117 MODULE_INCEPTION
147118] ) ;
@@ -167,33 +138,42 @@ fn partial_rmatch(post: &str, name: &str) -> usize {
167138}
168139
169140fn check_variant (
170- cx : & EarlyContext < ' _ > ,
141+ cx : & LateContext < ' _ > ,
171142 threshold : u64 ,
172- def : & EnumDef ,
143+ def : & EnumDef < ' _ > ,
173144 item_name : & str ,
174145 item_name_chars : usize ,
175146 span : Span ,
176- lint : & ' static Lint ,
177147) {
178148 if ( def. variants . len ( ) as u64 ) < threshold {
179149 return ;
180150 }
181- for var in & def. variants {
151+ for var in def. variants {
182152 let name = var. ident . name . as_str ( ) ;
183153 if partial_match ( item_name, & name) == item_name_chars
184154 && name. chars ( ) . nth ( item_name_chars) . map_or ( false , |c| !c. is_lowercase ( ) )
185155 && name. chars ( ) . nth ( item_name_chars + 1 ) . map_or ( false , |c| !c. is_numeric ( ) )
186156 {
187- span_lint ( cx, lint, var. span , "variant name starts with the enum's name" ) ;
157+ span_lint (
158+ cx,
159+ ENUM_VARIANT_NAMES ,
160+ var. span ,
161+ "variant name starts with the enum's name" ,
162+ ) ;
188163 }
189164 if partial_rmatch ( item_name, & name) == item_name_chars {
190- span_lint ( cx, lint, var. span , "variant name ends with the enum's name" ) ;
165+ span_lint (
166+ cx,
167+ ENUM_VARIANT_NAMES ,
168+ var. span ,
169+ "variant name ends with the enum's name" ,
170+ ) ;
191171 }
192172 }
193173 let first = & def. variants [ 0 ] . ident . name . as_str ( ) ;
194174 let mut pre = & first[ ..camel_case:: until ( & * first) ] ;
195175 let mut post = & first[ camel_case:: from ( & * first) ..] ;
196- for var in & def. variants {
176+ for var in def. variants {
197177 let name = var. ident . name . as_str ( ) ;
198178
199179 let pre_match = partial_match ( pre, & name) ;
@@ -226,7 +206,7 @@ fn check_variant(
226206 } ;
227207 span_lint_and_help (
228208 cx,
229- lint ,
209+ ENUM_VARIANT_NAMES ,
230210 span,
231211 & format ! ( "all variants have the same {}fix: `{}`" , what, value) ,
232212 None ,
@@ -261,14 +241,14 @@ fn to_camel_case(item_name: &str) -> String {
261241 s
262242}
263243
264- impl EarlyLintPass for EnumVariantNames {
265- fn check_item_post ( & mut self , _cx : & EarlyContext < ' _ > , _item : & Item ) {
244+ impl LateLintPass < ' _ > for EnumVariantNames {
245+ fn check_item_post ( & mut self , _cx : & LateContext < ' _ > , _item : & Item < ' _ > ) {
266246 let last = self . modules . pop ( ) ;
267247 assert ! ( last. is_some( ) ) ;
268248 }
269249
270250 #[ allow( clippy:: similar_names) ]
271- fn check_item ( & mut self , cx : & EarlyContext < ' _ > , item : & Item ) {
251+ fn check_item ( & mut self , cx : & LateContext < ' _ > , item : & Item < ' _ > ) {
272252 let item_name = item. ident . name . as_str ( ) ;
273253 let item_name_chars = item_name. chars ( ) . count ( ) ;
274254 let item_camel = to_camel_case ( & item_name) ;
@@ -286,7 +266,7 @@ impl EarlyLintPass for EnumVariantNames {
286266 ) ;
287267 }
288268 }
289- if item. vis . kind . is_pub ( ) {
269+ if item. vis . node . is_pub ( ) {
290270 let matching = partial_match ( mod_camel, & item_camel) ;
291271 let rmatching = partial_rmatch ( mod_camel, & item_camel) ;
292272 let nchars = mod_camel. chars ( ) . count ( ) ;
@@ -317,11 +297,9 @@ impl EarlyLintPass for EnumVariantNames {
317297 }
318298 }
319299 if let ItemKind :: Enum ( ref def, _) = item. kind {
320- let lint = match item. vis . kind {
321- VisibilityKind :: Public => PUB_ENUM_VARIANT_NAMES ,
322- _ => ENUM_VARIANT_NAMES ,
323- } ;
324- check_variant ( cx, self . threshold , def, & item_name, item_name_chars, item. span , lint) ;
300+ if !( self . avoid_breaking_exported_api && cx. access_levels . is_exported ( item. hir_id ( ) ) ) {
301+ check_variant ( cx, self . threshold , def, & item_name, item_name_chars, item. span ) ;
302+ }
325303 }
326304 self . modules . push ( ( item. ident . name , item_camel) ) ;
327305 }
0 commit comments