Skip to content

Commit 9b25ac3

Browse files
committed
clippy_dev: Parse more parts of declare_clippy_lint macro calls.
1 parent 1fa4b2c commit 9b25ac3

9 files changed

Lines changed: 235 additions & 148 deletions

File tree

clippy_dev/src/edit_lints.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use crate::parse::cursor::{self, Capture, Cursor};
2-
use crate::parse::{ActiveLint, DeprecatedLint, Lint, LintData, LintName, ParseCx, ParsedLints, RenamedLint};
2+
use crate::parse::{
3+
ActiveLintData, DeprecatedLintData, Lint, LintData, LintName, ParseCx, ParsedLints, RenamedLintData,
4+
};
35
use crate::utils::{
46
ErrAction, FileUpdater, UpdateMode, UpdateStatus, Version, delete_dir_if_exists, delete_file_if_exists,
57
expect_action, try_rename_dir, try_rename_file, walk_dir_no_dot_or_target,
@@ -31,10 +33,8 @@ pub fn deprecate<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, name
3133
lint.get_mut(),
3234
Lint {
3335
name_sp: Span::new(data.deprecated_file, 0..0),
34-
data: LintData::Deprecated(DeprecatedLint {
35-
reason,
36-
version: cx.str_buf.alloc_display(cx.arena, clippy_version.rust_display()),
37-
}),
36+
version: cx.str_buf.alloc_display(cx.arena, clippy_version.rust_display()),
37+
data: LintData::Deprecated(DeprecatedLintData { reason }),
3838
},
3939
);
4040
let LintData::Active(prev_lint_data) = prev_lint.data else {
@@ -65,9 +65,9 @@ pub fn uplift<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_nam
6565
lint.get_mut(),
6666
Lint {
6767
name_sp: Span::new(data.deprecated_file, 0..0),
68-
data: LintData::Renamed(RenamedLint {
68+
version: cx.str_buf.alloc_display(cx.arena, clippy_version.rust_display()),
69+
data: LintData::Renamed(RenamedLintData {
6970
new_name: LintName::new_rustc(new_name),
70-
version: cx.str_buf.alloc_display(cx.arena, clippy_version.rust_display()),
7171
}),
7272
},
7373
);
@@ -117,9 +117,9 @@ pub fn rename<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_nam
117117
lint.get_mut(),
118118
Lint {
119119
name_sp: Span::new(data.deprecated_file, 0..0),
120-
data: LintData::Renamed(RenamedLint {
120+
version: cx.str_buf.alloc_display(cx.arena, clippy_version.rust_display()),
121+
data: LintData::Renamed(RenamedLintData {
121122
new_name: LintName::new_clippy(new_name),
122-
version: cx.str_buf.alloc_display(cx.arena, clippy_version.rust_display()),
123123
}),
124124
},
125125
);
@@ -173,7 +173,7 @@ pub fn rename<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_nam
173173
fn remove_lint_declaration(
174174
name: &str,
175175
lint_file: &SourceFile<'_>,
176-
lint_data: &ActiveLint<'_>,
176+
lint_data: &ActiveLintData<'_>,
177177
data: &ParsedLints<'_>,
178178
updater: &mut FileUpdater,
179179
) -> bool {

clippy_dev/src/fmt.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,9 @@ pub fn run(update_mode: UpdateMode) {
115115
let mut updater = FileUpdater::default();
116116

117117
#[expect(clippy::mutable_key_type)]
118-
let mut lints = lint_data.mk_file_to_lint_decl_map();
118+
let mut lints = lint_data.lints.mk_by_file_map();
119119
let mut ranges = VecBuf::with_capacity(256);
120-
for passes in lint_data.iter_passes_by_file_mut() {
120+
for passes in lint_data.lint_passes.iter_by_file_mut() {
121121
let file = passes[0].decl_sp.file;
122122
let mut lints = lints.remove(file);
123123
let lints = lints.as_deref_mut().unwrap_or_default();

clippy_dev/src/generate.rs

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::parse::cursor::Cursor;
2-
use crate::parse::{ConfDef, LintData, LintPass, ParsedLints};
2+
use crate::parse::{ActiveLint, ConfDef, LintData, LintPass, ParsedLints};
33
use crate::utils::{FileUpdater, UpdateMode, UpdateStatus, VecBuf, slice_groups, update_text_region_fn};
44
use core::range::Range;
55
use itertools::Itertools;
@@ -41,8 +41,8 @@ impl ParsedLints<'_> {
4141
for &(name, lint) in &lints {
4242
match &lint.data {
4343
LintData::Active(_) => active.push((name, lint.name_sp.file.path_as_krate_mod())),
44-
LintData::Deprecated(lint) => deprecated.push((name, lint)),
45-
LintData::Renamed(lint) => renamed.push((name, lint)),
44+
LintData::Deprecated(data) => deprecated.push((name, lint.version, data.reason)),
45+
LintData::Renamed(data) => renamed.push((name, lint.version, data.new_name)),
4646
}
4747
}
4848
active.sort_by_key(|&(_, path)| path);
@@ -78,11 +78,10 @@ impl ParsedLints<'_> {
7878
);
7979
dst.push_str(&src[..cursor.pos() as usize]);
8080
dst.push_str("! { DEPRECATED(DEPRECATED_VERSION) = [\n");
81-
for &(name, data) in &deprecated {
81+
for &(name, version, reason) in &deprecated {
8282
write!(
8383
dst,
84-
" #[clippy::version = \"{}\"]\n (\"clippy::{name}\", \"{}\"),\n",
85-
data.version, data.reason,
84+
" #[clippy::version = \"{version}\"]\n (\"clippy::{name}\", \"{reason}\"),\n",
8685
)
8786
.unwrap();
8887
}
@@ -92,11 +91,10 @@ impl ParsedLints<'_> {
9291
declare_with_version! { RENAMED(RENAMED_VERSION) = [\n\
9392
",
9493
);
95-
for &(name, data) in &renamed {
94+
for &(name, version, new_name) in &renamed {
9695
write!(
9796
dst,
98-
" #[clippy::version = \"{}\"]\n (\"clippy::{name}\", \"{}\"),\n",
99-
data.version, data.new_name,
97+
" #[clippy::version = \"{version}\"]\n (\"clippy::{name}\", \"{new_name}\"),\n",
10098
)
10199
.unwrap();
102100
}
@@ -110,7 +108,7 @@ impl ParsedLints<'_> {
110108
"tests/ui/deprecated.rs",
111109
&mut |_, src, dst| {
112110
dst.push_str(GENERATED_FILE_COMMENT);
113-
for &(lint, _) in &deprecated {
111+
for &(lint, _, _) in &deprecated {
114112
writeln!(dst, "#![warn(clippy::{lint})] //~ ERROR: lint `clippy::{lint}`").unwrap();
115113
}
116114
dst.push_str("\nfn main() {}\n");
@@ -125,12 +123,12 @@ impl ParsedLints<'_> {
125123
let mut seen_lints = HashSet::new();
126124
dst.push_str(GENERATED_FILE_COMMENT);
127125
dst.push_str("#![allow(clippy::duplicated_attributes)]\n");
128-
for &(_, lint) in &renamed {
129-
if seen_lints.insert(lint.new_name) {
130-
writeln!(dst, "#![allow({})]", lint.new_name).unwrap();
126+
for &(_, _, new_name) in &renamed {
127+
if seen_lints.insert(new_name) {
128+
writeln!(dst, "#![allow({new_name})]").unwrap();
131129
}
132130
}
133-
for &(lint, _) in &renamed {
131+
for &(lint, _, _) in &renamed {
134132
writeln!(dst, "#![warn(clippy::{lint})] //~ ERROR: lint `clippy::{lint}`").unwrap();
135133
}
136134
dst.push_str("\nfn main() {}\n");
@@ -188,6 +186,27 @@ impl ParsedLints<'_> {
188186
}
189187
}
190188

189+
impl ActiveLint<'_, '_> {
190+
pub fn gen_mac(&self, dst: &mut String) {
191+
dst.push_str("declare_clippy_lint! {");
192+
write_comment_lines(self.data.docs, "\n ", dst);
193+
dst.extend(["\n #[clippy::version = \"", self.version, "\"]\n pub "]);
194+
195+
// Lint names are stored in lower case, but the declaration needs to be upper case.
196+
let name_pos = dst.len();
197+
dst.push_str(self.name);
198+
dst[name_pos..].make_ascii_uppercase();
199+
dst.push(',');
200+
201+
write_comment_lines(self.data.group_comments, "\n ", dst);
202+
dst.extend(["\n ", self.data.group, ",\n ", self.data.desc]);
203+
if !self.data.opts.is_empty() {
204+
dst.extend([",\n ", self.data.opts]);
205+
}
206+
dst.push_str("\n}");
207+
}
208+
}
209+
191210
impl LintPass<'_> {
192211
pub fn gen_mac(&self, dst: &mut String) {
193212
let mut line_start = dst.len();
@@ -288,23 +307,23 @@ fn write_list<'a>(
288307
pub fn gen_sorted_lints_file(
289308
src: &str,
290309
dst: &mut String,
291-
lints: &mut [(&str, Range<u32>)],
310+
lints: &mut [ActiveLint<'_, '_>],
292311
passes: &mut [LintPass<'_>],
293312
ranges: &mut VecBuf<Range<u32>>,
294313
) {
295314
ranges.with(|ranges| {
296-
ranges.extend(lints.iter().map(|&(_, x)| x));
315+
ranges.extend(lints.iter().map(|x| x.data.decl_range));
297316
ranges.extend(passes.iter().map(|x| x.decl_sp.range));
298317
ranges.sort_unstable_by_key(|x| x.start);
299318

300-
lints.sort_unstable_by_key(|&(x, _)| x);
319+
lints.sort_unstable_by_key(|x| x.name);
301320
passes.sort_by_key(|x| x.name);
302321

303322
let mut ranges = ranges.iter();
304323
let pos = if let Some(range) = ranges.next() {
305324
dst.push_str(&src[..range.start as usize]);
306-
for &(_, range) in &*lints {
307-
dst.push_str(&src[range.start as usize..range.end as usize]);
325+
for lint in &*lints {
326+
lint.gen_mac(dst);
308327
dst.push_str("\n\n");
309328
}
310329
for pass in passes {

0 commit comments

Comments
 (0)