Skip to content

Commit 7700820

Browse files
committed
clippy_dev: order deprecated_lints.rs in update_lints
1 parent c62fbd5 commit 7700820

File tree

9 files changed

+516
-513
lines changed

9 files changed

+516
-513
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
@@ -5,7 +5,6 @@ use itertools::Itertools;
55
use rustc_lexer::unescape;
66
use std::collections::HashSet;
77
use std::fmt::Write;
8-
use std::fs::OpenOptions;
98
use std::ops::Range;
109
use std::path::{Path, PathBuf};
1110
use walkdir::{DirEntry, WalkDir};
@@ -27,12 +26,11 @@ const DOCS_LINK: &str = "https://rust-lang.github.io/rust-clippy/master/index.ht
2726
/// Panics if a file path could not read from or then written to
2827
pub fn update(update_mode: UpdateMode) {
2928
let lints = find_lint_decls();
30-
let DeprecatedLints {
31-
renamed, deprecated, ..
32-
} = read_deprecated_lints();
29+
let (deprecated, renamed) = read_deprecated_lints();
3330
generate_lint_files(update_mode, &lints, &deprecated, &renamed);
3431
}
3532

33+
#[expect(clippy::too_many_lines)]
3634
pub fn generate_lint_files(
3735
update_mode: UpdateMode,
3836
lints: &[Lint],
@@ -94,6 +92,40 @@ pub fn generate_lint_files(
9492
dst.push_str("];\n");
9593
UpdateStatus::from_changed(src != dst)
9694
}),
95+
("clippy_lints/src/deprecated_lints.rs", &mut |_, src, dst| {
96+
let mut searcher = RustSearcher::new(src);
97+
assert!(
98+
searcher.find_token(Token::Ident("declare_with_version"))
99+
&& searcher.find_token(Token::Ident("declare_with_version")),
100+
"error reading deprecated lints"
101+
);
102+
dst.push_str(&src[..searcher.pos() as usize]);
103+
dst.push_str("! { DEPRECATED(DEPRECATED_VERSION) = [\n");
104+
for lint in deprecated {
105+
write!(
106+
dst,
107+
" #[clippy::version = \"{}\"]\n (\"{}\", \"{}\"),\n",
108+
lint.version, lint.name, lint.reason,
109+
)
110+
.unwrap();
111+
}
112+
dst.push_str(
113+
"]}\n\n\
114+
#[rustfmt::skip]\n\
115+
declare_with_version! { RENAMED(RENAMED_VERSION) = [\n\
116+
",
117+
);
118+
for lint in renamed {
119+
write!(
120+
dst,
121+
" #[clippy::version = \"{}\"]\n (\"{}\", \"{}\"),\n",
122+
lint.version, lint.old_name, lint.new_name,
123+
)
124+
.unwrap();
125+
}
126+
dst.push_str("]}\n");
127+
UpdateStatus::from_changed(src != dst)
128+
}),
97129
("tests/ui/deprecated.rs", &mut |_, src, dst| {
98130
dst.push_str(GENERATED_FILE_COMMENT);
99131
for lint in deprecated {
@@ -129,7 +161,7 @@ fn round_to_fifty(count: usize) -> usize {
129161
}
130162

131163
/// Lint data parsed from the Clippy source code.
132-
#[derive(Clone, PartialEq, Eq, Debug)]
164+
#[derive(PartialEq, Eq, Debug)]
133165
pub struct Lint {
134166
pub name: String,
135167
pub group: String,
@@ -138,15 +170,16 @@ pub struct Lint {
138170
pub declaration_range: Range<usize>,
139171
}
140172

141-
#[derive(Clone, PartialEq, Eq, Debug)]
142173
pub struct DeprecatedLint {
143174
pub name: String,
144175
pub reason: String,
176+
pub version: String,
145177
}
146178

147179
pub struct RenamedLint {
148180
pub old_name: String,
149181
pub new_name: String,
182+
pub version: String,
150183
}
151184

152185
/// Finds all lint declarations (`declare_clippy_lint!`)
@@ -230,23 +263,14 @@ fn parse_clippy_lint_decls(path: &Path, contents: &str, module: &str, lints: &mu
230263
}
231264
}
232265

233-
pub struct DeprecatedLints {
234-
pub file: File<'static>,
235-
pub contents: String,
236-
pub deprecated: Vec<DeprecatedLint>,
237-
pub renamed: Vec<RenamedLint>,
238-
pub deprecated_end: u32,
239-
pub renamed_end: u32,
240-
}
241-
242266
#[must_use]
243-
pub fn read_deprecated_lints() -> DeprecatedLints {
267+
pub fn read_deprecated_lints() -> (Vec<DeprecatedLint>, Vec<RenamedLint>) {
244268
#[allow(clippy::enum_glob_use)]
245269
use Token::*;
246270
#[rustfmt::skip]
247271
static DECL_TOKENS: &[Token<'_>] = &[
248272
// #[clippy::version = "version"]
249-
Pound, OpenBracket, Ident("clippy"), DoubleColon, Ident("version"), Eq, LitStr, CloseBracket,
273+
Pound, OpenBracket, Ident("clippy"), DoubleColon, Ident("version"), Eq, CaptureLitStr, CloseBracket,
250274
// ("first", "second"),
251275
OpenParen, CaptureLitStr, Comma, CaptureLitStr, CloseParen, Comma,
252276
];
@@ -262,17 +286,12 @@ pub fn read_deprecated_lints() -> DeprecatedLints {
262286
];
263287

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

274-
res.file.read_append_to_string(&mut res.contents);
275-
let mut searcher = RustSearcher::new(&res.contents);
294+
let mut searcher = RustSearcher::new(&contents);
276295

277296
// First instance is the macro definition.
278297
assert!(
@@ -281,36 +300,38 @@ pub fn read_deprecated_lints() -> DeprecatedLints {
281300
);
282301

283302
if searcher.find_token(Ident("declare_with_version")) && searcher.match_tokens(DEPRECATED_TOKENS, &mut []) {
303+
let mut version = "";
284304
let mut name = "";
285305
let mut reason = "";
286-
while searcher.match_tokens(DECL_TOKENS, &mut [&mut name, &mut reason]) {
287-
res.deprecated.push(DeprecatedLint {
306+
while searcher.match_tokens(DECL_TOKENS, &mut [&mut version, &mut name, &mut reason]) {
307+
deprecated.push(DeprecatedLint {
288308
name: parse_str_single_line(path.as_ref(), name),
289309
reason: parse_str_single_line(path.as_ref(), reason),
310+
version: parse_str_single_line(path.as_ref(), version),
290311
});
291312
}
292313
} else {
293314
panic!("error reading deprecated lints");
294315
}
295-
// position of the closing `]}` of `declare_with_version`
296-
res.deprecated_end = searcher.pos();
297316

298317
if searcher.find_token(Ident("declare_with_version")) && searcher.match_tokens(RENAMED_TOKENS, &mut []) {
318+
let mut version = "";
299319
let mut old_name = "";
300320
let mut new_name = "";
301-
while searcher.match_tokens(DECL_TOKENS, &mut [&mut old_name, &mut new_name]) {
302-
res.renamed.push(RenamedLint {
321+
while searcher.match_tokens(DECL_TOKENS, &mut [&mut version, &mut old_name, &mut new_name]) {
322+
renamed.push(RenamedLint {
303323
old_name: parse_str_single_line(path.as_ref(), old_name),
304324
new_name: parse_str_single_line(path.as_ref(), new_name),
325+
version: parse_str_single_line(path.as_ref(), version),
305326
});
306327
}
307328
} else {
308329
panic!("error reading renamed lints");
309330
}
310-
// position of the closing `]}` of `declare_with_version`
311-
res.renamed_end = searcher.pos();
312331

313-
res
332+
deprecated.sort_by(|lhs, rhs| lhs.name.cmp(&rhs.name));
333+
renamed.sort_by(|lhs, rhs| lhs.old_name.cmp(&rhs.old_name));
334+
(deprecated, renamed)
314335
}
315336

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

0 commit comments

Comments
 (0)