Skip to content

Commit 1969ea7

Browse files
committed
Generate lint categories and explanations with declare_clippy_lint
Changes it to be a proc_macro rather than macro_rules
1 parent cf93865 commit 1969ea7

20 files changed

+886
-2489
lines changed

clippy_dev/src/update_lints.rs

Lines changed: 7 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use aho_corasick::AhoCorasickBuilder;
33
use indoc::writedoc;
44
use itertools::Itertools;
55
use rustc_lexer::{tokenize, unescape, LiteralKind, TokenKind};
6-
use std::collections::{BTreeSet, HashMap, HashSet};
6+
use std::collections::{HashMap, HashSet};
77
use std::ffi::OsStr;
88
use std::fmt::Write;
99
use std::fs::{self, OpenOptions};
@@ -105,99 +105,23 @@ fn generate_lint_files(
105105
);
106106

107107
process_file(
108-
"clippy_lints/src/lib.register_lints.rs",
108+
"clippy_lints/src/declared_lints.rs",
109109
update_mode,
110-
&gen_register_lint_list(internal_lints.iter(), usable_lints.iter()),
110+
&gen_declared_lints(internal_lints.iter(), usable_lints.iter()),
111111
);
112112
process_file(
113113
"clippy_lints/src/lib.deprecated.rs",
114114
update_mode,
115115
&gen_deprecated(deprecated_lints),
116116
);
117117

118-
let all_group_lints = usable_lints.iter().filter(|l| {
119-
matches!(
120-
&*l.group,
121-
"correctness" | "suspicious" | "style" | "complexity" | "perf"
122-
)
123-
});
124-
let content = gen_lint_group_list("all", all_group_lints);
125-
process_file("clippy_lints/src/lib.register_all.rs", update_mode, &content);
126-
127-
update_docs(update_mode, &usable_lints);
128-
129-
for (lint_group, lints) in Lint::by_lint_group(usable_lints.into_iter().chain(internal_lints)) {
130-
let content = gen_lint_group_list(&lint_group, lints.iter());
131-
process_file(
132-
&format!("clippy_lints/src/lib.register_{lint_group}.rs"),
133-
update_mode,
134-
&content,
135-
);
136-
}
137-
138118
let content = gen_deprecated_lints_test(deprecated_lints);
139119
process_file("tests/ui/deprecated.rs", update_mode, &content);
140120

141121
let content = gen_renamed_lints_test(renamed_lints);
142122
process_file("tests/ui/rename.rs", update_mode, &content);
143123
}
144124

145-
fn update_docs(update_mode: UpdateMode, usable_lints: &[Lint]) {
146-
replace_region_in_file(update_mode, Path::new("src/docs.rs"), "docs! {\n", "\n}\n", |res| {
147-
for name in usable_lints.iter().map(|lint| lint.name.clone()).sorted() {
148-
writeln!(res, r#" "{name}","#).unwrap();
149-
}
150-
});
151-
152-
if update_mode == UpdateMode::Check {
153-
let mut extra = BTreeSet::new();
154-
let mut lint_names = usable_lints
155-
.iter()
156-
.map(|lint| lint.name.clone())
157-
.collect::<BTreeSet<_>>();
158-
for file in std::fs::read_dir("src/docs").unwrap() {
159-
let filename = file.unwrap().file_name().into_string().unwrap();
160-
if let Some(name) = filename.strip_suffix(".txt") {
161-
if !lint_names.remove(name) {
162-
extra.insert(name.to_string());
163-
}
164-
}
165-
}
166-
167-
let failed = print_lint_names("extra lint docs:", &extra) | print_lint_names("missing lint docs:", &lint_names);
168-
169-
if failed {
170-
exit_with_failure();
171-
}
172-
} else {
173-
if std::fs::remove_dir_all("src/docs").is_err() {
174-
eprintln!("could not remove src/docs directory");
175-
}
176-
if std::fs::create_dir("src/docs").is_err() {
177-
eprintln!("could not recreate src/docs directory");
178-
}
179-
}
180-
for lint in usable_lints {
181-
process_file(
182-
Path::new("src/docs").join(lint.name.clone() + ".txt"),
183-
update_mode,
184-
&lint.documentation,
185-
);
186-
}
187-
}
188-
189-
fn print_lint_names(header: &str, lints: &BTreeSet<String>) -> bool {
190-
if lints.is_empty() {
191-
return false;
192-
}
193-
println!("{header}");
194-
for lint in lints.iter().sorted() {
195-
println!(" {lint}");
196-
}
197-
println!();
198-
true
199-
}
200-
201125
pub fn print_lints() {
202126
let (lint_list, _, _) = gather_all();
203127
let usable_lints = Lint::usable_lints(&lint_list);
@@ -717,25 +641,6 @@ impl RenamedLint {
717641
}
718642
}
719643

720-
/// Generates the code for registering a group
721-
fn gen_lint_group_list<'a>(group_name: &str, lints: impl Iterator<Item = &'a Lint>) -> String {
722-
let mut details: Vec<_> = lints.map(|l| (&l.module, l.name.to_uppercase())).collect();
723-
details.sort_unstable();
724-
725-
let mut output = GENERATED_FILE_COMMENT.to_string();
726-
727-
let _ = writeln!(
728-
output,
729-
"store.register_group(true, \"clippy::{group_name}\", Some(\"clippy_{group_name}\"), vec![",
730-
);
731-
for (module, name) in details {
732-
let _ = writeln!(output, " LintId::of({module}::{name}),");
733-
}
734-
output.push_str("])\n");
735-
736-
output
737-
}
738-
739644
/// Generates the `register_removed` code
740645
#[must_use]
741646
fn gen_deprecated(lints: &[DeprecatedLint]) -> String {
@@ -760,7 +665,7 @@ fn gen_deprecated(lints: &[DeprecatedLint]) -> String {
760665

761666
/// Generates the code for registering lints
762667
#[must_use]
763-
fn gen_register_lint_list<'a>(
668+
fn gen_declared_lints<'a>(
764669
internal_lints: impl Iterator<Item = &'a Lint>,
765670
usable_lints: impl Iterator<Item = &'a Lint>,
766671
) -> String {
@@ -771,15 +676,15 @@ fn gen_register_lint_list<'a>(
771676
details.sort_unstable();
772677

773678
let mut output = GENERATED_FILE_COMMENT.to_string();
774-
output.push_str("store.register_lints(&[\n");
679+
output.push_str("pub(crate) static LINTS: &[&crate::LintInfo] = &[\n");
775680

776681
for (is_public, module_name, lint_name) in details {
777682
if !is_public {
778683
output.push_str(" #[cfg(feature = \"internal\")]\n");
779684
}
780-
let _ = writeln!(output, " {module_name}::{lint_name},");
685+
let _ = writeln!(output, " crate::{module_name}::{lint_name}_INFO,");
781686
}
782-
output.push_str("])\n");
687+
output.push_str("];\n");
783688

784689
output
785690
}
@@ -1360,48 +1265,4 @@ mod tests {
13601265

13611266
assert_eq!(expected, gen_deprecated(&lints));
13621267
}
1363-
1364-
#[test]
1365-
fn test_gen_lint_group_list() {
1366-
let lints = vec![
1367-
Lint::new(
1368-
"abc",
1369-
"group1",
1370-
"\"abc\"",
1371-
"module_name",
1372-
Range::default(),
1373-
String::new(),
1374-
),
1375-
Lint::new(
1376-
"should_assert_eq",
1377-
"group1",
1378-
"\"abc\"",
1379-
"module_name",
1380-
Range::default(),
1381-
String::new(),
1382-
),
1383-
Lint::new(
1384-
"internal",
1385-
"internal_style",
1386-
"\"abc\"",
1387-
"module_name",
1388-
Range::default(),
1389-
String::new(),
1390-
),
1391-
];
1392-
let expected = GENERATED_FILE_COMMENT.to_string()
1393-
+ &[
1394-
"store.register_group(true, \"clippy::group1\", Some(\"clippy_group1\"), vec![",
1395-
" LintId::of(module_name::ABC),",
1396-
" LintId::of(module_name::INTERNAL),",
1397-
" LintId::of(module_name::SHOULD_ASSERT_EQ),",
1398-
"])",
1399-
]
1400-
.join("\n")
1401-
+ "\n";
1402-
1403-
let result = gen_lint_group_list("group1", lints.iter());
1404-
1405-
assert_eq!(expected, result);
1406-
}
14071268
}

clippy_lints/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ edition = "2021"
1111
[dependencies]
1212
cargo_metadata = "0.14"
1313
clippy_utils = { path = "../clippy_utils" }
14+
declare_clippy_lint = { path = "../declare_clippy_lint" }
1415
if_chain = "1.0"
1516
itertools = "0.10.1"
1617
pulldown-cmark = { version = "0.9", default-features = false }

0 commit comments

Comments
 (0)