Skip to main content

luaur_compiler/methods/
table_mutation_tracker_mark_escaped.rs

1use crate::records::table_mutation_tracker::TableMutationTracker;
2use luaur_ast::records::ast_expr::AstExpr;
3use luaur_ast::records::ast_expr_binary::{AstExprBinary, AstExprBinary_Op};
4use luaur_ast::records::ast_expr_group::AstExprGroup;
5use luaur_ast::records::ast_expr_if_else::AstExprIfElse;
6use luaur_ast::records::ast_expr_instantiate::AstExprInstantiate;
7use luaur_ast::records::ast_expr_local::AstExprLocal;
8use luaur_ast::records::ast_expr_type_assertion::AstExprTypeAssertion;
9use luaur_ast::records::ast_node::AstNode;
10use luaur_ast::rtti::{ast_node_as, ast_node_is};
11
12impl<'a> TableMutationTracker<'a> {
13    #[allow(non_snake_case)]
14    pub fn mark_escaped_impl(&mut self, mut expr: *mut AstExpr) {
15        loop {
16            if expr.is_null() {
17                return;
18            }
19
20            let expr_ptr = expr as *mut AstNode;
21
22            let expr_local = unsafe { ast_node_as::<AstExprLocal>(expr_ptr) };
23            if !expr_local.is_null() {
24                unsafe {
25                    self.escaped.insert((*expr_local).local);
26                }
27                return;
28            }
29
30            let expr_group = unsafe { ast_node_as::<AstExprGroup>(expr_ptr) };
31            if !expr_group.is_null() {
32                expr = unsafe { (*expr_group).expr };
33                continue;
34            }
35
36            let expr_assertion = unsafe { ast_node_as::<AstExprTypeAssertion>(expr_ptr) };
37            if !expr_assertion.is_null() {
38                expr = unsafe { (*expr_assertion).expr };
39                continue;
40            }
41
42            let expr_instantiate = unsafe { ast_node_as::<AstExprInstantiate>(expr_ptr) };
43            if !expr_instantiate.is_null() {
44                expr = unsafe { (*expr_instantiate).expr };
45                continue;
46            }
47
48            let expr_if_else = unsafe { ast_node_as::<AstExprIfElse>(expr_ptr) };
49            if !expr_if_else.is_null() {
50                self.mark_escaped_impl(unsafe { (*expr_if_else).true_expr });
51                expr = unsafe { (*expr_if_else).false_expr };
52                continue;
53            }
54
55            let bin_expr = unsafe { ast_node_as::<AstExprBinary>(expr_ptr) };
56            if !bin_expr.is_null() {
57                let op = unsafe { (*bin_expr).op };
58                if op == AstExprBinary_Op::And || op == AstExprBinary_Op::Or {
59                    self.mark_escaped_impl(unsafe { (*bin_expr).left });
60                    expr = unsafe { (*bin_expr).right };
61                    continue;
62                } else {
63                    return;
64                }
65            }
66
67            return;
68        }
69    }
70}
71
72#[allow(non_snake_case)]
73pub fn table_mutation_tracker_mark_escaped(tracker: &mut TableMutationTracker, expr: *mut AstExpr) {
74    tracker.mark_escaped_impl(expr);
75}