rapx/analysis/core/api_dependency/
default.rs

1/// NOTE: This analysis module is currently under development and is highly unstable.
2/// The #[allow(unused)] attribute is applied to suppress excessive lint warnings.
3/// Once the analysis stabilizes, this marker should be removed.
4use 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        // print all statistics
61        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}