use crate::adapters::analyzers::architecture::ArchitectureAnalyzer;
use crate::config::Config;
use crate::domain::Finding;
use crate::findings::{Dimension, Suppression};
use crate::ports::{AnalysisContext, DimensionAnalyzer, ParsedFile};
use crate::report::Summary;
use std::collections::HashMap;
pub(super) fn collect_architecture_findings(
parsed: &[(String, String, syn::File)],
config: &Config,
suppression_lines: &HashMap<String, Vec<Suppression>>,
summary: &mut Summary,
) -> Vec<Finding> {
let mut findings = run_architecture_dimension(parsed, config, suppression_lines);
summary.architecture_warnings = findings.iter().filter(|f| !f.suppressed).count();
findings.sort_by(|a, b| {
a.file
.cmp(&b.file)
.then(a.line.cmp(&b.line))
.then(a.column.cmp(&b.column))
});
findings
}
fn run_architecture_dimension(
parsed: &[(String, String, syn::File)],
config: &Config,
suppression_lines: &HashMap<String, Vec<Suppression>>,
) -> Vec<Finding> {
let files: Vec<ParsedFile> = parsed
.iter()
.map(|(p, c, f)| ParsedFile {
path: p.clone(),
content: c.clone(),
ast: f.clone(),
})
.collect();
let ctx = AnalysisContext {
files: &files,
config,
};
let analyzers: Vec<Box<dyn DimensionAnalyzer>> = vec![Box::new(ArchitectureAnalyzer)];
let mut findings = crate::app::analyze_codebase(&analyzers, &ctx);
mark_architecture_suppressions(&mut findings, suppression_lines);
findings
}
fn mark_architecture_suppressions(
findings: &mut [Finding],
suppression_lines: &HashMap<String, Vec<Suppression>>,
) {
findings.iter_mut().for_each(|f| {
let suppressed = suppression_lines
.get(&f.file)
.map(|sups| {
sups.iter().any(|s| {
s.covers(Dimension::Architecture)
&& crate::findings::is_within_window(s.line, f.line)
})
})
.unwrap_or(false);
if suppressed {
f.suppressed = true;
}
});
}