luaur_analysis/functions/
is_optional.rs1use 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}