Skip to content

Commit e6747df

Browse files
author
Michael Wright
committed
Fix lint register code format
Also change the generation functions to return `String` instead of `Vec<String>`. This makes sense now as the updates aren't line oriented anymore.
1 parent 50ea370 commit e6747df

16 files changed

+1433
-1424
lines changed

clippy_dev/src/lib.rs

Lines changed: 99 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
use itertools::Itertools;
77
use regex::Regex;
8-
use std::collections::HashMap;
8+
use std::collections::{BTreeSet, HashMap};
99
use std::ffi::OsStr;
1010
use std::fs;
1111
use std::lazy::SyncLazy;
@@ -19,6 +19,10 @@ pub mod serve;
1919
pub mod setup;
2020
pub mod update_lints;
2121

22+
const GENERATED_FILE_COMMENT: &str = "// This file was generated by `cargo dev update_lints`.\n\
23+
// Use that command to update this file and do not edit by hand.\n\
24+
// Manual edits will be overwritten.\n\n";
25+
2226
static DEC_CLIPPY_LINT_RE: SyncLazy<Regex> = SyncLazy::new(|| {
2327
Regex::new(
2428
r#"(?x)
@@ -98,37 +102,35 @@ impl Lint {
98102
}
99103
}
100104

101-
/// Generates the Vec items for `register_lint_group` calls in `clippy_lints/src/lib.rs`.
102-
#[must_use]
103-
pub fn gen_lint_group_list<'a>(group_name: &str, lints: impl Iterator<Item = &'a Lint>) -> Vec<String> {
104-
let header = format!(
105-
r#"store.register_group(true, "clippy::{0}", Some("clippy_{0}"), vec!["#,
106-
group_name
107-
);
108-
let footer = "])".to_string();
109-
110-
let mut result = vec![header];
105+
/// Generates the code for registering a group
106+
pub fn gen_lint_group_list<'a>(group_name: &str, lints: impl Iterator<Item = &'a Lint>) -> String {
107+
let mut details: Vec<_> = lints.map(|l| (&l.module, l.name.to_uppercase())).collect();
108+
details.sort_unstable();
111109

112-
result.extend(
113-
lints
114-
.map(|l| format!("LintId::of({}::{}),", l.module, l.name.to_uppercase()))
115-
.sorted(),
116-
);
110+
let mut output = GENERATED_FILE_COMMENT.to_string();
117111

118-
result.push(footer);
112+
output.push_str(&format!(
113+
"store.register_group(true, \"clippy::{0}\", Some(\"clippy_{0}\"), vec![\n",
114+
group_name
115+
));
116+
for (module, name) in details {
117+
output.push_str(&format!(" LintId::of({}::{}),\n", module, name));
118+
}
119+
output.push_str("])\n");
119120

120-
result
121+
output
121122
}
122123

123-
/// Generates the `pub mod module_name` list in `clippy_lints/src/lib.rs`.
124+
/// Generates the module declarations for `lints`
124125
#[must_use]
125-
pub fn gen_modules_list<'a>(lints: impl Iterator<Item = &'a Lint>) -> Vec<String> {
126-
lints
127-
.map(|l| &l.module)
128-
.unique()
129-
.map(|module| format!("mod {};", module))
130-
.sorted()
131-
.collect::<Vec<String>>()
126+
pub fn gen_modules_list<'a>(lints: impl Iterator<Item = &'a Lint>) -> String {
127+
let module_names: BTreeSet<_> = lints.map(|l| &l.module).collect();
128+
129+
let mut output = GENERATED_FILE_COMMENT.to_string();
130+
for name in module_names {
131+
output.push_str(&format!("mod {};\n", name));
132+
}
133+
output
132134
}
133135

134136
/// Generates the list of lint links at the bottom of the README
@@ -140,52 +142,52 @@ pub fn gen_changelog_lint_list<'a>(lints: impl Iterator<Item = &'a Lint>) -> Vec
140142
.collect()
141143
}
142144

143-
/// Generates the `register_removed` code in `./clippy_lints/src/lib.rs`.
145+
/// Generates the `register_removed` code
144146
#[must_use]
145-
pub fn gen_deprecated<'a>(lints: impl Iterator<Item = &'a Lint>) -> Vec<String> {
146-
let mut result = vec!["{".to_string()];
147-
result.extend(lints.flat_map(|l| {
148-
l.deprecation
149-
.clone()
150-
.map(|depr_text| {
151-
vec![
152-
" store.register_removed(".to_string(),
153-
format!(" \"clippy::{}\",", l.name),
154-
format!(" \"{}\",", depr_text),
155-
" );".to_string(),
156-
]
157-
})
158-
.expect("only deprecated lints should be passed")
159-
}));
160-
result.push("}".to_string());
161-
result
147+
pub fn gen_deprecated<'a>(lints: impl Iterator<Item = &'a Lint>) -> String {
148+
let mut output = GENERATED_FILE_COMMENT.to_string();
149+
output.push_str("{\n");
150+
for Lint { name, deprecation, .. } in lints {
151+
output.push_str(&format!(
152+
concat!(
153+
" store.register_removed(\n",
154+
" \"clippy::{}\",\n",
155+
" \"{}\",\n",
156+
" );\n"
157+
),
158+
name,
159+
deprecation.as_ref().expect("`lints` are deprecated")
160+
));
161+
}
162+
output.push_str("}\n");
163+
164+
output
162165
}
163166

167+
/// Generates the code for registering lints
164168
#[must_use]
165169
pub fn gen_register_lint_list<'a>(
166170
internal_lints: impl Iterator<Item = &'a Lint>,
167171
usable_lints: impl Iterator<Item = &'a Lint>,
168-
) -> Vec<String> {
169-
let header = " store.register_lints(&[".to_string();
170-
let footer = " ])".to_string();
171-
let internal_lints = internal_lints
172-
.sorted_by_key(|l| format!(" {}::{},", l.module, l.name.to_uppercase()))
173-
.map(|l| {
174-
format!(
175-
" #[cfg(feature = \"internal-lints\")]\n {}::{},",
176-
l.module,
177-
l.name.to_uppercase()
178-
)
179-
});
180-
let other_lints = usable_lints
181-
.sorted_by_key(|l| format!(" {}::{},", l.module, l.name.to_uppercase()))
182-
.map(|l| format!(" {}::{},", l.module, l.name.to_uppercase()))
183-
.sorted();
184-
let mut lint_list = vec![header];
185-
lint_list.extend(internal_lints);
186-
lint_list.extend(other_lints);
187-
lint_list.push(footer);
188-
lint_list
172+
) -> String {
173+
let mut details: Vec<_> = internal_lints
174+
.map(|l| (false, &l.module, l.name.to_uppercase()))
175+
.chain(usable_lints.map(|l| (true, &l.module, l.name.to_uppercase())))
176+
.collect();
177+
details.sort_unstable();
178+
179+
let mut output = GENERATED_FILE_COMMENT.to_string();
180+
output.push_str("store.register_lints(&[\n");
181+
182+
for (is_public, module_name, lint_name) in details {
183+
if !is_public {
184+
output.push_str(" #[cfg(feature = \"internal-lints\")]\n");
185+
}
186+
output.push_str(&format!(" {}::{},\n", module_name, lint_name));
187+
}
188+
output.push_str("])\n");
189+
190+
output
189191
}
190192

191193
/// Gathers all files in `src/clippy_lints` and gathers all lints inside
@@ -524,21 +526,23 @@ fn test_gen_deprecated() {
524526
"module_name",
525527
),
526528
];
527-
let expected: Vec<String> = vec![
528-
"{",
529-
" store.register_removed(",
530-
" \"clippy::should_assert_eq\",",
531-
" \"has been superseded by should_assert_eq2\",",
532-
" );",
533-
" store.register_removed(",
534-
" \"clippy::another_deprecated\",",
535-
" \"will be removed\",",
536-
" );",
537-
"}",
538-
]
539-
.into_iter()
540-
.map(String::from)
541-
.collect();
529+
530+
let expected = GENERATED_FILE_COMMENT.to_string()
531+
+ &[
532+
"{",
533+
" store.register_removed(",
534+
" \"clippy::should_assert_eq\",",
535+
" \"has been superseded by should_assert_eq2\",",
536+
" );",
537+
" store.register_removed(",
538+
" \"clippy::another_deprecated\",",
539+
" \"will be removed\",",
540+
" );",
541+
"}",
542+
]
543+
.join("\n")
544+
+ "\n";
545+
542546
assert_eq!(expected, gen_deprecated(lints.iter()));
543547
}
544548

@@ -555,7 +559,7 @@ fn test_gen_modules_list() {
555559
Lint::new("should_assert_eq", "group1", "abc", None, "module_name"),
556560
Lint::new("incorrect_stuff", "group3", "abc", None, "another_module"),
557561
];
558-
let expected = vec!["mod another_module;".to_string(), "mod module_name;".to_string()];
562+
let expected = GENERATED_FILE_COMMENT.to_string() + &["mod another_module;", "mod module_name;"].join("\n") + "\n";
559563
assert_eq!(expected, gen_modules_list(lints.iter()));
560564
}
561565

@@ -566,12 +570,18 @@ fn test_gen_lint_group_list() {
566570
Lint::new("should_assert_eq", "group1", "abc", None, "module_name"),
567571
Lint::new("internal", "internal_style", "abc", None, "module_name"),
568572
];
569-
let expected = vec![
570-
"store.register_group(true, \"clippy::group1\", Some(\"clippy_group1\"), vec![",
571-
"LintId::of(module_name::ABC),",
572-
"LintId::of(module_name::INTERNAL),",
573-
"LintId::of(module_name::SHOULD_ASSERT_EQ),",
574-
"])",
575-
];
576-
assert_eq!(expected, gen_lint_group_list("group1", lints.iter()));
573+
let expected = GENERATED_FILE_COMMENT.to_string()
574+
+ &[
575+
"store.register_group(true, \"clippy::group1\", Some(\"clippy_group1\"), vec![",
576+
" LintId::of(module_name::ABC),",
577+
" LintId::of(module_name::INTERNAL),",
578+
" LintId::of(module_name::SHOULD_ASSERT_EQ),",
579+
"])",
580+
]
581+
.join("\n")
582+
+ "\n";
583+
584+
let result = gen_lint_group_list("group1", lints.iter());
585+
586+
assert_eq!(expected, result);
577587
}

clippy_dev/src/update_lints.rs

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -66,32 +66,37 @@ pub fn run(update_mode: UpdateMode) {
6666
exit_with_failure();
6767
}
6868

69-
for (name, lines) in [
70-
("mods", gen_modules_list(usable_lints.iter())),
71-
("deprecated", gen_deprecated(deprecated_lints.iter())),
72-
(
73-
"register_lints",
74-
gen_register_lint_list(internal_lints.iter(), usable_lints.iter()),
75-
),
76-
("register_all", {
77-
let all_group_lints = usable_lints.iter().filter(|l| {
78-
matches!(
79-
&*l.group,
80-
"correctness" | "suspicious" | "style" | "complexity" | "perf"
81-
)
82-
});
83-
84-
gen_lint_group_list("all", all_group_lints)
85-
}),
86-
] {
87-
process_file(&format!("clippy_lints/src/lib.{}.rs", name), update_mode, &lines[..]);
88-
}
69+
process_file(
70+
"clippy_lints/src/lib.register_lints.rs",
71+
update_mode,
72+
&gen_register_lint_list(internal_lints.iter(), usable_lints.iter()),
73+
);
74+
process_file(
75+
"clippy_lints/src/lib.deprecated.rs",
76+
update_mode,
77+
&gen_deprecated(deprecated_lints.iter()),
78+
);
79+
process_file(
80+
"clippy_lints/src/lib.mods.rs",
81+
update_mode,
82+
&gen_modules_list(usable_lints.iter()),
83+
);
84+
85+
let all_group_lints = usable_lints.iter().filter(|l| {
86+
matches!(
87+
&*l.group,
88+
"correctness" | "suspicious" | "style" | "complexity" | "perf"
89+
)
90+
});
91+
let content = gen_lint_group_list("all", all_group_lints);
92+
process_file("clippy_lints/src/lib.register_all.rs", update_mode, &content);
8993

9094
for (lint_group, lints) in Lint::by_lint_group(usable_lints.into_iter().chain(internal_lints)) {
95+
let content = gen_lint_group_list(&lint_group, lints.iter());
9196
process_file(
9297
&format!("clippy_lints/src/lib.register_{}.rs", lint_group),
9398
update_mode,
94-
&gen_lint_group_list(&lints.get(0).expect("group non-empty").group, lints.iter())[..],
99+
&content,
95100
);
96101
}
97102
}
@@ -122,21 +127,15 @@ fn round_to_fifty(count: usize) -> usize {
122127
count / 50 * 50
123128
}
124129

125-
fn process_file(path: impl AsRef<Path>, update_mode: UpdateMode, new_lines: &[String]) {
126-
let mut new_content = "// This file was generated by `cargo dev update_lints`.\n\
127-
// Use that command to update this file and do not edit by hand.\n\
128-
// Manual edits will be overwritten.\n\n"
129-
.to_string();
130-
new_content.push_str(&new_lines.join("\n"));
131-
130+
fn process_file(path: impl AsRef<Path>, update_mode: UpdateMode, content: &str) {
132131
if update_mode == UpdateMode::Check {
133132
let old_content =
134133
fs::read_to_string(&path).unwrap_or_else(|e| panic!("Cannot read from {}: {}", path.as_ref().display(), e));
135-
if new_content != old_content {
134+
if content != old_content {
136135
exit_with_failure();
137136
}
138137
} else {
139-
fs::write(&path, new_content.as_bytes())
138+
fs::write(&path, content.as_bytes())
140139
.unwrap_or_else(|e| panic!("Cannot write to {}: {}", path.as_ref().display(), e));
141140
}
142141
}

clippy_lints/src/lib.deprecated.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,4 @@
6767
"clippy::wrong_pub_self_convention",
6868
"set the `avoid-breaking-exported-api` config option to `false` to enable the `wrong_self_convention` lint for public items",
6969
);
70-
}
70+
}

clippy_lints/src/lib.mods.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,4 +229,4 @@ mod wildcard_dependencies;
229229
mod wildcard_imports;
230230
mod write;
231231
mod zero_div_zero;
232-
mod zero_sized_map_values;
232+
mod zero_sized_map_values;

0 commit comments

Comments
 (0)