rapx/analysis/core/api_dep/
mod.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/// NOTE: This analysis module is currently under development and is highly unstable.
/// The #[allow(unused)] attribute is applied to suppress excessive lint warnings.
/// Once the analysis stabilizes, this marker should be removed.

#[allow(unused)]
mod extract;
#[allow(unused)]
mod graph;
#[allow(unused)]
mod lifetime;
#[allow(unused)]
mod visitor;

use crate::{rap_debug, rap_info};
use graph::ApiDepGraph;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::ty::TyCtxt;

use visitor::FnVisitor;

pub struct ApiDep<'tcx> {
    pub tcx: TyCtxt<'tcx>,
}

impl<'tcx> ApiDep<'tcx> {
    pub fn new(tcx: TyCtxt<'tcx>) -> ApiDep<'tcx> {
        ApiDep { tcx }
    }
    pub fn start(&self) -> ApiDepGraph<'tcx> {
        let local_crate_name = self.tcx.crate_name(LOCAL_CRATE);
        let local_crate_type = self.tcx.crate_types()[0];
        rap_debug!(
            "Build API dependency graph on {} ({})",
            local_crate_name.as_str(),
            local_crate_type
        );

        let mut api_graph = ApiDepGraph::new();
        let mut fn_visitor = FnVisitor::new(self.tcx, &mut api_graph);
        self.tcx
            .hir()
            .visit_all_item_likes_in_crate(&mut fn_visitor);
        rap_debug!("api-dep find {} APIs.", fn_visitor.fn_cnt());

        let statistics = api_graph.statistics();
        // print all statistics
        rap_debug!(
            "API Graph contains {} API nodes, {} type nodes, {} generic parameter def nodes",
            statistics.api_count,
            statistics.type_count,
            statistics.generic_param_count
        );

        let dot_filename = format!("api_graph_{}_{}.dot", local_crate_name, local_crate_type);
        rap_info!("Dump API dependency graph to {}", dot_filename);
        api_graph.dump_to_dot(dot_filename, self.tcx);
        api_graph
    }
}