1use std::collections::HashMap;
4use std::path::Path;
5
6use crate::diagnostics::{CheckId, DiagCtx};
7use crate::walk::{filter_dirs, walk};
8
9fn filter_used_messages(
10 contents: &str,
11 msgs_not_appeared_yet: &mut HashMap<String, String>,
12 msgs_appeared_only_once: &mut HashMap<String, String>,
13) {
14 let matches = static_regex!(r"\w+").find_iter(contents);
18 for name in matches {
19 if let Some((name, filename)) = msgs_not_appeared_yet.remove_entry(name.as_str()) {
20 msgs_appeared_only_once.insert(name, filename);
23 } else {
24 msgs_appeared_only_once.remove(name.as_str());
27 }
28 }
29}
30
31pub fn check(path: &Path, mut all_defined_msgs: HashMap<String, String>, diag_ctx: DiagCtx) {
32 let mut check = diag_ctx.start_check(CheckId::new("fluent_used").path(path));
33
34 let mut msgs_appear_only_once = HashMap::new();
35 walk(path, |path, _| filter_dirs(path), &mut |_, contents| {
36 filter_used_messages(contents, &mut all_defined_msgs, &mut msgs_appear_only_once);
37 });
38
39 for (name, filename) in msgs_appear_only_once {
40 check.error(format!("{filename}: message `{name}` is not used"));
41 }
42}