luaur_analysis/functions/
extract_stat.rs1extern crate alloc;
2
3use crate::functions::is_identifier::is_identifier;
4use alloc::vec::Vec;
5use luaur_ast::records::ast_node::AstNode;
6use luaur_ast::records::ast_stat_block::AstStatBlock;
7use luaur_ast::records::ast_stat_error::AstStatError;
8use luaur_ast::rtti::AstNodeClass;
9
10pub fn extract_stat<T: AstNodeClass>(ancestry: &Vec<*mut AstNode>) -> *mut T {
11 let node = if ancestry.len() >= 1 {
12 ancestry[ancestry.len() - 1]
13 } else {
14 core::ptr::null_mut()
15 };
16
17 if node.is_null() {
18 return core::ptr::null_mut();
19 }
20
21 let t = unsafe { (*node).as_item_mut::<T>() };
22 if !t.is_null() {
23 return t;
24 }
25
26 let parent = if ancestry.len() >= 2 {
27 ancestry[ancestry.len() - 2]
28 } else {
29 core::ptr::null_mut()
30 };
31
32 if parent.is_null() {
33 return core::ptr::null_mut();
34 }
35
36 let grand_parent = if ancestry.len() >= 3 {
37 ancestry[ancestry.len() - 3]
38 } else {
39 core::ptr::null_mut()
40 };
41
42 let great_grand_parent = if ancestry.len() >= 4 {
43 ancestry[ancestry.len() - 4]
44 } else {
45 core::ptr::null_mut()
46 };
47
48 if grand_parent.is_null() {
49 return core::ptr::null_mut();
50 }
51
52 let t_parent = unsafe { (*parent).as_item_mut::<T>() };
53 if !t_parent.is_null() && unsafe { (*grand_parent).is::<AstStatBlock>() } {
54 return t_parent;
55 }
56
57 if great_grand_parent.is_null() {
58 return core::ptr::null_mut();
59 }
60
61 let t_great = unsafe { (*great_grand_parent).as_item_mut::<T>() };
62 if !t_great.is_null()
63 && unsafe { (*grand_parent).is::<AstStatBlock>() }
64 && unsafe { (*parent).is::<AstStatError>() }
65 && is_identifier(node)
66 {
67 return t_great;
68 }
69
70 core::ptr::null_mut()
71}