mago_codex/ttype/
combination.rs1use std::collections::BTreeMap;
2
3use ahash::HashSet;
4use ordered_float::OrderedFloat;
5
6use mago_atom::Atom;
7use mago_atom::AtomMap;
8use mago_atom::AtomSet;
9
10use crate::ttype::atomic::TAtomic;
11use crate::ttype::atomic::array::key::ArrayKey;
12use crate::ttype::atomic::derived::TDerived;
13use crate::ttype::atomic::scalar::int::TInteger;
14use crate::ttype::union::TUnion;
15
16#[derive(Debug)]
17pub struct TypeCombination {
18 pub value_types: AtomMap<TAtomic>,
19 pub has_object_top_type: bool,
20 pub enum_names: HashSet<(Atom, Option<Atom>)>,
21 pub object_type_params: AtomMap<(Atom, Vec<TUnion>)>,
22 pub object_static: AtomMap<bool>,
23 pub list_array_counts: Option<HashSet<usize>>,
24 pub list_array_sometimes_filled: bool,
25 pub list_array_always_filled: bool,
26 pub keyed_array_sometimes_filled: bool,
27 pub keyed_array_always_filled: bool,
28 pub has_empty_array: bool,
29 pub has_keyed_array: bool,
30 pub keyed_array_entries: BTreeMap<ArrayKey, (bool, TUnion)>,
31 pub list_array_entries: BTreeMap<usize, (bool, TUnion)>,
32 pub keyed_array_parameters: Option<(TUnion, TUnion)>,
33 pub list_array_parameter: Option<TUnion>,
34 pub falsy_mixed: Option<bool>,
35 pub truthy_mixed: Option<bool>,
36 pub nonnull_mixed: Option<bool>,
37 pub generic_mixed: bool,
38 pub has_mixed: bool,
39 pub mixed_from_loop_isset: Option<bool>,
40 pub integers: HashSet<TInteger>,
41 pub literal_strings: AtomSet,
42 pub literal_floats: HashSet<OrderedFloat<f64>>,
43 pub class_string_types: AtomMap<TAtomic>,
44 pub derived_types: HashSet<TDerived>,
45 pub resource: bool,
46 pub open_resource: bool,
47 pub closed_resource: bool,
48}
49
50impl Default for TypeCombination {
51 fn default() -> Self {
52 Self::new()
53 }
54}
55
56impl TypeCombination {
57 pub fn new() -> Self {
58 Self {
59 value_types: AtomMap::default(),
60 has_object_top_type: false,
61 object_type_params: AtomMap::default(),
62 object_static: AtomMap::default(),
63 list_array_counts: Some(HashSet::default()),
64 list_array_sometimes_filled: false,
65 list_array_always_filled: true,
66 keyed_array_sometimes_filled: false,
67 keyed_array_always_filled: true,
68 has_empty_array: false,
69 has_keyed_array: false,
70 keyed_array_entries: BTreeMap::new(),
71 list_array_entries: BTreeMap::new(),
72 keyed_array_parameters: None,
73 list_array_parameter: None,
74 falsy_mixed: None,
75 truthy_mixed: None,
76 nonnull_mixed: None,
77 generic_mixed: false,
78 has_mixed: false,
79 mixed_from_loop_isset: None,
80 literal_strings: AtomSet::default(),
81 integers: HashSet::default(),
82 literal_floats: HashSet::default(),
83 class_string_types: AtomMap::default(),
84 enum_names: HashSet::default(),
85 derived_types: HashSet::default(),
86 resource: false,
87 open_resource: false,
88 closed_resource: false,
89 }
90 }
91
92 #[inline]
93 pub fn is_simple(&self) -> bool {
94 if self.value_types.len() == 1
95 && !self.has_keyed_array
96 && !self.has_empty_array
97 && !self.resource
98 && !self.open_resource
99 && !self.closed_resource
100 && let (None, None) = (&self.keyed_array_parameters, &self.list_array_parameter)
101 {
102 return self.keyed_array_entries.is_empty()
103 && self.list_array_entries.is_empty()
104 && self.object_type_params.is_empty()
105 && self.enum_names.is_empty()
106 && self.literal_strings.is_empty()
107 && self.class_string_types.is_empty()
108 && self.integers.is_empty()
109 && self.derived_types.is_empty();
110 }
111
112 false
113 }
114}