luaur_analysis/methods/
lint_unbalanced_assignment_assign.rs1use crate::records::lint_unbalanced_assignment::LintUnbalancedAssignment;
2use luaur_ast::records::ast_array::AstArray;
3use luaur_ast::records::ast_expr::AstExpr;
4use luaur_ast::records::ast_expr_call::AstExprCall;
5use luaur_ast::records::ast_expr_constant_nil::AstExprConstantNil;
6use luaur_ast::records::ast_expr_varargs::AstExprVarargs;
7use luaur_ast::records::ast_node::AstNode;
8use luaur_ast::records::ast_stat_assign::AstStatAssign;
9use luaur_ast::records::ast_stat_local::AstStatLocal;
10use luaur_ast::records::location::Location;
11use luaur_ast::rtti::ast_node_as;
12use luaur_config::enums::code::Code;
13
14impl LintUnbalancedAssignment {
15 pub fn assign(&mut self, vars: usize, values: &AstArray<*mut AstExpr>, location: Location) {
16 if vars != values.size && values.size > 0 {
17 let last = unsafe { *values.data.add(values.size - 1) };
18
19 if vars < values.size {
20 let msg = format!(
21 "Assigning {} values to {} variables leaves some values unused",
22 values.size, vars
23 );
24 crate::functions::emit_warning::emit_warning(
25 unsafe { &mut *self.context },
26 Code::Code_UnbalancedAssignment,
27 location,
28 format_args!("{}", msg),
29 );
30 } else if !unsafe { ast_node_as::<AstExprCall>(last as *mut AstNode) }.is_null()
31 || !unsafe { ast_node_as::<AstExprVarargs>(last as *mut AstNode) }.is_null()
32 || !unsafe { ast_node_as::<AstExprConstantNil>(last as *mut AstNode) }.is_null()
33 {
34 } else {
37 let msg = format!(
38 "Assigning {} values to {} variables initializes extra variables with nil; add 'nil' to value list to silence",
39 values.size, vars
40 );
41 crate::functions::emit_warning::emit_warning(
42 unsafe { &mut *self.context },
43 Code::Code_UnbalancedAssignment,
44 location,
45 format_args!("{}", msg),
46 );
47 }
48 }
49 }
50
51 pub fn visit_stat_local(&mut self, node: *mut core::ffi::c_void) -> bool {
52 let node = node as *mut AstStatLocal;
53 unsafe {
54 self.assign(
55 (*node).vars.size,
56 &(*node).values,
57 (*node).base.base.location,
58 );
59 }
60
61 true
62 }
63
64 pub fn visit_stat_assign(&mut self, node: *mut core::ffi::c_void) -> bool {
65 let node = node as *mut AstStatAssign;
66 unsafe {
67 self.assign(
68 (*node).vars.size,
69 &(*node).values,
70 (*node).base.base.location,
71 );
72 }
73
74 true
75 }
76}