logicaffeine_compile/analysis/
relay.rs1use crate::ast::component::{ComponentDef, ComponentKind, StoreMode, Trigger};
12use crate::ast::stmt::{SelectBranch, Stmt, UiStmt};
13
14pub fn pages_use_the_relay(stmts: &[Stmt]) -> bool {
18 stmts
19 .iter()
20 .any(|s| matches!(s, Stmt::ComponentDef(def) if component_uses_the_relay(def)))
21}
22
23pub fn source_uses_the_relay(source: &str) -> bool {
26 crate::ui_bridge::with_parsed_program(source, |parsed, _| {
27 parsed.is_ok_and(|(stmts, _, _)| pages_use_the_relay(stmts))
28 })
29}
30
31pub fn component_uses_the_relay(def: &ComponentDef) -> bool {
33 matches!(
34 def.kind,
35 ComponentKind::Store {
36 mode: StoreMode::Shared { .. }
37 }
38 ) || def
39 .events
40 .iter()
41 .any(|h| matches!(h.trigger, Trigger::Message { .. }) || publishes(h.body))
42 || def.actions.iter().any(|a| publishes(a.body))
43}
44
45fn publishes(stmts: &[Stmt]) -> bool {
47 stmts.iter().any(|s| match s {
48 Stmt::Ui(UiStmt::Publish { .. }) => true,
49 Stmt::If {
50 then_block,
51 else_block,
52 ..
53 } => publishes(then_block) || else_block.is_some_and(publishes),
54 Stmt::While { body, .. }
55 | Stmt::Repeat { body, .. }
56 | Stmt::Zone { body, .. }
57 | Stmt::Splice { body } => publishes(body),
58 Stmt::Concurrent { tasks } | Stmt::Parallel { tasks } => publishes(tasks),
59 Stmt::Inspect { arms, .. } => arms.iter().any(|a| publishes(a.body)),
60 Stmt::Select { branches } => branches.iter().any(|b| match b {
61 SelectBranch::Receive { body, .. } | SelectBranch::Timeout { body, .. } => {
62 publishes(body)
63 }
64 }),
65 _ => false,
66 })
67}
68
69#[cfg(test)]
70#[path = "../../../logicaffeine_tests/unit/logicaffeine_compile/analysis/relay/tests.rs"]
71mod tests;