rapx/analysis/core/
call_graph.rs

1pub mod call_graph_helper;
2pub mod call_graph_visitor;
3
4use std::collections::HashSet;
5
6use call_graph_helper::CallGraphInfo;
7use call_graph_visitor::CallGraphVisitor;
8use rustc_hir::def::DefKind;
9use rustc_middle::mir::Body;
10use rustc_middle::ty::TyCtxt;
11
12pub struct CallGraph<'tcx> {
13    pub tcx: TyCtxt<'tcx>,
14    pub graph: CallGraphInfo,
15}
16
17impl<'tcx> CallGraph<'tcx> {
18    pub fn new(tcx: TyCtxt<'tcx>) -> Self {
19        Self {
20            tcx: tcx,
21            graph: CallGraphInfo::new(),
22        }
23    }
24
25    pub fn start(&mut self) {
26        for local_def_id in self.tcx.iter_local_def_id() {
27            if self.tcx.hir_maybe_body_owned_by(local_def_id).is_some() {
28                let def_id = local_def_id.to_def_id();
29                if self.tcx.is_mir_available(def_id) {
30                    let def_kind = self.tcx.def_kind(def_id);
31                    let body: &Body = match def_kind {
32                        DefKind::Const | DefKind::Static { .. } => {
33                            // Compile Time Function Evaluation
34                            &self.tcx.mir_for_ctfe(def_id)
35                        }
36                        _ => &self.tcx.optimized_mir(def_id),
37                    };
38                    let mut call_graph_visitor =
39                        CallGraphVisitor::new(self.tcx, def_id.into(), body, &mut self.graph);
40                    call_graph_visitor.visit();
41                }
42            }
43        }
44        // for &def_id in self.tcx.mir_keys(()).iter() {
45        //     if self.tcx.is_mir_available(def_id) {
46        //         let body = &self.tcx.optimized_mir(def_id);
47        //         let mut call_graph_visitor =
48        //             CallGraphVisitor::new(self.tcx, def_id.into(), body, &mut self.graph);
49        //         call_graph_visitor.visit();
50        //     }
51        // }
52        self.graph.print_call_graph();
53    }
54
55    pub fn get_callee_def_path(&self, def_path: String) -> Option<HashSet<String>> {
56        self.graph.get_callees_path(&def_path)
57    }
58}