1
- use crate :: utils:: { UpdateMode , exit_with_failure , replace_region_in_file } ;
1
+ use crate :: utils:: { FileUpdater , UpdateMode , UpdateStatus , update_text_region_fn } ;
2
2
use itertools:: Itertools ;
3
3
use rustc_lexer:: { LiteralKind , TokenKind , tokenize} ;
4
4
use rustc_literal_escaper:: { Mode , unescape_unicode} ;
5
5
use std:: collections:: { HashMap , HashSet } ;
6
6
use std:: ffi:: OsStr ;
7
- use std:: fmt:: { self , Write } ;
7
+ use std:: fmt:: Write ;
8
8
use std:: fs;
9
9
use std:: ops:: Range ;
10
10
use std:: path:: Path ;
@@ -33,74 +33,77 @@ pub fn update(update_mode: UpdateMode) {
33
33
pub fn generate_lint_files (
34
34
update_mode : UpdateMode ,
35
35
lints : & [ Lint ] ,
36
- deprecated_lints : & [ DeprecatedLint ] ,
37
- renamed_lints : & [ RenamedLint ] ,
36
+ deprecated : & [ DeprecatedLint ] ,
37
+ renamed : & [ RenamedLint ] ,
38
38
) {
39
39
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" ,
95
43
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
+ ] ,
97
106
) ;
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) ;
104
107
}
105
108
106
109
pub fn print_lints ( ) {
@@ -125,19 +128,6 @@ fn round_to_fifty(count: usize) -> usize {
125
128
count / 50 * 50
126
129
}
127
130
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
-
141
131
/// Lint data parsed from the Clippy source code.
142
132
#[ derive( Clone , PartialEq , Eq , Debug ) ]
143
133
pub struct Lint {
@@ -194,51 +184,25 @@ impl RenamedLint {
194
184
}
195
185
}
196
186
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
+ }
232
196
}
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
+ }
238
202
}
203
+ dst. push_str ( "\n fn main() {}\n " ) ;
204
+ UpdateStatus :: from_changed ( src != dst)
239
205
}
240
- res. push_str ( "\n fn main() {}\n " ) ;
241
- res
242
206
}
243
207
244
208
/// Gathers all lints defined in `clippy_lints/src`
0 commit comments