1use crate::graph::{CodePropertyGraph, Edge};
2use icb_common::NodeKind;
3use petgraph::visit::{EdgeRef, IntoEdgeReferences};
4use std::fmt::Write;
5
6pub fn export_call_dot(cpg: &CodePropertyGraph) -> String {
10 let mut s = String::new();
11 writeln!(s, "digraph CallGraph {{").unwrap();
12 writeln!(s, " rankdir=LR;").unwrap();
13 writeln!(s, " node [shape=box, style=rounded];").unwrap();
14
15 for node_idx in cpg.graph.node_indices() {
16 let node = &cpg.graph[node_idx];
17 match node.kind {
18 NodeKind::Function | NodeKind::Class => {
19 let label = node.name.as_deref().unwrap_or("?");
20 writeln!(
21 s,
22 " n{} [label=\"{}\\nline {}\"];",
23 node_idx.index(),
24 label,
25 node.start_line
26 )
27 .unwrap();
28 }
29 _ => {}
30 }
31 }
32
33 for edge_ref in cpg.graph.edge_references() {
34 if *edge_ref.weight() == Edge::Call {
35 writeln!(
36 s,
37 " n{} -> n{};",
38 edge_ref.source().index(),
39 edge_ref.target().index()
40 )
41 .unwrap();
42 }
43 }
44
45 writeln!(s, "}}").unwrap();
46 s
47}