Skip to content

Commit

Permalink
Merge pull request #18 from santisq/17-indexing-fails-on-$using-state…
Browse files Browse the repository at this point in the history
…ments

fixes indexing on using: statements
  • Loading branch information
santisq authored Jan 25, 2024
2 parents 46c9d32 + 1b4d2b0 commit 7e18153
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 25 deletions.
2 changes: 1 addition & 1 deletion Module/PSParallelPipeline.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
RootModule = 'PSParallelPipeline.psm1'

# Version number of this module.
ModuleVersion = '1.1.3'
ModuleVersion = '1.1.4'

# Supported PSEditions
# CompatiblePSEditions = @()
Expand Down
40 changes: 40 additions & 0 deletions Module/private/InvocationManager.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using namespace System.Diagnostics
using namespace System.Management.Automation
using namespace System.Management.Automation.Host
using namespace System.Management.Automation.Language
using namespace System.Text
using namespace System.Threading

class InvocationManager : IDisposable {
Expand Down Expand Up @@ -107,4 +109,42 @@ class InvocationManager : IDisposable {
$runspace.Dispose()
}
}

static [hashtable] GetUsingStatements([scriptblock] $scriptblock, [PSCmdlet] $cmdlet) {
$usingParams = @{}
foreach ($usingstatement in $scriptblock.Ast.FindAll({ $args[0] -is [UsingExpressionAst] }, $true)) {
$variableAst = [UsingExpressionAst]::ExtractUsingVariable($usingstatement)
$varPath = $variableAst.VariablePath.UserPath
$varText = $usingstatement.ToString()

if ($usingstatement.SubExpression -is [VariableExpressionAst]) {
$varText = $varText.ToLowerInvariant()
}

$key = [Convert]::ToBase64String([Encoding]::Unicode.GetBytes($varText))

if ($usingParams.ContainsKey($key)) {
continue
}

$value = $cmdlet.SessionState.PSVariable.GetValue($varPath)

if ($value -is [scriptblock]) {
$cmdlet.ThrowTerminatingError([ErrorRecord]::new(
[PSArgumentException]::new('Passed-in script block variables are not supported.'),
'VariableCannotBeScriptBlock',
[ErrorCategory]::InvalidType,
$value))
}

if ($usingstatement.SubExpression -is [IndexExpressionAst]) {
$idx = $usingstatement.SubExpression.Index.SafeGetValue()
$value = $value[$idx]
}

$usingParams.Add($key, $value)
}

return $usingParams
}
}
28 changes: 4 additions & 24 deletions Module/public/Invoke-Parallel.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ function Invoke-Parallel {
)

begin {
$usingParams = [InvocationManager]::GetUsingStatements(
$ScriptBlock,
$PSCmdlet)

try {
$iss = [initialsessionstate]::CreateDefault2()

Expand All @@ -60,30 +64,6 @@ function Invoke-Parallel {
[SessionStateFunctionEntry]::new($function, $def.Definition))
}

$usingParams = @{}

# Thanks to mklement0 for catching up a bug here.
# https://github.com/mklement0
foreach ($usingstatement in $ScriptBlock.Ast.FindAll({ $args[0] -is [UsingExpressionAst] }, $true)) {
$varText = $usingstatement.Extent.Text
$varPath = $usingstatement.SubExpression.VariablePath.UserPath

$key = [Convert]::ToBase64String([Encoding]::Unicode.GetBytes($varText.ToLowerInvariant()))
if (-not $usingParams.ContainsKey($key)) {
$value = $PSCmdlet.SessionState.PSVariable.GetValue($varPath)

if ($value -is [scriptblock]) {
$PSCmdlet.ThrowTerminatingError([ErrorRecord]::new(
[PSArgumentException]::new('Passed-in script block variables are not supported.'),
'VariableCannotBeScriptBlock',
[ErrorCategory]::InvalidType,
$value))
}

$usingParams.Add($key, $value)
}
}

$im = [InvocationManager]::new($ThrottleLimit, $Host, $iss, $UseNewRunspace.IsPresent)

if ($withTimeout = $PSBoundParameters.ContainsKey('TimeoutSeconds')) {
Expand Down
6 changes: 6 additions & 0 deletions tests/PSParallelPipeline.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -134,5 +134,11 @@
1..1 | Invoke-Parallel { $sb } -Variables @{ sb = $sb }
} | Should -Throw
}

It 'Allows indexing on using: statements' {
$arr = 0..10; $hash = @{ foo = 'bar' }
1 | Invoke-Parallel { $using:arr[-1] } | Should -BeExactly 10
1 | Invoke-Parallel { $using:hash['FOO'] } | Should -BeExactly 'bar'
}
}
}

0 comments on commit 7e18153

Please sign in to comment.