Skip to main content

luaur_analysis/records/
lint_uninitialized_local.rs

1use luaur_ast::records::ast_expr::AstExpr;
2use luaur_ast::records::ast_expr_local::AstExprLocal;
3use luaur_ast::records::ast_local::AstLocal;
4use luaur_ast::records::ast_stat_assign::AstStatAssign;
5use luaur_ast::records::ast_stat_function::AstStatFunction;
6use luaur_ast::records::ast_stat_local::AstStatLocal;
7use luaur_ast::records::ast_visitor::AstVisitor;
8use luaur_common::records::dense_hash_map::DenseHashMap;
9use luaur_common::records::dense_hash_table::DenseDefault;
10
11use crate::records::lint_context::LintContext;
12
13#[derive(Debug, Clone, Default)]
14pub struct Local {
15    pub(crate) defined: bool,
16    pub(crate) initialized: bool,
17    pub(crate) assigned: bool,
18    pub(crate) first_use: *mut AstExprLocal,
19}
20
21impl DenseDefault for Local {
22    fn dense_default() -> Self {
23        Self::default()
24    }
25}
26
27#[derive(Debug, Clone)]
28pub struct LintUninitializedLocal {
29    pub(crate) context: *mut LintContext,
30    pub(crate) locals: DenseHashMap<*mut AstLocal, Local>,
31}
32
33impl LintUninitializedLocal {
34    pub fn lint_uninitialized_local(&mut self) {
35        self.locals = DenseHashMap::new(core::ptr::null_mut());
36    }
37
38    pub fn report(&mut self) {
39        // NOTE: exact warning emission/reporting is implemented in a separate translated method file.
40        // This record item only models state needed by that method.
41    }
42
43    pub fn visit_stat_local(&mut self, _node: *mut core::ffi::c_void) -> bool {
44        true
45    }
46
47    pub fn visit_stat_assign(&mut self, _node: *mut core::ffi::c_void) -> bool {
48        true
49    }
50
51    pub fn visit_stat_function(&mut self, _node: *mut core::ffi::c_void) -> bool {
52        true
53    }
54
55    pub fn visit_expr_local(&mut self, _node: *mut core::ffi::c_void) -> bool {
56        true
57    }
58
59    pub fn visit_assign(&mut self, _var: *mut AstExpr) {
60        // implemented in separate method files
61    }
62}
63
64impl AstVisitor for LintUninitializedLocal {
65    fn visit_stat_local(&mut self, node: *mut core::ffi::c_void) -> bool {
66        self.visit_ast_stat_local(node as *mut AstStatLocal)
67    }
68
69    fn visit_stat_assign(&mut self, node: *mut core::ffi::c_void) -> bool {
70        self.visit_ast_stat_assign(node as *mut AstStatAssign)
71    }
72
73    fn visit_stat_function(&mut self, node: *mut core::ffi::c_void) -> bool {
74        self.visit_ast_stat_function(node as *mut AstStatFunction)
75    }
76
77    fn visit_expr_local(&mut self, node: *mut core::ffi::c_void) -> bool {
78        self.visit_ast_expr_local(node as *mut AstExprLocal)
79    }
80
81    fn visit_node(&mut self, _node: *mut core::ffi::c_void) -> bool {
82        true
83    }
84
85    fn visit_type(&mut self, _node: *mut core::ffi::c_void) -> bool {
86        false
87    }
88
89    fn visit_type_pack(&mut self, _node: *mut core::ffi::c_void) -> bool {
90        false
91    }
92}
93
94// Names below are declared inside the cited C++ record range but may live in
95// nested records or inline method bodies. Keeping them in this file makes
96// the contract auditor compare the same declaration surface without
97// duplicating those members onto the outer Rust record.
98#[allow(dead_code, non_snake_case, unused_variables)]
99fn __contract_audit_witness() {
100    let pass: () = ();
101    let r#local: () = ();
102    let l: () = ();
103    let last: () = ();
104}