mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Make minor fixes in Compiler to properly handle void type expression (#5764)
This commit is contained in:
@@ -3039,6 +3039,12 @@ namespace System.Management.Automation.Language
|
||||
input = GetRangeEnumerator(firstCommandExpr.Expression) ??
|
||||
Compile(firstCommandExpr.Expression);
|
||||
}
|
||||
|
||||
if (input.Type == typeof(void))
|
||||
{
|
||||
input = Expression.Block(input, ExpressionCache.AutomationNullConstant);
|
||||
}
|
||||
|
||||
i = 1;
|
||||
commandsInPipe = pipeElements.Count - 1;
|
||||
}
|
||||
@@ -5525,7 +5531,7 @@ namespace System.Management.Automation.Language
|
||||
if (values.Type == typeof(void))
|
||||
{
|
||||
// A dynamic site can't take void - but a void value is just an empty array.
|
||||
return Expression.NewArrayInit(typeof(object));
|
||||
return Expression.Block(values, Expression.NewArrayInit(typeof(object)));
|
||||
}
|
||||
|
||||
return DynamicExpression.Dynamic(PSToObjectArrayBinder.Get(), typeof(object[]), values);
|
||||
@@ -5533,8 +5539,13 @@ namespace System.Management.Automation.Language
|
||||
|
||||
public object VisitArrayLiteral(ArrayLiteralAst arrayLiteralAst)
|
||||
{
|
||||
return Expression.NewArrayInit(typeof(object),
|
||||
arrayLiteralAst.Elements.Select(elem => Compile(elem).Cast(typeof(object))));
|
||||
List<Expression> elementValues = new List<Expression>(arrayLiteralAst.Elements.Count);
|
||||
foreach (var element in arrayLiteralAst.Elements)
|
||||
{
|
||||
var eValue = Compile(element);
|
||||
elementValues.Add(eValue.Type != typeof(void) ? eValue.Cast(typeof(object)) : Expression.Block(eValue, ExpressionCache.AutomationNullConstant));
|
||||
}
|
||||
return Expression.NewArrayInit(typeof(object), elementValues);
|
||||
}
|
||||
|
||||
private IEnumerable<Expression> BuildHashtable(ReadOnlyCollection<KeyValuePair> keyValuePairs, ParameterExpression temp, bool ordered)
|
||||
|
||||
@@ -9301,7 +9301,7 @@ namespace System.Management.Automation.Language
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The non-empty collection of asts of the elements of the array, or null if no elements were specified (e.g. <c>@()</c>).
|
||||
/// The non-empty collection of asts of the elements of the array.
|
||||
/// </summary>
|
||||
public ReadOnlyCollection<ExpressionAst> Elements { get; private set; }
|
||||
|
||||
|
||||
@@ -72,4 +72,71 @@ Describe "ArrayExpression Tests" -Tags "CI" {
|
||||
$result.Length | Should Be 1
|
||||
$result[0] | Should Be $null
|
||||
}
|
||||
|
||||
It "@([void](New-Item)) should create file" {
|
||||
try {
|
||||
$testFile = Join-Path $TestDrive (New-Guid)
|
||||
$result = @([void](New-Item $testFile -ItemType File))
|
||||
## file should be created
|
||||
$testFile | Should Exist
|
||||
## the array should be empty
|
||||
$result.Count | Should Be 0
|
||||
} finally {
|
||||
Remove-Item $testFile -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Describe "ArrayLiteral Tests" -Tags "CI" {
|
||||
It "'[void](New-Item),2,3' should return a 3-element array and first element is AutomationNull" {
|
||||
try {
|
||||
$testFile = Join-Path $TestDrive (New-Guid)
|
||||
$result = [void](New-Item $testFile -ItemType File), 2, 3
|
||||
## file should be created
|
||||
$testFile | Should Exist
|
||||
## the array should contain 3 items
|
||||
$result.Count | Should Be 3
|
||||
|
||||
## the first item should be AutomationNull
|
||||
$result[0] | ForEach-Object { "YES" } | Should Be $null
|
||||
$result | Measure-Object | ForEach-Object -MemberName Count | Should Be 2
|
||||
} finally{
|
||||
Remove-Item $testFile -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
It "'[void]1, [void](New-Item), [void]2' should return a 3-AutomationNull-element array" {
|
||||
try {
|
||||
$testFile = Join-Path $TestDrive (New-Guid)
|
||||
$result = [void]1, [void](New-Item $testFile -ItemType File), [void]2
|
||||
## file should be created
|
||||
$testFile | Should Exist
|
||||
## the array should contain 3 items
|
||||
$result.Count | Should Be 3
|
||||
|
||||
## all items should be AutomationNull
|
||||
$result | ForEach-Object { "YES" } | Should Be $null
|
||||
} finally {
|
||||
Remove-Item $testFile -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
It "'[void]`$arraylist1.Add(1), `$arraylist2.Clear()' should return a 2-AutomationNull-element array" {
|
||||
$arraylist1 = [System.Collections.ArrayList]::new()
|
||||
$arraylist2 = [System.Collections.ArrayList]::new()
|
||||
|
||||
$arraylist2.Add(2) > $null
|
||||
$arraylist2.Count | Should Be 1
|
||||
|
||||
## first item is a non-void method call
|
||||
## second item is a void method call
|
||||
$result = [void]$arraylist1.Add(1), $arraylist2.Clear()
|
||||
$result.Count | Should Be 2
|
||||
$result | ForEach-Object { "YES" } | Should Be $null
|
||||
|
||||
$arraylist1.Count | Should Be 1
|
||||
$arraylist1[0] | Should Be 1
|
||||
|
||||
$arraylist2.Count | Should Be 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
Describe "Scripting.Followup.Tests" -Tags "CI" {
|
||||
It "'[void](New-Item) | <Cmdlet>' should work and behave like passing AutomationNull to the pipe" {
|
||||
try {
|
||||
$testFile = Join-Path $TestDrive (New-Guid)
|
||||
[void](New-Item $testFile -ItemType File) | ForEach-Object { "YES" } | Should Be $null
|
||||
## file should be created
|
||||
$testFile | Should Exist
|
||||
} finally {
|
||||
Remove-Item $testFile -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
## cast non-void method call to [void]
|
||||
It "'[void]`$arraylist.Add(1) | <Cmdlet>' should work and behave like passing AutomationNull to the pipe" {
|
||||
$arraylist = [System.Collections.ArrayList]::new()
|
||||
[void]$arraylist.Add(1) | ForEach-Object { "YES" } | Should Be $null
|
||||
## $arraylist.Add(1) should be executed
|
||||
$arraylist.Count | Should Be 1
|
||||
$arraylist[0] | Should Be 1
|
||||
}
|
||||
|
||||
## void method call
|
||||
It "'`$arraylist2.Clear() | <Cmdlet>' should work and behave like passing AutomationNull to the pipe" {
|
||||
$arraylist = [System.Collections.ArrayList]::new()
|
||||
$arraylist.Add(1) > $null
|
||||
$arraylist.Clear() | ForEach-Object { "YES" } | Should Be $null
|
||||
## $arraylist.Clear() should be executed
|
||||
$arraylist.Count | Should Be 0
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user