rapx/analysis/core/api_dependency/
default.rs1use crate::{
5 analysis::core::api_dependency::{ApiDependencyAnalysis, ApiDependencyGraph},
6 rap_debug, rap_info, Analysis,
7};
8use rustc_hir::def_id::LOCAL_CRATE;
9use rustc_middle::ty::TyCtxt;
10
11use super::visitor::FnVisitor;
12
13pub struct ApiDependencyAnalyzer<'tcx> {
14 pub tcx: TyCtxt<'tcx>,
15 pub api_graph: ApiDependencyGraph<'tcx>,
16}
17
18impl<'tcx> Analysis for ApiDependencyAnalyzer<'tcx> {
19 fn name(&self) -> &'static str {
20 "Default API dependency graph analysis algorithm."
21 }
22
23 fn run(&mut self) {
24 self.start();
25 }
26
27 fn reset(&mut self) {
28 todo!();
29 }
30}
31
32impl<'tcx> ApiDependencyAnalysis<'tcx> for ApiDependencyAnalyzer<'tcx> {
33 fn get_api_dependency_graph(&self) -> ApiDependencyGraph<'tcx> {
34 self.api_graph.clone()
35 }
36}
37
38impl<'tcx> ApiDependencyAnalyzer<'tcx> {
39 pub fn new(tcx: TyCtxt<'tcx>) -> ApiDependencyAnalyzer<'tcx> {
40 ApiDependencyAnalyzer {
41 tcx,
42 api_graph: ApiDependencyGraph::new(),
43 }
44 }
45 pub fn start(&mut self) {
46 let local_crate_name = self.tcx.crate_name(LOCAL_CRATE);
47 let local_crate_type = self.tcx.crate_types()[0];
48 rap_debug!(
49 "Build API dependency graph on {} ({})",
50 local_crate_name.as_str(),
51 local_crate_type
52 );
53
54 let mut api_graph = ApiDependencyGraph::new();
55 let mut fn_visitor = FnVisitor::new(self.tcx, &mut api_graph);
56 self.tcx.hir_visit_all_item_likes_in_crate(&mut fn_visitor);
57 rap_debug!("api-dep find {} APIs.", fn_visitor.fn_cnt());
58
59 let statistics = api_graph.statistics();
60 rap_debug!(
62 "API Graph contains {} API nodes, {} type nodes, {} generic parameter def nodes",
63 statistics.api_count,
64 statistics.type_count,
65 statistics.generic_param_count
66 );
67
68 let dot_filename = format!("api_graph_{}_{}.dot", local_crate_name, local_crate_type);
69 rap_info!("Dump API dependency graph to {}", dot_filename);
70 api_graph.dump_to_dot(dot_filename, self.tcx);
71 self.api_graph = api_graph;
72 }
73}