diff --git a/src/System.Management.Automation/engine/parser/TypeInferenceVisitor.cs b/src/System.Management.Automation/engine/parser/TypeInferenceVisitor.cs index 9d14d2a1b3..5be3e414c7 100644 --- a/src/System.Management.Automation/engine/parser/TypeInferenceVisitor.cs +++ b/src/System.Management.Automation/engine/parser/TypeInferenceVisitor.cs @@ -2462,6 +2462,14 @@ namespace System.Management.Automation { if (currentAst is IParameterMetadataProvider) { + if (currentAst is ScriptBlockAst && currentAst.Parent is FunctionDefinitionAst) + { + // If this scriptblock belongs to a function we want to visit that instead so we can get the parameters + // function X ($Param1){} + currentAst = currentAst.Parent; + } + + assignmentVisitor.ScopeDefinitionAst = currentAst; currentAst.Visit(assignmentVisitor); if (assignmentVisitor.LocalScopeOnly @@ -2912,6 +2920,11 @@ namespace System.Management.Automation /// Whether or not the last assignment was via command redirection. /// internal bool RedirectionAssignment; + + /// + /// The Ast of the scope we are currently analyzing. + /// + internal Ast ScopeDefinitionAst; internal int StopSearchOffset; private int LastAssignmentOffset = -1; @@ -3259,7 +3272,9 @@ namespace System.Management.Automation public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst functionDefinitionAst) { - return AstVisitAction.SkipChildren; + return functionDefinitionAst == ScopeDefinitionAst + ? AstVisitAction.Continue + : AstVisitAction.SkipChildren; } } } diff --git a/test/powershell/engine/Api/TypeInference.Tests.ps1 b/test/powershell/engine/Api/TypeInference.Tests.ps1 index e134cfb97e..4ba8ffd17d 100644 --- a/test/powershell/engine/Api/TypeInference.Tests.ps1 +++ b/test/powershell/engine/Api/TypeInference.Tests.ps1 @@ -268,6 +268,16 @@ Describe "Type inference Tests" -tags "CI" { $res.Name | Should -Be 'System.Management.ManagementObject#root\cimv2\Win32_Process' } + It "Infers type from parameter in classic function definition" { + $res = [AstTypeInference]::InferTypeOf(({ + function MyFunction ([int]$param1) + { + $param1 + } + }.Ast.FindAll({param($Ast) $Ast -is [Language.VariableExpressionAst]}, $true) | Select-Object -Last 1 )) + $res.Name | Should -Be 'System.Int32' + } + It "Infers type from binary expression with a bool operator as bool" { $res = [AstTypeInference]::InferTypeOf( { (1..10) -contains 5