|
1 | 1 | use crate::error::{Error, MinusOneResult}; |
| 2 | +use crate::ps::tool::CommandTool; |
2 | 3 | use crate::ps::Powershell; |
3 | 4 | use crate::ps::Powershell::{Array, PSItem, Raw}; |
4 | 5 | use crate::rule::RuleMut; |
@@ -84,20 +85,25 @@ impl<'a> RuleMut<'a> for PSItemInferrator { |
84 | 85 | if let Some(script_block_expression) = |
85 | 86 | view.get_parent_of_types(vec!["script_block_expression"]) |
86 | 87 | { |
87 | | - if let Some(foreach_command) = |
88 | | - script_block_expression.get_parent_of_types(vec!["foreach_command"]) |
| 88 | + if let Some(command) = script_block_expression.get_parent_of_types(vec!["command"]) |
89 | 89 | { |
90 | | - if let Some(previous) = find_previous_expr(&foreach_command.parent().unwrap())? |
91 | | - { |
92 | | - // the previous in the pipeline |
93 | | - match previous.data() { |
94 | | - Some(Array(values)) => { |
95 | | - node.set(PSItem(values.clone())); |
96 | | - } |
97 | | - Some(Raw(value)) => { |
98 | | - node.set(PSItem(vec![value.clone()])); |
| 90 | + if let Some(command_name) = command.child(0) { |
| 91 | + if matches!( |
| 92 | + command_name.text().unwrap(), |
| 93 | + "foreach" | "%" | "foreach-object" |
| 94 | + ) { |
| 95 | + if let Some(previous) = find_previous_expr(&command)? { |
| 96 | + // the previous in the pipeline |
| 97 | + match previous.data() { |
| 98 | + Some(Array(values)) => { |
| 99 | + node.set(PSItem(values.clone())); |
| 100 | + } |
| 101 | + Some(Raw(value)) => { |
| 102 | + node.set(PSItem(vec![value.clone()])); |
| 103 | + } |
| 104 | + _ => (), |
| 105 | + } |
99 | 106 | } |
100 | | - _ => (), |
101 | 107 | } |
102 | 108 | } |
103 | 109 | } |
@@ -163,61 +169,67 @@ impl<'a> RuleMut<'a> for ForEach { |
163 | 169 | ) -> MinusOneResult<()> { |
164 | 170 | let view = node.view(); |
165 | 171 | // find usage of magic variable |
166 | | - if view.kind() == "foreach_command" |
167 | | - && view.child_count() == 2 |
168 | | - && view.child(1).unwrap().kind() == "script_block_expression" |
169 | | - { |
170 | | - let script_block_expression = view.child(1).unwrap(); |
171 | | - if let Some(previous_command) = find_previous_expr(&view.parent().unwrap())? { |
172 | | - // if the previous pipeline was inferred as an array |
173 | | - let mut previous_values = Vec::new(); |
174 | | - match previous_command.data() { |
175 | | - Some(Array(values)) => previous_values.extend(values.clone()), |
176 | | - // array of size 1 |
177 | | - Some(Raw(value)) => previous_values.push(value.clone()), |
178 | | - _ => (), |
179 | | - } |
180 | | - let script_block_body = script_block_expression |
181 | | - .child(1) |
182 | | - .ok_or(Error::invalid_child())? // script_block node |
183 | | - .named_child("script_block_body"); |
| 172 | + if view.is_command() { |
| 173 | + let args = view.get_command_args(); |
| 174 | + if matches!( |
| 175 | + view.get_command_name().as_str(), |
| 176 | + "foreach" | "foreach-object" | "%" |
| 177 | + ) && args.len() == 1 |
| 178 | + { |
| 179 | + let script_block_expression = args[0].smallest_child(); |
| 180 | + if script_block_expression.kind() == "script_block_expression" { |
| 181 | + if let Some(previous_command) = find_previous_expr(&view)? { |
| 182 | + // if the previous pipeline was inferred as an array |
| 183 | + let mut previous_values = Vec::new(); |
| 184 | + match previous_command.data() { |
| 185 | + Some(Array(values)) => previous_values.extend(values.clone()), |
| 186 | + // array of size 1 |
| 187 | + Some(Raw(value)) => previous_values.push(value.clone()), |
| 188 | + _ => (), |
| 189 | + } |
| 190 | + let script_block_body = script_block_expression |
| 191 | + .child(1) |
| 192 | + .ok_or(Error::invalid_child())? // script_block node |
| 193 | + .named_child("script_block_body"); |
184 | 194 |
|
185 | | - if let Some(script_block_body_node) = script_block_body { |
186 | | - if let Some(statement_list) = |
187 | | - script_block_body_node.named_child("statement_list") |
188 | | - { |
189 | | - // determine the number of loop |
190 | | - // by looping over the size of the array |
| 195 | + if let Some(script_block_body_node) = script_block_body { |
| 196 | + if let Some(statement_list) = |
| 197 | + script_block_body_node.named_child("statement_list") |
| 198 | + { |
| 199 | + // determine the number of loop |
| 200 | + // by looping over the size of the array |
191 | 201 |
|
192 | | - let mut result = Vec::new(); |
193 | | - for i in 0..previous_values.len() { |
194 | | - for child_statement in statement_list.iter() { |
195 | | - if child_statement.kind() == "empty_statement" { |
196 | | - continue; |
197 | | - } |
| 202 | + let mut result = Vec::new(); |
| 203 | + for i in 0..previous_values.len() { |
| 204 | + for child_statement in statement_list.iter() { |
| 205 | + if child_statement.kind() == "empty_statement" { |
| 206 | + continue; |
| 207 | + } |
198 | 208 |
|
199 | | - match child_statement.data() { |
200 | | - Some(PSItem(values)) => { |
201 | | - result.push(values[i].clone()); |
202 | | - } |
203 | | - Some(Raw(r)) => { |
204 | | - result.push(r.clone()); |
205 | | - } |
206 | | - Some(Array(array_value)) => { |
207 | | - for v in array_value { |
208 | | - result.push(v.clone()); |
| 209 | + match child_statement.data() { |
| 210 | + Some(PSItem(values)) => { |
| 211 | + result.push(values[i].clone()); |
| 212 | + } |
| 213 | + Some(Raw(r)) => { |
| 214 | + result.push(r.clone()); |
| 215 | + } |
| 216 | + Some(Array(array_value)) => { |
| 217 | + for v in array_value { |
| 218 | + result.push(v.clone()); |
| 219 | + } |
| 220 | + } |
| 221 | + _ => { |
| 222 | + // stop inferring we have not enough infos |
| 223 | + return Ok(()); |
| 224 | + } |
209 | 225 | } |
210 | 226 | } |
211 | | - _ => { |
212 | | - // stop inferring we have not enough infos |
213 | | - return Ok(()); |
214 | | - } |
| 227 | + } |
| 228 | + if !result.is_empty() { |
| 229 | + node.set(Array(result)); |
215 | 230 | } |
216 | 231 | } |
217 | 232 | } |
218 | | - if !result.is_empty() { |
219 | | - node.set(Array(result)); |
220 | | - } |
221 | 233 | } |
222 | 234 | } |
223 | 235 | } |
|
0 commit comments