Skip to main content

luaur_analysis/methods/
normalizer_intersect_strings.rs

1use crate::records::normalized_string_type::NormalizedStringType;
2use crate::records::normalizer::Normalizer;
3
4use alloc::collections::BTreeMap;
5
6impl Normalizer {
7    pub fn intersect_strings(
8        &mut self,
9        here: &mut NormalizedStringType,
10        there: &NormalizedStringType,
11    ) {
12        self.consume_fuel();
13
14        // Case 1,2,3
15        if there.is_string() {
16            return;
17        }
18        // Case 4, Case 7
19        else if here.is_string() {
20            here.singletons.clear();
21            for (key, type_id) in &there.singletons {
22                here.singletons.insert(key.clone(), *type_id);
23            }
24            here.isCofinite = here.isCofinite && there.isCofinite;
25        }
26        // Case 5
27        else if here.is_intersection() && there.is_intersection() {
28            here.isCofinite = true;
29            for (key, type_id) in &there.singletons {
30                here.singletons.insert(key.clone(), *type_id);
31            }
32        }
33        // Case 6
34        else if here.is_union() && there.is_intersection() {
35            here.isCofinite = false;
36            for key in there.singletons.keys() {
37                here.singletons.remove(key);
38            }
39        }
40        // Case 8
41        else if here.is_intersection() && there.is_union() {
42            here.isCofinite = false;
43            let mut result: BTreeMap<alloc::string::String, crate::type_aliases::type_id::TypeId> =
44                there.singletons.clone();
45            for key in here.singletons.keys().cloned().collect::<Vec<_>>() {
46                result.remove(&key);
47            }
48            here.singletons = result;
49        }
50        // Case 9
51        else if here.is_union() && there.is_union() {
52            here.isCofinite = false;
53
54            let mut result = BTreeMap::new();
55            result.extend(here.singletons.iter().map(|(k, v)| (k.clone(), *v)));
56            result.extend(there.singletons.iter().map(|(k, v)| (k.clone(), *v)));
57
58            let mut to_remove = Vec::new();
59            for (key, _) in &result {
60                if !here.singletons.contains_key(key) || !there.singletons.contains_key(key) {
61                    to_remove.push(key.clone());
62                }
63            }
64            for key in to_remove {
65                result.remove(&key);
66            }
67
68            here.singletons = result;
69        } else {
70            luaur_common::LUAU_ASSERT!(false);
71        }
72    }
73}