1use std::ffi::OsStr;
4use std::path::Path;
5
6use crate::diagnostics::{CheckId, TidyCtx};
7use crate::walk::walk;
8
9fn is_codegen_repo_path(path: &Path) -> bool {
10 const CODEGEN_REPO_PATHS: &[&str] =
11 &["compiler/rustc_codegen_cranelift", "compiler/rustc_codegen_gcc"];
12
13 CODEGEN_REPO_PATHS.iter().any(|repo| path.ancestors().any(|p| p.ends_with(Path::new(repo))))
14}
15
16fn has_supported_extension(path: &Path) -> bool {
17 const EXTENSIONS: &[&str] =
18 &["rs", "py", "js", "sh", "c", "cpp", "h", "md", "css", "ftl", "toml", "yml", "yaml"];
19 path.extension().is_some_and(|ext| EXTENSIONS.iter().any(|e| ext == OsStr::new(e)))
20}
21
22pub fn check(path: &Path, tidy_ctx: TidyCtx) {
23 let mut check = tidy_ctx.start_check(CheckId::new("codegen").path(path));
24
25 fn skip(path: &Path, is_dir: bool) -> bool {
26 if path.file_name().is_some_and(|name| name.to_string_lossy().starts_with(".#")) {
27 return true;
29 }
30
31 if is_dir {
32 return false;
33 }
34
35 !has_supported_extension(path)
37 }
38
39 walk(path, skip, &mut |entry, contents| {
40 let file = entry.path();
41
42 if !is_codegen_repo_path(file) {
43 return;
44 }
45
46 for (i, line) in contents.split('\n').enumerate() {
47 let trimmed = line.trim();
48
49 if trimmed.contains("TODO") {
51 check.error(format!(
52 "{}:{}: TODO is used for tasks that should be done before merging a PR; \
53 if you want to leave a message in the codebase use FIXME",
54 file.display(),
55 i + 1
56 ));
57 }
58 }
59 });
60}