Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RIIR update lints: Generate modules section and lint group sections #3399

Merged
merged 5 commits into from Nov 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions ci/base-tests.sh
Expand Up @@ -22,6 +22,7 @@ cargo build --features debugging
cargo test --features debugging
cd clippy_lints && cargo test && cd ..
cd rustc_tools_util && cargo test && cd ..
cd clippy_dev && cargo test && cd ..
# check that the lint lists are up-to-date
./util/update_lints.py -c

Expand Down
66 changes: 64 additions & 2 deletions clippy_dev/src/lib.rs
Expand Up @@ -72,6 +72,32 @@ impl Lint {
}
}

/// Generates the Vec items for `register_lint_group` calls in `clippy_lints/src/lib.rs`.
pub fn gen_lint_group_list(lints: Vec<Lint>) -> Vec<String> {
lints.into_iter()
.filter_map(|l| {
if l.is_internal() || l.deprecation.is_some() {
None
} else {
Some(format!(" {}::{},", l.module, l.name.to_uppercase()))
}
})
.sorted()
}

/// Generates the `pub mod module_name` list in `clippy_lints/src/lib.rs`.
pub fn gen_modules_list(lints: Vec<Lint>) -> Vec<String> {
lints.into_iter()
.filter_map(|l| {
if l.is_internal() || l.deprecation.is_some() { None } else { Some(l.module) }
})
.unique()
.map(|module| {
format!("pub mod {};", module)
})
.sorted()
}

/// Generates the list of lint links at the bottom of the README
pub fn gen_changelog_lint_list(lints: Vec<Lint>) -> Vec<String> {
let mut lint_list_sorted: Vec<Lint> = lints;
Expand Down Expand Up @@ -113,7 +139,13 @@ fn gather_from_file(dir_entry: &walkdir::DirEntry) -> impl Iterator<Item=Lint> {
let mut file = fs::File::open(dir_entry.path()).unwrap();
let mut content = String::new();
file.read_to_string(&mut content).unwrap();
parse_contents(&content, dir_entry.path().file_stem().unwrap().to_str().unwrap())
let mut filename = dir_entry.path().file_stem().unwrap().to_str().unwrap();
// If the lints are stored in mod.rs, we get the module name from
// the containing directory:
if filename == "mod" {
filename = dir_entry.path().parent().unwrap().file_stem().unwrap().to_str().unwrap()
}
parse_contents(&content, filename)
}

fn parse_contents(content: &str, filename: &str) -> impl Iterator<Item=Lint> {
Expand Down Expand Up @@ -215,7 +247,7 @@ pub fn replace_region_in_text<F>(text: &str, start: &str, end: &str, replace_sta
// This happens if the provided regex in `clippy_dev/src/main.rs` is not found in the
// given text or file. Most likely this is an error on the programmer's side and the Regex
// is incorrect.
println!("regex {:?} not found. You may have to update it.", start);
eprintln!("error: regex `{:?}` not found. You may have to update it.", start);
}
new_lines.join("\n")
}
Expand Down Expand Up @@ -356,3 +388,33 @@ fn test_gen_deprecated() {
];
assert_eq!(expected, gen_deprecated(&lints));
}

#[test]
fn test_gen_modules_list() {
let lints = vec![
Lint::new("should_assert_eq", "group1", "abc", None, "module_name"),
Lint::new("should_assert_eq2", "group2", "abc", Some("abc"), "deprecated"),
Lint::new("incorrect_stuff", "group3", "abc", None, "another_module"),
Lint::new("incorrect_internal", "internal_style", "abc", None, "module_name"),
];
let expected = vec![
"pub mod another_module;".to_string(),
"pub mod module_name;".to_string(),
];
assert_eq!(expected, gen_modules_list(lints));
}

#[test]
fn test_gen_lint_group_list() {
let lints = vec![
Lint::new("abc", "group1", "abc", None, "module_name"),
Lint::new("should_assert_eq", "group1", "abc", None, "module_name"),
Lint::new("should_assert_eq2", "group2", "abc", Some("abc"), "deprecated"),
Lint::new("incorrect_internal", "internal_style", "abc", None, "module_name"),
];
let expected = vec![
" module_name::ABC,".to_string(),
" module_name::SHOULD_ASSERT_EQ,".to_string(),
];
assert_eq!(expected, gen_lint_group_list(lints));
}
47 changes: 45 additions & 2 deletions clippy_dev/src/main.rs
Expand Up @@ -19,12 +19,17 @@ fn main() {
let matches = App::new("Clippy developer tooling")
.subcommand(
SubCommand::with_name("update_lints")
.about("Update the lint list")
.about("Makes sure that:\n \
* the lint count in README.md is correct\n \
* the changelog contains markdown link references at the bottom\n \
* all lint groups include the correct lints\n \
* lint modules in `clippy_lints/*` are visible in `src/lib.rs` via `pub mod`\n \
* all lints are registered in the lint store")
.arg(
Arg::with_name("print-only")
.long("print-only")
.short("p")
.help("Print a table of lints to STDOUT. Does not modify any files."),
.help("Print a table of lints to STDOUT. This does not include deprecated and internal lints. (Does not modify any files)"),
)
)
.get_matches();
Expand Down Expand Up @@ -90,4 +95,42 @@ fn update_lints() {
false,
|| { gen_deprecated(&lint_list) }
);

replace_region_in_file(
"../clippy_lints/src/lib.rs",
"begin lints modules",
"end lints modules",
false,
|| { gen_modules_list(lint_list.clone()) }
);

// Generate lists of lints in the clippy::all lint group
replace_region_in_file(
"../clippy_lints/src/lib.rs",
r#"reg.register_lint_group\("clippy::all""#,
r#"\]\);"#,
false,
|| {
// clippy::all should only include the following lint groups:
let all_group_lints = usable_lints.clone().into_iter().filter(|l| {
l.group == "correctness" ||
l.group == "style" ||
l.group == "complexity" ||
l.group == "perf"
}).collect();

gen_lint_group_list(all_group_lints)
}
);

// Generate the list of lints for all other lint groups
for (lint_group, lints) in Lint::by_lint_group(&usable_lints) {
replace_region_in_file(
"../clippy_lints/src/lib.rs",
&format!("reg.register_lint_group\\(\"clippy::{}\"", lint_group),
r#"\]\);"#,
false,
|| { gen_lint_group_list(lints.clone()) }
);
}
}