fallout2: rework clippy_dev & _lints fmt inlining
* Inline format args where possible * simplify a few complex macros into format str * use formatdoc!() instead format!(indoc!(...))
This commit is contained in:
@@ -82,16 +82,16 @@ pub fn run(check: bool, verbose: bool) {
|
|||||||
fn output_err(err: CliError) {
|
fn output_err(err: CliError) {
|
||||||
match err {
|
match err {
|
||||||
CliError::CommandFailed(command, stderr) => {
|
CliError::CommandFailed(command, stderr) => {
|
||||||
eprintln!("error: A command failed! `{}`\nstderr: {}", command, stderr);
|
eprintln!("error: A command failed! `{command}`\nstderr: {stderr}");
|
||||||
},
|
},
|
||||||
CliError::IoError(err) => {
|
CliError::IoError(err) => {
|
||||||
eprintln!("error: {}", err);
|
eprintln!("error: {err}");
|
||||||
},
|
},
|
||||||
CliError::RustfmtNotInstalled => {
|
CliError::RustfmtNotInstalled => {
|
||||||
eprintln!("error: rustfmt nightly is not installed.");
|
eprintln!("error: rustfmt nightly is not installed.");
|
||||||
},
|
},
|
||||||
CliError::WalkDirError(err) => {
|
CliError::WalkDirError(err) => {
|
||||||
eprintln!("error: {}", err);
|
eprintln!("error: {err}");
|
||||||
},
|
},
|
||||||
CliError::IntellijSetupActive => {
|
CliError::IntellijSetupActive => {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::clippy_project_root;
|
use crate::clippy_project_root;
|
||||||
use indoc::{indoc, writedoc};
|
use indoc::{formatdoc, writedoc};
|
||||||
use std::fmt::Write as _;
|
use std::fmt::Write as _;
|
||||||
use std::fs::{self, OpenOptions};
|
use std::fs::{self, OpenOptions};
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
@@ -23,7 +23,7 @@ impl<T> Context for io::Result<T> {
|
|||||||
match self {
|
match self {
|
||||||
Ok(t) => Ok(t),
|
Ok(t) => Ok(t),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let message = format!("{}: {}", text.as_ref(), e);
|
let message = format!("{}: {e}", text.as_ref());
|
||||||
Err(io::Error::new(ErrorKind::Other, message))
|
Err(io::Error::new(ErrorKind::Other, message))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@ fn create_lint(lint: &LintData<'_>, enable_msrv: bool) -> io::Result<()> {
|
|||||||
let lint_contents = get_lint_file_contents(lint, enable_msrv);
|
let lint_contents = get_lint_file_contents(lint, enable_msrv);
|
||||||
let lint_path = format!("clippy_lints/src/{}.rs", lint.name);
|
let lint_path = format!("clippy_lints/src/{}.rs", lint.name);
|
||||||
write_file(lint.project_root.join(&lint_path), lint_contents.as_bytes())?;
|
write_file(lint.project_root.join(&lint_path), lint_contents.as_bytes())?;
|
||||||
println!("Generated lint file: `{}`", lint_path);
|
println!("Generated lint file: `{lint_path}`");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -86,7 +86,7 @@ fn create_test(lint: &LintData<'_>) -> io::Result<()> {
|
|||||||
|
|
||||||
path.push("src");
|
path.push("src");
|
||||||
fs::create_dir(&path)?;
|
fs::create_dir(&path)?;
|
||||||
let header = format!("// compile-flags: --crate-name={}", lint_name);
|
let header = format!("// compile-flags: --crate-name={lint_name}");
|
||||||
write_file(path.join("main.rs"), get_test_file_contents(lint_name, Some(&header)))?;
|
write_file(path.join("main.rs"), get_test_file_contents(lint_name, Some(&header)))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -106,7 +106,7 @@ fn create_test(lint: &LintData<'_>) -> io::Result<()> {
|
|||||||
let test_contents = get_test_file_contents(lint.name, None);
|
let test_contents = get_test_file_contents(lint.name, None);
|
||||||
write_file(lint.project_root.join(&test_path), test_contents)?;
|
write_file(lint.project_root.join(&test_path), test_contents)?;
|
||||||
|
|
||||||
println!("Generated test file: `{}`", test_path);
|
println!("Generated test file: `{test_path}`");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -184,38 +184,36 @@ pub(crate) fn get_stabilization_version() -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_test_file_contents(lint_name: &str, header_commands: Option<&str>) -> String {
|
fn get_test_file_contents(lint_name: &str, header_commands: Option<&str>) -> String {
|
||||||
let mut contents = format!(
|
let mut contents = formatdoc!(
|
||||||
indoc! {"
|
r#"
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
#![warn(clippy::{})]
|
#![warn(clippy::{lint_name})]
|
||||||
|
|
||||||
fn main() {{
|
fn main() {{
|
||||||
// test code goes here
|
// test code goes here
|
||||||
}}
|
}}
|
||||||
"},
|
"#
|
||||||
lint_name
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(header) = header_commands {
|
if let Some(header) = header_commands {
|
||||||
contents = format!("{}\n{}", header, contents);
|
contents = format!("{header}\n{contents}");
|
||||||
}
|
}
|
||||||
|
|
||||||
contents
|
contents
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_manifest_contents(lint_name: &str, hint: &str) -> String {
|
fn get_manifest_contents(lint_name: &str, hint: &str) -> String {
|
||||||
format!(
|
formatdoc!(
|
||||||
indoc! {r#"
|
r#"
|
||||||
# {}
|
# {hint}
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "{}"
|
name = "{lint_name}"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
"#},
|
"#
|
||||||
hint, lint_name
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,38 +234,32 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
|
|||||||
let name_upper = lint_name.to_uppercase();
|
let name_upper = lint_name.to_uppercase();
|
||||||
|
|
||||||
result.push_str(&if enable_msrv {
|
result.push_str(&if enable_msrv {
|
||||||
format!(
|
formatdoc!(
|
||||||
indoc! {"
|
r#"
|
||||||
use clippy_utils::msrvs;
|
use clippy_utils::msrvs;
|
||||||
{pass_import}
|
{pass_import}
|
||||||
use rustc_lint::{{{context_import}, {pass_type}, LintContext}};
|
use rustc_lint::{{{context_import}, {pass_type}, LintContext}};
|
||||||
use rustc_semver::RustcVersion;
|
use rustc_semver::RustcVersion;
|
||||||
use rustc_session::{{declare_tool_lint, impl_lint_pass}};
|
use rustc_session::{{declare_tool_lint, impl_lint_pass}};
|
||||||
|
|
||||||
"},
|
"#
|
||||||
pass_type = pass_type,
|
|
||||||
pass_import = pass_import,
|
|
||||||
context_import = context_import,
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
format!(
|
formatdoc!(
|
||||||
indoc! {"
|
r#"
|
||||||
{pass_import}
|
{pass_import}
|
||||||
use rustc_lint::{{{context_import}, {pass_type}}};
|
use rustc_lint::{{{context_import}, {pass_type}}};
|
||||||
use rustc_session::{{declare_lint_pass, declare_tool_lint}};
|
use rustc_session::{{declare_lint_pass, declare_tool_lint}};
|
||||||
|
|
||||||
"},
|
"#
|
||||||
pass_import = pass_import,
|
|
||||||
pass_type = pass_type,
|
|
||||||
context_import = context_import
|
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
let _ = write!(result, "{}", get_lint_declaration(&name_upper, category));
|
let _ = write!(result, "{}", get_lint_declaration(&name_upper, category));
|
||||||
|
|
||||||
result.push_str(&if enable_msrv {
|
result.push_str(&if enable_msrv {
|
||||||
format!(
|
formatdoc!(
|
||||||
indoc! {"
|
r#"
|
||||||
pub struct {name_camel} {{
|
pub struct {name_camel} {{
|
||||||
msrv: Option<RustcVersion>,
|
msrv: Option<RustcVersion>,
|
||||||
}}
|
}}
|
||||||
@@ -288,24 +280,15 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
|
|||||||
// TODO: Add MSRV level to `clippy_utils/src/msrvs.rs` if needed.
|
// TODO: Add MSRV level to `clippy_utils/src/msrvs.rs` if needed.
|
||||||
// TODO: Add MSRV test to `tests/ui/min_rust_version_attr.rs`.
|
// TODO: Add MSRV test to `tests/ui/min_rust_version_attr.rs`.
|
||||||
// TODO: Update msrv config comment in `clippy_lints/src/utils/conf.rs`
|
// TODO: Update msrv config comment in `clippy_lints/src/utils/conf.rs`
|
||||||
"},
|
"#
|
||||||
pass_type = pass_type,
|
|
||||||
pass_lifetimes = pass_lifetimes,
|
|
||||||
name_upper = name_upper,
|
|
||||||
name_camel = name_camel,
|
|
||||||
context_import = context_import,
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
format!(
|
formatdoc!(
|
||||||
indoc! {"
|
r#"
|
||||||
declare_lint_pass!({name_camel} => [{name_upper}]);
|
declare_lint_pass!({name_camel} => [{name_upper}]);
|
||||||
|
|
||||||
impl {pass_type}{pass_lifetimes} for {name_camel} {{}}
|
impl {pass_type}{pass_lifetimes} for {name_camel} {{}}
|
||||||
"},
|
"#
|
||||||
pass_type = pass_type,
|
|
||||||
pass_lifetimes = pass_lifetimes,
|
|
||||||
name_upper = name_upper,
|
|
||||||
name_camel = name_camel,
|
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -313,8 +296,8 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_lint_declaration(name_upper: &str, category: &str) -> String {
|
fn get_lint_declaration(name_upper: &str, category: &str) -> String {
|
||||||
format!(
|
formatdoc!(
|
||||||
indoc! {r#"
|
r#"
|
||||||
declare_clippy_lint! {{
|
declare_clippy_lint! {{
|
||||||
/// ### What it does
|
/// ### What it does
|
||||||
///
|
///
|
||||||
@@ -328,15 +311,13 @@ fn get_lint_declaration(name_upper: &str, category: &str) -> String {
|
|||||||
/// ```rust
|
/// ```rust
|
||||||
/// // example code which does not raise clippy warning
|
/// // example code which does not raise clippy warning
|
||||||
/// ```
|
/// ```
|
||||||
#[clippy::version = "{version}"]
|
#[clippy::version = "{}"]
|
||||||
pub {name_upper},
|
pub {name_upper},
|
||||||
{category},
|
{category},
|
||||||
"default lint description"
|
"default lint description"
|
||||||
}}
|
}}
|
||||||
"#},
|
"#,
|
||||||
version = get_stabilization_version(),
|
get_stabilization_version(),
|
||||||
name_upper = name_upper,
|
|
||||||
category = category,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,7 +331,7 @@ fn create_lint_for_ty(lint: &LintData<'_>, enable_msrv: bool, ty: &str) -> io::R
|
|||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
let ty_dir = lint.project_root.join(format!("clippy_lints/src/{}", ty));
|
let ty_dir = lint.project_root.join(format!("clippy_lints/src/{ty}"));
|
||||||
assert!(
|
assert!(
|
||||||
ty_dir.exists() && ty_dir.is_dir(),
|
ty_dir.exists() && ty_dir.is_dir(),
|
||||||
"Directory `{}` does not exist!",
|
"Directory `{}` does not exist!",
|
||||||
@@ -410,10 +391,10 @@ fn create_lint_for_ty(lint: &LintData<'_>, enable_msrv: bool, ty: &str) -> io::R
|
|||||||
}
|
}
|
||||||
|
|
||||||
write_file(lint_file_path.as_path(), lint_file_contents)?;
|
write_file(lint_file_path.as_path(), lint_file_contents)?;
|
||||||
println!("Generated lint file: `clippy_lints/src/{}/{}.rs`", ty, lint.name);
|
println!("Generated lint file: `clippy_lints/src/{ty}/{}.rs`", lint.name);
|
||||||
println!(
|
println!(
|
||||||
"Be sure to add a call to `{}::check` in `clippy_lints/src/{}/mod.rs`!",
|
"Be sure to add a call to `{}::check` in `clippy_lints/src/{ty}/mod.rs`!",
|
||||||
lint.name, ty
|
lint.name
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -540,7 +521,7 @@ fn setup_mod_file(path: &Path, lint: &LintData<'_>) -> io::Result<&'static str>
|
|||||||
.chain(std::iter::once(&*lint_name_upper))
|
.chain(std::iter::once(&*lint_name_upper))
|
||||||
.filter(|s| !s.is_empty())
|
.filter(|s| !s.is_empty())
|
||||||
{
|
{
|
||||||
let _ = write!(new_arr_content, "\n {},", ident);
|
let _ = write!(new_arr_content, "\n {ident},");
|
||||||
}
|
}
|
||||||
new_arr_content.push('\n');
|
new_arr_content.push('\n');
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ use std::time::{Duration, SystemTime};
|
|||||||
/// Panics if the python commands could not be spawned
|
/// Panics if the python commands could not be spawned
|
||||||
pub fn run(port: u16, lint: Option<&String>) -> ! {
|
pub fn run(port: u16, lint: Option<&String>) -> ! {
|
||||||
let mut url = Some(match lint {
|
let mut url = Some(match lint {
|
||||||
None => format!("http://localhost:{}", port),
|
None => format!("http://localhost:{port}"),
|
||||||
Some(lint) => format!("http://localhost:{}/#{}", port, lint),
|
Some(lint) => format!("http://localhost:{port}/#{lint}"),
|
||||||
});
|
});
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
|||||||
@@ -30,10 +30,7 @@ pub fn install_hook(force_override: bool) {
|
|||||||
println!("info: the hook can be removed with `cargo dev remove git-hook`");
|
println!("info: the hook can be removed with `cargo dev remove git-hook`");
|
||||||
println!("git hook successfully installed");
|
println!("git hook successfully installed");
|
||||||
},
|
},
|
||||||
Err(err) => eprintln!(
|
Err(err) => eprintln!("error: unable to copy `{HOOK_SOURCE_FILE}` to `{HOOK_TARGET_FILE}` ({err})"),
|
||||||
"error: unable to copy `{}` to `{}` ({})",
|
|
||||||
HOOK_SOURCE_FILE, HOOK_TARGET_FILE, err
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +74,7 @@ pub fn remove_hook() {
|
|||||||
|
|
||||||
fn delete_git_hook_file(path: &Path) -> bool {
|
fn delete_git_hook_file(path: &Path) -> bool {
|
||||||
if let Err(err) = fs::remove_file(path) {
|
if let Err(err) = fs::remove_file(path) {
|
||||||
eprintln!("error: unable to delete existing pre-commit git hook ({})", err);
|
eprintln!("error: unable to delete existing pre-commit git hook ({err})");
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ fn check_and_get_rustc_dir(rustc_path: &str) -> Result<PathBuf, ()> {
|
|||||||
path = absolute_path;
|
path = absolute_path;
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("error: unable to get the absolute path of rustc ({})", err);
|
eprintln!("error: unable to get the absolute path of rustc ({err})");
|
||||||
return Err(());
|
return Err(());
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -103,14 +103,14 @@ fn inject_deps_into_project(rustc_source_dir: &Path, project: &ClippyProjectInfo
|
|||||||
fn read_project_file(file_path: &str) -> Result<String, ()> {
|
fn read_project_file(file_path: &str) -> Result<String, ()> {
|
||||||
let path = Path::new(file_path);
|
let path = Path::new(file_path);
|
||||||
if !path.exists() {
|
if !path.exists() {
|
||||||
eprintln!("error: unable to find the file `{}`", file_path);
|
eprintln!("error: unable to find the file `{file_path}`");
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
match fs::read_to_string(path) {
|
match fs::read_to_string(path) {
|
||||||
Ok(content) => Ok(content),
|
Ok(content) => Ok(content),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("error: the file `{}` could not be read ({})", file_path, err);
|
eprintln!("error: the file `{file_path}` could not be read ({err})");
|
||||||
Err(())
|
Err(())
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -124,10 +124,7 @@ fn inject_deps_into_manifest(
|
|||||||
) -> std::io::Result<()> {
|
) -> std::io::Result<()> {
|
||||||
// do not inject deps if we have already done so
|
// do not inject deps if we have already done so
|
||||||
if cargo_toml.contains(RUSTC_PATH_SECTION) {
|
if cargo_toml.contains(RUSTC_PATH_SECTION) {
|
||||||
eprintln!(
|
eprintln!("warn: dependencies are already setup inside {manifest_path}, skipping file");
|
||||||
"warn: dependencies are already setup inside {}, skipping file",
|
|
||||||
manifest_path
|
|
||||||
);
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,11 +139,7 @@ fn inject_deps_into_manifest(
|
|||||||
|
|
||||||
let new_deps = extern_crates.map(|dep| {
|
let new_deps = extern_crates.map(|dep| {
|
||||||
// format the dependencies that are going to be put inside the Cargo.toml
|
// format the dependencies that are going to be put inside the Cargo.toml
|
||||||
format!(
|
format!("{dep} = {{ path = \"{}/{dep}\" }}\n", rustc_source_dir.display())
|
||||||
"{dep} = {{ path = \"{source_path}/{dep}\" }}\n",
|
|
||||||
dep = dep,
|
|
||||||
source_path = rustc_source_dir.display()
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// format a new [dependencies]-block with the new deps we need to inject
|
// format a new [dependencies]-block with the new deps we need to inject
|
||||||
@@ -163,11 +156,11 @@ fn inject_deps_into_manifest(
|
|||||||
// etc
|
// etc
|
||||||
let new_manifest = cargo_toml.replacen("[dependencies]\n", &all_deps, 1);
|
let new_manifest = cargo_toml.replacen("[dependencies]\n", &all_deps, 1);
|
||||||
|
|
||||||
// println!("{}", new_manifest);
|
// println!("{new_manifest}");
|
||||||
let mut file = File::create(manifest_path)?;
|
let mut file = File::create(manifest_path)?;
|
||||||
file.write_all(new_manifest.as_bytes())?;
|
file.write_all(new_manifest.as_bytes())?;
|
||||||
|
|
||||||
println!("info: successfully setup dependencies inside {}", manifest_path);
|
println!("info: successfully setup dependencies inside {manifest_path}");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -214,8 +207,8 @@ fn remove_rustc_src_from_project(project: &ClippyProjectInfo) -> bool {
|
|||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"error: unable to open file `{}` to remove rustc dependencies for {} ({})",
|
"error: unable to open file `{}` to remove rustc dependencies for {} ({err})",
|
||||||
project.cargo_file, project.name, err
|
project.cargo_file, project.name
|
||||||
);
|
);
|
||||||
false
|
false
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -17,10 +17,7 @@ pub fn install_tasks(force_override: bool) {
|
|||||||
println!("info: the task file can be removed with `cargo dev remove vscode-tasks`");
|
println!("info: the task file can be removed with `cargo dev remove vscode-tasks`");
|
||||||
println!("vscode tasks successfully installed");
|
println!("vscode tasks successfully installed");
|
||||||
},
|
},
|
||||||
Err(err) => eprintln!(
|
Err(err) => eprintln!("error: unable to copy `{TASK_SOURCE_FILE}` to `{TASK_TARGET_FILE}` ({err})"),
|
||||||
"error: unable to copy `{}` to `{}` ({})",
|
|
||||||
TASK_SOURCE_FILE, TASK_TARGET_FILE, err
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,23 +41,17 @@ fn check_install_precondition(force_override: bool) -> bool {
|
|||||||
return delete_vs_task_file(path);
|
return delete_vs_task_file(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
eprintln!(
|
eprintln!("error: there is already a `task.json` file inside the `{VSCODE_DIR}` directory");
|
||||||
"error: there is already a `task.json` file inside the `{}` directory",
|
|
||||||
VSCODE_DIR
|
|
||||||
);
|
|
||||||
println!("info: use the `--force-override` flag to override the existing `task.json` file");
|
println!("info: use the `--force-override` flag to override the existing `task.json` file");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match fs::create_dir(vs_dir_path) {
|
match fs::create_dir(vs_dir_path) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
println!("info: created `{}` directory for clippy", VSCODE_DIR);
|
println!("info: created `{VSCODE_DIR}` directory for clippy");
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!(
|
eprintln!("error: the task target directory `{VSCODE_DIR}` could not be created ({err})");
|
||||||
"error: the task target directory `{}` could not be created ({})",
|
|
||||||
VSCODE_DIR, err
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,7 +73,7 @@ pub fn remove_tasks() {
|
|||||||
|
|
||||||
fn delete_vs_task_file(path: &Path) -> bool {
|
fn delete_vs_task_file(path: &Path) -> bool {
|
||||||
if let Err(err) = fs::remove_file(path) {
|
if let Err(err) = fs::remove_file(path) {
|
||||||
eprintln!("error: unable to delete the existing `tasks.json` file ({})", err);
|
eprintln!("error: unable to delete the existing `tasks.json` file ({err})");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ fn generate_lint_files(
|
|||||||
)
|
)
|
||||||
.sorted()
|
.sorted()
|
||||||
{
|
{
|
||||||
writeln!(res, "[`{}`]: {}#{}", lint, DOCS_LINK, lint).unwrap();
|
writeln!(res, "[`{lint}`]: {DOCS_LINK}#{lint}").unwrap();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -99,7 +99,7 @@ fn generate_lint_files(
|
|||||||
"// end lints modules, do not remove this comment, it’s used in `update_lints`",
|
"// end lints modules, do not remove this comment, it’s used in `update_lints`",
|
||||||
|res| {
|
|res| {
|
||||||
for lint_mod in usable_lints.iter().map(|l| &l.module).unique().sorted() {
|
for lint_mod in usable_lints.iter().map(|l| &l.module).unique().sorted() {
|
||||||
writeln!(res, "mod {};", lint_mod).unwrap();
|
writeln!(res, "mod {lint_mod};").unwrap();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -129,7 +129,7 @@ fn generate_lint_files(
|
|||||||
for (lint_group, lints) in Lint::by_lint_group(usable_lints.into_iter().chain(internal_lints)) {
|
for (lint_group, lints) in Lint::by_lint_group(usable_lints.into_iter().chain(internal_lints)) {
|
||||||
let content = gen_lint_group_list(&lint_group, lints.iter());
|
let content = gen_lint_group_list(&lint_group, lints.iter());
|
||||||
process_file(
|
process_file(
|
||||||
&format!("clippy_lints/src/lib.register_{}.rs", lint_group),
|
&format!("clippy_lints/src/lib.register_{lint_group}.rs"),
|
||||||
update_mode,
|
update_mode,
|
||||||
&content,
|
&content,
|
||||||
);
|
);
|
||||||
@@ -190,9 +190,9 @@ fn print_lint_names(header: &str, lints: &BTreeSet<String>) -> bool {
|
|||||||
if lints.is_empty() {
|
if lints.is_empty() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
println!("{}", header);
|
println!("{header}");
|
||||||
for lint in lints.iter().sorted() {
|
for lint in lints.iter().sorted() {
|
||||||
println!(" {}", lint);
|
println!(" {lint}");
|
||||||
}
|
}
|
||||||
println!();
|
println!();
|
||||||
true
|
true
|
||||||
@@ -205,16 +205,16 @@ pub fn print_lints() {
|
|||||||
let grouped_by_lint_group = Lint::by_lint_group(usable_lints.into_iter());
|
let grouped_by_lint_group = Lint::by_lint_group(usable_lints.into_iter());
|
||||||
|
|
||||||
for (lint_group, mut lints) in grouped_by_lint_group {
|
for (lint_group, mut lints) in grouped_by_lint_group {
|
||||||
println!("\n## {}", lint_group);
|
println!("\n## {lint_group}");
|
||||||
|
|
||||||
lints.sort_by_key(|l| l.name.clone());
|
lints.sort_by_key(|l| l.name.clone());
|
||||||
|
|
||||||
for lint in lints {
|
for lint in lints {
|
||||||
println!("* [{}]({}#{}) ({})", lint.name, DOCS_LINK, lint.name, lint.desc);
|
println!("* [{}]({DOCS_LINK}#{}) ({})", lint.name, lint.name, lint.desc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("there are {} lints", usable_lint_count);
|
println!("there are {usable_lint_count} lints");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Runs the `rename_lint` command.
|
/// Runs the `rename_lint` command.
|
||||||
@@ -235,10 +235,10 @@ pub fn print_lints() {
|
|||||||
#[allow(clippy::too_many_lines)]
|
#[allow(clippy::too_many_lines)]
|
||||||
pub fn rename(old_name: &str, new_name: &str, uplift: bool) {
|
pub fn rename(old_name: &str, new_name: &str, uplift: bool) {
|
||||||
if let Some((prefix, _)) = old_name.split_once("::") {
|
if let Some((prefix, _)) = old_name.split_once("::") {
|
||||||
panic!("`{}` should not contain the `{}` prefix", old_name, prefix);
|
panic!("`{old_name}` should not contain the `{prefix}` prefix");
|
||||||
}
|
}
|
||||||
if let Some((prefix, _)) = new_name.split_once("::") {
|
if let Some((prefix, _)) = new_name.split_once("::") {
|
||||||
panic!("`{}` should not contain the `{}` prefix", new_name, prefix);
|
panic!("`{new_name}` should not contain the `{prefix}` prefix");
|
||||||
}
|
}
|
||||||
|
|
||||||
let (mut lints, deprecated_lints, mut renamed_lints) = gather_all();
|
let (mut lints, deprecated_lints, mut renamed_lints) = gather_all();
|
||||||
@@ -251,14 +251,14 @@ pub fn rename(old_name: &str, new_name: &str, uplift: bool) {
|
|||||||
found_new_name = true;
|
found_new_name = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let old_lint_index = old_lint_index.unwrap_or_else(|| panic!("could not find lint `{}`", old_name));
|
let old_lint_index = old_lint_index.unwrap_or_else(|| panic!("could not find lint `{old_name}`"));
|
||||||
|
|
||||||
let lint = RenamedLint {
|
let lint = RenamedLint {
|
||||||
old_name: format!("clippy::{}", old_name),
|
old_name: format!("clippy::{old_name}"),
|
||||||
new_name: if uplift {
|
new_name: if uplift {
|
||||||
new_name.into()
|
new_name.into()
|
||||||
} else {
|
} else {
|
||||||
format!("clippy::{}", new_name)
|
format!("clippy::{new_name}")
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -266,13 +266,11 @@ pub fn rename(old_name: &str, new_name: &str, uplift: bool) {
|
|||||||
// case.
|
// case.
|
||||||
assert!(
|
assert!(
|
||||||
!renamed_lints.iter().any(|l| lint.old_name == l.old_name),
|
!renamed_lints.iter().any(|l| lint.old_name == l.old_name),
|
||||||
"`{}` has already been renamed",
|
"`{old_name}` has already been renamed"
|
||||||
old_name
|
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
!deprecated_lints.iter().any(|l| lint.old_name == l.name),
|
!deprecated_lints.iter().any(|l| lint.old_name == l.name),
|
||||||
"`{}` has already been deprecated",
|
"`{old_name}` has already been deprecated"
|
||||||
old_name
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Update all lint level attributes. (`clippy::lint_name`)
|
// Update all lint level attributes. (`clippy::lint_name`)
|
||||||
@@ -309,14 +307,12 @@ pub fn rename(old_name: &str, new_name: &str, uplift: bool) {
|
|||||||
if uplift {
|
if uplift {
|
||||||
write_file(Path::new("tests/ui/rename.rs"), &gen_renamed_lints_test(&renamed_lints));
|
write_file(Path::new("tests/ui/rename.rs"), &gen_renamed_lints_test(&renamed_lints));
|
||||||
println!(
|
println!(
|
||||||
"`{}` has be uplifted. All the code inside `clippy_lints` related to it needs to be removed manually.",
|
"`{old_name}` has be uplifted. All the code inside `clippy_lints` related to it needs to be removed manually."
|
||||||
old_name
|
|
||||||
);
|
);
|
||||||
} else if found_new_name {
|
} else if found_new_name {
|
||||||
write_file(Path::new("tests/ui/rename.rs"), &gen_renamed_lints_test(&renamed_lints));
|
write_file(Path::new("tests/ui/rename.rs"), &gen_renamed_lints_test(&renamed_lints));
|
||||||
println!(
|
println!(
|
||||||
"`{}` is already defined. The old linting code inside `clippy_lints` needs to be updated/removed manually.",
|
"`{new_name}` is already defined. The old linting code inside `clippy_lints` needs to be updated/removed manually."
|
||||||
new_name
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// Rename the lint struct and source files sharing a name with the lint.
|
// Rename the lint struct and source files sharing a name with the lint.
|
||||||
@@ -327,16 +323,16 @@ pub fn rename(old_name: &str, new_name: &str, uplift: bool) {
|
|||||||
|
|
||||||
// Rename test files. only rename `.stderr` and `.fixed` files if the new test name doesn't exist.
|
// Rename test files. only rename `.stderr` and `.fixed` files if the new test name doesn't exist.
|
||||||
if try_rename_file(
|
if try_rename_file(
|
||||||
Path::new(&format!("tests/ui/{}.rs", old_name)),
|
Path::new(&format!("tests/ui/{old_name}.rs")),
|
||||||
Path::new(&format!("tests/ui/{}.rs", new_name)),
|
Path::new(&format!("tests/ui/{new_name}.rs")),
|
||||||
) {
|
) {
|
||||||
try_rename_file(
|
try_rename_file(
|
||||||
Path::new(&format!("tests/ui/{}.stderr", old_name)),
|
Path::new(&format!("tests/ui/{old_name}.stderr")),
|
||||||
Path::new(&format!("tests/ui/{}.stderr", new_name)),
|
Path::new(&format!("tests/ui/{new_name}.stderr")),
|
||||||
);
|
);
|
||||||
try_rename_file(
|
try_rename_file(
|
||||||
Path::new(&format!("tests/ui/{}.fixed", old_name)),
|
Path::new(&format!("tests/ui/{old_name}.fixed")),
|
||||||
Path::new(&format!("tests/ui/{}.fixed", new_name)),
|
Path::new(&format!("tests/ui/{new_name}.fixed")),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,8 +340,8 @@ pub fn rename(old_name: &str, new_name: &str, uplift: bool) {
|
|||||||
let replacements;
|
let replacements;
|
||||||
let replacements = if lint.module == old_name
|
let replacements = if lint.module == old_name
|
||||||
&& try_rename_file(
|
&& try_rename_file(
|
||||||
Path::new(&format!("clippy_lints/src/{}.rs", old_name)),
|
Path::new(&format!("clippy_lints/src/{old_name}.rs")),
|
||||||
Path::new(&format!("clippy_lints/src/{}.rs", new_name)),
|
Path::new(&format!("clippy_lints/src/{new_name}.rs")),
|
||||||
) {
|
) {
|
||||||
// Edit the module name in the lint list. Note there could be multiple lints.
|
// Edit the module name in the lint list. Note there could be multiple lints.
|
||||||
for lint in lints.iter_mut().filter(|l| l.module == old_name) {
|
for lint in lints.iter_mut().filter(|l| l.module == old_name) {
|
||||||
@@ -356,14 +352,14 @@ pub fn rename(old_name: &str, new_name: &str, uplift: bool) {
|
|||||||
} else if !lint.module.contains("::")
|
} else if !lint.module.contains("::")
|
||||||
// Catch cases like `methods/lint_name.rs` where the lint is stored in `methods/mod.rs`
|
// Catch cases like `methods/lint_name.rs` where the lint is stored in `methods/mod.rs`
|
||||||
&& try_rename_file(
|
&& try_rename_file(
|
||||||
Path::new(&format!("clippy_lints/src/{}/{}.rs", lint.module, old_name)),
|
Path::new(&format!("clippy_lints/src/{}/{old_name}.rs", lint.module)),
|
||||||
Path::new(&format!("clippy_lints/src/{}/{}.rs", lint.module, new_name)),
|
Path::new(&format!("clippy_lints/src/{}/{new_name}.rs", lint.module)),
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Edit the module name in the lint list. Note there could be multiple lints, or none.
|
// Edit the module name in the lint list. Note there could be multiple lints, or none.
|
||||||
let renamed_mod = format!("{}::{}", lint.module, old_name);
|
let renamed_mod = format!("{}::{old_name}", lint.module);
|
||||||
for lint in lints.iter_mut().filter(|l| l.module == renamed_mod) {
|
for lint in lints.iter_mut().filter(|l| l.module == renamed_mod) {
|
||||||
lint.module = format!("{}::{}", lint.module, new_name);
|
lint.module = format!("{}::{new_name}", lint.module);
|
||||||
}
|
}
|
||||||
replacements = [(&*old_name_upper, &*new_name_upper), (old_name, new_name)];
|
replacements = [(&*old_name_upper, &*new_name_upper), (old_name, new_name)];
|
||||||
replacements.as_slice()
|
replacements.as_slice()
|
||||||
@@ -379,7 +375,7 @@ pub fn rename(old_name: &str, new_name: &str, uplift: bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
generate_lint_files(UpdateMode::Change, &lints, &deprecated_lints, &renamed_lints);
|
generate_lint_files(UpdateMode::Change, &lints, &deprecated_lints, &renamed_lints);
|
||||||
println!("{} has been successfully renamed", old_name);
|
println!("{old_name} has been successfully renamed");
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("note: `cargo uitest` still needs to be run to update the test results");
|
println!("note: `cargo uitest` still needs to be run to update the test results");
|
||||||
@@ -408,7 +404,7 @@ pub fn deprecate(name: &str, reason: Option<&String>) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
generate_lint_files(UpdateMode::Change, &lints, &deprecated_lints, &renamed_lints);
|
generate_lint_files(UpdateMode::Change, &lints, &deprecated_lints, &renamed_lints);
|
||||||
println!("info: `{}` has successfully been deprecated", name);
|
println!("info: `{name}` has successfully been deprecated");
|
||||||
|
|
||||||
if reason == DEFAULT_DEPRECATION_REASON {
|
if reason == DEFAULT_DEPRECATION_REASON {
|
||||||
println!("note: the deprecation reason must be updated in `clippy_lints/src/deprecated_lints.rs`");
|
println!("note: the deprecation reason must be updated in `clippy_lints/src/deprecated_lints.rs`");
|
||||||
@@ -421,7 +417,7 @@ pub fn deprecate(name: &str, reason: Option<&String>) {
|
|||||||
let name_upper = name.to_uppercase();
|
let name_upper = name.to_uppercase();
|
||||||
|
|
||||||
let (mut lints, deprecated_lints, renamed_lints) = gather_all();
|
let (mut lints, deprecated_lints, renamed_lints) = gather_all();
|
||||||
let Some(lint) = lints.iter().find(|l| l.name == name_lower) else { eprintln!("error: failed to find lint `{}`", name); return; };
|
let Some(lint) = lints.iter().find(|l| l.name == name_lower) else { eprintln!("error: failed to find lint `{name}`"); return; };
|
||||||
|
|
||||||
let mod_path = {
|
let mod_path = {
|
||||||
let mut mod_path = PathBuf::from(format!("clippy_lints/src/{}", lint.module));
|
let mut mod_path = PathBuf::from(format!("clippy_lints/src/{}", lint.module));
|
||||||
@@ -450,7 +446,7 @@ fn remove_lint_declaration(name: &str, path: &Path, lints: &mut Vec<Lint>) -> io
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn remove_test_assets(name: &str) {
|
fn remove_test_assets(name: &str) {
|
||||||
let test_file_stem = format!("tests/ui/{}", name);
|
let test_file_stem = format!("tests/ui/{name}");
|
||||||
let path = Path::new(&test_file_stem);
|
let path = Path::new(&test_file_stem);
|
||||||
|
|
||||||
// Some lints have their own directories, delete them
|
// Some lints have their own directories, delete them
|
||||||
@@ -512,8 +508,7 @@ fn remove_lint_declaration(name: &str, path: &Path, lints: &mut Vec<Lint>) -> io
|
|||||||
fs::read_to_string(path).unwrap_or_else(|_| panic!("failed to read `{}`", path.to_string_lossy()));
|
fs::read_to_string(path).unwrap_or_else(|_| panic!("failed to read `{}`", path.to_string_lossy()));
|
||||||
|
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"warn: you will have to manually remove any code related to `{}` from `{}`",
|
"warn: you will have to manually remove any code related to `{name}` from `{}`",
|
||||||
name,
|
|
||||||
path.display()
|
path.display()
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -528,7 +523,7 @@ fn remove_lint_declaration(name: &str, path: &Path, lints: &mut Vec<Lint>) -> io
|
|||||||
content.replace_range(lint.declaration_range.clone(), "");
|
content.replace_range(lint.declaration_range.clone(), "");
|
||||||
|
|
||||||
// Remove the module declaration (mod xyz;)
|
// Remove the module declaration (mod xyz;)
|
||||||
let mod_decl = format!("\nmod {};", name);
|
let mod_decl = format!("\nmod {name};");
|
||||||
content = content.replacen(&mod_decl, "", 1);
|
content = content.replacen(&mod_decl, "", 1);
|
||||||
|
|
||||||
remove_impl_lint_pass(&lint.name.to_uppercase(), &mut content);
|
remove_impl_lint_pass(&lint.name.to_uppercase(), &mut content);
|
||||||
@@ -621,13 +616,13 @@ fn round_to_fifty(count: usize) -> usize {
|
|||||||
fn process_file(path: impl AsRef<Path>, update_mode: UpdateMode, content: &str) {
|
fn process_file(path: impl AsRef<Path>, update_mode: UpdateMode, content: &str) {
|
||||||
if update_mode == UpdateMode::Check {
|
if update_mode == UpdateMode::Check {
|
||||||
let old_content =
|
let old_content =
|
||||||
fs::read_to_string(&path).unwrap_or_else(|e| panic!("Cannot read from {}: {}", path.as_ref().display(), e));
|
fs::read_to_string(&path).unwrap_or_else(|e| panic!("Cannot read from {}: {e}", path.as_ref().display()));
|
||||||
if content != old_content {
|
if content != old_content {
|
||||||
exit_with_failure();
|
exit_with_failure();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fs::write(&path, content.as_bytes())
|
fs::write(&path, content.as_bytes())
|
||||||
.unwrap_or_else(|e| panic!("Cannot write to {}: {}", path.as_ref().display(), e));
|
.unwrap_or_else(|e| panic!("Cannot write to {}: {e}", path.as_ref().display()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -731,11 +726,10 @@ fn gen_lint_group_list<'a>(group_name: &str, lints: impl Iterator<Item = &'a Lin
|
|||||||
|
|
||||||
let _ = writeln!(
|
let _ = writeln!(
|
||||||
output,
|
output,
|
||||||
"store.register_group(true, \"clippy::{0}\", Some(\"clippy_{0}\"), vec![",
|
"store.register_group(true, \"clippy::{group_name}\", Some(\"clippy_{group_name}\"), vec![",
|
||||||
group_name
|
|
||||||
);
|
);
|
||||||
for (module, name) in details {
|
for (module, name) in details {
|
||||||
let _ = writeln!(output, " LintId::of({}::{}),", module, name);
|
let _ = writeln!(output, " LintId::of({module}::{name}),");
|
||||||
}
|
}
|
||||||
output.push_str("])\n");
|
output.push_str("])\n");
|
||||||
|
|
||||||
@@ -783,7 +777,7 @@ fn gen_register_lint_list<'a>(
|
|||||||
if !is_public {
|
if !is_public {
|
||||||
output.push_str(" #[cfg(feature = \"internal\")]\n");
|
output.push_str(" #[cfg(feature = \"internal\")]\n");
|
||||||
}
|
}
|
||||||
let _ = writeln!(output, " {}::{},", module_name, lint_name);
|
let _ = writeln!(output, " {module_name}::{lint_name},");
|
||||||
}
|
}
|
||||||
output.push_str("])\n");
|
output.push_str("])\n");
|
||||||
|
|
||||||
@@ -841,7 +835,7 @@ fn gather_all() -> (Vec<Lint>, Vec<DeprecatedLint>, Vec<RenamedLint>) {
|
|||||||
for (rel_path, file) in clippy_lints_src_files() {
|
for (rel_path, file) in clippy_lints_src_files() {
|
||||||
let path = file.path();
|
let path = file.path();
|
||||||
let contents =
|
let contents =
|
||||||
fs::read_to_string(path).unwrap_or_else(|e| panic!("Cannot read from `{}`: {}", path.display(), e));
|
fs::read_to_string(path).unwrap_or_else(|e| panic!("Cannot read from `{}`: {e}", path.display()));
|
||||||
let module = rel_path
|
let module = rel_path
|
||||||
.components()
|
.components()
|
||||||
.map(|c| c.as_os_str().to_str().unwrap())
|
.map(|c| c.as_os_str().to_str().unwrap())
|
||||||
@@ -1050,7 +1044,7 @@ fn remove_line_splices(s: &str) -> String {
|
|||||||
.trim_matches('#')
|
.trim_matches('#')
|
||||||
.strip_prefix('"')
|
.strip_prefix('"')
|
||||||
.and_then(|s| s.strip_suffix('"'))
|
.and_then(|s| s.strip_suffix('"'))
|
||||||
.unwrap_or_else(|| panic!("expected quoted string, found `{}`", s));
|
.unwrap_or_else(|| panic!("expected quoted string, found `{s}`"));
|
||||||
let mut res = String::with_capacity(s.len());
|
let mut res = String::with_capacity(s.len());
|
||||||
unescape::unescape_literal(s, unescape::Mode::Str, &mut |range, ch| {
|
unescape::unescape_literal(s, unescape::Mode::Str, &mut |range, ch| {
|
||||||
if ch.is_ok() {
|
if ch.is_ok() {
|
||||||
@@ -1076,10 +1070,10 @@ fn replace_region_in_file(
|
|||||||
end: &str,
|
end: &str,
|
||||||
write_replacement: impl FnMut(&mut String),
|
write_replacement: impl FnMut(&mut String),
|
||||||
) {
|
) {
|
||||||
let contents = fs::read_to_string(path).unwrap_or_else(|e| panic!("Cannot read from `{}`: {}", path.display(), e));
|
let contents = fs::read_to_string(path).unwrap_or_else(|e| panic!("Cannot read from `{}`: {e}", path.display()));
|
||||||
let new_contents = match replace_region_in_text(&contents, start, end, write_replacement) {
|
let new_contents = match replace_region_in_text(&contents, start, end, write_replacement) {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(delim) => panic!("Couldn't find `{}` in file `{}`", delim, path.display()),
|
Err(delim) => panic!("Couldn't find `{delim}` in file `{}`", path.display()),
|
||||||
};
|
};
|
||||||
|
|
||||||
match update_mode {
|
match update_mode {
|
||||||
@@ -1087,7 +1081,7 @@ fn replace_region_in_file(
|
|||||||
UpdateMode::Check => (),
|
UpdateMode::Check => (),
|
||||||
UpdateMode::Change => {
|
UpdateMode::Change => {
|
||||||
if let Err(e) = fs::write(path, new_contents.as_bytes()) {
|
if let Err(e) = fs::write(path, new_contents.as_bytes()) {
|
||||||
panic!("Cannot write to `{}`: {}", path.display(), e);
|
panic!("Cannot write to `{}`: {e}", path.display());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -1135,7 +1129,7 @@ fn try_rename_file(old_name: &Path, new_name: &Path) -> bool {
|
|||||||
|
|
||||||
#[allow(clippy::needless_pass_by_value)]
|
#[allow(clippy::needless_pass_by_value)]
|
||||||
fn panic_file(error: io::Error, name: &Path, action: &str) -> ! {
|
fn panic_file(error: io::Error, name: &Path, action: &str) -> ! {
|
||||||
panic!("failed to {} file `{}`: {}", action, name.display(), error)
|
panic!("failed to {action} file `{}`: {error}", name.display())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rewrite_file(path: &Path, f: impl FnOnce(&str) -> Option<String>) {
|
fn rewrite_file(path: &Path, f: impl FnOnce(&str) -> Option<String>) {
|
||||||
|
|||||||
@@ -530,7 +530,7 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass {
|
|||||||
cx,
|
cx,
|
||||||
LINT_WITHOUT_LINT_PASS,
|
LINT_WITHOUT_LINT_PASS,
|
||||||
lint_span,
|
lint_span,
|
||||||
&format!("the lint `{}` is not added to any `LintPass`", lint_name),
|
&format!("the lint `{lint_name}` is not added to any `LintPass`"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -666,7 +666,7 @@ impl<'tcx> LateLintPass<'tcx> for CompilerLintFunctions {
|
|||||||
path.ident.span,
|
path.ident.span,
|
||||||
"usage of a compiler lint function",
|
"usage of a compiler lint function",
|
||||||
None,
|
None,
|
||||||
&format!("please use the Clippy variant of this function: `{}`", sugg),
|
&format!("please use the Clippy variant of this function: `{sugg}`"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -854,13 +854,8 @@ fn suggest_help(
|
|||||||
"this call is collapsible",
|
"this call is collapsible",
|
||||||
"collapse into",
|
"collapse into",
|
||||||
format!(
|
format!(
|
||||||
"span_lint_and_help({}, {}, {}, {}, {}, {})",
|
"span_lint_and_help({}, {}, {}, {}, {}, {help})",
|
||||||
and_then_snippets.cx,
|
and_then_snippets.cx, and_then_snippets.lint, and_then_snippets.span, and_then_snippets.msg, &option_span,
|
||||||
and_then_snippets.lint,
|
|
||||||
and_then_snippets.span,
|
|
||||||
and_then_snippets.msg,
|
|
||||||
&option_span,
|
|
||||||
help
|
|
||||||
),
|
),
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
@@ -886,13 +881,8 @@ fn suggest_note(
|
|||||||
"this call is collapsible",
|
"this call is collapsible",
|
||||||
"collapse into",
|
"collapse into",
|
||||||
format!(
|
format!(
|
||||||
"span_lint_and_note({}, {}, {}, {}, {}, {})",
|
"span_lint_and_note({}, {}, {}, {}, {note_span}, {note})",
|
||||||
and_then_snippets.cx,
|
and_then_snippets.cx, and_then_snippets.lint, and_then_snippets.span, and_then_snippets.msg,
|
||||||
and_then_snippets.lint,
|
|
||||||
and_then_snippets.span,
|
|
||||||
and_then_snippets.msg,
|
|
||||||
note_span,
|
|
||||||
note
|
|
||||||
),
|
),
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
@@ -927,7 +917,7 @@ impl<'tcx> LateLintPass<'tcx> for MatchTypeOnDiagItem {
|
|||||||
expr.span,
|
expr.span,
|
||||||
"usage of `clippy_utils::ty::match_type()` on a type diagnostic item",
|
"usage of `clippy_utils::ty::match_type()` on a type diagnostic item",
|
||||||
"try",
|
"try",
|
||||||
format!("clippy_utils::ty::is_type_diagnostic_item({}, {}, sym::{})", cx_snippet, ty_snippet, item_name),
|
format!("clippy_utils::ty::is_type_diagnostic_item({cx_snippet}, {ty_snippet}, sym::{item_name})"),
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,46 +64,6 @@ const DEFAULT_LINT_LEVELS: &[(&str, &str)] = &[
|
|||||||
/// This prefix is in front of the lint groups in the lint store. The prefix will be trimmed
|
/// This prefix is in front of the lint groups in the lint store. The prefix will be trimmed
|
||||||
/// to only keep the actual lint group in the output.
|
/// to only keep the actual lint group in the output.
|
||||||
const CLIPPY_LINT_GROUP_PREFIX: &str = "clippy::";
|
const CLIPPY_LINT_GROUP_PREFIX: &str = "clippy::";
|
||||||
|
|
||||||
/// This template will be used to format the configuration section in the lint documentation.
|
|
||||||
/// The `configurations` parameter will be replaced with one or multiple formatted
|
|
||||||
/// `ClippyConfiguration` instances. See `CONFIGURATION_VALUE_TEMPLATE` for further customizations
|
|
||||||
macro_rules! CONFIGURATION_SECTION_TEMPLATE {
|
|
||||||
() => {
|
|
||||||
r#"
|
|
||||||
### Configuration
|
|
||||||
This lint has the following configuration variables:
|
|
||||||
|
|
||||||
{configurations}
|
|
||||||
"#
|
|
||||||
};
|
|
||||||
}
|
|
||||||
/// This template will be used to format an individual `ClippyConfiguration` instance in the
|
|
||||||
/// lint documentation.
|
|
||||||
///
|
|
||||||
/// The format function will provide strings for the following parameters: `name`, `ty`, `doc` and
|
|
||||||
/// `default`
|
|
||||||
macro_rules! CONFIGURATION_VALUE_TEMPLATE {
|
|
||||||
() => {
|
|
||||||
"* `{name}`: `{ty}`: {doc} (defaults to `{default}`)\n"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! RENAMES_SECTION_TEMPLATE {
|
|
||||||
() => {
|
|
||||||
r#"
|
|
||||||
### Past names
|
|
||||||
|
|
||||||
{names}
|
|
||||||
"#
|
|
||||||
};
|
|
||||||
}
|
|
||||||
macro_rules! RENAME_VALUE_TEMPLATE {
|
|
||||||
() => {
|
|
||||||
"* `{name}`\n"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const LINT_EMISSION_FUNCTIONS: [&[&str]; 7] = [
|
const LINT_EMISSION_FUNCTIONS: [&[&str]; 7] = [
|
||||||
&["clippy_utils", "diagnostics", "span_lint"],
|
&["clippy_utils", "diagnostics", "span_lint"],
|
||||||
&["clippy_utils", "diagnostics", "span_lint_and_help"],
|
&["clippy_utils", "diagnostics", "span_lint_and_help"],
|
||||||
@@ -205,7 +165,16 @@ impl MetadataCollector {
|
|||||||
.filter(|config| config.lints.iter().any(|lint| lint == lint_name))
|
.filter(|config| config.lints.iter().any(|lint| lint == lint_name))
|
||||||
.map(ToString::to_string)
|
.map(ToString::to_string)
|
||||||
.reduce(|acc, x| acc + &x)
|
.reduce(|acc, x| acc + &x)
|
||||||
.map(|configurations| format!(CONFIGURATION_SECTION_TEMPLATE!(), configurations = configurations))
|
.map(|configurations| {
|
||||||
|
format!(
|
||||||
|
r#"
|
||||||
|
### Configuration
|
||||||
|
This lint has the following configuration variables:
|
||||||
|
|
||||||
|
{configurations}
|
||||||
|
"#
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,16 +260,13 @@ fn replace_produces(lint_name: &str, docs: &mut String, clippy_project_root: &Pa
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
panic!("lint `{}` has an unterminated code block", lint_name)
|
panic!("lint `{lint_name}` has an unterminated code block")
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
},
|
},
|
||||||
Some(line) if line.trim_start() == "{{produces}}" => {
|
Some(line) if line.trim_start() == "{{produces}}" => {
|
||||||
panic!(
|
panic!("lint `{lint_name}` has marker {{{{produces}}}} with an ignored or missing code block")
|
||||||
"lint `{}` has marker {{{{produces}}}} with an ignored or missing code block",
|
|
||||||
lint_name
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
Some(line) => {
|
Some(line) => {
|
||||||
let line = line.trim();
|
let line = line.trim();
|
||||||
@@ -319,7 +285,7 @@ fn replace_produces(lint_name: &str, docs: &mut String, clippy_project_root: &Pa
|
|||||||
match lines.next() {
|
match lines.next() {
|
||||||
Some(line) if line.trim_start() == "```" => break,
|
Some(line) if line.trim_start() == "```" => break,
|
||||||
Some(line) => example.push(line),
|
Some(line) => example.push(line),
|
||||||
None => panic!("lint `{}` has an unterminated code block", lint_name),
|
None => panic!("lint `{lint_name}` has an unterminated code block"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,10 +302,9 @@ fn replace_produces(lint_name: &str, docs: &mut String, clippy_project_root: &Pa
|
|||||||
<summary>Produces</summary>\n\
|
<summary>Produces</summary>\n\
|
||||||
\n\
|
\n\
|
||||||
```text\n\
|
```text\n\
|
||||||
{}\n\
|
{output}\n\
|
||||||
```\n\
|
```\n\
|
||||||
</details>",
|
</details>"
|
||||||
output
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -394,7 +359,7 @@ fn get_lint_output(lint_name: &str, example: &[&mut String], clippy_project_root
|
|||||||
panic!("failed to write to `{}`: {e}", file.as_path().to_string_lossy());
|
panic!("failed to write to `{}`: {e}", file.as_path().to_string_lossy());
|
||||||
}
|
}
|
||||||
|
|
||||||
let prefixed_name = format!("{}{lint_name}", CLIPPY_LINT_GROUP_PREFIX);
|
let prefixed_name = format!("{CLIPPY_LINT_GROUP_PREFIX}{lint_name}");
|
||||||
|
|
||||||
let mut cmd = Command::new("cargo");
|
let mut cmd = Command::new("cargo");
|
||||||
|
|
||||||
@@ -417,7 +382,7 @@ fn get_lint_output(lint_name: &str, example: &[&mut String], clippy_project_root
|
|||||||
let output = cmd
|
let output = cmd
|
||||||
.arg(file.as_path())
|
.arg(file.as_path())
|
||||||
.output()
|
.output()
|
||||||
.unwrap_or_else(|e| panic!("failed to run `{:?}`: {e}", cmd));
|
.unwrap_or_else(|e| panic!("failed to run `{cmd:?}`: {e}"));
|
||||||
|
|
||||||
let tmp_file_path = file.to_string_lossy();
|
let tmp_file_path = file.to_string_lossy();
|
||||||
let stderr = std::str::from_utf8(&output.stderr).unwrap();
|
let stderr = std::str::from_utf8(&output.stderr).unwrap();
|
||||||
@@ -441,8 +406,7 @@ fn get_lint_output(lint_name: &str, example: &[&mut String], clippy_project_root
|
|||||||
let rendered: Vec<&str> = msgs.iter().filter_map(|msg| msg["rendered"].as_str()).collect();
|
let rendered: Vec<&str> = msgs.iter().filter_map(|msg| msg["rendered"].as_str()).collect();
|
||||||
let non_json: Vec<&str> = stderr.lines().filter(|line| !line.starts_with('{')).collect();
|
let non_json: Vec<&str> = stderr.lines().filter(|line| !line.starts_with('{')).collect();
|
||||||
panic!(
|
panic!(
|
||||||
"did not find lint `{}` in output of example, got:\n{}\n{}",
|
"did not find lint `{lint_name}` in output of example, got:\n{}\n{}",
|
||||||
lint_name,
|
|
||||||
non_json.join("\n"),
|
non_json.join("\n"),
|
||||||
rendered.join("\n")
|
rendered.join("\n")
|
||||||
);
|
);
|
||||||
@@ -588,13 +552,10 @@ fn to_kebab(config_name: &str) -> String {
|
|||||||
|
|
||||||
impl fmt::Display for ClippyConfiguration {
|
impl fmt::Display for ClippyConfiguration {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
writeln!(
|
||||||
f,
|
f,
|
||||||
CONFIGURATION_VALUE_TEMPLATE!(),
|
"* `{}`: `{}`: {} (defaults to `{}`)",
|
||||||
name = self.name,
|
self.name, self.config_type, self.doc, self.default
|
||||||
ty = self.config_type,
|
|
||||||
doc = self.doc,
|
|
||||||
default = self.default
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -811,7 +772,7 @@ fn get_lint_group_and_level_or_lint(
|
|||||||
lint_collection_error_item(
|
lint_collection_error_item(
|
||||||
cx,
|
cx,
|
||||||
item,
|
item,
|
||||||
&format!("Unable to determine lint level for found group `{}`", group),
|
&format!("Unable to determine lint level for found group `{group}`"),
|
||||||
);
|
);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -869,7 +830,7 @@ fn collect_renames(lints: &mut Vec<LintMetadata>) {
|
|||||||
if name == lint_name;
|
if name == lint_name;
|
||||||
if let Some(past_name) = k.strip_prefix(CLIPPY_LINT_GROUP_PREFIX);
|
if let Some(past_name) = k.strip_prefix(CLIPPY_LINT_GROUP_PREFIX);
|
||||||
then {
|
then {
|
||||||
write!(collected, RENAME_VALUE_TEMPLATE!(), name = past_name).unwrap();
|
writeln!(collected, "* `{past_name}`").unwrap();
|
||||||
names.push(past_name.to_string());
|
names.push(past_name.to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -882,7 +843,15 @@ fn collect_renames(lints: &mut Vec<LintMetadata>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !collected.is_empty() {
|
if !collected.is_empty() {
|
||||||
write!(&mut lint.docs, RENAMES_SECTION_TEMPLATE!(), names = collected).unwrap();
|
write!(
|
||||||
|
&mut lint.docs,
|
||||||
|
r#"
|
||||||
|
### Past names
|
||||||
|
|
||||||
|
{collected}
|
||||||
|
"#
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -895,7 +864,7 @@ fn lint_collection_error_item(cx: &LateContext<'_>, item: &Item<'_>, message: &s
|
|||||||
cx,
|
cx,
|
||||||
INTERNAL_METADATA_COLLECTOR,
|
INTERNAL_METADATA_COLLECTOR,
|
||||||
item.ident.span,
|
item.ident.span,
|
||||||
&format!("metadata collection error for `{}`: {}", item.ident.name, message),
|
&format!("metadata collection error for `{}`: {message}", item.ident.name),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user