File tree Expand file tree Collapse file tree 2 files changed +48
-6
lines changed
crates/emmylua_code_analysis/src Expand file tree Collapse file tree 2 files changed +48
-6
lines changed Original file line number Diff line number Diff line change @@ -50,4 +50,22 @@ mod test {
5050 let t_expected = ws. ty ( "integer[]" ) ;
5151 assert_eq ! ( t, t_expected)
5252 }
53+
54+ #[ test]
55+ fn test_array_for_flow ( ) {
56+ let mut ws = VirtualWorkspace :: new ( ) ;
57+ assert ! ( ws. check_code_for(
58+ DiagnosticCode :: NeedCheckNil ,
59+ r#"
60+ --- @param _x string
61+ local function foo(_x) end
62+
63+ local list = {} --- @type string[]
64+
65+ for i = #list, 1, -1 do
66+ foo(list[i])
67+ end
68+ "# ,
69+ ) ) ;
70+ }
5371}
Original file line number Diff line number Diff line change @@ -285,18 +285,42 @@ fn check_iter_var_range(
285285 let token = decl_syntax_id. to_token_from_root ( & root) ?;
286286 let parent_node = token. parent ( ) ?;
287287 let for_stat = LuaForStat :: cast ( parent_node) ?;
288- // get second expr
289- let test_len_expr = for_stat. get_iter_expr ( ) . skip ( 1 ) . next ( ) ?;
290- let LuaExpr :: UnaryExpr ( unary_expr) = test_len_expr else {
291- return None ;
288+ let iter_exprs = for_stat. get_iter_expr ( ) . collect :: < Vec < _ > > ( ) ;
289+ let test_len_expr = match iter_exprs. len ( ) {
290+ 2 => {
291+ let LuaExpr :: UnaryExpr ( unary_expr) = iter_exprs[ 1 ] . clone ( ) else {
292+ return None ;
293+ } ;
294+ unary_expr
295+ }
296+ 3 => {
297+ let step_type = infer_expr ( db, cache, iter_exprs[ 2 ] . clone ( ) ) . ok ( ) ?;
298+ let LuaType :: IntegerConst ( step_value) = step_type else {
299+ return None ;
300+ } ;
301+ if step_value > 0 {
302+ let LuaExpr :: UnaryExpr ( unary_expr) = iter_exprs[ 1 ] . clone ( ) else {
303+ return None ;
304+ } ;
305+ unary_expr
306+ } else if step_value < 0 {
307+ let LuaExpr :: UnaryExpr ( unary_expr) = iter_exprs[ 0 ] . clone ( ) else {
308+ return None ;
309+ } ;
310+ unary_expr
311+ } else {
312+ return None ;
313+ }
314+ }
315+ _ => return None ,
292316 } ;
293317
294- let op = unary_expr . get_op_token ( ) ?;
318+ let op = test_len_expr . get_op_token ( ) ?;
295319 if op. get_op ( ) != UnaryOperator :: OpLen {
296320 return None ;
297321 }
298322
299- let len_expr = unary_expr . get_expr ( ) ?;
323+ let len_expr = test_len_expr . get_expr ( ) ?;
300324 let len_expr_var_ref_id = get_var_expr_var_ref_id ( db, cache, len_expr) ?;
301325 let prefix_expr_var_ref_id = get_var_expr_var_ref_id ( db, cache, prefix_expr) ?;
302326
You can’t perform that action at this time.
0 commit comments