Skip to main content

luaur_analysis/functions/
is_optional.rs

1use crate::functions::follow_type::follow_type_id;
2use crate::functions::get_type_alt_j::get_type_id;
3use crate::functions::is_nil::is_nil;
4use crate::records::any_type::AnyType;
5use crate::records::union_type::UnionType;
6use crate::records::unknown_type::UnknownType;
7use crate::type_aliases::type_id::TypeId;
8use std::collections::HashSet;
9
10pub fn is_optional(ty: TypeId) -> bool {
11    unsafe {
12        let mut seen = HashSet::<TypeId>::new();
13        let mut stack = vec![ty];
14
15        while let Some(ty) = stack.pop() {
16            let ty = follow_type_id(ty);
17            if !seen.insert(ty) {
18                continue;
19            }
20
21            if is_nil(ty)
22                || !get_type_id::<AnyType>(ty).is_null()
23                || !get_type_id::<UnknownType>(ty).is_null()
24            {
25                return true;
26            }
27
28            let utv = get_type_id::<UnionType>(ty);
29            if !utv.is_null() {
30                stack.extend((*utv).options.iter().copied());
31            }
32        }
33
34        false
35    }
36}