Skip to main content

luaur_compiler/records/
function_visitor.rs

1use luaur_ast::records::ast_expr_function::AstExprFunction;
2use luaur_ast::records::ast_visitor::AstVisitor;
3
4#[derive(Debug)]
5pub struct FunctionVisitor<'a> {
6    pub(crate) functions: &'a mut Vec<*mut AstExprFunction>,
7    pub(crate) has_types: bool,
8    pub(crate) has_native_function: bool,
9}
10
11impl<'a> FunctionVisitor<'a> {
12    pub fn new(functions: &'a mut Vec<*mut AstExprFunction>) -> Self {
13        functions.reserve(16);
14        Self {
15            functions,
16            has_types: false,
17            has_native_function: false,
18        }
19    }
20}
21
22impl<'a> AstVisitor for FunctionVisitor<'a> {
23    fn visit_expr_function(&mut self, node: *mut core::ffi::c_void) -> bool {
24        let node = node as *mut AstExprFunction;
25        let node_ref = unsafe { &*node };
26
27        unsafe {
28            luaur_ast::visit::ast_stat_visit(
29                node_ref.body as *mut luaur_ast::records::ast_stat::AstStat,
30                self,
31            );
32        }
33
34        for arg_ptr in node_ref.args.iter() {
35            let arg = unsafe { &**arg_ptr };
36            self.has_types |= !arg.annotation.is_null();
37        }
38
39        // this makes sure all functions that are used when compiling this one have been already added to the vector
40        luaur_common::LUAU_ASSERT!(self.functions.iter().all(|&f| f != node));
41        self.functions.push(node);
42
43        if !self.has_native_function && node_ref.has_native_attribute() {
44            self.has_native_function = true;
45        }
46
47        false
48    }
49
50    fn visit_stat_type_function(&mut self, _node: *mut core::ffi::c_void) -> bool {
51        false
52    }
53}