cairo_lang_lowering/scc/
mod.rs

1use cairo_lang_utils::graph_algos::graph_node::GraphNode;
2use cairo_lang_utils::graph_algos::strongly_connected_components::compute_scc;
3
4use crate::DependencyType;
5use crate::db::LoweringGroup;
6use crate::ids::FunctionWithBodyId;
7
8/// Query implementation of [crate::db::LoweringGroup::function_with_body_scc].
9pub fn function_with_body_scc(
10    db: &dyn LoweringGroup,
11    function_id: FunctionWithBodyId,
12    dependency_type: DependencyType,
13) -> Vec<FunctionWithBodyId> {
14    compute_scc(&FunctionWithBodyNode {
15        function_with_body_id: function_id,
16        dependency_type,
17        db: db.upcast(),
18    })
19}
20
21/// A node to use in the SCC computation.
22#[derive(Clone)]
23struct FunctionWithBodyNode<'a> {
24    function_with_body_id: FunctionWithBodyId,
25    dependency_type: DependencyType,
26    db: &'a dyn LoweringGroup,
27}
28impl GraphNode for FunctionWithBodyNode<'_> {
29    type NodeId = FunctionWithBodyId;
30
31    fn get_neighbors(&self) -> Vec<Self> {
32        self.db
33            .function_with_body_direct_function_with_body_callees(
34                self.function_with_body_id,
35                self.dependency_type,
36            )
37            .unwrap_or_default()
38            .into_iter()
39            .map(|function_with_body_id| FunctionWithBodyNode {
40                function_with_body_id,
41                dependency_type: self.dependency_type,
42                db: self.db,
43            })
44            .collect()
45    }
46
47    fn get_id(&self) -> Self::NodeId {
48        self.function_with_body_id
49    }
50}