Skip to main content

luaur_analysis/methods/
data_flow_graph_builder_lookup_data_flow_graph.rs

1use crate::records::data_flow_graph_builder::DataFlowGraphBuilder;
2use crate::records::dfg_scope::DfgScope;
3use crate::records::symbol::Symbol;
4use crate::type_aliases::def_id_def::DefId;
5use luaur_ast::records::location::Location;
6
7impl DataFlowGraphBuilder {
8    pub fn lookup_symbol_location(&mut self, symbol: Symbol, location: Location) -> DefId {
9        let scope = self.current_scope();
10
11        let mut outside_loop_scope = false;
12        let mut current: *mut DfgScope = scope;
13        while !current.is_null() {
14            unsafe {
15                outside_loop_scope = outside_loop_scope
16                    || (*current).scope_type == crate::enums::scope_type::ScopeType::Loop;
17
18                if let Some(found) = (*current).bindings.find(&symbol) {
19                    return *found;
20                } else if (*current).scope_type == crate::enums::scope_type::ScopeType::Function {
21                    let capture = self.captures.get_or_insert(symbol.clone());
22                    let capture_def = (*self.def_arena).phi_vector_def_id(&alloc::vec::Vec::new());
23                    capture.capture_defs.push(capture_def);
24
25                    if !outside_loop_scope {
26                        *(*scope).bindings.get_or_insert(symbol.clone()) = capture_def;
27                    }
28
29                    return capture_def;
30                }
31            }
32
33            unsafe {
34                current = (*current).parent;
35            }
36        }
37
38        unsafe {
39            let result = (*self.def_arena).fresh_cell(symbol.clone(), location, false);
40            *(*scope).bindings.get_or_insert(symbol.clone()) = result;
41            self.captures
42                .get_or_insert(symbol)
43                .all_versions
44                .push(result);
45            result
46        }
47    }
48}