rapx/analysis/core/api_dependency/graph/
avail.rs1use 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}