luaur_analysis/records/
refinement_arena_control_flow_graph.rs1use crate::records::conjunction_control_flow_graph::Conjunction;
3use crate::records::disjunction_control_flow_graph::Disjunction;
4use crate::records::negation_control_flow_graph::Negation;
5use crate::records::proposition_control_flow_graph::Proposition;
6use crate::records::typed_allocator::TypedAllocator;
7use crate::type_aliases::def_id_control_flow_graph::DefId;
8use crate::type_aliases::refinement_control_flow_graph::{Refinement, RefinementMember};
9use crate::type_aliases::refinement_id_control_flow_graph::RefinementId;
10use alloc::string::String;
11use luaur_common::macros::luau_assert::LUAU_ASSERT;
12
13#[derive(Debug)]
14pub struct RefinementArena {
15 pub(crate) allocator: TypedAllocator<Refinement>,
16}
17
18impl RefinementArena {
19 pub fn proposition(&mut self, def: DefId, sense: bool) -> RefinementId {
21 self.allocator
23 .allocate(Refinement::Proposition(Proposition {
24 ptr: def,
25 r#type: None,
26 is_typeof: false,
27 sense,
28 }))
29 }
30
31 pub fn type_proposition(
33 &mut self,
34 def: DefId,
35 r#type: Option<String>,
36 is_typeof: bool,
37 sense: bool,
38 ) -> RefinementId {
39 self.allocator
41 .allocate(Refinement::Proposition(Proposition {
42 ptr: def,
43 r#type,
44 is_typeof,
45 sense,
46 }))
47 }
48
49 pub fn conjunction(&mut self, lhs: RefinementId, rhs: RefinementId) -> RefinementId {
51 self.allocator
53 .allocate(Refinement::Conjunction(Conjunction { lhs, rhs }))
54 }
55
56 pub fn disjunction(&mut self, lhs: RefinementId, rhs: RefinementId) -> RefinementId {
58 self.allocator
60 .allocate(Refinement::Disjunction(Disjunction { lhs, rhs }))
61 }
62
63 pub fn negation(&mut self, r: RefinementId) -> RefinementId {
65 if let Some((lhs, rhs)) = unsafe { Conjunction::get_if(&*r) }.map(|c| (c.lhs, c.rhs)) {
69 let nl = self.negation(lhs);
70 let nr = self.negation(rhs);
71 return self.disjunction(nl, nr);
72 }
73 if let Some((lhs, rhs)) = unsafe { Disjunction::get_if(&*r) }.map(|d| (d.lhs, d.rhs)) {
76 let nl = self.negation(lhs);
77 let nr = self.negation(rhs);
78 return self.conjunction(nl, nr);
79 }
80 if let Some(refinement) = unsafe { Negation::get_if(&*r) }.map(|n| n.refinement) {
83 return refinement;
84 }
85
86 LUAU_ASSERT!(unsafe { Proposition::get_if(&*r) }.is_some());
88 self.allocator
90 .allocate(Refinement::Negation(Negation { refinement: r }))
91 }
92
93 pub fn freeze(&mut self) {
95 self.allocator.freeze();
97 }
98}