Skip to content

Commit b3f4902

Browse files
committed
clippy_dev: order deprecated_lints.rs in update_lints
1 parent 44681fd commit b3f4902

File tree

9 files changed

+556
-553
lines changed

9 files changed

+556
-553
lines changed

clippy_dev/src/deprecate_lint.rs

Lines changed: 24 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
use crate::update_lints::{
2-
DeprecatedLint, DeprecatedLints, Lint, find_lint_decls, generate_lint_files, read_deprecated_lints,
3-
};
1+
use crate::update_lints::{DeprecatedLint, Lint, find_lint_decls, generate_lint_files, read_deprecated_lints};
42
use crate::utils::{UpdateMode, Version};
53
use std::ffi::OsStr;
64
use std::path::{Path, PathBuf};
@@ -16,28 +14,34 @@ use std::{fs, io};
1614
///
1715
/// If a file path could not read from or written to
1816
pub fn deprecate(clippy_version: Version, name: &str, reason: &str) {
19-
let prefixed_name = if name.starts_with("clippy::") {
20-
name.to_owned()
21-
} else {
22-
format!("clippy::{name}")
23-
};
24-
let stripped_name = &prefixed_name[8..];
17+
if let Some((prefix, _)) = name.split_once("::") {
18+
panic!("`{name}` should not contain the `{prefix}` prefix");
19+
}
2520

2621
let mut lints = find_lint_decls();
27-
let DeprecatedLints {
28-
renamed: renamed_lints,
29-
deprecated: mut deprecated_lints,
30-
file: mut deprecated_file,
31-
contents: mut deprecated_contents,
32-
deprecated_end,
33-
..
34-
} = read_deprecated_lints();
35-
36-
let Some(lint) = lints.iter().find(|l| l.name == stripped_name) else {
22+
let (mut deprecated_lints, renamed_lints) = read_deprecated_lints();
23+
24+
let Some(lint) = lints.iter().find(|l| l.name == name) else {
3725
eprintln!("error: failed to find lint `{name}`");
3826
return;
3927
};
4028

29+
let prefixed_name = String::from_iter(["clippy::", name]);
30+
match deprecated_lints.binary_search_by(|x| x.name.cmp(&prefixed_name)) {
31+
Ok(_) => {
32+
println!("`{name}` is already deprecated");
33+
return;
34+
},
35+
Err(idx) => deprecated_lints.insert(
36+
idx,
37+
DeprecatedLint {
38+
name: prefixed_name,
39+
reason: reason.into(),
40+
version: clippy_version.rust_display().to_string(),
41+
},
42+
),
43+
}
44+
4145
let mod_path = {
4246
let mut mod_path = PathBuf::from(format!("clippy_lints/src/{}", lint.module));
4347
if mod_path.is_dir() {
@@ -48,24 +52,7 @@ pub fn deprecate(clippy_version: Version, name: &str, reason: &str) {
4852
mod_path
4953
};
5054

51-
if remove_lint_declaration(stripped_name, &mod_path, &mut lints).unwrap_or(false) {
52-
deprecated_contents.insert_str(
53-
deprecated_end as usize,
54-
&format!(
55-
" #[clippy::version = \"{}\"]\n (\"{}\", \"{}\"),\n",
56-
clippy_version.rust_display(),
57-
prefixed_name,
58-
reason,
59-
),
60-
);
61-
deprecated_file.replace_contents(deprecated_contents.as_bytes());
62-
drop(deprecated_file);
63-
64-
deprecated_lints.push(DeprecatedLint {
65-
name: prefixed_name,
66-
reason: reason.into(),
67-
});
68-
55+
if remove_lint_declaration(name, &mod_path, &mut lints).unwrap_or(false) {
6956
generate_lint_files(UpdateMode::Change, &lints, &deprecated_lints, &renamed_lints);
7057
println!("info: `{name}` has successfully been deprecated");
7158
println!("note: you must run `cargo uitest` to update the test results");

clippy_dev/src/rename_lint.rs

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::update_lints::{DeprecatedLints, RenamedLint, find_lint_decls, generate_lint_files, read_deprecated_lints};
1+
use crate::update_lints::{RenamedLint, find_lint_decls, generate_lint_files, read_deprecated_lints};
22
use crate::utils::{
33
FileUpdater, RustSearcher, Token, UpdateMode, UpdateStatus, Version, delete_dir_if_exists, delete_file_if_exists,
44
try_rename_dir, try_rename_file,
@@ -35,39 +35,34 @@ pub fn rename(clippy_version: Version, old_name: &str, new_name: &str, uplift: b
3535

3636
let mut updater = FileUpdater::default();
3737
let mut lints = find_lint_decls();
38-
let DeprecatedLints {
39-
renamed: mut renamed_lints,
40-
deprecated: deprecated_lints,
41-
file: mut deprecated_file,
42-
contents: mut deprecated_contents,
43-
renamed_end,
44-
..
45-
} = read_deprecated_lints();
38+
let (deprecated_lints, mut renamed_lints) = read_deprecated_lints();
4639

4740
let Ok(lint_idx) = lints.binary_search_by(|x| x.name.as_str().cmp(old_name)) else {
4841
panic!("could not find lint `{old_name}`");
4942
};
5043
let lint = &lints[lint_idx];
5144

52-
let renamed_lint = RenamedLint {
53-
old_name: String::from_iter(["clippy::", old_name]),
54-
new_name: if uplift {
55-
new_name.to_owned()
56-
} else {
57-
String::from_iter(["clippy::", new_name])
45+
let old_name_prefixed = String::from_iter(["clippy::", old_name]);
46+
match renamed_lints.binary_search_by(|x| x.old_name.cmp(&old_name_prefixed)) {
47+
Ok(_) => {
48+
println!("`{old_name}` already has a rename registered");
49+
return;
5850
},
59-
};
60-
deprecated_contents.insert_str(
61-
renamed_end as usize,
62-
&format!(
63-
" #[clippy::version = \"{}\"]\n (\"{}\", \"{}\"),\n",
64-
clippy_version.rust_display(),
65-
renamed_lint.old_name,
66-
renamed_lint.new_name,
67-
),
68-
);
69-
deprecated_file.replace_contents(deprecated_contents.as_bytes());
70-
renamed_lints.push(renamed_lint);
51+
Err(idx) => {
52+
renamed_lints.insert(
53+
idx,
54+
RenamedLint {
55+
old_name: old_name_prefixed,
56+
new_name: if uplift {
57+
new_name.to_owned()
58+
} else {
59+
String::from_iter(["clippy::", new_name])
60+
},
61+
version: clippy_version.rust_display().to_string(),
62+
},
63+
);
64+
},
65+
}
7166

7267
// Some tests are named `lint_name_suffix` which should also be renamed,
7368
// but we can't do that if the renamed lint's name overlaps with another

clippy_dev/src/update_lints.rs

Lines changed: 57 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use crate::utils::{
44
use itertools::Itertools;
55
use std::collections::HashSet;
66
use std::fmt::Write;
7-
use std::fs::OpenOptions;
87
use std::ops::Range;
98
use std::path::{Path, PathBuf};
109
use walkdir::{DirEntry, WalkDir};
@@ -26,12 +25,11 @@ const DOCS_LINK: &str = "https://rust-lang.github.io/rust-clippy/master/index.ht
2625
/// Panics if a file path could not read from or then written to
2726
pub fn update(update_mode: UpdateMode) {
2827
let lints = find_lint_decls();
29-
let DeprecatedLints {
30-
renamed, deprecated, ..
31-
} = read_deprecated_lints();
28+
let (deprecated, renamed) = read_deprecated_lints();
3229
generate_lint_files(update_mode, &lints, &deprecated, &renamed);
3330
}
3431

32+
#[expect(clippy::too_many_lines)]
3533
pub fn generate_lint_files(
3634
update_mode: UpdateMode,
3735
lints: &[Lint],
@@ -93,6 +91,40 @@ pub fn generate_lint_files(
9391
dst.push_str("];\n");
9492
UpdateStatus::from_changed(src != dst)
9593
}),
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();
110+
}
111+
dst.push_str(
112+
"]}\n\n\
113+
#[rustfmt::skip]\n\
114+
declare_with_version! { RENAMED(RENAMED_VERSION) = [\n\
115+
",
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+
}),
96128
("tests/ui/deprecated.rs", &mut |_, src, dst| {
97129
dst.push_str(GENERATED_FILE_COMMENT);
98130
for lint in deprecated {
@@ -128,7 +160,7 @@ fn round_to_fifty(count: usize) -> usize {
128160
}
129161

130162
/// Lint data parsed from the Clippy source code.
131-
#[derive(Clone, PartialEq, Eq, Debug)]
163+
#[derive(PartialEq, Eq, Debug)]
132164
pub struct Lint {
133165
pub name: String,
134166
pub group: String,
@@ -137,15 +169,16 @@ pub struct Lint {
137169
pub declaration_range: Range<usize>,
138170
}
139171

140-
#[derive(Clone, PartialEq, Eq, Debug)]
141172
pub struct DeprecatedLint {
142173
pub name: String,
143174
pub reason: String,
175+
pub version: String,
144176
}
145177

146178
pub struct RenamedLint {
147179
pub old_name: String,
148180
pub new_name: String,
181+
pub version: String,
149182
}
150183

151184
/// Finds all lint declarations (`declare_clippy_lint!`)
@@ -229,23 +262,14 @@ fn parse_clippy_lint_decls(path: &Path, contents: &str, module: &str, lints: &mu
229262
}
230263
}
231264

232-
pub struct DeprecatedLints {
233-
pub file: File<'static>,
234-
pub contents: String,
235-
pub deprecated: Vec<DeprecatedLint>,
236-
pub renamed: Vec<RenamedLint>,
237-
pub deprecated_end: u32,
238-
pub renamed_end: u32,
239-
}
240-
241265
#[must_use]
242-
pub fn read_deprecated_lints() -> DeprecatedLints {
266+
pub fn read_deprecated_lints() -> (Vec<DeprecatedLint>, Vec<RenamedLint>) {
243267
#[allow(clippy::enum_glob_use)]
244268
use Token::*;
245269
#[rustfmt::skip]
246270
static DECL_TOKENS: &[Token<'_>] = &[
247271
// #[clippy::version = "version"]
248-
Pound, OpenBracket, Ident("clippy"), DoubleColon, Ident("version"), Eq, LitStr, CloseBracket,
272+
Pound, OpenBracket, Ident("clippy"), DoubleColon, Ident("version"), Eq, CaptureLitStr, CloseBracket,
249273
// ("first", "second"),
250274
OpenParen, CaptureLitStr, Comma, CaptureLitStr, CloseParen, Comma,
251275
];
@@ -261,17 +285,12 @@ pub fn read_deprecated_lints() -> DeprecatedLints {
261285
];
262286

263287
let path = "clippy_lints/src/deprecated_lints.rs";
264-
let mut res = DeprecatedLints {
265-
file: File::open(path, OpenOptions::new().read(true).write(true)),
266-
contents: String::new(),
267-
deprecated: Vec::with_capacity(30),
268-
renamed: Vec::with_capacity(80),
269-
deprecated_end: 0,
270-
renamed_end: 0,
271-
};
288+
let mut deprecated = Vec::with_capacity(30);
289+
let mut renamed = Vec::with_capacity(80);
290+
let mut contents = String::new();
291+
File::open_read_to_cleared_string(path, &mut contents);
272292

273-
res.file.read_append_to_string(&mut res.contents);
274-
let mut searcher = RustSearcher::new(&res.contents);
293+
let mut searcher = RustSearcher::new(&contents);
275294

276295
// First instance is the macro definition.
277296
assert!(
@@ -280,36 +299,38 @@ pub fn read_deprecated_lints() -> DeprecatedLints {
280299
);
281300

282301
if searcher.find_token(Ident("declare_with_version")) && searcher.match_tokens(DEPRECATED_TOKENS, &mut []) {
302+
let mut version = "";
283303
let mut name = "";
284304
let mut reason = "";
285-
while searcher.match_tokens(DECL_TOKENS, &mut [&mut name, &mut reason]) {
286-
res.deprecated.push(DeprecatedLint {
305+
while searcher.match_tokens(DECL_TOKENS, &mut [&mut version, &mut name, &mut reason]) {
306+
deprecated.push(DeprecatedLint {
287307
name: parse_str_single_line(path.as_ref(), name),
288308
reason: parse_str_single_line(path.as_ref(), reason),
309+
version: parse_str_single_line(path.as_ref(), version),
289310
});
290311
}
291312
} else {
292313
panic!("error reading deprecated lints");
293314
}
294-
// position of the closing `]}` of `declare_with_version`
295-
res.deprecated_end = searcher.pos();
296315

297316
if searcher.find_token(Ident("declare_with_version")) && searcher.match_tokens(RENAMED_TOKENS, &mut []) {
317+
let mut version = "";
298318
let mut old_name = "";
299319
let mut new_name = "";
300-
while searcher.match_tokens(DECL_TOKENS, &mut [&mut old_name, &mut new_name]) {
301-
res.renamed.push(RenamedLint {
320+
while searcher.match_tokens(DECL_TOKENS, &mut [&mut version, &mut old_name, &mut new_name]) {
321+
renamed.push(RenamedLint {
302322
old_name: parse_str_single_line(path.as_ref(), old_name),
303323
new_name: parse_str_single_line(path.as_ref(), new_name),
324+
version: parse_str_single_line(path.as_ref(), version),
304325
});
305326
}
306327
} else {
307328
panic!("error reading renamed lints");
308329
}
309-
// position of the closing `]}` of `declare_with_version`
310-
res.renamed_end = searcher.pos();
311330

312-
res
331+
deprecated.sort_by(|lhs, rhs| lhs.name.cmp(&rhs.name));
332+
renamed.sort_by(|lhs, rhs| lhs.old_name.cmp(&rhs.old_name));
333+
(deprecated, renamed)
313334
}
314335

315336
/// Removes the line splices and surrounding quotes from a string literal

0 commit comments

Comments
 (0)