Skip to main content

luaur_analysis/methods/
data_flow_graph_builder_visit_function.rs

1use crate::records::data_flow_graph_builder::DataFlowGraphBuilder;
2use crate::records::data_flow_result::DataFlowResult;
3use crate::records::symbol::Symbol;
4use luaur_ast::records::ast_expr_function::AstExprFunction;
5use luaur_ast::records::ast_local::AstLocal;
6use luaur_common::macros::luau_assert::LUAU_ASSERT;
7
8impl DataFlowGraphBuilder {
9    pub fn visit_function(
10        &mut self,
11        f: *mut AstExprFunction,
12        signature_scope: *mut crate::records::dfg_scope::DfgScope,
13    ) -> DataFlowResult {
14        unsafe {
15            let f_ref = &*f;
16
17            let self_local = f_ref.self_;
18            if !self_local.is_null() {
19                let self_local_ref = &*self_local;
20                // There's no syntax for `self` to have an annotation if using `function t:m()`
21                LUAU_ASSERT!(self_local_ref.annotation.is_null());
22
23                let symbol = Symbol::from_local(self_local);
24                let def = (*self.def_arena).fresh_cell(
25                    Symbol::from_global(f_ref.debugname),
26                    f_ref.base.base.location,
27                    false,
28                );
29                *self.graph.local_defs.get_or_insert(self_local as *const _) = def;
30                *(*signature_scope).bindings.get_or_insert(symbol.clone()) = def;
31                self.captures.get_or_insert(symbol).all_versions.push(def);
32            }
33
34            for i in 0..f_ref.args.size {
35                let param_ptr = *f_ref.args.data.add(i) as *mut AstLocal;
36                if param_ptr.is_null() {
37                    continue;
38                }
39
40                let param = &*param_ptr;
41                if !param.annotation.is_null() {
42                    self.visit_type_ast_type(param.annotation);
43                }
44
45                let symbol = Symbol::from_local(param_ptr);
46                let def = (*self.def_arena).fresh_cell(symbol.clone(), param.location, false);
47                *self.graph.local_defs.get_or_insert(param_ptr as *const _) = def;
48                *(*signature_scope).bindings.get_or_insert(symbol.clone()) = def;
49                self.captures.get_or_insert(symbol).all_versions.push(def);
50            }
51
52            if !f_ref.vararg_annotation.is_null() {
53                self.visit_type_pack_ast_type_pack(f_ref.vararg_annotation);
54            }
55
56            if !f_ref.return_annotation.is_null() {
57                self.visit_type_pack_ast_type_pack(f_ref.return_annotation);
58            }
59
60            self.visit_ast_stat_block(f_ref.body);
61
62            DataFlowResult {
63                def: (*self.def_arena).fresh_cell(
64                    Symbol::from_global(f_ref.debugname),
65                    f_ref.base.base.location,
66                    false,
67                ) as *const core::ffi::c_void,
68                parent: core::ptr::null(),
69            }
70        }
71    }
72}