1+ use std:: process:: id;
2+
13use crate :: {
24 ps:: {
35 LoopStatus :: { Dead , Inifite , OneTurn } ,
@@ -128,18 +130,23 @@ impl<'a> RuleMut<'a> for ForStatementCondition {
128130/// ```
129131#[ derive( Default ) ]
130132pub struct ForStatementFlowControl {
131- statment_count : u32 ,
132133 iterators : Vec < IteratorVariable > ,
134+ loop_id : Option < usize > ,
135+ statment_count : u32 ,
133136}
134137
135138impl < ' a > RuleMut < ' a > for ForStatementFlowControl {
136139 type Language = Powershell ;
137140
138141 fn enter (
139142 & mut self ,
140- _node : & mut crate :: tree:: NodeMut < ' a , Self :: Language > ,
143+ node : & mut crate :: tree:: NodeMut < ' a , Self :: Language > ,
141144 _flow : crate :: tree:: ControlFlow ,
142145 ) -> crate :: error:: MinusOneResult < ( ) > {
146+ if matches ! ( node. view( ) . kind( ) , "while_statement" | "for_statement" ) {
147+ self . loop_id = Some ( node. id ( ) ) ;
148+ }
149+
143150 Ok ( ( ) )
144151 }
145152
@@ -150,6 +157,11 @@ impl<'a> RuleMut<'a> for ForStatementFlowControl {
150157 ) -> crate :: error:: MinusOneResult < ( ) > {
151158 let view = node. view ( ) ;
152159 match view. kind ( ) {
160+ "for_statement" | "while_statement" if self . loop_id == Some ( view. id ( ) ) => {
161+ self . loop_id = None ;
162+ self . iterators . clear ( ) ;
163+ self . statment_count = 0 ;
164+ }
153165 // Track control flow statments
154166 "flow_control_statement" => {
155167 // TODO: Review control flow count if we are in imbricated loops
@@ -179,7 +191,6 @@ impl<'a> RuleMut<'a> for ForStatementFlowControl {
179191 }
180192 }
181193 }
182-
183194 "variable" => {
184195 if let Some ( iterator_variable) = self
185196 . iterators
@@ -189,23 +200,21 @@ impl<'a> RuleMut<'a> for ForStatementFlowControl {
189200 iterator_variable. references . push ( node. id ( ) ) ;
190201 }
191202 }
192- "for_statement " => {
193- if view. data ( ) . is_none ( ) && self . statment_count == 1 {
194- if let Some ( statement_list ) = view
195- . child ( 8 )
196- . filter ( |n| n . kind ( ) == "statement_block" )
197- . and_then ( |n| n . named_child ( "statement_list" ) )
198- {
203+ "statement_block " => {
204+ let parent = view. parent ( ) . unwrap ( ) ;
205+ if matches ! ( parent . kind ( ) , "while_statement" | "for_statement" )
206+ && parent . data ( ) . is_none ( )
207+ && self . statment_count == 1
208+ {
209+ if let Some ( statement_list ) = view . named_child ( "statement_list" ) {
199210 let mut iter = statement_list
200211 . iter ( )
201212 . skip_while ( |n| n. kind ( ) != "flow_control_statement" ) ;
202213
203214 match iter. next ( ) . map ( |n| n. smallest_child ( ) . kind ( ) ) {
204215 Some ( "break" | "return" | "exit" | "throw" ) => {
205- node. set ( Loop ( OneTurn ) ) ;
216+ node. set_by_node_id ( parent . id ( ) , Loop ( OneTurn ) ) ;
206217
207- // TODO: What if we set the node but it was after the break and was Some(Null)
208- // ex: for ($i = 0; $true;) {$i; break; $i} should give "0" but gives "0\n0" currently
209218 self . iterators . iter ( ) . for_each ( |it| {
210219 it. references . iter ( ) . for_each ( |& id| {
211220 node. set_by_node_id ( id, Powershell :: Raw ( it. value . clone ( ) ) )
0 commit comments