Merge commit '0cb0f7636851f9fcc57085cf80197a2ef6db098f' into clippyup
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
use clap::{Arg, ArgAction, ArgMatches, Command, PossibleValue};
|
||||
use clippy_dev::{bless, fmt, lint, new_lint, serve, setup, update_lints};
|
||||
use indoc::indoc;
|
||||
|
||||
fn main() {
|
||||
let matches = get_clap_config();
|
||||
|
||||
@@ -85,6 +86,11 @@ fn main() {
|
||||
let uplift = matches.contains_id("uplift");
|
||||
update_lints::rename(old_name, new_name, uplift);
|
||||
},
|
||||
Some(("deprecate", matches)) => {
|
||||
let name = matches.get_one::<String>("name").unwrap();
|
||||
let reason = matches.get_one("reason");
|
||||
update_lints::deprecate(name, reason);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
@@ -266,6 +272,18 @@ fn get_clap_config() -> ArgMatches {
|
||||
.long("uplift")
|
||||
.help("This lint will be uplifted into rustc"),
|
||||
]),
|
||||
Command::new("deprecate").about("Deprecates the given lint").args([
|
||||
Arg::new("name")
|
||||
.index(1)
|
||||
.required(true)
|
||||
.help("The name of the lint to deprecate"),
|
||||
Arg::new("reason")
|
||||
.long("reason")
|
||||
.short('r')
|
||||
.required(false)
|
||||
.takes_value(true)
|
||||
.help("The reason for deprecation"),
|
||||
]),
|
||||
])
|
||||
.get_matches()
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ fn to_camel_case(name: &str) -> String {
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn get_stabilization_version() -> String {
|
||||
pub(crate) fn get_stabilization_version() -> String {
|
||||
fn parse_manifest(contents: &str) -> Option<String> {
|
||||
let version = contents
|
||||
.lines()
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
use crate::clippy_project_root;
|
||||
use aho_corasick::AhoCorasickBuilder;
|
||||
use core::fmt::Write as _;
|
||||
use indoc::writedoc;
|
||||
use itertools::Itertools;
|
||||
use rustc_lexer::{tokenize, unescape, LiteralKind, TokenKind};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::ffi::OsStr;
|
||||
use std::fs;
|
||||
use std::io::{self, Read as _, Seek as _, Write as _};
|
||||
use std::fmt::Write;
|
||||
use std::fs::{self, OpenOptions};
|
||||
use std::io::{self, Read, Seek, SeekFrom, Write as _};
|
||||
use std::ops::Range;
|
||||
use std::path::{Path, PathBuf};
|
||||
use walkdir::{DirEntry, WalkDir};
|
||||
|
||||
use crate::clippy_project_root;
|
||||
|
||||
const GENERATED_FILE_COMMENT: &str = "// This file was generated by `cargo dev update_lints`.\n\
|
||||
// Use that command to update this file and do not edit by hand.\n\
|
||||
// Manual edits will be overwritten.\n\n";
|
||||
@@ -326,6 +327,200 @@ pub fn rename(old_name: &str, new_name: &str, uplift: bool) {
|
||||
println!("note: `cargo uitest` still needs to be run to update the test results");
|
||||
}
|
||||
|
||||
const DEFAULT_DEPRECATION_REASON: &str = "default deprecation note";
|
||||
/// Runs the `deprecate` command
|
||||
///
|
||||
/// This does the following:
|
||||
/// * Adds an entry to `deprecated_lints.rs`.
|
||||
/// * Removes the lint declaration (and the entire file if applicable)
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// If a file path could not read from or written to
|
||||
pub fn deprecate(name: &str, reason: Option<&String>) {
|
||||
fn finish(
|
||||
(lints, mut deprecated_lints, renamed_lints): (Vec<Lint>, Vec<DeprecatedLint>, Vec<RenamedLint>),
|
||||
name: &str,
|
||||
reason: &str,
|
||||
) {
|
||||
deprecated_lints.push(DeprecatedLint {
|
||||
name: name.to_string(),
|
||||
reason: reason.to_string(),
|
||||
declaration_range: Range::default(),
|
||||
});
|
||||
|
||||
generate_lint_files(UpdateMode::Change, &lints, &deprecated_lints, &renamed_lints);
|
||||
println!("info: `{}` has successfully been deprecated", name);
|
||||
|
||||
if reason == DEFAULT_DEPRECATION_REASON {
|
||||
println!("note: the deprecation reason must be updated in `clippy_lints/src/deprecated_lints.rs`");
|
||||
}
|
||||
println!("note: you must run `cargo uitest` to update the test results");
|
||||
}
|
||||
|
||||
let reason = reason.map_or(DEFAULT_DEPRECATION_REASON, String::as_str);
|
||||
let name_lower = name.to_lowercase();
|
||||
let name_upper = name.to_uppercase();
|
||||
|
||||
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 mod_path = {
|
||||
let mut mod_path = PathBuf::from(format!("clippy_lints/src/{}", lint.module));
|
||||
if mod_path.is_dir() {
|
||||
mod_path = mod_path.join("mod");
|
||||
}
|
||||
|
||||
mod_path.set_extension("rs");
|
||||
mod_path
|
||||
};
|
||||
|
||||
let deprecated_lints_path = &*clippy_project_root().join("clippy_lints/src/deprecated_lints.rs");
|
||||
|
||||
if remove_lint_declaration(&name_lower, &mod_path, &mut lints).unwrap_or(false) {
|
||||
declare_deprecated(&name_upper, deprecated_lints_path, reason).unwrap();
|
||||
finish((lints, deprecated_lints, renamed_lints), name, reason);
|
||||
return;
|
||||
}
|
||||
|
||||
eprintln!("error: lint not found");
|
||||
}
|
||||
|
||||
fn remove_lint_declaration(name: &str, path: &Path, lints: &mut Vec<Lint>) -> io::Result<bool> {
|
||||
fn remove_lint(name: &str, lints: &mut Vec<Lint>) {
|
||||
lints.iter().position(|l| l.name == name).map(|pos| lints.remove(pos));
|
||||
}
|
||||
|
||||
fn remove_test_assets(name: &str) {
|
||||
let test_file_stem = format!("tests/ui/{}", name);
|
||||
let path = Path::new(&test_file_stem);
|
||||
|
||||
// Some lints have their own directories, delete them
|
||||
if path.is_dir() {
|
||||
fs::remove_dir_all(path).ok();
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove all related test files
|
||||
fs::remove_file(path.with_extension("rs")).ok();
|
||||
fs::remove_file(path.with_extension("stderr")).ok();
|
||||
fs::remove_file(path.with_extension("fixed")).ok();
|
||||
}
|
||||
|
||||
fn remove_impl_lint_pass(lint_name_upper: &str, content: &mut String) {
|
||||
let impl_lint_pass_start = content.find("impl_lint_pass!").unwrap_or_else(|| {
|
||||
content
|
||||
.find("declare_lint_pass!")
|
||||
.unwrap_or_else(|| panic!("failed to find `impl_lint_pass`"))
|
||||
});
|
||||
let mut impl_lint_pass_end = content[impl_lint_pass_start..]
|
||||
.find(']')
|
||||
.expect("failed to find `impl_lint_pass` terminator");
|
||||
|
||||
impl_lint_pass_end += impl_lint_pass_start;
|
||||
if let Some(lint_name_pos) = content[impl_lint_pass_start..impl_lint_pass_end].find(&lint_name_upper) {
|
||||
let mut lint_name_end = impl_lint_pass_start + (lint_name_pos + lint_name_upper.len());
|
||||
for c in content[lint_name_end..impl_lint_pass_end].chars() {
|
||||
// Remove trailing whitespace
|
||||
if c == ',' || c.is_whitespace() {
|
||||
lint_name_end += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
content.replace_range(impl_lint_pass_start + lint_name_pos..lint_name_end, "");
|
||||
}
|
||||
}
|
||||
|
||||
if path.exists() {
|
||||
if let Some(lint) = lints.iter().find(|l| l.name == name) {
|
||||
if lint.module == name {
|
||||
// The lint name is the same as the file, we can just delete the entire file
|
||||
fs::remove_file(path)?;
|
||||
} else {
|
||||
// We can't delete the entire file, just remove the declaration
|
||||
|
||||
if let Some(Some("mod.rs")) = path.file_name().map(OsStr::to_str) {
|
||||
// Remove clippy_lints/src/some_mod/some_lint.rs
|
||||
let mut lint_mod_path = path.to_path_buf();
|
||||
lint_mod_path.set_file_name(name);
|
||||
lint_mod_path.set_extension("rs");
|
||||
|
||||
fs::remove_file(lint_mod_path).ok();
|
||||
}
|
||||
|
||||
let mut content =
|
||||
fs::read_to_string(&path).unwrap_or_else(|_| panic!("failed to read `{}`", path.to_string_lossy()));
|
||||
|
||||
eprintln!(
|
||||
"warn: you will have to manually remove any code related to `{}` from `{}`",
|
||||
name,
|
||||
path.display()
|
||||
);
|
||||
|
||||
assert!(
|
||||
content[lint.declaration_range.clone()].contains(&name.to_uppercase()),
|
||||
"error: `{}` does not contain lint `{}`'s declaration",
|
||||
path.display(),
|
||||
lint.name
|
||||
);
|
||||
|
||||
// Remove lint declaration (declare_clippy_lint!)
|
||||
content.replace_range(lint.declaration_range.clone(), "");
|
||||
|
||||
// Remove the module declaration (mod xyz;)
|
||||
let mod_decl = format!("\nmod {};", name);
|
||||
content = content.replacen(&mod_decl, "", 1);
|
||||
|
||||
remove_impl_lint_pass(&lint.name.to_uppercase(), &mut content);
|
||||
fs::write(path, content).unwrap_or_else(|_| panic!("failed to write to `{}`", path.to_string_lossy()));
|
||||
}
|
||||
|
||||
remove_test_assets(name);
|
||||
remove_lint(name, lints);
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
fn declare_deprecated(name: &str, path: &Path, reason: &str) -> io::Result<()> {
|
||||
let mut file = OpenOptions::new().write(true).open(path)?;
|
||||
|
||||
file.seek(SeekFrom::End(0))?;
|
||||
|
||||
let version = crate::new_lint::get_stabilization_version();
|
||||
let deprecation_reason = if reason == DEFAULT_DEPRECATION_REASON {
|
||||
"TODO"
|
||||
} else {
|
||||
reason
|
||||
};
|
||||
|
||||
writedoc!(
|
||||
file,
|
||||
"
|
||||
|
||||
declare_deprecated_lint! {{
|
||||
/// ### What it does
|
||||
/// Nothing. This lint has been deprecated.
|
||||
///
|
||||
/// ### Deprecation reason
|
||||
/// {}
|
||||
#[clippy::version = \"{}\"]
|
||||
pub {},
|
||||
\"{}\"
|
||||
}}
|
||||
|
||||
",
|
||||
deprecation_reason,
|
||||
version,
|
||||
name,
|
||||
reason,
|
||||
)
|
||||
}
|
||||
|
||||
/// Replace substrings if they aren't bordered by identifier characters. Returns `None` if there
|
||||
/// were no replacements.
|
||||
fn replace_ident_like(contents: &str, replacements: &[(&str, &str)]) -> Option<String> {
|
||||
@@ -393,16 +588,18 @@ struct Lint {
|
||||
group: String,
|
||||
desc: String,
|
||||
module: String,
|
||||
declaration_range: Range<usize>,
|
||||
}
|
||||
|
||||
impl Lint {
|
||||
#[must_use]
|
||||
fn new(name: &str, group: &str, desc: &str, module: &str) -> Self {
|
||||
fn new(name: &str, group: &str, desc: &str, module: &str, declaration_range: Range<usize>) -> Self {
|
||||
Self {
|
||||
name: name.to_lowercase(),
|
||||
group: group.into(),
|
||||
desc: remove_line_splices(desc),
|
||||
module: module.into(),
|
||||
declaration_range,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -433,12 +630,14 @@ impl Lint {
|
||||
struct DeprecatedLint {
|
||||
name: String,
|
||||
reason: String,
|
||||
declaration_range: Range<usize>,
|
||||
}
|
||||
impl DeprecatedLint {
|
||||
fn new(name: &str, reason: &str) -> Self {
|
||||
fn new(name: &str, reason: &str, declaration_range: Range<usize>) -> Self {
|
||||
Self {
|
||||
name: name.to_lowercase(),
|
||||
reason: remove_line_splices(reason),
|
||||
declaration_range,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -610,7 +809,11 @@ fn clippy_lints_src_files() -> impl Iterator<Item = (PathBuf, DirEntry)> {
|
||||
macro_rules! match_tokens {
|
||||
($iter:ident, $($token:ident $({$($fields:tt)*})? $(($capture:ident))?)*) => {
|
||||
{
|
||||
$($(let $capture =)? if let Some((TokenKind::$token $({$($fields)*})?, _x)) = $iter.next() {
|
||||
$($(let $capture =)? if let Some(LintDeclSearchResult {
|
||||
token_kind: TokenKind::$token $({$($fields)*})?,
|
||||
content: _x,
|
||||
..
|
||||
}) = $iter.next() {
|
||||
_x
|
||||
} else {
|
||||
continue;
|
||||
@@ -621,40 +824,72 @@ macro_rules! match_tokens {
|
||||
}
|
||||
}
|
||||
|
||||
struct LintDeclSearchResult<'a> {
|
||||
token_kind: TokenKind,
|
||||
content: &'a str,
|
||||
range: Range<usize>,
|
||||
}
|
||||
|
||||
/// Parse a source file looking for `declare_clippy_lint` macro invocations.
|
||||
fn parse_contents(contents: &str, module: &str, lints: &mut Vec<Lint>) {
|
||||
let mut offset = 0usize;
|
||||
let mut iter = tokenize(contents).map(|t| {
|
||||
let range = offset..offset + t.len;
|
||||
offset = range.end;
|
||||
(t.kind, &contents[range])
|
||||
|
||||
LintDeclSearchResult {
|
||||
token_kind: t.kind,
|
||||
content: &contents[range.clone()],
|
||||
range,
|
||||
}
|
||||
});
|
||||
|
||||
while iter.any(|(kind, s)| kind == TokenKind::Ident && s == "declare_clippy_lint") {
|
||||
while let Some(LintDeclSearchResult { range, .. }) = iter.find(
|
||||
|LintDeclSearchResult {
|
||||
token_kind, content, ..
|
||||
}| token_kind == &TokenKind::Ident && *content == "declare_clippy_lint",
|
||||
) {
|
||||
let start = range.start;
|
||||
|
||||
let mut iter = iter
|
||||
.by_ref()
|
||||
.filter(|&(kind, _)| !matches!(kind, TokenKind::Whitespace | TokenKind::LineComment { .. }));
|
||||
.filter(|t| !matches!(t.token_kind, TokenKind::Whitespace | TokenKind::LineComment { .. }));
|
||||
// matches `!{`
|
||||
match_tokens!(iter, Bang OpenBrace);
|
||||
match iter.next() {
|
||||
// #[clippy::version = "version"] pub
|
||||
Some((TokenKind::Pound, _)) => {
|
||||
Some(LintDeclSearchResult {
|
||||
token_kind: TokenKind::Pound,
|
||||
..
|
||||
}) => {
|
||||
match_tokens!(iter, OpenBracket Ident Colon Colon Ident Eq Literal{..} CloseBracket Ident);
|
||||
},
|
||||
// pub
|
||||
Some((TokenKind::Ident, _)) => (),
|
||||
Some(LintDeclSearchResult {
|
||||
token_kind: TokenKind::Ident,
|
||||
..
|
||||
}) => (),
|
||||
_ => continue,
|
||||
}
|
||||
|
||||
let (name, group, desc) = match_tokens!(
|
||||
iter,
|
||||
// LINT_NAME
|
||||
Ident(name) Comma
|
||||
// group,
|
||||
Ident(group) Comma
|
||||
// "description" }
|
||||
Literal{..}(desc) CloseBrace
|
||||
// "description"
|
||||
Literal{..}(desc)
|
||||
);
|
||||
lints.push(Lint::new(name, group, desc, module));
|
||||
|
||||
if let Some(LintDeclSearchResult {
|
||||
token_kind: TokenKind::CloseBrace,
|
||||
range,
|
||||
..
|
||||
}) = iter.next()
|
||||
{
|
||||
lints.push(Lint::new(name, group, desc, module, start..range.end));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -664,12 +899,24 @@ fn parse_deprecated_contents(contents: &str, lints: &mut Vec<DeprecatedLint>) {
|
||||
let mut iter = tokenize(contents).map(|t| {
|
||||
let range = offset..offset + t.len;
|
||||
offset = range.end;
|
||||
(t.kind, &contents[range])
|
||||
|
||||
LintDeclSearchResult {
|
||||
token_kind: t.kind,
|
||||
content: &contents[range.clone()],
|
||||
range,
|
||||
}
|
||||
});
|
||||
while iter.any(|(kind, s)| kind == TokenKind::Ident && s == "declare_deprecated_lint") {
|
||||
let mut iter = iter
|
||||
.by_ref()
|
||||
.filter(|&(kind, _)| !matches!(kind, TokenKind::Whitespace | TokenKind::LineComment { .. }));
|
||||
|
||||
while let Some(LintDeclSearchResult { range, .. }) = iter.find(
|
||||
|LintDeclSearchResult {
|
||||
token_kind, content, ..
|
||||
}| token_kind == &TokenKind::Ident && *content == "declare_deprecated_lint",
|
||||
) {
|
||||
let start = range.start;
|
||||
|
||||
let mut iter = iter.by_ref().filter(|LintDeclSearchResult { ref token_kind, .. }| {
|
||||
!matches!(token_kind, TokenKind::Whitespace | TokenKind::LineComment { .. })
|
||||
});
|
||||
let (name, reason) = match_tokens!(
|
||||
iter,
|
||||
// !{
|
||||
@@ -680,10 +927,16 @@ fn parse_deprecated_contents(contents: &str, lints: &mut Vec<DeprecatedLint>) {
|
||||
Ident Ident(name) Comma
|
||||
// "description"
|
||||
Literal{kind: LiteralKind::Str{..},..}(reason)
|
||||
// }
|
||||
CloseBrace
|
||||
);
|
||||
lints.push(DeprecatedLint::new(name, reason));
|
||||
|
||||
if let Some(LintDeclSearchResult {
|
||||
token_kind: TokenKind::CloseBrace,
|
||||
range,
|
||||
..
|
||||
}) = iter.next()
|
||||
{
|
||||
lints.push(DeprecatedLint::new(name, reason, start..range.end));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -693,8 +946,14 @@ fn parse_renamed_contents(contents: &str, lints: &mut Vec<RenamedLint>) {
|
||||
let mut iter = tokenize(line).map(|t| {
|
||||
let range = offset..offset + t.len;
|
||||
offset = range.end;
|
||||
(t.kind, &line[range])
|
||||
|
||||
LintDeclSearchResult {
|
||||
token_kind: t.kind,
|
||||
content: &line[range.clone()],
|
||||
range,
|
||||
}
|
||||
});
|
||||
|
||||
let (old_name, new_name) = match_tokens!(
|
||||
iter,
|
||||
// ("old_name",
|
||||
@@ -844,10 +1103,25 @@ mod tests {
|
||||
"#;
|
||||
let mut result = Vec::new();
|
||||
parse_contents(CONTENTS, "module_name", &mut result);
|
||||
for r in &mut result {
|
||||
r.declaration_range = Range::default();
|
||||
}
|
||||
|
||||
let expected = vec![
|
||||
Lint::new("ptr_arg", "style", "\"really long text\"", "module_name"),
|
||||
Lint::new("doc_markdown", "pedantic", "\"single line\"", "module_name"),
|
||||
Lint::new(
|
||||
"ptr_arg",
|
||||
"style",
|
||||
"\"really long text\"",
|
||||
"module_name",
|
||||
Range::default(),
|
||||
),
|
||||
Lint::new(
|
||||
"doc_markdown",
|
||||
"pedantic",
|
||||
"\"single line\"",
|
||||
"module_name",
|
||||
Range::default(),
|
||||
),
|
||||
];
|
||||
assert_eq!(expected, result);
|
||||
}
|
||||
@@ -865,10 +1139,14 @@ mod tests {
|
||||
|
||||
let mut result = Vec::new();
|
||||
parse_deprecated_contents(DEPRECATED_CONTENTS, &mut result);
|
||||
for r in &mut result {
|
||||
r.declaration_range = Range::default();
|
||||
}
|
||||
|
||||
let expected = vec![DeprecatedLint::new(
|
||||
"should_assert_eq",
|
||||
"\"`assert!()` will be more flexible with RFC 2011\"",
|
||||
Range::default(),
|
||||
)];
|
||||
assert_eq!(expected, result);
|
||||
}
|
||||
@@ -876,15 +1154,34 @@ mod tests {
|
||||
#[test]
|
||||
fn test_usable_lints() {
|
||||
let lints = vec![
|
||||
Lint::new("should_assert_eq2", "Not Deprecated", "\"abc\"", "module_name"),
|
||||
Lint::new("should_assert_eq2", "internal", "\"abc\"", "module_name"),
|
||||
Lint::new("should_assert_eq2", "internal_style", "\"abc\"", "module_name"),
|
||||
Lint::new(
|
||||
"should_assert_eq2",
|
||||
"Not Deprecated",
|
||||
"\"abc\"",
|
||||
"module_name",
|
||||
Range::default(),
|
||||
),
|
||||
Lint::new(
|
||||
"should_assert_eq2",
|
||||
"internal",
|
||||
"\"abc\"",
|
||||
"module_name",
|
||||
Range::default(),
|
||||
),
|
||||
Lint::new(
|
||||
"should_assert_eq2",
|
||||
"internal_style",
|
||||
"\"abc\"",
|
||||
"module_name",
|
||||
Range::default(),
|
||||
),
|
||||
];
|
||||
let expected = vec![Lint::new(
|
||||
"should_assert_eq2",
|
||||
"Not Deprecated",
|
||||
"\"abc\"",
|
||||
"module_name",
|
||||
Range::default(),
|
||||
)];
|
||||
assert_eq!(expected, Lint::usable_lints(&lints));
|
||||
}
|
||||
@@ -892,21 +1189,33 @@ mod tests {
|
||||
#[test]
|
||||
fn test_by_lint_group() {
|
||||
let lints = vec![
|
||||
Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name"),
|
||||
Lint::new("should_assert_eq2", "group2", "\"abc\"", "module_name"),
|
||||
Lint::new("incorrect_match", "group1", "\"abc\"", "module_name"),
|
||||
Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name", Range::default()),
|
||||
Lint::new(
|
||||
"should_assert_eq2",
|
||||
"group2",
|
||||
"\"abc\"",
|
||||
"module_name",
|
||||
Range::default(),
|
||||
),
|
||||
Lint::new("incorrect_match", "group1", "\"abc\"", "module_name", Range::default()),
|
||||
];
|
||||
let mut expected: HashMap<String, Vec<Lint>> = HashMap::new();
|
||||
expected.insert(
|
||||
"group1".to_string(),
|
||||
vec![
|
||||
Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name"),
|
||||
Lint::new("incorrect_match", "group1", "\"abc\"", "module_name"),
|
||||
Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name", Range::default()),
|
||||
Lint::new("incorrect_match", "group1", "\"abc\"", "module_name", Range::default()),
|
||||
],
|
||||
);
|
||||
expected.insert(
|
||||
"group2".to_string(),
|
||||
vec![Lint::new("should_assert_eq2", "group2", "\"abc\"", "module_name")],
|
||||
vec![Lint::new(
|
||||
"should_assert_eq2",
|
||||
"group2",
|
||||
"\"abc\"",
|
||||
"module_name",
|
||||
Range::default(),
|
||||
)],
|
||||
);
|
||||
assert_eq!(expected, Lint::by_lint_group(lints.into_iter()));
|
||||
}
|
||||
@@ -914,8 +1223,12 @@ mod tests {
|
||||
#[test]
|
||||
fn test_gen_deprecated() {
|
||||
let lints = vec![
|
||||
DeprecatedLint::new("should_assert_eq", "\"has been superseded by should_assert_eq2\""),
|
||||
DeprecatedLint::new("another_deprecated", "\"will be removed\""),
|
||||
DeprecatedLint::new(
|
||||
"should_assert_eq",
|
||||
"\"has been superseded by should_assert_eq2\"",
|
||||
Range::default(),
|
||||
),
|
||||
DeprecatedLint::new("another_deprecated", "\"will be removed\"", Range::default()),
|
||||
];
|
||||
|
||||
let expected = GENERATED_FILE_COMMENT.to_string()
|
||||
@@ -940,9 +1253,9 @@ mod tests {
|
||||
#[test]
|
||||
fn test_gen_lint_group_list() {
|
||||
let lints = vec![
|
||||
Lint::new("abc", "group1", "\"abc\"", "module_name"),
|
||||
Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name"),
|
||||
Lint::new("internal", "internal_style", "\"abc\"", "module_name"),
|
||||
Lint::new("abc", "group1", "\"abc\"", "module_name", Range::default()),
|
||||
Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name", Range::default()),
|
||||
Lint::new("internal", "internal_style", "\"abc\"", "module_name", Range::default()),
|
||||
];
|
||||
let expected = GENERATED_FILE_COMMENT.to_string()
|
||||
+ &[
|
||||
|
||||
Reference in New Issue
Block a user