@@ -14,6 +14,43 @@ const GENERATED_FILE_COMMENT: &str = "// This file was generated by `cargo dev u
1414
1515const DOCS_LINK : & str = "https://rust-lang.github.io/rust-clippy/master/index.html" ;
1616
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+
1754/// Runs the `update_lints` command.
1855///
1956/// This updates various generated values from the lint source code.
@@ -36,123 +73,159 @@ pub fn generate_lint_files(
3673 deprecated : & [ DeprecatedLint ] ,
3774 renamed : & [ RenamedLint ] ,
3875) {
39- FileUpdater :: default ( ) . update_files_checked (
76+ let mut updater = FileUpdater :: default ( ) ;
77+ updater. update_file_checked (
4078 "cargo dev update_lints" ,
4179 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 ( ) ;
110109 }
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 \
113136 #[rustfmt::skip]\n \
114137 declare_with_version! { RENAMED(RENAMED_VERSION) = [\n \
115138 ",
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 ( ) ;
132176 }
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 ( ) ;
144182 }
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 ( ) ;
149205 }
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 ( ) ;
150223 }
151- dst. push_str ( "\n fn main() {} \n " ) ;
224+ dst. push_str ( "]; \n " ) ;
152225 UpdateStatus :: from_changed ( src != dst)
153- } ) ,
154- ] ,
155- ) ;
226+ } ,
227+ ) ;
228+ }
156229}
157230
158231fn round_to_fifty ( count : usize ) -> usize {
@@ -167,6 +240,7 @@ pub struct Lint {
167240 pub module : String ,
168241 pub path : PathBuf ,
169242 pub declaration_range : Range < usize > ,
243+ pub def_crate : Crate ,
170244}
171245
172246pub struct DeprecatedLint {
@@ -186,13 +260,16 @@ pub struct RenamedLint {
186260pub fn find_lint_decls ( ) -> Vec < Lint > {
187261 let mut lints = Vec :: with_capacity ( 1000 ) ;
188262 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+ }
196273 }
197274 lints. sort_by ( |lhs, rhs| lhs. name . cmp ( & rhs. name ) ) ;
198275 lints
@@ -233,7 +310,7 @@ fn read_src_with_module(src_root: &Path) -> impl use<'_> + Iterator<Item = (DirE
233310}
234311
235312/// 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 > ) {
237314 #[ allow( clippy:: enum_glob_use) ]
238315 use Token :: * ;
239316 #[ rustfmt:: skip]
@@ -257,6 +334,7 @@ fn parse_clippy_lint_decls(path: &Path, contents: &str, module: &str, lints: &mu
257334 module : module. into ( ) ,
258335 path : path. into ( ) ,
259336 declaration_range : start..searcher. pos ( ) as usize ,
337+ def_crate,
260338 } ) ;
261339 }
262340 }
0 commit comments