use crate::report_types::StaticFlag;
use crate::types::{FileRecord, FindingTier};
use super::similarity;
fn comment_text(source: &str) -> String {
let mut comments = Vec::new();
let mut in_block_comment = false;
for line in source.lines() {
let trimmed = line.trim_start();
if in_block_comment {
comments.push(trimmed.to_string());
if trimmed.contains("*/") {
in_block_comment = false;
}
continue;
}
if trimmed.starts_with("//")
|| trimmed.starts_with('#')
|| trimmed.starts_with("/*")
|| trimmed.starts_with('*')
{
comments.push(trimmed.to_string());
if trimmed.starts_with("/*") && !trimmed.contains("*/") {
in_block_comment = true;
}
}
}
comments.join("\n").to_lowercase()
}
pub(crate) fn provenance_flags(file_records: &[FileRecord]) -> Vec<StaticFlag> {
let mut flags = Vec::new();
let markers = [
"generated by",
"auto-generated",
"autogenerated",
"do not edit",
"copied from",
"machine generated",
"generated automatically",
"ai-generated",
];
for file in file_records {
if crate::roles::is_intentional_surface_record(file) {
continue;
}
let comments = comment_text(&file.source);
if let Some(marker) = markers.iter().find(|marker| comments.contains(**marker)) {
flags.push(similarity::make_file_flag(
&file.file_path,
format!("generated-style marker present ('{}')", marker),
FindingTier::KindaSlop,
"provenance",
));
}
}
flags
}