rapx/analysis/core/api_dependency/graph/
avail.rs

1use super::super::visitor::FnVisitor;
2use super::dep_edge::DepEdge;
3use super::dep_node::{desc_str, DepNode};
4use super::transform::TransformKind;
5use super::ty_wrapper::TyWrapper;
6use super::utils;
7use super::ApiDependencyGraph;
8use super::Config;
9use crate::analysis::utils::def_path::path_str_def_id;
10use crate::rap_debug;
11use crate::rap_trace;
12use crate::utils::fs::rap_create_file;
13use petgraph::visit::EdgeRef;
14use petgraph::Direction;
15use rustc_middle::ty::{self, Ty, TyCtxt};
16use std::collections::HashSet;
17
18impl<'tcx> ApiDependencyGraph<'tcx> {
19    pub fn eligible_nodes_with(&self, tys: &[Ty<'tcx>]) -> Vec<DepNode<'tcx>> {
20        let check_ty = |ty: Ty<'tcx>| {
21            tys.iter()
22                .any(|avail_ty| utils::is_ty_eq(*avail_ty, ty, self.tcx))
23        };
24
25        self.graph
26            .node_indices()
27            .filter_map(|index| match self.graph[index] {
28                DepNode::Api(fn_did, args)
29                    if self
30                        .graph
31                        .neighbors_directed(index, Direction::Incoming)
32                        .all(|neighbor| {
33                            let ty = self.graph[neighbor].expect_ty().ty();
34                            utils::is_fuzzable_ty(ty, self.tcx) || check_ty(ty)
35                        }) =>
36                {
37                    Some(self.graph[index])
38                }
39                DepNode::Ty(ty)
40                    if self
41                        .graph
42                        .neighbors_directed(index, Direction::Incoming)
43                        .any(|neighbor| {
44                            if let Some(ty) = self.graph[neighbor].as_ty() {
45                                check_ty(ty.ty())
46                            } else {
47                                false
48                            }
49                        }) =>
50                {
51                    Some(self.graph[index])
52                }
53                _ => None,
54            })
55            .collect()
56    }
57
58    pub fn eligible_transforms_to(&self, ty: Ty<'tcx>) -> Vec<(TyWrapper<'tcx>, TransformKind)> {
59        let mut set = HashSet::new();
60        if let Some(node) = self.get_index(DepNode::Ty(ty.into())) {
61            for edge in self.graph.edges_directed(node, Direction::Incoming) {
62                if let Some(kind) = edge.weight().as_transform_kind() {
63                    let source_ty = self.graph[edge.source()].expect_ty();
64                    set.insert((source_ty, kind));
65                }
66            }
67        }
68        set.into_iter().collect()
69    }
70}