Skip to main content

luaur_analysis/functions/
extract_stat.rs

1extern 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}