Skip to main content

luaur_analysis/functions/
get_components.rs

1use crate::functions::alloc_type_user_data::alloc_type_user_data;
2use crate::functions::get_tag::get_tag;
3use crate::functions::get_type_function_runtime_alt_o::get_type_function_type_id;
4use crate::functions::get_type_user_data::get_type_user_data;
5use crate::records::type_function_intersection_type::TypeFunctionIntersectionType;
6use crate::records::type_function_union_type::TypeFunctionUnionType;
7use crate::type_aliases::lua_state::lua_State;
8use crate::type_aliases::type_function_type_id::TypeFunctionTypeId;
9use luaur_vm::functions::lua_createtable::lua_createtable;
10use luaur_vm::functions::lua_gettop::lua_gettop;
11use luaur_vm::functions::lua_l_error_l::lua_l_error_l;
12use luaur_vm::functions::lua_rawseti::lua_rawseti;
13
14pub unsafe fn get_components(l: *mut lua_State) -> core::ffi::c_int {
15    let vm_l = l as *mut luaur_vm::records::lua_state::lua_State;
16    let argument_count = lua_gettop(vm_l);
17    if argument_count != 1 {
18        lua_l_error_l(
19            vm_l,
20            c"%s".as_ptr(),
21            core::format_args!(
22                "type.components: expected 1 argument, but got {}",
23                argument_count
24            ),
25        );
26    }
27
28    let self_ty = get_type_user_data(l, 1);
29
30    let tfut = get_type_function_type_id::<TypeFunctionUnionType>(self_ty);
31    if !tfut.is_null() {
32        let arg_size = (*tfut).components.len() as core::ffi::c_int;
33
34        lua_createtable(vm_l, arg_size, 0);
35        for i in 0..arg_size {
36            let component = {
37                let c = &(*tfut).components;
38                c[i as usize]
39            };
40            alloc_type_user_data(l, (*component).type_variant.clone(), false);
41            lua_rawseti(vm_l, -2, i + 1);
42        }
43
44        return 1;
45    }
46
47    let tfit = get_type_function_type_id::<TypeFunctionIntersectionType>(self_ty);
48    if !tfit.is_null() {
49        let arg_size = (*tfit).components.len() as core::ffi::c_int;
50
51        lua_createtable(vm_l, arg_size, 0);
52        for i in 0..arg_size {
53            let component = {
54                let c = &(*tfit).components;
55                c[i as usize]
56            };
57            alloc_type_user_data(l, (*component).type_variant.clone(), false);
58            lua_rawseti(vm_l, -2, i + 1);
59        }
60
61        return 1;
62    }
63
64    let tag = get_tag(l, self_ty);
65    lua_l_error_l(
66        vm_l,
67        c"%s".as_ptr(),
68        core::format_args!("type.components: cannot call components of `{}` type", tag),
69    );
70    0
71}