1- using namespace System.Management.Automation.Language
21<#
32. SYNOPSIS
43 all keyword
@@ -34,6 +33,9 @@ using namespace System.Management.Automation.Language
3433
3534
3635#>
36+
37+ using namespace System.Management.Automation.Language
38+
3739[ValidateScript ({
3840 $validateVar = $_
3941 if ($validateVar -is [CommandAst ]) {
@@ -44,6 +46,7 @@ using namespace System.Management.Automation.Language
4446 }
4547 return $false
4648})]
49+ [Reflection.AssemblyMetadata (" PipeScript.Keyword" , $true )]
4750param (
4851# If set, include all functions in the input.
4952[Alias (' Function' )]
@@ -89,14 +92,25 @@ $InputObject,
8992
9093# An optional condition
9194[Parameter (ValueFromPipelineByPropertyName , Position = 1 )]
92- [Alias (' That' , ' Condition' )]
95+ [Alias (' That Are ' , ' That Have ' , ' That ' , ' Condition' , ' Where-Object ' , ' With a ' , ' With the ' , ' With ' )]
9396$Where ,
9497
9598# The action that will be run
9699[Parameter (ValueFromPipelineByPropertyName , Position = 2 )]
97- [Alias (' Is' , ' Are' , ' Foreach' , ' Can' , ' Could' , ' Should' )]
100+ [Alias (' Is' , ' Are' , ' Foreach' , ' Foreach-Object ' , ' Can' , ' Could' , ' Should' )]
98101$For ,
99102
103+ # The way to sort data before it is outputted.
104+ [Parameter (ValueFromPipelineByPropertyName , Position = 3 )]
105+ [Alias (' sorted by' , ' sort by' , ' sort on' , ' sorted on' , ' sorted' , ' Sort-Object' )]
106+ $Sort ,
107+
108+ # If output should be sorted in descending order.
109+ [Parameter (ValueFromPipelineByPropertyName )]
110+ [Alias (' ascending' )]
111+ [switch ]
112+ $Descending ,
113+
100114# The Command AST
101115[Parameter (Mandatory , ParameterSetName = ' CommandAST' , ValueFromPipeline )]
102116[CommandAst ]
@@ -148,6 +162,9 @@ process {
148162 elseif ($myParam.Name -eq ' Scripts' ) {
149163 $commandTypes = $commandTypes -bor [Management.Automation.CommandTypes ]' ExternalScript'
150164 }
165+ elseif ($myParam.Name -eq ' Commands' ) {
166+ $commandTypes = ' All'
167+ }
151168 }
152169 }
153170
@@ -164,7 +181,11 @@ process {
164181 } else {
165182 $InputObject.Extent.ToString ()
166183 }
167- } else {
184+ }
185+ elseif ($InputObject -is [scriptblock ]) {
186+ " & {$ ( $InputObject ) }"
187+ }
188+ else {
168189 $InputObject
169190 }
170191 }
@@ -191,16 +212,32 @@ process {
191212 }
192213 }
193214
215+ if ($CommandAst.IsPiped ) {
216+ if ($inputSet ) {
217+ $inputSet = @ ({$_ }) + $inputSet
218+ } else {
219+ $inputSet = @ ({$_ })
220+ }
221+ }
194222
195- # If we still don't have an inputset, default it to 'things'
223+
196224 if (-not $InputSet ) {
225+ # If we still don't have an input set, grab any variables from the arguments.
197226 $InputSet =
198227 if ($mySentence.Arguments ) {
199- $mySentence.Arguments
200- } else {
228+ foreach ($sentenceArg in $mySentence.Arguments ) {
229+ if ($sentenceArg -is [Management.Automation.Language.VariableExpressionAst ]) {
230+ $sentenceArg
231+ }
232+ }
233+ }
234+ # If we still don't have an inputset, default it to 'things'
235+ if (-not $inputSet ) {
236+ $inputSet = @ (
201237 {$ExecutionContext.SessionState.InvokeCommand.GetCommands (' *' , ' Alias,Function,Filter,Cmdlet' , $true )},
202238 {Get-ChildItem - Path variable:}
203- }
239+ )
240+ }
204241 }
205242
206243 # Note: there's still a lot of room for this syntax to grow and become even more natural.
@@ -227,7 +264,9 @@ $inputCollection =' + $(
227264"
228265# 'unroll' the collection by iterating over it once.
229266`$ filteredCollection = `$ inputCollection =
230- @(foreach (`$ in in `$ inputCollection) { `$ in })
267+ @(foreach (`$ in in `$ inputCollection) {
268+ `$ in
269+ })
231270"
232271
233272if ($Where ) {
@@ -236,39 +275,76 @@ if ($Where) {
236275
237276"
238277# Since filtering conditions have been passed, we must filter item-by-item
239- `$ filteredCollection = foreach (`$ item in `$ inputCollection) {
278+ `$ filteredCollection = :nextItem foreach (`$ item in `$ inputCollection) {
240279 # we set `$ this, `$ psItem, and `$ _ for ease-of-use.
241280 `$ this = `$ _ = `$ psItem = `$ item
242- "
243- foreach ($wh in $where ) {
244- if ($wh -is [ScriptBlockExpressionAst ]) {
245- $wh = $wh.ConvertFromAST ()
246- }
247- if ($wh -is [ScriptBlock ] -or $wh -is [Ast ]) {
248- " if (-not `$ ($ ( $wh.Transpile ())
249- )) { continue } "
250- }
251- elseif ($wh -is [string ]) {
252- $safeStr = $ ($wh -replace " '" , " ''" )
253- " if (-not ( # Unless it
254- (`$ null -ne `$ item.'$safeStr ') -or # has a '$safeStr ' property
255- (`$ null -ne `$ item.value.'$safeStr ') -or # or it's value has the property '$safeStr '
256- (`$ null -ne `$ item.Parameters.'$safeStr ') -or # or it's parameters have the property '$safeStr '
257- (`$ item.pstypenames -contains '$safeStr ') # or it's typenames have the property '$safeStr '
258- )) {
259- continue # keep moving
260- }"
281+
282+ # Some of the items may be variables.
283+ if (`$ item -is [Management.Automation.PSVariable]) {
284+ # In this case, reassign them to their value.
285+ `$ this = `$ _ = `$ psItem = `$ item = `$ item.Value
286+ }
287+
288+ # Some of the items may be enumerables
289+ `$ unrolledItems =
290+ if (`$ item.GetEnumerator -and `$ item -isnot [string]) {
291+ @(`$ item.GetEnumerator())
292+ } else {
293+ `$ item
261294 }
295+ foreach (`$ item in `$ unrolledItems) {
296+ `$ this = `$ _ = `$ psItem = `$ item
297+ $ (
298+ foreach ($wh in $where ) {
299+ if ($wh -is [ScriptBlockExpressionAst ]) {
300+ $wh = $wh.ConvertFromAST ()
301+ }
302+ if ($wh -is [ScriptBlock ] -or $wh -is [Ast ]) {
303+ " if (-not `$ ($ ( $wh.Transpile ())
304+ )) { continue } "
305+ }
306+ elseif ($wh -is [string ]) {
307+ $safeStr = $ ($wh -replace " '" , " ''" )
308+ " if (-not ( # Unless it
309+ (`$ null -ne `$ item.'$safeStr ') -or # has a '$safeStr ' property
310+ (`$ null -ne `$ item.Parameters.'$safeStr ') -or # or it's parameters have the property '$safeStr '
311+ (`$ item.pstypenames -contains '$safeStr ') # or it's typenames have the property '$safeStr '
312+ )) {
313+ continue # keep moving
314+ }"
315+ }
316+ }
317+ )
318+ `$ item
262319 }
320+ "
321+
263322"
264- `$ item
323+
265324}"
266325)
267326}
268327
328+ if ($Sort ) {
329+ # If -Sort was specified, we generate code to walk over each sorted item.
330+ $actualSort =
331+ @ (foreach ($sorter in $sort ) {
332+ if ($sorter -is [string ]) {
333+ " '$ ( $sorter -replace " '" , " ''" ) '"
334+ } elseif ($sorter -is [ScriptBlockExpressionAst ]) {
335+ " {$ ( $sorter.ConvertFromAST.Transpile ()) }"
336+ } elseif ($sorter -is [HashtableAst ]) {
337+ $sorter.Extent.ToString ()
338+ }
339+ }) -join ' ,'
340+
341+ "
342+ `$ filteredCollection = `$ filteredCollection | Sort-Object $Sort $ ( if ($Descending ) { ' -Descending' })
343+ "
344+ }
269345
270346if ($For ) {
271- # If -For was
347+ # If -For was specified, we generate code to walk over each item in the filtered collection
272348"
273349# Walk over each item in the filtered collection
274350foreach (`$ item in `$ filteredCollection) {
@@ -295,13 +371,13 @@ if (`$item.value -and `$item.value.pstypenames.insert) {
295371elseif (`$ item.pstypenames.insert -and `$ item.pstypenames -notcontains '$safeStr ') {
296372 `$ item.pstypenames.insert(0, '$safeStr ')
297373}
374+ `$ item
298375 "
299376 }
300377
301378 }
302379
303380"
304- `$ item
305381}
306382"
307383} else {
@@ -318,7 +394,7 @@ elseif (`$item.pstypenames.insert -and `$item.pstypenames -notcontains '$safeStr
318394 # If the command was piped to, wrap the script in a command expression.
319395 if ($CommandAst.IsPiped ) {
320396 $generatedScript = " & { process {
321- $generatedScript
397+ $generatedScript
322398} }"
323399 }
324400
0 commit comments