Skip to content

Commit 9e59644

Browse files
committed
update for stat analyze
1 parent 0c31378 commit 9e59644

File tree

1 file changed

+69
-12
lines changed
  • crates/emmylua_code_analysis/src/compilation/analyzer/flow/bind_analyze

1 file changed

+69
-12
lines changed

crates/emmylua_code_analysis/src/compilation/analyzer/flow/bind_analyze/stats.rs

Lines changed: 69 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
use emmylua_parser::{
2-
LuaAssignStat, LuaAst, LuaAstNode, LuaBreakStat, LuaCallExprStat, LuaDoStat, LuaForRangeStat,
3-
LuaFuncStat, LuaGotoStat, LuaIfStat, LuaLabelStat, LuaLocalStat, LuaRepeatStat, LuaReturnStat,
4-
LuaVarExpr, LuaWhileStat, PathTrait,
2+
LuaAssignStat, LuaAst, LuaAstNode, LuaBreakStat, LuaCallExprStat, LuaDoStat, LuaExpr, LuaForRangeStat, LuaForStat, LuaFuncStat, LuaGotoStat, LuaIfStat, LuaLabelStat, LuaLocalStat, LuaRepeatStat, LuaReturnStat, LuaUnaryExpr, LuaVarExpr, LuaWhileStat, PathTrait, UnaryOperator
53
};
64

75
use crate::{
86
compilation::analyzer::flow::{
97
bind_analyze::{bind_block, bind_each_child, exprs::bind_expr},
108
binder::FlowBinder,
11-
flow_node::{FlowAssignment, FlowId, FlowNodeKind},
9+
flow_node::{FlowAssertion, FlowAssignment, FlowId, FlowNodeKind},
1210
},
1311
LuaClosureId, LuaDeclId, LuaVarRefId,
1412
};
@@ -331,16 +329,75 @@ pub fn bind_for_range_stat(
331329
for_range_stat: LuaForRangeStat,
332330
current: FlowId,
333331
) -> FlowId {
334-
bind_each_child(binder, LuaAst::LuaForRangeStat(for_range_stat), current);
332+
let loop_label = binder.create_loop_label();
333+
binder.add_antecedent(loop_label, current);
334+
let old_loop_label = binder.loop_label;
335+
binder.loop_label = loop_label;
336+
bind_each_child(binder, LuaAst::LuaForRangeStat(for_range_stat), loop_label);
337+
binder.loop_label = old_loop_label;
335338
current
336339
}
337340

338-
pub fn bind_for_stat(
339-
binder: &mut FlowBinder,
340-
_for_stat: emmylua_parser::LuaForStat,
341-
current: FlowId,
342-
) -> FlowId {
343-
// For loops are not yet implemented
344-
// For now, we just return the current flow
341+
pub fn bind_for_stat(binder: &mut FlowBinder, for_stat: LuaForStat, current: FlowId) -> FlowId {
342+
let loop_label = binder.create_loop_label();
343+
binder.add_antecedent(loop_label, current);
344+
let old_loop_label = binder.loop_label;
345+
binder.loop_label = loop_label;
346+
347+
let Some(var_name_token) = for_stat.get_var_name() else {
348+
binder.loop_label = old_loop_label;
349+
return current;
350+
};
351+
352+
let var_name = var_name_token.get_name_text();
353+
let var_list = for_stat.get_iter_expr().collect::<Vec<_>>();
354+
for expr in &var_list {
355+
bind_expr(binder, expr.clone(), loop_label);
356+
}
357+
358+
if var_list.len() < 2 {
359+
binder.loop_label = old_loop_label;
360+
return current;
361+
}
362+
363+
let mut parent_flow_id = loop_label;
364+
let second_expr = var_list[1].clone();
365+
if let LuaExpr::UnaryExpr(unary_expr) = second_expr {
366+
if let Some(length_var_name) = get_for_length_name(unary_expr) {
367+
let var_ref_id = LuaVarRefId::Name(format!("{}.[{}]", length_var_name, var_name).into());
368+
let flow_id = binder.create_node(FlowNodeKind::Assertion(
369+
FlowAssertion::Truthy(var_ref_id).into(),
370+
));
371+
binder.add_antecedent(flow_id, loop_label);
372+
parent_flow_id = flow_id;
373+
}
374+
}
375+
376+
if let Some(block) = for_stat.get_block() {
377+
bind_block(binder, block, parent_flow_id);
378+
}
379+
380+
binder.loop_label = old_loop_label;
345381
current
346382
}
383+
384+
fn get_for_length_name(unary_expr: LuaUnaryExpr) -> Option<String> {
385+
let op_token = unary_expr.get_op_token()?;
386+
if op_token.get_op() == UnaryOperator::OpLen {
387+
if let Some(inner) = unary_expr.get_expr() {
388+
match inner {
389+
LuaExpr::IndexExpr(index_expr) => {
390+
if let Some(access_path) = index_expr.get_access_path() {
391+
return Some(access_path.into());
392+
}
393+
}
394+
LuaExpr::NameExpr(name_expr) => {
395+
return Some(name_expr.get_name_text()?);
396+
}
397+
_ => {}
398+
}
399+
}
400+
}
401+
402+
None
403+
}

0 commit comments

Comments
 (0)