Skip to main content

luaur_analysis/functions/
flatten_intersection.rs

1//! Node: `cxx:Function:Luau.Analysis:Analysis/src/Type.cpp:134:flatten_intersection`
2//! Source: `Analysis/src/Type.cpp:134-164` (hand-ported)
3
4use crate::functions::follow_type::follow;
5use crate::functions::get_type_alt_j::get;
6use crate::records::intersection_type::IntersectionType;
7use crate::type_aliases::type_id::TypeId;
8use alloc::collections::VecDeque;
9use alloc::vec;
10use alloc::vec::Vec;
11
12pub fn flatten_intersection(ty: TypeId) -> Vec<TypeId> {
13    unsafe {
14        if get::<IntersectionType>(follow(ty)).is_null() {
15            return vec![ty];
16        }
17
18        let mut seen = std::collections::HashSet::<TypeId>::new();
19        let mut queue: VecDeque<TypeId> = VecDeque::from(vec![ty]);
20
21        let mut result = Vec::new();
22
23        while let Some(front) = queue.pop_front() {
24            let current = follow(front);
25
26            if seen.contains(&current) {
27                continue;
28            }
29
30            seen.insert(current);
31
32            let itv = get::<IntersectionType>(current);
33            if !itv.is_null() {
34                for &t in (*itv).parts.iter() {
35                    queue.push_back(t);
36                }
37            } else {
38                result.push(current);
39            }
40        }
41
42        result
43    }
44}