mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Update Named and Statement block type inference to not consider AssignmentStatements and Increment/decrement operators as part of their output (#21137)
This commit is contained in:
@@ -850,9 +850,20 @@ namespace System.Management.Automation
|
||||
object ICustomAstVisitor.VisitNamedBlock(NamedBlockAst namedBlockAst)
|
||||
{
|
||||
var inferredTypes = new List<PSTypeName>();
|
||||
for (var index = 0; index < namedBlockAst.Statements.Count; index++)
|
||||
for (int index = 0; index < namedBlockAst.Statements.Count; index++)
|
||||
{
|
||||
var ast = namedBlockAst.Statements[index];
|
||||
StatementAst ast = namedBlockAst.Statements[index];
|
||||
if (ast is AssignmentStatementAst
|
||||
|| (ast is PipelineAst pipe && pipe.PipelineElements.Count == 1 && pipe.PipelineElements[0] is CommandExpressionAst cmd
|
||||
&& cmd.Redirections.Count == 0 && cmd.Expression is UnaryExpressionAst unary
|
||||
&& unary.TokenKind is TokenKind.PostfixPlusPlus or TokenKind.PlusPlus or TokenKind.PostfixMinusMinus or TokenKind.MinusMinus))
|
||||
{
|
||||
// Assignments don't output anything to the named block unless they are wrapped in parentheses.
|
||||
// When they are wrapped in parentheses, they are seen as PipelineAst.
|
||||
// Increment/decrement operators like $i++ also don't output anything unless there's a redirection, or they are wrapped in parentheses.
|
||||
continue;
|
||||
}
|
||||
|
||||
inferredTypes.AddRange(InferTypes(ast));
|
||||
}
|
||||
|
||||
@@ -921,8 +932,19 @@ namespace System.Management.Automation
|
||||
object ICustomAstVisitor.VisitStatementBlock(StatementBlockAst statementBlockAst)
|
||||
{
|
||||
var inferredTypes = new List<PSTypeName>();
|
||||
foreach (var ast in statementBlockAst.Statements)
|
||||
foreach (StatementAst ast in statementBlockAst.Statements)
|
||||
{
|
||||
if (ast is AssignmentStatementAst
|
||||
|| (ast is PipelineAst pipe && pipe.PipelineElements.Count == 1 && pipe.PipelineElements[0] is CommandExpressionAst cmd
|
||||
&& cmd.Redirections.Count == 0 && cmd.Expression is UnaryExpressionAst unary
|
||||
&& unary.TokenKind is TokenKind.PostfixPlusPlus or TokenKind.PlusPlus or TokenKind.PostfixMinusMinus or TokenKind.MinusMinus))
|
||||
{
|
||||
// Assignments don't output anything to the statement block unless they are wrapped in parentheses.
|
||||
// When they are wrapped in parentheses, they are seen as PipelineAst.
|
||||
// Increment operators like $i++ also don't output anything unless there's a redirection, or they are wrapped in parentheses.
|
||||
continue;
|
||||
}
|
||||
|
||||
inferredTypes.AddRange(InferTypes(ast));
|
||||
}
|
||||
|
||||
|
||||
@@ -361,10 +361,8 @@ Describe "Type inference Tests" -tags "CI" {
|
||||
|
||||
It "Infers type from foreach-object of integer" {
|
||||
$res = [AstTypeInference]::InferTypeOf( { [int[]] $i = 1..20; $i | ForEach-Object {$_ * 10} }.Ast)
|
||||
$res.Count | Should -Be 2
|
||||
foreach ($r in $res) {
|
||||
$r.Name -In 'System.Int32', 'System.Int32[]' | Should -BeTrue
|
||||
}
|
||||
$res.Count | Should -Be 1
|
||||
$res.Name | Should -Be 'System.Int32'
|
||||
}
|
||||
|
||||
It "Infers type from generic new" {
|
||||
@@ -386,9 +384,9 @@ Describe "Type inference Tests" -tags "CI" {
|
||||
|
||||
It "Infers type from foreach-object with begin/end" {
|
||||
$res = [AstTypeInference]::InferTypeOf( { [int[]] $i = 1..20; $i | ForEach-Object -Begin {"Hi"} {$_ * 10} -End {[int]} }.Ast)
|
||||
$res.Count | Should -Be 4
|
||||
$res.Count | Should -Be 3
|
||||
foreach ($r in $res) {
|
||||
$r.Name -In 'System.Int32', 'System.Int32[]', 'System.String', 'System.Type' | Should -BeTrue
|
||||
$r.Name -In 'System.Int32', 'System.String', 'System.Type' | Should -BeTrue
|
||||
}
|
||||
}
|
||||
|
||||
@@ -618,16 +616,6 @@ Describe "Type inference Tests" -tags "CI" {
|
||||
$res.Name | Should -Be 'System.Int32'
|
||||
}
|
||||
|
||||
It 'Infers type from attributed expession' {
|
||||
$res = [AstTypeInference]::InferTypeOf( {
|
||||
[ValidateRange(1, 2)]
|
||||
[int]$i = 1
|
||||
}.Ast)
|
||||
|
||||
$res.Count | Should -Be 1
|
||||
$res.Name | Should -Be System.Int32
|
||||
}
|
||||
|
||||
It 'Infers type from if statement' {
|
||||
$res = [AstTypeInference]::InferTypeOf( {
|
||||
if ($true) { return 1}
|
||||
@@ -1399,7 +1387,8 @@ Describe "Type inference Tests" -tags "CI" {
|
||||
|
||||
It 'Infers closest variable type' {
|
||||
$res = [AstTypeInference]::InferTypeOf( { [string]$TestVar = "";[hashtable]$TestVar = @{};$TestVar }.Ast)
|
||||
$res.Name | Select-Object -Last 1 | Should -Be "System.Collections.Hashtable"
|
||||
$res.Count | Should -Be 1
|
||||
$res.Name | Should -Be "System.Collections.Hashtable"
|
||||
}
|
||||
|
||||
It 'Infers closest variable type and ignores unrelated param blocks' {
|
||||
@@ -1444,6 +1433,66 @@ Describe "Type inference Tests" -tags "CI" {
|
||||
)
|
||||
$null = [AstTypeInference]::InferTypeOf($FoundAst)
|
||||
}
|
||||
|
||||
It 'Should only consider assignments wrapped in parentheses to be a part of the output in a Named block' {
|
||||
$res = [AstTypeInference]::InferTypeOf( { [string]$Assignment1 = "Hello"; ([int]$Assignment2 = 42) }.Ast)
|
||||
$res.Count | Should -Be 1
|
||||
$res.Name | Should -Be 'System.Int32'
|
||||
}
|
||||
|
||||
It 'Should only consider assignments wrapped in parentheses to be a part of the output in a Statement block' {
|
||||
$res = [AstTypeInference]::InferTypeOf( { if ($true){ [string]$Assignment1 = "Hello"; ([int]$Assignment2 = 42) }}.Ast)
|
||||
$res.Count | Should -Be 1
|
||||
$res.Name | Should -Be 'System.Int32'
|
||||
}
|
||||
|
||||
It 'Should only consider increments/decrements wrapped in parentheses to be a part of the output in a Named block' {
|
||||
$res = [AstTypeInference]::InferTypeOf( {
|
||||
[Int16]$Int16 = 1; [Int32]$Int32 = 1; [Int64]$Int64 = 1; [System.Int128]$Int128 = 1;
|
||||
|
||||
$Int16++; $Int32--; ++$Int64; --$Int128}.Ast)
|
||||
$res.Count | Should -Be 0
|
||||
|
||||
$res = [AstTypeInference]::InferTypeOf( {
|
||||
[UInt16]$Uint16 = 1; [UInt32]$Uint32 = 1; [UInt64]$Uint64 = 1; [System.UInt128]$Uint128 = 1
|
||||
|
||||
($Uint16++); ($Uint32--); (++$Uint64); (--$Uint128) }.Ast)
|
||||
$res.Count | Should -Be 4
|
||||
$res.Name -join ',' | Should -Be ('System.UInt16', 'System.UInt32', 'System.UInt64', 'System.UInt128' -join ',')
|
||||
}
|
||||
|
||||
It 'Should only consider increments/decrements wrapped in parentheses to be a part of the output in a Statement block' {
|
||||
$res = [AstTypeInference]::InferTypeOf( {if ($true){
|
||||
[Int16]$Int16 = 1; [Int32]$Int32 = 1; [Int64]$Int64 = 1; [System.Int128]$Int128 = 1;
|
||||
|
||||
$Int16++; $Int32--; ++$Int64; --$Int128}}.Ast)
|
||||
$res.Count | Should -Be 0
|
||||
|
||||
$res = [AstTypeInference]::InferTypeOf( {if ($true){
|
||||
[UInt16]$Uint16 = 1; [UInt32]$Uint32 = 1; [UInt64]$Uint64 = 1; [System.UInt128]$Uint128 = 1
|
||||
|
||||
($Uint16++); ($Uint32--); (++$Uint64); (--$Uint128) }}.Ast)
|
||||
$res.Count | Should -Be 4
|
||||
$res.Name -join ',' | Should -Be ('System.UInt16', 'System.UInt32', 'System.UInt64', 'System.UInt128' -join ',')
|
||||
}
|
||||
|
||||
It 'Redirected increments/decrements should be considered part of the output in a Named block' {
|
||||
$res = [AstTypeInference]::InferTypeOf( {
|
||||
[Int16]$Int16 = 1; [Int32]$Int32 = 1; [Int64]$Int64 = 1; [System.Int128]$Int128 = 1;
|
||||
|
||||
$Int16++ *>&1; $Int32-- *>&1; ++$Int64 *>&1; --$Int128 *>&1}.Ast)
|
||||
$res.Count | Should -Be 4
|
||||
$res.Name -join ',' | Should -Be ('System.Int16', 'System.Int32', 'System.Int64', 'System.Int128' -join ',')
|
||||
}
|
||||
|
||||
It 'Redirected increments/decrements should be considered part of the output in a Statement block' {
|
||||
$res = [AstTypeInference]::InferTypeOf( {if ($true){
|
||||
[Int16]$Int16 = 1; [Int32]$Int32 = 1; [Int64]$Int64 = 1; [System.Int128]$Int128 = 1;
|
||||
|
||||
$Int16++ *>&1; $Int32-- *>&1; ++$Int64 *>&1; --$Int128 *>&1}}.Ast)
|
||||
$res.Count | Should -Be 4
|
||||
$res.Name -join ',' | Should -Be ('System.Int16', 'System.Int32', 'System.Int64', 'System.Int128' -join ',')
|
||||
}
|
||||
}
|
||||
|
||||
Describe "AstTypeInference tests" -Tags CI {
|
||||
|
||||
Reference in New Issue
Block a user