luaur_analysis/functions/
get_metatable_documentation.rs1use 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 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 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}