use super::{enumerate_paths, Path};
#[derive(Debug, Clone)]
pub struct IncrementalPathsResult {
pub analyzed_functions: usize,
pub skipped_functions: usize,
pub paths: Vec<Path>,
}
pub fn enumerate_paths_incremental(
function_id: &str,
backend: &crate::storage::MirageDb,
repo_path: &std::path::Path,
since_revision: &str,
max_length: Option<usize>,
) -> anyhow::Result<IncrementalPathsResult> {
use crate::cfg::{load_cfg_from_db, PathLimits};
if function_id != "all" {
let fid = function_id
.parse::<i64>()
.map_err(|_| anyhow::anyhow!("Invalid function ID: {}", function_id))?;
let cfg = load_cfg_from_db(backend, fid)?;
let limits = PathLimits {
max_length: max_length.unwrap_or(1000),
..Default::default()
};
let paths = enumerate_paths(&cfg, &limits);
return Ok(IncrementalPathsResult {
analyzed_functions: 1,
skipped_functions: 0,
paths,
});
}
let changed_function_ids =
crate::cfg::git_utils::get_changed_functions(backend, repo_path, since_revision)?;
if changed_function_ids.is_empty() {
return Ok(IncrementalPathsResult {
analyzed_functions: 0,
skipped_functions: 0,
paths: vec![],
});
}
let mut all_paths = Vec::new();
let mut analyzed = 0;
for fid in changed_function_ids {
match load_cfg_from_db(backend, fid) {
Ok(cfg) => {
let limits = PathLimits {
max_length: max_length.unwrap_or(1000),
..Default::default()
};
let paths = enumerate_paths(&cfg, &limits);
all_paths.extend(paths);
analyzed += 1;
}
Err(e) => {
tracing::warn!("Failed to load CFG for function {}: {}", fid, e);
}
}
}
Ok(IncrementalPathsResult {
analyzed_functions: analyzed,
skipped_functions: 0,
paths: all_paths,
})
}