@@ -14,6 +14,43 @@ const GENERATED_FILE_COMMENT: &str = "// This file was generated by `cargo dev u
14
14
15
15
const DOCS_LINK : & str = "https://rust-lang.github.io/rust-clippy/master/index.html" ;
16
16
17
+ macro_rules! declare_lint_crates {
18
+ ( $( $name: ident, ) * ) => {
19
+ #[ allow( non_camel_case_types) ]
20
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
21
+ pub enum Crate {
22
+ $( $name) ,*
23
+ }
24
+ impl Crate {
25
+ #[ must_use]
26
+ pub fn src_path( self ) -> & ' static str {
27
+ match self {
28
+ $( Self :: $name => concat!( stringify!( $name) , "/src" ) ) ,*
29
+ }
30
+ }
31
+
32
+ fn crate_root_path( self ) -> & ' static str {
33
+ match self {
34
+ $( Self :: $name => concat!( stringify!( $name) , "/src/lib.rs" ) ) ,*
35
+ }
36
+ }
37
+
38
+ fn declared_lints_path( self ) -> & ' static str {
39
+ match self {
40
+ $( Self :: $name => concat!( stringify!( $name) , "/src/declared_lints.rs" ) ) ,*
41
+ }
42
+ }
43
+
44
+ fn all( ) -> impl Iterator <Item = Crate > {
45
+ [ $( Self :: $name) ,* ] . into_iter( )
46
+ }
47
+ }
48
+ }
49
+ }
50
+ declare_lint_crates ! {
51
+ clippy_lints,
52
+ }
53
+
17
54
/// Runs the `update_lints` command.
18
55
///
19
56
/// This updates various generated values from the lint source code.
@@ -36,123 +73,159 @@ pub fn generate_lint_files(
36
73
deprecated : & [ DeprecatedLint ] ,
37
74
renamed : & [ RenamedLint ] ,
38
75
) {
39
- FileUpdater :: default ( ) . update_files_checked (
76
+ let mut updater = FileUpdater :: default ( ) ;
77
+ updater. update_file_checked (
40
78
"cargo dev update_lints" ,
41
79
update_mode,
42
- & mut [
43
- (
44
- "README.md" ,
45
- & mut update_text_region_fn ( "[There are over " , " lints included in this crate!]" , |dst| {
46
- write ! ( dst, "{}" , round_to_fifty( lints. len( ) ) ) . unwrap ( ) ;
47
- } ) ,
48
- ) ,
49
- (
50
- "book/src/README.md" ,
51
- & mut update_text_region_fn ( "[There are over " , " lints included in this crate!]" , |dst| {
52
- write ! ( dst, "{}" , round_to_fifty( lints. len( ) ) ) . unwrap ( ) ;
53
- } ) ,
54
- ) ,
55
- (
56
- "CHANGELOG.md" ,
57
- & mut update_text_region_fn (
58
- "<!-- begin autogenerated links to lint list -->\n " ,
59
- "<!-- end autogenerated links to lint list -->" ,
60
- |dst| {
61
- for lint in lints
62
- . iter ( )
63
- . map ( |l| & * l. name )
64
- . chain ( deprecated. iter ( ) . filter_map ( |l| l. name . strip_prefix ( "clippy::" ) ) )
65
- . chain ( renamed. iter ( ) . filter_map ( |l| l. old_name . strip_prefix ( "clippy::" ) ) )
66
- . sorted ( )
67
- {
68
- writeln ! ( dst, "[`{lint}`]: {DOCS_LINK}#{lint}" ) . unwrap ( ) ;
69
- }
70
- } ,
71
- ) ,
72
- ) ,
73
- (
74
- "clippy_lints/src/lib.rs" ,
75
- & mut update_text_region_fn (
76
- "// begin lints modules, do not remove this comment, it’s used in `update_lints`\n " ,
77
- "// end lints modules, do not remove this comment, it’s used in `update_lints`" ,
78
- |dst| {
79
- for lint_mod in lints. iter ( ) . map ( |l| & l. module ) . sorted ( ) . dedup ( ) {
80
- writeln ! ( dst, "mod {lint_mod};" ) . unwrap ( ) ;
81
- }
82
- } ,
83
- ) ,
84
- ) ,
85
- ( "clippy_lints/src/declared_lints.rs" , & mut |_, src, dst| {
86
- dst. push_str ( GENERATED_FILE_COMMENT ) ;
87
- dst. push_str ( "pub static LINTS: &[&crate::LintInfo] = &[\n " ) ;
88
- for ( module_name, lint_name) in lints. iter ( ) . map ( |l| ( & l. module , l. name . to_uppercase ( ) ) ) . sorted ( ) {
89
- writeln ! ( dst, " crate::{module_name}::{lint_name}_INFO," ) . unwrap ( ) ;
90
- }
91
- dst. push_str ( "];\n " ) ;
92
- UpdateStatus :: from_changed ( src != dst)
93
- } ) ,
94
- ( "clippy_lints/src/deprecated_lints.rs" , & mut |_, src, dst| {
95
- let mut searcher = RustSearcher :: new ( src) ;
96
- assert ! (
97
- searcher. find_token( Token :: Ident ( "declare_with_version" ) )
98
- && searcher. find_token( Token :: Ident ( "declare_with_version" ) ) ,
99
- "error reading deprecated lints"
100
- ) ;
101
- dst. push_str ( & src[ ..searcher. pos ( ) as usize ] ) ;
102
- dst. push_str ( "! { DEPRECATED(DEPRECATED_VERSION) = [\n " ) ;
103
- for lint in deprecated {
104
- write ! (
105
- dst,
106
- " #[clippy::version = \" {}\" ]\n (\" {}\" , \" {}\" ),\n " ,
107
- lint. version, lint. name, lint. reason,
108
- )
109
- . unwrap ( ) ;
80
+ "README.md" ,
81
+ & mut update_text_region_fn ( "[There are over " , " lints included in this crate!]" , |dst| {
82
+ write ! ( dst, "{}" , round_to_fifty( lints. len( ) ) ) . unwrap ( ) ;
83
+ } ) ,
84
+ ) ;
85
+ updater. update_file_checked (
86
+ "cargo dev update_lints" ,
87
+ update_mode,
88
+ "book/src/README.md" ,
89
+ & mut update_text_region_fn ( "[There are over " , " lints included in this crate!]" , |dst| {
90
+ write ! ( dst, "{}" , round_to_fifty( lints. len( ) ) ) . unwrap ( ) ;
91
+ } ) ,
92
+ ) ;
93
+ updater. update_file_checked (
94
+ "cargo dev update_lints" ,
95
+ update_mode,
96
+ "CHANGELOG.md" ,
97
+ & mut update_text_region_fn (
98
+ "<!-- begin autogenerated links to lint list -->\n " ,
99
+ "<!-- end autogenerated links to lint list -->" ,
100
+ |dst| {
101
+ for lint in lints
102
+ . iter ( )
103
+ . map ( |l| & * l. name )
104
+ . chain ( deprecated. iter ( ) . filter_map ( |l| l. name . strip_prefix ( "clippy::" ) ) )
105
+ . chain ( renamed. iter ( ) . filter_map ( |l| l. old_name . strip_prefix ( "clippy::" ) ) )
106
+ . sorted ( )
107
+ {
108
+ writeln ! ( dst, "[`{lint}`]: {DOCS_LINK}#{lint}" ) . unwrap ( ) ;
110
109
}
111
- dst. push_str (
112
- "]}\n \n \
110
+ } ,
111
+ ) ,
112
+ ) ;
113
+ updater. update_file_checked (
114
+ "cargo dev update_lints" ,
115
+ update_mode,
116
+ "clippy_lints/src/deprecated_lints.rs" ,
117
+ & mut |_, src, dst| {
118
+ let mut searcher = RustSearcher :: new ( src) ;
119
+ assert ! (
120
+ searcher. find_token( Token :: Ident ( "declare_with_version" ) )
121
+ && searcher. find_token( Token :: Ident ( "declare_with_version" ) ) ,
122
+ "error reading deprecated lints"
123
+ ) ;
124
+ dst. push_str ( & src[ ..searcher. pos ( ) as usize ] ) ;
125
+ dst. push_str ( "! { DEPRECATED(DEPRECATED_VERSION) = [\n " ) ;
126
+ for lint in deprecated {
127
+ write ! (
128
+ dst,
129
+ " #[clippy::version = \" {}\" ]\n (\" {}\" , \" {}\" ),\n " ,
130
+ lint. version, lint. name, lint. reason,
131
+ )
132
+ . unwrap ( ) ;
133
+ }
134
+ dst. push_str (
135
+ "]}\n \n \
113
136
#[rustfmt::skip]\n \
114
137
declare_with_version! { RENAMED(RENAMED_VERSION) = [\n \
115
138
",
116
- ) ;
117
- for lint in renamed {
118
- write ! (
119
- dst,
120
- " #[clippy::version = \" {}\" ]\n (\" {}\" , \" {}\" ),\n " ,
121
- lint. version, lint. old_name, lint. new_name,
122
- )
123
- . unwrap ( ) ;
124
- }
125
- dst. push_str ( "]}\n " ) ;
126
- UpdateStatus :: from_changed ( src != dst)
127
- } ) ,
128
- ( "tests/ui/deprecated.rs" , & mut |_, src, dst| {
129
- dst. push_str ( GENERATED_FILE_COMMENT ) ;
130
- for lint in deprecated {
131
- writeln ! ( dst, "#![warn({})] //~ ERROR: lint `{}`" , lint. name, lint. name) . unwrap ( ) ;
139
+ ) ;
140
+ for lint in renamed {
141
+ write ! (
142
+ dst,
143
+ " #[clippy::version = \" {}\" ]\n (\" {}\" , \" {}\" ),\n " ,
144
+ lint. version, lint. old_name, lint. new_name,
145
+ )
146
+ . unwrap ( ) ;
147
+ }
148
+ dst. push_str ( "]}\n " ) ;
149
+ UpdateStatus :: from_changed ( src != dst)
150
+ } ,
151
+ ) ;
152
+ updater. update_file_checked (
153
+ "cargo dev update_lints" ,
154
+ update_mode,
155
+ "tests/ui/deprecated.rs" ,
156
+ & mut |_, src, dst| {
157
+ dst. push_str ( GENERATED_FILE_COMMENT ) ;
158
+ for lint in deprecated {
159
+ writeln ! ( dst, "#![warn({})] //~ ERROR: lint `{}`" , lint. name, lint. name) . unwrap ( ) ;
160
+ }
161
+ dst. push_str ( "\n fn main() {}\n " ) ;
162
+ UpdateStatus :: from_changed ( src != dst)
163
+ } ,
164
+ ) ;
165
+ updater. update_file_checked (
166
+ "cargo dev update_lints" ,
167
+ update_mode,
168
+ "tests/ui/rename.rs" ,
169
+ & mut move |_, src, dst| {
170
+ let mut seen_lints = HashSet :: new ( ) ;
171
+ dst. push_str ( GENERATED_FILE_COMMENT ) ;
172
+ dst. push_str ( "#![allow(clippy::duplicated_attributes)]\n " ) ;
173
+ for lint in renamed {
174
+ if seen_lints. insert ( & lint. new_name ) {
175
+ writeln ! ( dst, "#![allow({})]" , lint. new_name) . unwrap ( ) ;
132
176
}
133
- dst. push_str ( "\n fn main() {}\n " ) ;
134
- UpdateStatus :: from_changed ( src != dst)
135
- } ) ,
136
- ( "tests/ui/rename.rs" , & mut move |_, src, dst| {
137
- let mut seen_lints = HashSet :: new ( ) ;
138
- dst. push_str ( GENERATED_FILE_COMMENT ) ;
139
- dst. push_str ( "#![allow(clippy::duplicated_attributes)]\n " ) ;
140
- for lint in renamed {
141
- if seen_lints. insert ( & lint. new_name ) {
142
- writeln ! ( dst, "#![allow({})]" , lint. new_name) . unwrap ( ) ;
143
- }
177
+ }
178
+ seen_lints. clear ( ) ;
179
+ for lint in renamed {
180
+ if seen_lints. insert ( & lint. old_name ) {
181
+ writeln ! ( dst, "#![warn({})] //~ ERROR: lint `{}`" , lint. old_name, lint. old_name) . unwrap ( ) ;
144
182
}
145
- seen_lints. clear ( ) ;
146
- for lint in renamed {
147
- if seen_lints. insert ( & lint. old_name ) {
148
- writeln ! ( dst, "#![warn({})] //~ ERROR: lint `{}`" , lint. old_name, lint. old_name) . unwrap ( ) ;
183
+ }
184
+ dst. push_str ( "\n fn main() {}\n " ) ;
185
+ UpdateStatus :: from_changed ( src != dst)
186
+ } ,
187
+ ) ;
188
+ for c in Crate :: all ( ) {
189
+ updater. update_file_checked (
190
+ "cargo dev update_lints" ,
191
+ update_mode,
192
+ c. crate_root_path ( ) ,
193
+ & mut update_text_region_fn (
194
+ "// begin lints modules, do not remove this comment, it’s used in `update_lints`\n " ,
195
+ "// end lints modules, do not remove this comment, it’s used in `update_lints`" ,
196
+ |dst| {
197
+ for lint_mod in lints
198
+ . iter ( )
199
+ . filter ( |l| l. def_crate == c)
200
+ . map ( |l| l. module . split_once ( "::" ) . map_or ( & * l. module , |x| x. 0 ) )
201
+ . sorted ( )
202
+ . dedup ( )
203
+ {
204
+ writeln ! ( dst, "mod {lint_mod};" ) . unwrap ( ) ;
149
205
}
206
+ } ,
207
+ ) ,
208
+ ) ;
209
+ updater. update_file_checked (
210
+ "cargo dev update_lints" ,
211
+ update_mode,
212
+ c. declared_lints_path ( ) ,
213
+ & mut |_, src, dst| {
214
+ dst. push_str ( GENERATED_FILE_COMMENT ) ;
215
+ dst. push_str ( "pub static LINTS: &[&crate::LintInfo] = &[\n " ) ;
216
+ for ( module_name, lint_name) in lints
217
+ . iter ( )
218
+ . filter ( |l| l. def_crate == c)
219
+ . map ( |l| ( & l. module , l. name . to_uppercase ( ) ) )
220
+ . sorted ( )
221
+ {
222
+ writeln ! ( dst, " crate::{module_name}::{lint_name}_INFO," ) . unwrap ( ) ;
150
223
}
151
- dst. push_str ( "\n fn main() {} \n " ) ;
224
+ dst. push_str ( "]; \n " ) ;
152
225
UpdateStatus :: from_changed ( src != dst)
153
- } ) ,
154
- ] ,
155
- ) ;
226
+ } ,
227
+ ) ;
228
+ }
156
229
}
157
230
158
231
fn round_to_fifty ( count : usize ) -> usize {
@@ -167,6 +240,7 @@ pub struct Lint {
167
240
pub module : String ,
168
241
pub path : PathBuf ,
169
242
pub declaration_range : Range < usize > ,
243
+ pub def_crate : Crate ,
170
244
}
171
245
172
246
pub struct DeprecatedLint {
@@ -186,13 +260,16 @@ pub struct RenamedLint {
186
260
pub fn find_lint_decls ( ) -> Vec < Lint > {
187
261
let mut lints = Vec :: with_capacity ( 1000 ) ;
188
262
let mut contents = String :: new ( ) ;
189
- for ( file, module) in read_src_with_module ( "clippy_lints/src" . as_ref ( ) ) {
190
- parse_clippy_lint_decls (
191
- file. path ( ) ,
192
- File :: open_read_to_cleared_string ( file. path ( ) , & mut contents) ,
193
- & module,
194
- & mut lints,
195
- ) ;
263
+ for c in Crate :: all ( ) {
264
+ for ( file, module) in read_src_with_module ( c. src_path ( ) . as_ref ( ) ) {
265
+ parse_clippy_lint_decls (
266
+ file. path ( ) ,
267
+ File :: open_read_to_cleared_string ( file. path ( ) , & mut contents) ,
268
+ c,
269
+ & module,
270
+ & mut lints,
271
+ ) ;
272
+ }
196
273
}
197
274
lints. sort_by ( |lhs, rhs| lhs. name . cmp ( & rhs. name ) ) ;
198
275
lints
@@ -233,7 +310,7 @@ fn read_src_with_module(src_root: &Path) -> impl use<'_> + Iterator<Item = (DirE
233
310
}
234
311
235
312
/// Parse a source file looking for `declare_clippy_lint` macro invocations.
236
- fn parse_clippy_lint_decls ( path : & Path , contents : & str , module : & str , lints : & mut Vec < Lint > ) {
313
+ fn parse_clippy_lint_decls ( path : & Path , contents : & str , def_crate : Crate , module : & str , lints : & mut Vec < Lint > ) {
237
314
#[ allow( clippy:: enum_glob_use) ]
238
315
use Token :: * ;
239
316
#[ rustfmt:: skip]
@@ -257,6 +334,7 @@ fn parse_clippy_lint_decls(path: &Path, contents: &str, module: &str, lints: &mu
257
334
module : module. into ( ) ,
258
335
path : path. into ( ) ,
259
336
declaration_range : start..searcher. pos ( ) as usize ,
337
+ def_crate,
260
338
} ) ;
261
339
}
262
340
}
0 commit comments