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