Skip to main content

luaur_analysis/functions/
get_metatable_documentation.rs

1use crate::functions::check_overloaded_documentation_symbol::check_overloaded_documentation_symbol;
2use crate::functions::follow_type::follow_type_id;
3use crate::functions::get_type_alt_j::get_type_id;
4use crate::records::module::Module;
5use crate::records::table_type::TableType;
6use crate::type_aliases::documentation_symbol::DocumentationSymbol;
7use crate::type_aliases::type_id::TypeId;
8use luaur_ast::records::ast_expr::AstExpr;
9use luaur_ast::records::ast_name::AstName;
10
11pub fn get_metatable_documentation(
12    module: &Module,
13    parent_expr: *const AstExpr,
14    mtable: &TableType,
15    index: &AstName,
16) -> Option<DocumentationSymbol> {
17    // C++: auto indexIt = mtable->props.find("__index");
18    let index_prop = mtable.props.get("__index")?;
19
20    let followed = if let Some(read_ty) = index_prop.read_ty {
21        unsafe { follow_type_id(read_ty) }
22    } else if let Some(write_ty) = index_prop.write_ty {
23        unsafe { follow_type_id(write_ty) }
24    } else {
25        return None;
26    };
27
28    let ttv_ptr = unsafe { get_type_id::<TableType>(followed) };
29    if ttv_ptr.is_null() {
30        return None;
31    }
32
33    let ttv = unsafe { &*ttv_ptr };
34    // C++: auto propIt = ttv->props.find(index.value); — props keyed by std::string.
35    let index_key = unsafe {
36        core::ffi::CStr::from_ptr(index.value)
37            .to_string_lossy()
38            .into_owned()
39    };
40    let prop = ttv.props.get(&index_key)?;
41
42    if let Some(ty) = prop.read_ty {
43        return check_overloaded_documentation_symbol(
44            module,
45            ty,
46            parent_expr,
47            prop.documentation_symbol.clone(),
48        );
49    }
50
51    None
52}