11use emmylua_parser:: {
2- LuaAssignStat , LuaAst , LuaAstNode , LuaCallExprStat , LuaLabelStat , LuaLocalStat , LuaVarExpr , PathTrait
2+ LuaAssignStat , LuaAst , LuaAstNode , LuaBreakStat , LuaCallExprStat , LuaDoStat , LuaGotoStat , LuaIfStat , LuaLabelStat , LuaLocalStat , LuaRepeatStat , LuaVarExpr , LuaWhileStat , PathTrait
33} ;
44
55use crate :: {
66 compilation:: analyzer:: flow:: {
7- bind_analyze:: { bind_each_child, exprs:: bind_condition_expr} ,
7+ bind_analyze:: { bind_block , bind_each_child, exprs:: { bind_condition_expr, bind_expr } } ,
88 binder:: FlowBinder ,
9- flow_node:: { FlowNodeType , LuaFlowAssignment } ,
9+ flow_node:: { FlowAssignment , FlowNodeKind } ,
1010 } ,
11- LuaDeclId , LuaVarRefId ,
11+ LuaClosureId , LuaDeclId , LuaVarRefId ,
1212} ;
1313
1414pub fn bind_local_stat ( binder : & mut FlowBinder , local_stat : LuaLocalStat ) -> Option < ( ) > {
@@ -53,16 +53,14 @@ pub fn bind_assign_stat(binder: &mut FlowBinder, assign_stat: LuaAssignStat) ->
5353
5454 if let Some ( var_ref_id) = get_var_ref_id ( binder, var. clone ( ) ) {
5555 // Create a flow node for the assignment
56- let flow_id = binder. create_node (
57- FlowNodeType :: Assignment (
58- LuaFlowAssignment {
59- var_ref_id,
60- expr,
61- idx : idx as u32 ,
62- }
63- . into ( ) ,
64- ) ,
65- ) ;
56+ let flow_id = binder. create_node ( FlowNodeKind :: Assignment (
57+ FlowAssignment {
58+ var_ref_id,
59+ expr,
60+ idx : idx as u32 ,
61+ }
62+ . into ( ) ,
63+ ) ) ;
6664
6765 binder. add_antecedent ( flow_id, binder. current ) ;
6866 binder. current = flow_id;
@@ -114,8 +112,157 @@ pub fn bind_call_expr_stat(binder: &mut FlowBinder, call_expr_stat: LuaCallExprS
114112pub fn bind_label_stat ( binder : & mut FlowBinder , label_stat : LuaLabelStat ) -> Option < ( ) > {
115113 let label_name_token = label_stat. get_label_name_token ( ) ?;
116114 let label_name = label_name_token. get_name_text ( ) ;
117-
115+ let closure_id = LuaClosureId :: from_node ( label_stat. syntax ( ) ) ;
116+ let name_label = binder. create_name_label ( label_name, closure_id) ;
117+ binder. add_antecedent ( name_label, binder. current ) ;
118+ binder. current = name_label;
119+
120+ Some ( ( ) )
121+ }
122+
123+ pub fn bind_break_stat ( binder : & mut FlowBinder , break_stat : LuaBreakStat ) -> Option < ( ) > {
124+ // let
125+ // binder.add_antecedent(loop_label, current);
126+ // binder.current = loop_label;
127+
128+ Some ( ( ) )
129+ }
130+
131+ pub fn bind_goto_stat ( binder : & mut FlowBinder , goto_stat : LuaGotoStat ) -> Option < ( ) > {
132+ // Goto statements are handled separately in the flow analysis
133+ // They will be processed when we analyze the labels
134+ // For now, we just return None to indicate no flow node is created
135+ let closure_id = LuaClosureId :: from_node ( goto_stat. syntax ( ) ) ;
136+ binder. add_goto_stat ( goto_stat, closure_id) ;
137+
138+ Some ( ( ) )
139+ }
140+
141+ pub fn bind_do_stat ( binder : & mut FlowBinder , do_stat : LuaDoStat ) -> Option < ( ) > {
142+ // Do statements are typically used for blocks of code
143+ // We can treat them as a block and bind their contents
144+ bind_each_child ( binder, LuaAst :: cast ( do_stat. syntax ( ) . clone ( ) ) ?) ;
145+
146+ Some ( ( ) )
147+ }
148+
149+ pub fn bind_while_stat ( binder : & mut FlowBinder , while_stat : LuaWhileStat ) -> Option < ( ) > {
150+ // While statements are typically used for loops
151+ // We can treat them as a loop and bind their contents
152+ // For now, we just return None to indicate no flow node is created
153+ let current = binder. current ;
154+ let old_loop_label = binder. loop_label ;
155+ let loop_label = binder. create_loop_label ( ) ;
156+ binder. add_antecedent ( loop_label, current) ;
157+
158+ binder. loop_label = loop_label;
159+ binder. current = loop_label;
160+ let condition_expr = while_stat. get_condition_expr ( ) ?;
161+ if let Some ( condition_flow_id) = bind_condition_expr ( binder, condition_expr) {
162+ binder. add_antecedent ( condition_flow_id, loop_label) ;
163+ binder. current = condition_flow_id;
164+ binder. loop_label = loop_label;
165+ } else {
166+ binder. current = loop_label;
167+ binder. loop_label = current;
168+ }
118169
170+ if let Some ( while_block) = while_stat. get_block ( ) {
171+ bind_block ( binder, while_block) ;
172+ }
173+
174+ binder. current = current;
175+ binder. loop_label = old_loop_label;
119176
177+ Some ( ( ) )
178+ }
179+
180+
181+ pub fn bind_repeat_stat ( binder : & mut FlowBinder , repeat_stat : LuaRepeatStat ) -> Option < ( ) > {
182+ let current = binder. current ;
183+ let old_loop_label = binder. loop_label ;
184+
185+ // Create a loop label for the repeat statement
186+ let loop_label = binder. create_loop_label ( ) ;
187+ binder. add_antecedent ( loop_label, current) ;
188+
189+ binder. loop_label = loop_label;
190+ binder. current = loop_label;
191+
192+ // Bind the block first (repeat-until executes the block at least once)
193+ if let Some ( repeat_block) = repeat_stat. get_block ( ) {
194+ bind_block ( binder, repeat_block) ;
195+ }
196+
197+ let current = binder. current ;
198+ bind_expr ( binder, repeat_stat. get_condition_expr ( ) ?) ;
199+
200+ // Restore previous state
201+ binder. current = current;
202+ binder. loop_label = old_loop_label;
203+
204+ Some ( ( ) )
205+ }
206+
207+ pub fn bind_if_stat ( binder : & mut FlowBinder , if_stat : LuaIfStat ) -> Option < ( ) > {
208+ // let current = binder.current;
209+ // let mut branch_endings = Vec::new();
210+
211+ // // Process the main if condition
212+ // let condition = if_stat.get_condition_expr()?;
213+ // if let Some(condition_flow_id) = bind_condition_expr(binder, condition) {
214+ // binder.add_antecedent(condition_flow_id, current);
215+ // binder.current = condition_flow_id;
216+ // } else {
217+ // binder.current = current;
218+ // }
219+
220+ // // Process the if block (true branch)
221+ // if let Some(if_block) = if_stat.get_block() {
222+ // bind_block(binder, if_block);
223+ // branch_endings.push(binder.current);
224+ // }
225+
226+ // // Process elseif clauses
227+ // for elseif_clause in if_stat.get_else_if_clause_list() {
228+ // binder.current = current; // Reset to the beginning for each elseif
229+
230+ // if let Some(elseif_condition) = elseif_clause.get_condition_expr() {
231+ // if let Some(condition_flow_id) = bind_condition_expr(binder, elseif_condition) {
232+ // binder.add_antecedent(condition_flow_id, current);
233+ // binder.current = condition_flow_id;
234+ // }
235+ // }
236+
237+ // if let Some(elseif_block) = elseif_clause.get_block() {
238+ // bind_block(binder, elseif_block);
239+ // branch_endings.push(binder.current);
240+ // }
241+ // }
242+
243+ // // Process else clause if it exists
244+ // if let Some(else_clause) = if_stat.get_else_clause() {
245+ // binder.current = current; // Reset to the beginning for else
246+
247+ // if let Some(else_block) = else_clause.get_block() {
248+ // bind_block(binder, else_block);
249+ // branch_endings.push(binder.current);
250+ // }
251+ // } else {
252+ // // If there's no else clause, the original flow continues
253+ // branch_endings.push(current);
254+ // }
255+
256+ // // Create a branch label to merge all branches
257+ // if !branch_endings.is_empty() {
258+ // let branch_label = binder.create_branch_label();
259+ // for ending in branch_endings {
260+ // binder.add_antecedent(branch_label, ending);
261+ // }
262+ // binder.current = branch_label;
263+ // } else {
264+ // binder.current = current;
265+ // }
266+
120267 Some ( ( ) )
121268}
0 commit comments