Skip to main content

luaur_analysis/methods/
normalizer_negate.rs

1use crate::functions::follow_type::follow_type_id;
2use crate::functions::get_type_alt_j::get_type_id;
3use crate::records::any_type::AnyType;
4use crate::records::builtin_types::BuiltinTypes;
5use crate::records::intersection_type::IntersectionType;
6use crate::records::negation_type::NegationType;
7use crate::records::never_type::NeverType;
8use crate::records::normalizer::Normalizer;
9use crate::records::union_type::UnionType;
10use crate::records::unknown_type::UnknownType;
11use crate::type_aliases::type_id::TypeId;
12
13impl Normalizer {
14    pub fn negate(&mut self, mut there: TypeId) -> TypeId {
15        self.consume_fuel();
16
17        there = unsafe { follow_type_id(there) };
18
19        if unsafe { !get_type_id::<AnyType>(there).is_null() } {
20            return there;
21        } else if unsafe { !get_type_id::<UnknownType>(there).is_null() } {
22            return unsafe { (*self.builtin_types).neverType };
23        } else if unsafe { !get_type_id::<NeverType>(there).is_null() } {
24            return unsafe { (*self.builtin_types).unknownType };
25        } else if let Some(ntv) = unsafe { get_type_id::<NegationType>(there).as_ref() } {
26            return ntv.ty;
27        } else if let Some(utv) = unsafe { get_type_id::<UnionType>(there).as_ref() } {
28            let mut parts = Vec::new();
29            for option in utv.options.iter() {
30                parts.push(self.negate(*option));
31            }
32            return unsafe { (*self.arena).add_type(IntersectionType { parts }) };
33        } else if let Some(itv) = unsafe { get_type_id::<IntersectionType>(there).as_ref() } {
34            let mut options = Vec::new();
35            for part in itv.parts.iter() {
36                options.push(self.negate(*part));
37            }
38            return unsafe { (*self.arena).add_type(UnionType { options }) };
39        } else {
40            return there;
41        }
42    }
43}