luaur_analysis/functions/
set_write_table_prop.rs1use crate::functions::get_mutable_type_function_runtime_alt_g::get_mutable_type_function_type_id;
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_property::TypeFunctionProperty;
6use crate::records::type_function_singleton_type::TypeFunctionSingletonType;
7use crate::records::type_function_table_type::TypeFunctionTableType;
8use crate::type_aliases::lua_state::lua_State;
9use luaur_vm::functions::lua_gettop::lua_gettop;
10use luaur_vm::functions::lua_l_error_l::lua_l_error_l;
11use luaur_vm::macros::lua_isnil::lua_isnil;
12
13pub unsafe fn set_write_table_prop(l: *mut lua_State) -> i32 {
14 let vm_l = l as *mut luaur_vm::records::lua_state::lua_State;
15 let argument_count = lua_gettop(vm_l);
16 if argument_count < 2 || argument_count > 3 {
17 lua_l_error_l(
18 vm_l,
19 c"%s".as_ptr(),
20 core::format_args!(
21 "type.setwriteproperty: expected 2-3 arguments, but got {}",
22 argument_count
23 ),
24 );
25 }
26
27 let self_ty = get_type_user_data(l, 1);
28 let tftt = get_mutable_type_function_type_id::<TypeFunctionTableType>(self_ty);
29 if tftt.is_null() {
30 lua_l_error_l(
31 vm_l,
32 c"%s".as_ptr(),
33 core::format_args!(
34 "type.setwriteproperty: expected self to be a table, but got {} instead",
35 get_tag(l, self_ty)
36 ),
37 );
38 }
39
40 if luaur_common::FFlag::LuauTypeFunctionSupportsFrozen.get() && (*self_ty).frozen {
41 lua_l_error_l(
42 vm_l,
43 c"%s".as_ptr(),
44 core::format_args!(
45 "type.setwriteproperty: cannot be called to mutate a frozen type, use `types.copy` to make a copy"
46 ),
47 );
48 }
49
50 let key = get_type_user_data(l, 2);
51 let tfst = get_type_function_type_id::<TypeFunctionSingletonType>(key);
52 if tfst.is_null() {
53 lua_l_error_l(
54 vm_l,
55 c"%s".as_ptr(),
56 core::format_args!(
57 "type.setwriteproperty: expected to be given a singleton type, but got {} instead",
58 get_tag(l, key)
59 ),
60 );
61 }
62
63 let tfsst = (*tfst).variant.get_if_1();
64 if tfsst.is_none() {
65 lua_l_error_l(
66 vm_l,
67 c"%s".as_ptr(),
68 core::format_args!(
69 "type.setwriteproperty: expected to be given a string singleton type, but got {} instead",
70 get_tag(l, key)
71 ),
72 );
73 }
74
75 let key_name = tfsst.unwrap().value.clone();
76
77 if argument_count == 2 || lua_isnil!(vm_l, 3) {
78 if let Some(existing) = (*tftt).props.get(&key_name) {
79 if existing.is_write_only() {
80 (*tftt).props.remove(&key_name);
81 } else if let Some(prop) = (*tftt).props.get_mut(&key_name) {
82 prop.write_ty = None;
83 }
84 }
85
86 return 0;
87 }
88
89 let value = get_type_user_data(l, 3);
90 if let Some(prop) = (*tftt).props.get_mut(&key_name) {
91 prop.write_ty = Some(value);
92 } else {
93 (*tftt)
94 .props
95 .insert(key_name, TypeFunctionProperty::writeonly(value));
96 }
97
98 0
99}