cairo_lang_lowering/graph_algorithms/
cycles.rs1use cairo_lang_diagnostics::Maybe;
2use cairo_lang_utils::ordered_hash_set::OrderedHashSet;
3
4use crate::DependencyType;
5use crate::db::{LoweringGroup, get_direct_callees};
6use crate::ids::{ConcreteFunctionWithBodyId, FunctionId, FunctionWithBodyId};
7
8pub fn function_with_body_direct_callees(
11 db: &dyn LoweringGroup,
12 function_id: FunctionWithBodyId,
13 dependency_type: DependencyType,
14) -> Maybe<OrderedHashSet<FunctionId>> {
15 let (lowered, block_extra_calls) =
16 db.function_with_body_lowering_with_borrow_check(function_id)?;
17 Ok(get_direct_callees(db, &lowered, dependency_type, &block_extra_calls).into_iter().collect())
18}
19
20pub fn function_with_body_direct_function_with_body_callees(
23 db: &dyn LoweringGroup,
24 function_id: FunctionWithBodyId,
25 dependency_type: DependencyType,
26) -> Maybe<OrderedHashSet<FunctionWithBodyId>> {
27 Ok(db
28 .function_with_body_direct_callees(function_id, dependency_type)?
29 .into_iter()
30 .map(|function_id| function_id.body(db))
31 .collect::<Maybe<Vec<Option<_>>>>()?
32 .into_iter()
33 .flatten()
34 .map(|x| x.function_with_body_id(db))
35 .collect())
36}
37
38pub fn final_contains_call_cycle(
40 db: &dyn LoweringGroup,
41 function_id: ConcreteFunctionWithBodyId,
42) -> Maybe<bool> {
43 let direct_callees = db.final_concrete_function_with_body_lowered_direct_callees(
44 function_id,
45 DependencyType::Call,
46 )?;
47 for callee in direct_callees {
48 if db.final_contains_call_cycle(callee)? {
49 return Ok(true);
50 }
51 }
52
53 Ok(false)
54}
55
56pub fn final_contains_call_cycle_handle_cycle(
58 _db: &dyn LoweringGroup,
59 _cycle: &salsa::Cycle,
60 _function_id: &ConcreteFunctionWithBodyId,
61) -> Maybe<bool> {
62 Ok(true)
63}
64
65pub fn in_cycle(
67 db: &dyn LoweringGroup,
68 function_id: FunctionWithBodyId,
69 dependency_type: DependencyType,
70) -> Maybe<bool> {
71 if db
72 .function_with_body_direct_function_with_body_callees(function_id, dependency_type)?
73 .contains(&function_id)
74 {
75 return Ok(true);
76 }
77 Ok(db.function_with_body_scc(function_id, dependency_type).len() > 1)
78}