use anyhow::{Context, Result};
use std::collections::HashMap;
use std::path::Path;
pub use crate::graph::cfg_edges_extract::CfgWithEdges;
pub use crate::graph::external_tools::tool_detector;
pub mod mir_invoker;
pub mod mir_parser;
pub fn extract_cfg_from_rust(source_path: &Path) -> Result<CfgWithEdges> {
let mir_content =
mir_invoker::dump_mir(source_path).context("Failed to dump MIR from Rust source")?;
let function_cfgs = mir_parser::extract_cfg_from_mir(&mir_content)
.context("Failed to parse CFG from MIR text")?;
let merged_cfg = merge_function_cfgs(function_cfgs);
Ok(merged_cfg)
}
fn merge_function_cfgs(function_cfgs: HashMap<String, CfgWithEdges>) -> CfgWithEdges {
let mut all_blocks = Vec::new();
let mut all_edges = Vec::new();
let mut offset = 0usize;
for (_name, cfg) in function_cfgs {
for edge in cfg.edges {
all_edges.push(crate::graph::cfg_edges_extract::CfgEdge {
source_idx: edge.source_idx + offset,
target_idx: edge.target_idx + offset,
edge_type: edge.edge_type,
});
}
all_blocks.extend(cfg.blocks);
offset += all_blocks.len();
}
CfgWithEdges {
blocks: all_blocks,
edges: all_edges,
function_id: 0,
}
}