mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Fall back to type inference when hashtable key value cannot be retrieved from safe expression (#21184)
This commit is contained in:
@@ -584,6 +584,20 @@ namespace System.Management.Automation
|
||||
if (hashtableAst.KeyValuePairs.Count > 0)
|
||||
{
|
||||
var properties = new List<PSMemberNameAndType>();
|
||||
void AddInferredTypes(Ast ast, string keyName)
|
||||
{
|
||||
bool foundAnyTypes = false;
|
||||
foreach (PSTypeName item in InferTypes(ast))
|
||||
{
|
||||
foundAnyTypes = true;
|
||||
properties.Add(new PSMemberNameAndType(keyName, item));
|
||||
}
|
||||
|
||||
if (!foundAnyTypes)
|
||||
{
|
||||
properties.Add(new PSMemberNameAndType(keyName, new PSTypeName("System.Object")));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var kv in hashtableAst.KeyValuePairs)
|
||||
{
|
||||
@@ -615,31 +629,18 @@ namespace System.Management.Automation
|
||||
_ = SafeExprEvaluator.TrySafeEval(expression, _context.ExecutionContext, out value);
|
||||
}
|
||||
|
||||
PSTypeName valueType;
|
||||
if (value is null)
|
||||
{
|
||||
valueType = new PSTypeName("System.Object");
|
||||
}
|
||||
else
|
||||
{
|
||||
valueType = new PSTypeName(value.GetType());
|
||||
AddInferredTypes(expression, name);
|
||||
continue;
|
||||
}
|
||||
|
||||
PSTypeName valueType = new(value.GetType());
|
||||
properties.Add(new PSMemberNameAndType(name, valueType, value));
|
||||
}
|
||||
else
|
||||
{
|
||||
bool foundAnyTypes = false;
|
||||
foreach (var item in InferTypes(kv.Item2))
|
||||
{
|
||||
foundAnyTypes = true;
|
||||
properties.Add(new PSMemberNameAndType(name, item));
|
||||
}
|
||||
|
||||
if (!foundAnyTypes)
|
||||
{
|
||||
properties.Add(new PSMemberNameAndType(name, new PSTypeName("System.Object")));
|
||||
}
|
||||
AddInferredTypes(kv.Item2, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1639,7 +1640,7 @@ namespace System.Management.Automation
|
||||
var memberNameList = new List<string> { memberAsStringConst.Value };
|
||||
foreach (var type in exprType)
|
||||
{
|
||||
if (type.Type == typeof(PSObject))
|
||||
if (type.Type == typeof(PSObject) && type is not PSSyntheticTypeName)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1379,12 +1379,24 @@ Describe "Type inference Tests" -tags "CI" {
|
||||
$res.Name -join ' ' | Should -Be "System.IO.FileInfo System.IO.DirectoryInfo"
|
||||
}
|
||||
|
||||
It 'Falls back to type inference for hashtable assignments with pure expression with no value' {
|
||||
$res = [AstTypeInference]::InferTypeOf( {$KeyWithNoValue = Get-ChildItem $HOME; (@{RandomKey = $KeyWithNoValue}).RandomKey }.Ast)
|
||||
$Res.Count | Should -Be 2
|
||||
$res.Name -join ' ' | Should -Be "System.IO.FileInfo System.IO.DirectoryInfo"
|
||||
}
|
||||
|
||||
It 'Infers type of index expression on hashtable with synthetic type' {
|
||||
$res = [AstTypeInference]::InferTypeOf( { (@{RandomKey = Get-ChildItem $HOME})['RandomKey'] }.Ast)
|
||||
$res.Count | Should -Be 2
|
||||
$res.Name -join ' ' | Should -Be "System.IO.FileInfo System.IO.DirectoryInfo"
|
||||
}
|
||||
|
||||
It 'Infers type of member expression on a custom object' {
|
||||
$res = [AstTypeInference]::InferTypeOf( { ([pscustomobject]@{RandomProp1 = Get-ChildItem $HOME}).RandomProp1 }.Ast)
|
||||
$res.Count | Should -Be 2
|
||||
$res.Name -join ' ' | Should -Be "System.IO.FileInfo System.IO.DirectoryInfo"
|
||||
}
|
||||
|
||||
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"
|
||||
|
||||
Reference in New Issue
Block a user