11use core:: fmt:: Write ;
22use itertools:: Itertools ;
33use rustc_lexer:: { tokenize, unescape, LiteralKind , TokenKind } ;
4- use std:: collections:: HashMap ;
4+ use std:: collections:: { HashMap , HashSet } ;
55use std:: ffi:: OsStr ;
66use std:: fs;
77use std:: path:: Path ;
@@ -32,7 +32,7 @@ pub enum UpdateMode {
3232/// Panics if a file path could not read from or then written to
3333#[ allow( clippy:: too_many_lines) ]
3434pub fn run ( update_mode : UpdateMode ) {
35- let ( lints, deprecated_lints) = gather_all ( ) ;
35+ let ( lints, deprecated_lints, renamed_lints ) = gather_all ( ) ;
3636
3737 let internal_lints = Lint :: internal_lints ( & lints) ;
3838 let usable_lints = Lint :: usable_lints ( & lints) ;
@@ -110,10 +110,13 @@ pub fn run(update_mode: UpdateMode) {
110110
111111 let content = gen_deprecated_lints_test ( & deprecated_lints) ;
112112 process_file ( "tests/ui/deprecated.rs" , update_mode, & content) ;
113+
114+ let content = gen_renamed_lints_test ( & renamed_lints) ;
115+ process_file ( "tests/ui/rename.rs" , update_mode, & content) ;
113116}
114117
115118pub fn print_lints ( ) {
116- let ( lint_list, _) = gather_all ( ) ;
119+ let ( lint_list, _, _ ) = gather_all ( ) ;
117120 let usable_lints = Lint :: usable_lints ( & lint_list) ;
118121 let usable_lint_count = usable_lints. len ( ) ;
119122 let grouped_by_lint_group = Lint :: by_lint_group ( usable_lints. into_iter ( ) ) ;
@@ -213,6 +216,19 @@ impl DeprecatedLint {
213216 }
214217}
215218
219+ struct RenamedLint {
220+ old_name : String ,
221+ new_name : String ,
222+ }
223+ impl RenamedLint {
224+ fn new ( old_name : & str , new_name : & str ) -> Self {
225+ Self {
226+ old_name : remove_line_splices ( old_name) ,
227+ new_name : remove_line_splices ( new_name) ,
228+ }
229+ }
230+ }
231+
216232/// Generates the code for registering a group
217233fn gen_lint_group_list < ' a > ( group_name : & str , lints : impl Iterator < Item = & ' a Lint > ) -> String {
218234 let mut details: Vec < _ > = lints. map ( |l| ( & l. module , l. name . to_uppercase ( ) ) ) . collect ( ) ;
@@ -288,10 +304,30 @@ fn gen_deprecated_lints_test(lints: &[DeprecatedLint]) -> String {
288304 res
289305}
290306
307+ fn gen_renamed_lints_test ( lints : & [ RenamedLint ] ) -> String {
308+ let mut seen_lints = HashSet :: new ( ) ;
309+ let mut res: String = GENERATED_FILE_COMMENT . into ( ) ;
310+ res. push_str ( "// run-rustfix\n \n " ) ;
311+ for lint in lints {
312+ if seen_lints. insert ( & lint. new_name ) {
313+ writeln ! ( res, "#![allow({})]" , lint. new_name) . unwrap ( ) ;
314+ }
315+ }
316+ seen_lints. clear ( ) ;
317+ for lint in lints {
318+ if seen_lints. insert ( & lint. old_name ) {
319+ writeln ! ( res, "#![warn({})]" , lint. old_name) . unwrap ( ) ;
320+ }
321+ }
322+ res. push_str ( "\n fn main() {}\n " ) ;
323+ res
324+ }
325+
291326/// Gathers all lints defined in `clippy_lints/src`
292- fn gather_all ( ) -> ( Vec < Lint > , Vec < DeprecatedLint > ) {
327+ fn gather_all ( ) -> ( Vec < Lint > , Vec < DeprecatedLint > , Vec < RenamedLint > ) {
293328 let mut lints = Vec :: with_capacity ( 1000 ) ;
294329 let mut deprecated_lints = Vec :: with_capacity ( 50 ) ;
330+ let mut renamed_lints = Vec :: with_capacity ( 50 ) ;
295331 let root_path = clippy_project_root ( ) . join ( "clippy_lints/src" ) ;
296332
297333 for ( rel_path, file) in WalkDir :: new ( & root_path)
@@ -317,13 +353,13 @@ fn gather_all() -> (Vec<Lint>, Vec<DeprecatedLint>) {
317353 module. strip_suffix ( ".rs" ) . unwrap_or ( & module)
318354 } ;
319355
320- if module == "deprecated_lints" {
321- parse_deprecated_contents ( & contents, & mut deprecated_lints) ;
322- } else {
323- parse_contents ( & contents, module, & mut lints) ;
356+ match module {
357+ "deprecated_lints" => parse_deprecated_contents ( & contents, & mut deprecated_lints) ,
358+ "renamed_lints" => parse_renamed_contents ( & contents , & mut renamed_lints ) ,
359+ _ => parse_contents ( & contents, module, & mut lints) ,
324360 }
325361 }
326- ( lints, deprecated_lints)
362+ ( lints, deprecated_lints, renamed_lints )
327363}
328364
329365macro_rules! match_tokens {
@@ -406,6 +442,25 @@ fn parse_deprecated_contents(contents: &str, lints: &mut Vec<DeprecatedLint>) {
406442 }
407443}
408444
445+ fn parse_renamed_contents ( contents : & str , lints : & mut Vec < RenamedLint > ) {
446+ for line in contents. lines ( ) {
447+ let mut offset = 0usize ;
448+ let mut iter = tokenize ( line) . map ( |t| {
449+ let range = offset..offset + t. len ;
450+ offset = range. end ;
451+ ( t. kind , & line[ range] )
452+ } ) ;
453+ let ( old_name, new_name) = match_tokens ! (
454+ iter,
455+ // ("old_name",
456+ Whitespace OpenParen Literal { kind: LiteralKind :: Str { ..} , ..} ( old_name) Comma
457+ // "new_name"),
458+ Whitespace Literal { kind: LiteralKind :: Str { ..} , ..} ( new_name) CloseParen Comma
459+ ) ;
460+ lints. push ( RenamedLint :: new ( old_name, new_name) ) ;
461+ }
462+ }
463+
409464/// Removes the line splices and surrounding quotes from a string literal
410465fn remove_line_splices ( s : & str ) -> String {
411466 let s = s
0 commit comments