Use AST extent for PSScriptRoot path completion (#17376)

This commit is contained in:
Patrick Meinecke
2022-06-06 10:33:52 -07:00
committed by GitHub
parent 8cc39848bc
commit 97e8e0c43a
2 changed files with 47 additions and 19 deletions
@@ -7168,7 +7168,7 @@ namespace System.Management.Automation
switch (binding.CommandName)
{
case "Get-WinEvent":
return GetSpecialHashTableKeyMembers(excludedKeys, wordToComplete, "LogName", "ProviderName", "Path", "Keywords", "ID", "Level",
return GetSpecialHashTableKeyMembers(excludedKeys, wordToComplete, "LogName", "ProviderName", "Path", "Keywords", "ID", "Level",
"StartTime", "EndTime", "UserID", "Data", "SuppressHashFilter");
}
}
@@ -7298,32 +7298,40 @@ namespace System.Management.Automation
internal static string CombineVariableWithPartialPath(VariableExpressionAst variableAst, string extraText, ExecutionContext executionContext)
{
var varPath = variableAst.VariablePath;
if (varPath.IsVariable || varPath.DriveName.Equals("env", StringComparison.OrdinalIgnoreCase))
if (!varPath.IsVariable && !varPath.DriveName.Equals("env", StringComparison.OrdinalIgnoreCase))
{
try
return null;
}
if (varPath.UnqualifiedPath.Equals(SpecialVariables.PSScriptRoot, StringComparison.OrdinalIgnoreCase)
&& !string.IsNullOrEmpty(variableAst.Extent.File))
{
return Path.GetDirectoryName(variableAst.Extent.File) + extraText;
}
try
{
// We check the strict mode inside GetVariableValue
object value = VariableOps.GetVariableValue(varPath, executionContext, variableAst);
var strValue = (value == null) ? string.Empty : value as string;
if (strValue == null)
{
// We check the strict mode inside GetVariableValue
object value = VariableOps.GetVariableValue(varPath, executionContext, variableAst);
var strValue = (value == null) ? string.Empty : value as string;
if (strValue == null)
object baseObj = PSObject.Base(value);
if (baseObj is string || baseObj?.GetType()?.IsPrimitive is true)
{
object baseObj = PSObject.Base(value);
if (baseObj is string || baseObj.GetType().IsPrimitive)
{
strValue = LanguagePrimitives.ConvertTo<string>(value);
}
}
if (strValue != null)
{
return strValue + extraText;
strValue = LanguagePrimitives.ConvertTo<string>(value);
}
}
catch (Exception)
if (strValue != null)
{
return strValue + extraText;
}
}
catch (Exception)
{
}
return null;
}
@@ -822,6 +822,26 @@ switch ($x)
$expected = ($expected | Sort-Object -CaseSensitive | ForEach-Object { "./$_" }) -join ":"
}
It "PSScriptRoot path completion when AST extent has file identity" {
$scriptText = '"$PSScriptRoot\BugFix.Tests"'
$tokens = $null
$scriptAst = [System.Management.Automation.Language.Parser]::ParseInput(
$scriptText,
$PSCommandPath,
[ref] $tokens,
[ref] $null)
$cursorPosition = $scriptAst.Extent.StartScriptPosition.
GetType().
GetMethod('CloneWithNewOffset', [System.Reflection.BindingFlags]'NonPublic, Instance').
Invoke($scriptAst.Extent.StartScriptPosition, @($scriptText.Length - 1))
$res = TabExpansion2 -ast $scriptAst -tokens $tokens -positionOfCursor $cursorPosition
$res.CompletionMatches | Should -HaveCount 1
$expectedPath = Join-Path $PSScriptRoot -ChildPath BugFix.Tests.ps1
$res.CompletionMatches[0].CompletionText | Should -Be "`"$expectedPath`""
}
}
Context "Cmdlet name completion" {