Skip to content

Commit 79f2db1

Browse files
committed
Ignore nested loops in OneTurn
1 parent 20f60f3 commit 79f2db1

File tree

2 files changed

+25
-10
lines changed

2 files changed

+25
-10
lines changed

src/ps/linter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ impl<'a> Rule<'a> for Linter {
229229
Some(&Powershell::Loop(LoopStatus::OneTurn)) => {
230230
if node.kind() == "statement_block" {
231231
self.statement_block_tab.pop();
232-
} else {
232+
} else if node.kind() != "for_initializer" {
233233
return Ok(false);
234234
}
235235
}

src/ps/loops.rs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::process::id;
2-
31
use crate::{
42
ps::{
53
LoopStatus::{Dead, Inifite, OneTurn},
@@ -107,6 +105,7 @@ impl<'a> RuleMut<'a> for ForStatementCondition {
107105
/// # Example
108106
/// ```
109107
/// use minusone::tree::{HashMapStorage, Tree};
108+
/// use minusone::engine::CleanEngine;
110109
/// use minusone::ps::build_powershell_tree;
111110
/// use minusone::ps::linter::Linter;
112111
/// use minusone::ps::forward::Forward;
@@ -125,8 +124,9 @@ impl<'a> RuleMut<'a> for ForStatementCondition {
125124
///
126125
/// let mut ps_litter_view = Linter::default();
127126
/// tree.apply(&mut ps_litter_view).unwrap();
127+
/// let clean = CleanEngine::from_powershell(&ps_litter_view.output).unwrap().clean().unwrap();
128128
///
129-
/// assert_eq!(ps_litter_view.output, "42");
129+
/// assert_eq!(clean.trim(), "42");
130130
/// ```
131131
#[derive(Default)]
132132
pub struct ForStatementFlowControl {
@@ -144,7 +144,14 @@ impl<'a> RuleMut<'a> for ForStatementFlowControl {
144144
_flow: crate::tree::ControlFlow,
145145
) -> crate::error::MinusOneResult<()> {
146146
if matches!(node.view().kind(), "while_statement" | "for_statement") {
147-
self.loop_id = Some(node.id());
147+
if self.loop_id.is_none() {
148+
self.loop_id = Some(node.id());
149+
} else {
150+
// We don't support nested loops
151+
self.loop_id = None;
152+
self.iterators.clear();
153+
self.statment_count = 0;
154+
}
148155
}
149156

150157
Ok(())
@@ -162,12 +169,14 @@ impl<'a> RuleMut<'a> for ForStatementFlowControl {
162169
self.iterators.clear();
163170
self.statment_count = 0;
164171
}
165-
// Track control flow statments
166172
"flow_control_statement" => {
167-
// TODO: Review control flow count if we are in imbricated loops
168-
self.statment_count += 1;
173+
// Update the statement count only if in followed loop
174+
// Skip in nested loops
175+
if self.loop_id.is_some() {
176+
self.statment_count += 1;
177+
}
169178

170-
// Infer dead code afer flow control in a loop
179+
// Infer dead code afer flow control in a loop, even in nested ones
171180
let following_children_ids: Vec<usize> = view
172181
.parent()
173182
.unwrap()
@@ -180,7 +189,12 @@ impl<'a> RuleMut<'a> for ForStatementFlowControl {
180189
}
181190
}
182191
"assignment_expression"
183-
if view.get_parent_of_types(vec!["for_initializer"]).is_some() =>
192+
if view.get_parent_of_types(vec!["for_initializer"]).is_some()
193+
&& self.loop_id.is_some()
194+
&& view
195+
.get_parent_of_types(vec!["for_statement"])
196+
.map(|n| n.id())
197+
== self.loop_id =>
184198
{
185199
if let (Some(left), Some(right)) = (view.child(0), view.child(2)) {
186200
if let Some(Powershell::Raw(value)) = right.data() {
@@ -203,6 +217,7 @@ impl<'a> RuleMut<'a> for ForStatementFlowControl {
203217
"statement_block" => {
204218
let parent = view.parent().unwrap();
205219
if matches!(parent.kind(), "while_statement" | "for_statement")
220+
&& self.loop_id == Some(parent.id())
206221
&& parent.data().is_none()
207222
&& self.statment_count == 1
208223
{

0 commit comments

Comments
 (0)