1- use crate :: utils:: { UpdateMode , exit_with_failure , replace_region_in_file } ;
1+ use crate :: utils:: { FileUpdater , UpdateMode , UpdateStatus , update_text_region_fn } ;
22use itertools:: Itertools ;
33use rustc_lexer:: { LiteralKind , TokenKind , tokenize} ;
44use rustc_literal_escaper:: { Mode , unescape_unicode} ;
55use std:: collections:: { HashMap , HashSet } ;
66use std:: ffi:: OsStr ;
7- use std:: fmt:: { self , Write } ;
7+ use std:: fmt:: Write ;
88use std:: fs;
99use std:: ops:: Range ;
1010use std:: path:: Path ;
@@ -33,74 +33,77 @@ pub fn update(update_mode: UpdateMode) {
3333pub fn generate_lint_files (
3434 update_mode : UpdateMode ,
3535 lints : & [ Lint ] ,
36- deprecated_lints : & [ DeprecatedLint ] ,
37- renamed_lints : & [ RenamedLint ] ,
36+ deprecated : & [ DeprecatedLint ] ,
37+ renamed : & [ RenamedLint ] ,
3838) {
3939 let mut lints = lints. to_owned ( ) ;
40- lints. sort_by_key ( |lint| lint. name . clone ( ) ) ;
41-
42- replace_region_in_file (
43- update_mode,
44- Path :: new ( "README.md" ) ,
45- "[There are over " ,
46- " lints included in this crate!]" ,
47- |res| {
48- write ! ( res, "{}" , round_to_fifty( lints. len( ) ) ) . unwrap ( ) ;
49- } ,
50- ) ;
51-
52- replace_region_in_file (
53- update_mode,
54- Path :: new ( "book/src/README.md" ) ,
55- "[There are over " ,
56- " lints included in this crate!]" ,
57- |res| {
58- write ! ( res, "{}" , round_to_fifty( lints. len( ) ) ) . unwrap ( ) ;
59- } ,
60- ) ;
61-
62- replace_region_in_file (
63- update_mode,
64- Path :: new ( "CHANGELOG.md" ) ,
65- "<!-- begin autogenerated links to lint list -->\n " ,
66- "<!-- end autogenerated links to lint list -->" ,
67- |res| {
68- for lint in lints
69- . iter ( )
70- . map ( |l| & * l. name )
71- . chain ( deprecated_lints. iter ( ) . filter_map ( |l| l. name . strip_prefix ( "clippy::" ) ) )
72- . chain ( renamed_lints. iter ( ) . filter_map ( |l| l. old_name . strip_prefix ( "clippy::" ) ) )
73- . sorted ( )
74- {
75- writeln ! ( res, "[`{lint}`]: {DOCS_LINK}#{lint}" ) . unwrap ( ) ;
76- }
77- } ,
78- ) ;
79-
80- // This has to be in lib.rs, otherwise rustfmt doesn't work
81- replace_region_in_file (
82- update_mode,
83- Path :: new ( "clippy_lints/src/lib.rs" ) ,
84- "// begin lints modules, do not remove this comment, it’s used in `update_lints`\n " ,
85- "// end lints modules, do not remove this comment, it’s used in `update_lints`" ,
86- |res| {
87- for lint_mod in lints. iter ( ) . map ( |l| & l. module ) . unique ( ) . sorted ( ) {
88- writeln ! ( res, "mod {lint_mod};" ) . unwrap ( ) ;
89- }
90- } ,
91- ) ;
92-
93- process_file (
94- "clippy_lints/src/declared_lints.rs" ,
40+ lints. sort_by ( |lhs, rhs| lhs. name . cmp ( & rhs. name ) ) ;
41+ FileUpdater :: default ( ) . update_files_checked (
42+ "cargo dev update_lints" ,
9543 update_mode,
96- & gen_declared_lints ( lints. iter ( ) ) ,
44+ & mut [
45+ (
46+ "README.md" ,
47+ & mut update_text_region_fn ( "[There are over " , " lints included in this crate!]" , |dst| {
48+ write ! ( dst, "{}" , round_to_fifty( lints. len( ) ) ) . unwrap ( ) ;
49+ } ) ,
50+ ) ,
51+ (
52+ "book/src/README.md" ,
53+ & mut update_text_region_fn ( "[There are over " , " lints included in this crate!]" , |dst| {
54+ write ! ( dst, "{}" , round_to_fifty( lints. len( ) ) ) . unwrap ( ) ;
55+ } ) ,
56+ ) ,
57+ (
58+ "CHANGELOG.md" ,
59+ & mut update_text_region_fn (
60+ "<!-- begin autogenerated links to lint list -->\n " ,
61+ "<!-- end autogenerated links to lint list -->" ,
62+ |dst| {
63+ for lint in lints
64+ . iter ( )
65+ . map ( |l| & * l. name )
66+ . chain ( deprecated. iter ( ) . filter_map ( |l| l. name . strip_prefix ( "clippy::" ) ) )
67+ . chain ( renamed. iter ( ) . filter_map ( |l| l. old_name . strip_prefix ( "clippy::" ) ) )
68+ . sorted ( )
69+ {
70+ writeln ! ( dst, "[`{lint}`]: {DOCS_LINK}#{lint}" ) . unwrap ( ) ;
71+ }
72+ } ,
73+ ) ,
74+ ) ,
75+ (
76+ "clippy_lints/src/lib.rs" ,
77+ & mut update_text_region_fn (
78+ "// begin lints modules, do not remove this comment, it’s used in `update_lints`\n " ,
79+ "// end lints modules, do not remove this comment, it’s used in `update_lints`" ,
80+ |dst| {
81+ for lint_mod in lints. iter ( ) . map ( |l| & l. module ) . sorted ( ) . dedup ( ) {
82+ writeln ! ( dst, "mod {lint_mod};" ) . unwrap ( ) ;
83+ }
84+ } ,
85+ ) ,
86+ ) ,
87+ ( "clippy_lints/src/declared_lints.rs" , & mut |_, src, dst| {
88+ dst. push_str ( GENERATED_FILE_COMMENT ) ;
89+ dst. push_str ( "pub static LINTS: &[&crate::LintInfo] = &[\n " ) ;
90+ for ( module_name, lint_name) in lints. iter ( ) . map ( |l| ( & l. module , l. name . to_uppercase ( ) ) ) . sorted ( ) {
91+ writeln ! ( dst, " crate::{module_name}::{lint_name}_INFO," ) . unwrap ( ) ;
92+ }
93+ dst. push_str ( "];\n " ) ;
94+ UpdateStatus :: from_changed ( src != dst)
95+ } ) ,
96+ ( "tests/ui/deprecated.rs" , & mut |_, src, dst| {
97+ dst. push_str ( GENERATED_FILE_COMMENT ) ;
98+ for lint in deprecated {
99+ writeln ! ( dst, "#![warn({})] //~ ERROR: lint `{}`" , lint. name, lint. name) . unwrap ( ) ;
100+ }
101+ dst. push_str ( "\n fn main() {}\n " ) ;
102+ UpdateStatus :: from_changed ( src != dst)
103+ } ) ,
104+ ( "tests/ui/rename.rs" , & mut gen_renamed_lints_test_fn ( renamed) ) ,
105+ ] ,
97106 ) ;
98-
99- let content = gen_deprecated_lints_test ( deprecated_lints) ;
100- process_file ( "tests/ui/deprecated.rs" , update_mode, & content) ;
101-
102- let content = gen_renamed_lints_test ( renamed_lints) ;
103- process_file ( "tests/ui/rename.rs" , update_mode, & content) ;
104107}
105108
106109pub fn print_lints ( ) {
@@ -125,19 +128,6 @@ fn round_to_fifty(count: usize) -> usize {
125128 count / 50 * 50
126129}
127130
128- fn process_file ( path : impl AsRef < Path > , update_mode : UpdateMode , content : & str ) {
129- if update_mode == UpdateMode :: Check {
130- let old_content =
131- fs:: read_to_string ( & path) . unwrap_or_else ( |e| panic ! ( "Cannot read from {}: {e}" , path. as_ref( ) . display( ) ) ) ;
132- if content != old_content {
133- exit_with_failure ( ) ;
134- }
135- } else {
136- fs:: write ( & path, content. as_bytes ( ) )
137- . unwrap_or_else ( |e| panic ! ( "Cannot write to {}: {e}" , path. as_ref( ) . display( ) ) ) ;
138- }
139- }
140-
141131/// Lint data parsed from the Clippy source code.
142132#[ derive( Clone , PartialEq , Eq , Debug ) ]
143133pub struct Lint {
@@ -194,51 +184,25 @@ impl RenamedLint {
194184 }
195185}
196186
197- /// Generates the code for registering lints
198- #[ must_use]
199- fn gen_declared_lints < ' a > ( lints : impl Iterator < Item = & ' a Lint > ) -> String {
200- let mut details: Vec < _ > = lints. map ( |l| ( & l. module , l. name . to_uppercase ( ) ) ) . collect ( ) ;
201- details. sort_unstable ( ) ;
202-
203- let mut output = GENERATED_FILE_COMMENT . to_string ( ) ;
204- output. push_str ( "pub static LINTS: &[&crate::LintInfo] = &[\n " ) ;
205-
206- for ( module_name, lint_name) in details {
207- let _: fmt:: Result = writeln ! ( output, " crate::{module_name}::{lint_name}_INFO," ) ;
208- }
209- output. push_str ( "];\n " ) ;
210-
211- output
212- }
213-
214- fn gen_deprecated_lints_test ( lints : & [ DeprecatedLint ] ) -> String {
215- let mut res: String = GENERATED_FILE_COMMENT . into ( ) ;
216- for lint in lints {
217- writeln ! ( res, "#![warn({})] //~ ERROR: lint `{}`" , lint. name, lint. name) . unwrap ( ) ;
218- }
219- res. push_str ( "\n fn main() {}\n " ) ;
220- res
221- }
222-
223- #[ must_use]
224- pub fn gen_renamed_lints_test ( lints : & [ RenamedLint ] ) -> String {
225- let mut seen_lints = HashSet :: new ( ) ;
226- let mut res: String = GENERATED_FILE_COMMENT . into ( ) ;
227-
228- res. push_str ( "#![allow(clippy::duplicated_attributes)]\n " ) ;
229- for lint in lints {
230- if seen_lints. insert ( & lint. new_name ) {
231- writeln ! ( res, "#![allow({})]" , lint. new_name) . unwrap ( ) ;
187+ pub fn gen_renamed_lints_test_fn ( lints : & [ RenamedLint ] ) -> impl Fn ( & Path , & str , & mut String ) -> UpdateStatus {
188+ move |_, src, dst| {
189+ let mut seen_lints = HashSet :: new ( ) ;
190+ dst. push_str ( GENERATED_FILE_COMMENT ) ;
191+ dst. push_str ( "#![allow(clippy::duplicated_attributes)]\n " ) ;
192+ for lint in lints {
193+ if seen_lints. insert ( & lint. new_name ) {
194+ writeln ! ( dst, "#![allow({})]" , lint. new_name) . unwrap ( ) ;
195+ }
232196 }
233- }
234- seen_lints . clear ( ) ;
235- for lint in lints {
236- if seen_lints . insert ( & lint. old_name ) {
237- writeln ! ( res , "#![warn({})] //~ ERROR: lint `{}`" , lint . old_name , lint . old_name ) . unwrap ( ) ;
197+ seen_lints . clear ( ) ;
198+ for lint in lints {
199+ if seen_lints . insert ( & lint . old_name ) {
200+ writeln ! ( dst , "#![warn({})] //~ ERROR: lint `{}`" , lint . old_name, lint . old_name ) . unwrap ( ) ;
201+ }
238202 }
203+ dst. push_str ( "\n fn main() {}\n " ) ;
204+ UpdateStatus :: from_changed ( src != dst)
239205 }
240- res. push_str ( "\n fn main() {}\n " ) ;
241- res
242206}
243207
244208/// Gathers all lints defined in `clippy_lints/src`
0 commit comments