blob: 212b1a40f655a60b3ae0661d4f9644f6b2189af4 [file] [log] [blame]
//! Tidy check to verify the validity of long error diagnostic codes.
//!
//! This ensures that error codes are used at most once and also prints out some
//! statistics about the error codes.
use std::collections::HashMap;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;
pub fn check(path: &Path, bad: &mut bool) {
let mut contents = String::new();
let mut map: HashMap<_, Vec<_>> = HashMap::new();
super::walk(path,
&mut |path| super::filter_dirs(path) || path.ends_with("src/test"),
&mut |file| {
let filename = file.file_name().unwrap().to_string_lossy();
if filename != "diagnostics.rs" && filename != "diagnostic_list.rs" {
return
}
contents.truncate(0);
t!(t!(File::open(file)).read_to_string(&mut contents));
// In the register_long_diagnostics! macro, entries look like this:
//
// EXXXX: r##"
// <Long diagnostic message>
// "##,
//
// and these long messages often have error codes themselves inside
// them, but we don't want to report duplicates in these cases. This
// variable keeps track of whether we're currently inside one of these
// long diagnostic messages.
let mut inside_long_diag = false;
for (num, line) in contents.lines().enumerate() {
if inside_long_diag {
inside_long_diag = !line.contains("\"##");
continue
}
let mut search = line;
while let Some(i) = search.find('E') {
search = &search[i + 1..];
let code = if search.len() > 4 {
search[..4].parse::<u32>()
} else {
continue
};
let code = match code {
Ok(n) => n,
Err(..) => continue,
};
map.entry(code).or_default()
.push((file.to_owned(), num + 1, line.to_owned()));
break
}
inside_long_diag = line.contains("r##\"");
}
});
let mut max = 0;
for (&code, entries) in map.iter() {
if code > max {
max = code;
}
if entries.len() == 1 {
continue
}
tidy_error!(bad, "duplicate error code: {}", code);
for &(ref file, line_num, ref line) in entries.iter() {
tidy_error!(bad, "{}:{}: {}", file.display(), line_num, line);
}
}
if !*bad {
println!("* {} error codes", map.len());
println!("* highest error code: E{:04}", max);
}
}