1
Fork 0

Rollup merge of #66574 - GuillaumeGomez:update-tidy-err-code-check, r=Mark-Simulacrum

Update tidy check for error codes testing

Now that all the error codes have been grouped into one file, we moved the long error explanations into markdown files, which means that we need to read those markdown file to also count their code blocks as well.

So 2 "big" things happened here:
* No more need to keep the current error code when reading the `error_codes.rs` file since it's been put into the equivalent markdown file.
* Need to instead read the markdown file (but it's simpler since I can just look for code blocks directly).
This commit is contained in:
Mazdak Farrokhzad 2019-11-23 02:22:45 +01:00 committed by GitHub
commit 8256e735cf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -3,6 +3,8 @@
use std::collections::HashMap;
use std::ffi::OsStr;
use std::fs::read_to_string;
use std::io::Read;
use std::path::Path;
// A few of those error codes can't be tested but all the others can and *should* be tested!
@ -50,29 +52,60 @@ const WHITELIST: &[&str] = &[
"E0729",
];
fn extract_error_codes(f: &str, error_codes: &mut HashMap<String, bool>) {
fn check_error_code_explanation(
f: &str,
error_codes: &mut HashMap<String, bool>,
err_code: String,
) {
for line in f.lines() {
let s = line.trim();
if s.starts_with("```") && s.contains("compile_fail") && s.contains('E') {
error_codes.insert(err_code, true);
return;
} else if s.starts_with("#### Note: this error code is no longer emitted by the compiler") {
error_codes.get_mut(&err_code).map(|x| *x = true);
return;
}
}
}
macro_rules! some_or_continue {
($e:expr) => (
match $e {
Some(e) => e,
None => continue,
}
);
}
fn extract_error_codes(f: &str, error_codes: &mut HashMap<String, bool>, path: &Path) {
let mut reached_no_explanation = false;
let mut last_error_code = None;
for line in f.lines() {
let s = line.trim();
if s.starts_with('E') && s.ends_with(": r##\"") {
if !reached_no_explanation && s.starts_with('E') && s.contains("include_str!(\"") {
if let Some(err_code) = s.splitn(2, ':').next() {
let err_code = err_code.to_owned();
last_error_code = Some(err_code.clone());
if !error_codes.contains_key(&err_code) {
error_codes.insert(err_code, false);
error_codes.insert(err_code.clone(), false);
}
// Now we extract the tests from the markdown file!
let md = some_or_continue!(s.splitn(2, "include_str!(\"").skip(1).next());
let md_file_name = some_or_continue!(md.splitn(2, "\")").next());
let path = some_or_continue!(path.parent()).join(md_file_name);
match read_to_string(&path) {
Ok(content) => {
check_error_code_explanation(
&content,
error_codes,
err_code,
);
}
Err(e) => {
eprintln!("Couldn't read `{}`: {}", path.display(), e);
}
}
}
} else if s.starts_with("```") && s.contains("compile_fail") && s.contains('E') {
if let Some(err_code) = s.splitn(2, 'E').skip(1).next() {
if let Some(err_code) = err_code.splitn(2, ',').next() {
let nb = error_codes.entry(format!("E{}", err_code)).or_insert(false);
*nb = true;
}
}
} else if s == ";" {
reached_no_explanation = true;
} else if reached_no_explanation && s.starts_with('E') {
if let Some(err_code) = s.splitn(2, ',').next() {
let err_code = err_code.to_owned();
@ -80,11 +113,8 @@ fn extract_error_codes(f: &str, error_codes: &mut HashMap<String, bool>) {
error_codes.insert(err_code, false);
}
}
} else if s.starts_with("#### Note: this error code is no longer emitted by the compiler") {
if let Some(last) = last_error_code {
error_codes.get_mut(&last).map(|x| *x = true);
}
last_error_code = None;
} else if s == ";" {
reached_no_explanation = true;
}
}
}
@ -111,7 +141,7 @@ pub fn check(path: &Path, bad: &mut bool) {
&mut |entry, contents| {
let file_name = entry.file_name();
if file_name == "error_codes.rs" {
extract_error_codes(contents, &mut error_codes);
extract_error_codes(contents, &mut error_codes, entry.path());
} else if entry.path().extension() == Some(OsStr::new("stderr")) {
extract_error_codes_from_tests(contents, &mut error_codes);
}