Skip to main content

luaur_analysis/methods/
error_converter_find_call_metamethod.rs

1use crate::functions::follow_type::follow_type_id;
2use crate::functions::get_table_type::get_table_type;
3use crate::functions::get_type_alt_j::get_type_id;
4use crate::records::any_type::AnyType;
5use crate::records::error_converter::ErrorConverter;
6use crate::records::extern_type::ExternType;
7use crate::records::metatable_type::MetatableType;
8use crate::type_aliases::type_id::TypeId;
9
10impl ErrorConverter {
11    pub fn find_call_metamethod(&self, _type: TypeId) -> Option<TypeId> {
12        let type_ = unsafe { follow_type_id(_type) };
13
14        let mut metatable: Option<TypeId> = None;
15        let metatable_ptr = unsafe { get_type_id::<MetatableType>(type_) };
16        if !metatable_ptr.is_null() {
17            metatable = Some(unsafe { (*metatable_ptr).metatable });
18        } else {
19            let extern_ptr = unsafe { get_type_id::<ExternType>(type_) };
20            if !extern_ptr.is_null() {
21                metatable = unsafe { (*extern_ptr).metatable };
22            }
23        }
24
25        if metatable.is_none() {
26            return None;
27        }
28
29        let unwrapped = unsafe { follow_type_id(metatable.unwrap()) };
30
31        let any_ptr = unsafe { get_type_id::<AnyType>(unwrapped) };
32        if !any_ptr.is_null() {
33            return Some(unwrapped);
34        }
35
36        let mtt = get_table_type(unwrapped);
37        if mtt.is_none() {
38            return None;
39        }
40
41        let mtt = mtt.unwrap();
42        if let Some(prop) = mtt.props.get("__call") {
43            return prop.read_ty;
44        }
45
46        None
47    }
48}