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