|
377 | 377 |
|
378 | 378 | # Check that the AttributeSyntaxTree is not a real type (return if it is) |
379 | 379 | $attributeType = $AttributeSyntaxTree.TypeName.GetReflectionType() |
380 | | - if ($attributeType) { return $AttributeSyntaxTree } |
| 380 | + if ($attributeType) { return } |
381 | 381 |
|
382 | 382 | # Check that the typename is not [Ordered] (return if it is). |
383 | | - if ($AttributeSyntaxTree.TypeName.Name -eq 'ordered') { return $AttributeSyntaxTree } |
| 383 | + if ($AttributeSyntaxTree.TypeName.Name -eq 'ordered') { return } |
384 | 384 |
|
385 | 385 | # Create a collection for stringified arguments. |
386 | 386 | $stringArguments = @() |
|
393 | 393 | $AttributeSyntaxTree.TypeName.Name |
394 | 394 | } |
395 | 395 |
|
| 396 | + # See if we could find a transpiler that fits. |
396 | 397 | $foundTranspiler = |
397 | 398 | if ($InputObject) { |
398 | 399 | Get-Transpiler -TranspilerName "$transpilerStepName" -CouldPipe $InputObject | |
399 | 400 | Select-Object -ExpandProperty ExtensionCommand |
400 | 401 | } else { |
401 | 402 | Get-Transpiler -TranspilerName "$transpilerStepName" |
402 | 403 | } |
403 | | - |
| 404 | + |
| 405 | + # Collect all of the arguments of the attribute, in the order they were specified. |
404 | 406 | $argsInOrder = @( |
405 | 407 | @($AttributeSyntaxTree.PositionalArguments) + @($AttributeSyntaxTree.NamedArguments) | Sort-Object { $_.Extent.StartOffset}) |
406 | 408 |
|
| 409 | + |
| 410 | + # Now we need to map each of those arguments into either named or positional arguments. |
407 | 411 | foreach ($attributeArg in $argsInOrder) { |
| 412 | + # Named arguments are fairly straightforward: |
408 | 413 | if ($attributeArg -is [Management.Automation.Language.NamedAttributeArgumentAst]) { |
409 | 414 | $argName = $attributeArg.ArgumentName |
410 | 415 | $argAst = $attributeArg.Argument |
411 | 416 | $parameter[$argName] = |
412 | | - if ($argName -eq $argAst) { |
413 | | - $true |
414 | | - } elseif ($argAst.Value) { |
415 | | - $argAst.Value.ToString() |
416 | | - } |
| 417 | + if ($argName -eq $argAst) { # If the argument is the name, |
| 418 | + $true # treat it as a [switch] parameter. |
| 419 | + } |
| 420 | + # If the argument value was an ScriptBlockExpression |
417 | 421 | elseif ($argAst -is [Management.Automation.Language.ScriptBlockExpressionAST]) { |
| 422 | + # Turn it into a [ScriptBlock] |
418 | 423 | $argScriptBlock = [ScriptBlock]::Create($argAst.Extent.ToString() -replace '^\{' -replace '\}$') |
| 424 | + # If the Transpiler had a parameter that took a [ScriptBlock] or [ScriptBlock[]] |
419 | 425 | if ($foundTranspiler.parameters.$argName.ParameterType -eq [ScriptBlock] -or |
420 | 426 | $foundTranspiler.parameters.$argName.ParameterType -eq [ScriptBlock[]]) { |
421 | | - $argScriptBlock |
422 | | - } elseif ($SafeScriptBlockAttributeEvaluation) { |
| 427 | + $argScriptBlock # pass the [ScriptBlock] directly. |
| 428 | + } |
| 429 | + # Now here is where things get a bit more interesting: |
| 430 | + # If the parameter type _was not_ a [ScriptBlock], we can evaluate the [ScriptBlock] to create a real value |
| 431 | + # If we want to do this "safely", we can pass -SafeScriptBlockAttributeEvaluation |
| 432 | + elseif ($SafeScriptBlockAttributeEvaluation) { |
| 433 | + # Which will run the [ScriptBlock] inside of a data block, thus preventing it from running commands. |
423 | 434 | & ([ScriptBlock]::Create("data {$argScriptBlock}")) |
424 | 435 | } else { |
| 436 | + # Otherwise, we want to run the [ScriptBlock] directly. |
425 | 437 | & ([ScriptBlock]::Create("$argScriptBlock")) |
426 | 438 | } |
427 | 439 | } |
| 440 | + elseif ($argAst.Value) { |
| 441 | + $argAst.Value.ToString() |
| 442 | + } |
428 | 443 | else { |
429 | 444 | $argAst.Extent.ToString() |
430 | 445 | } |
431 | 446 | } else { |
432 | | - foreach ($eachParameter in $foundTranspiler.Parameters.Values) { |
433 | | - $eachParameter |
434 | | - } |
| 447 | + # If we are a positional parameter, for the moment: |
435 | 448 | if ($parameter.Count) { |
| 449 | + # add it to the last named parameter. |
436 | 450 | $parameter[@($parameter.Keys)[-1]] = @() + $parameter[@($parameter.Keys)[-1]] + $attributeArg.Value.ToString() |
437 | 451 | } else { |
| 452 | + # Or add it to the list of string arguments. |
438 | 453 | $stringArguments += "$($attributeArg.Value)" |
439 | 454 | } |
| 455 | + |
| 456 | + # We _should_ get more intelligent over time here. |
| 457 | + # See [the GitHub Issue](https://github.com/StartAutomating/PipeScript/issues/70) for more details. |
440 | 458 | } |
441 | 459 | } |
442 | 460 |
|
| 461 | + # If we have found a transpiler, run it. |
443 | 462 | if ($foundTranspiler) { |
444 | 463 | $ArgumentList += $stringArguments |
445 | 464 | if ($InputObject) { |
|
490 | 509 | # Determine if the -Command is a real type. |
491 | 510 | $realType = $Command.TypeName.GetReflectionType() |
492 | 511 | if ($realType) { |
493 | | - # If it is, return the connstraint unmodified. |
494 | | - return $command |
| 512 | + # If it is, return. |
| 513 | + return |
495 | 514 | } |
496 | 515 | # Next, make sure it's not ```[ordered]``` (return it if is) |
497 | | - if ($command.TypeName.Name -eq 'ordered') { return $command } |
| 516 | + if ($command.TypeName.Name -eq 'ordered') { return} |
498 | 517 |
|
499 | 518 | # Determine the name of the transpiler step. |
500 | 519 | $transpilerStepName = |
|
0 commit comments