Fix static method invocation type inference (#8018)

Fixes type inference for static method invocations (e.g. [powershell]::Create()).
This commit is contained in:
Patrick Meinecke 2018-10-23 07:58:31 -04:00 committed by Ilya
parent 0a4f33a872
commit 57bf508fec
3 changed files with 47 additions and 16 deletions

View file

@ -1603,21 +1603,7 @@ namespace System.Management.Automation
if (methodCacheEntry[0].method.Name.Equals(memberName, StringComparison.OrdinalIgnoreCase))
{
maybeWantDefaultCtor = false;
if (isInvokeMemberExpressionAst)
{
foreach (var method in methodCacheEntry.methodInformationStructures)
{
if (method.method is MethodInfo methodInfo && !methodInfo.ReturnType.ContainsGenericParameters)
{
result.Add(new PSTypeName(methodInfo.ReturnType));
}
}
return true;
}
// Accessing a method as a property, we'd return a wrapper over the method.
result.Add(new PSTypeName(typeof(PSMethod)));
AddTypesFromMethodCacheEntry(methodCacheEntry, result, isInvokeMemberExpressionAst);
return true;
}
@ -1667,6 +1653,16 @@ namespace System.Management.Automation
ScriptBlock scriptBlock = null;
switch (memberInfo)
{
case PSMethod m:
{
if (m.adapterData is DotNetAdapter.MethodCacheEntry methodCacheEntry)
{
AddTypesFromMethodCacheEntry(methodCacheEntry, result, isInvokeMemberExpressionAst);
return true;
}
return false;
}
case PSProperty p:
{
result.Add(new PSTypeName(p.Value.GetType()));
@ -1739,6 +1735,28 @@ namespace System.Management.Automation
return false;
}
private void AddTypesFromMethodCacheEntry(
DotNetAdapter.MethodCacheEntry methodCacheEntry,
List<PSTypeName> result,
bool isInvokeMemberExpressionAst)
{
if (isInvokeMemberExpressionAst)
{
foreach (var method in methodCacheEntry.methodInformationStructures)
{
if (method.method is MethodInfo methodInfo && !methodInfo.ReturnType.ContainsGenericParameters)
{
result.Add(new PSTypeName(methodInfo.ReturnType));
}
}
return;
}
// Accessing a method as a property, we'd return a wrapper over the method.
result.Add(new PSTypeName(typeof(PSMethod)));
}
private PSTypeName[] GetExpressionType(ExpressionAst expression, bool isStatic)
{
PSTypeName[] exprType;

View file

@ -644,6 +644,13 @@ dir -Recurse `
$res.CompletionMatches | Should -HaveCount 1
$res.CompletionMatches[0].CompletionText | Should -BeExactly "-LiteralPath"
}
It "Test member completion of a static method invocation" {
$inputStr = '[powershell]::Create().'
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr.Length
$res.CompletionMatches | Should -HaveCount 31
$res.CompletionMatches[0].CompletionText | Should -BeExactly "Commands"
}
}
Context "Module completion for 'using module'" {

View file

@ -242,6 +242,12 @@ Describe "Type inference Tests" -tags "CI" {
$res.Name | Should -Be 'System.Type'
}
It "Infers type from static member method" {
$res = [AstTypeInference]::InferTypeOf( { [powershell]::Create() }.Ast)
$res.Count | Should -Be 1
$res.Name | Should -Be 'System.Management.Automation.PowerShell'
}
It "Infers type from integer * stringliteral" {
$res = [AstTypeInference]::InferTypeOf( { 5 * "5" }.Ast)
$res.Count | Should -Be 1
@ -412,7 +418,7 @@ Describe "Type inference Tests" -tags "CI" {
It "Infers typeof Select-Object when Parameter is ExcludeProperty" {
$res = [AstTypeInference]::InferTypeOf( { [io.fileinfo]::new("file") | Select-Object -ExcludeProperty *Time*, E* }.Ast)
$res.Count | Should -Be 1
$res[0].Name | Should -Be "System.Management.Automation.PSObject#Attributes:BaseName:Directory:DirectoryName:FullName:IsReadOnly:Length:LinkType:Mode:Name:Target"
$res[0].Name | Should -Be "System.Management.Automation.PSObject#Attributes:BaseName:Directory:DirectoryName:FullName:IsReadOnly:Length:LinkType:Mode:Name:Target:VersionInfo"
$names = $res[0].Members.Name
$names -contains "BaseName" | Should -BeTrue
$names -contains "Name" | Should -BeTrue