rapx/analysis/api_dependency/graph/
avail.rs

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