Improve the completion for attribute arguments (#25129)

This commit is contained in:
MartinGC94
2025-03-06 13:09:40 +00:00
committed by GitHub
parent 650189e603
commit d820692939
3 changed files with 89 additions and 3 deletions
@@ -693,6 +693,19 @@ namespace System.Management.Automation
return completions;
}
}
else if (lastAst is VariableExpressionAst && lastAst.Parent is ParameterAst paramAst && paramAst.Attributes.Count > 0)
{
foreach (AttributeBaseAst attribute in paramAst.Attributes)
{
if (IsCursorWithinOrJustAfterExtent(_cursorPosition, attribute.Extent))
{
completionContext.ReplacementIndex = replacementIndex += tokenAtCursor.Text.Length;
completionContext.ReplacementLength = replacementLength = 0;
result = GetResultForAttributeArgument(completionContext, ref replacementIndex, ref replacementLength);
break;
}
}
}
else
{
// Handle scenarios such as 'configuration foo { File ab { Attributes ='
@@ -928,6 +941,18 @@ namespace System.Management.Automation
{
result = GetResultForAttributeArgument(completionContext, ref replacementIndex, ref replacementLength);
}
if (lastAst is VariableExpressionAst && lastAst.Parent is ParameterAst paramAst && paramAst.Attributes.Count > 0)
{
foreach (AttributeBaseAst attribute in paramAst.Attributes)
{
if (IsCursorWithinOrJustAfterExtent(_cursorPosition, attribute.Extent))
{
result = GetResultForAttributeArgument(completionContext, ref replacementIndex, ref replacementLength);
break;
}
}
}
break;
case TokenKind.Ieq:
@@ -1003,6 +1028,21 @@ namespace System.Management.Automation
break;
}
if (lastAst is VariableExpressionAst && lastAst.Parent is ParameterAst paramAst && paramAst.Attributes.Count > 0)
{
foreach (AttributeBaseAst attribute in paramAst.Attributes)
{
if (IsCursorWithinOrJustAfterExtent(_cursorPosition, attribute.Extent))
{
completionContext.ReplacementLength = replacementLength = 0;
result = GetResultForAttributeArgument(completionContext, ref replacementIndex, ref replacementLength);
break;
}
}
break;
}
result = GetResultForEnumPropertyValueOfDSCResource(completionContext, string.Empty, ref replacementIndex, ref replacementLength, out _);
break;
}
@@ -2100,9 +2140,25 @@ namespace System.Management.Automation
}
}
}
if (completionContext.TokenAtCursor.TokenFlags == TokenFlags.MemberName && (lastAst is NamedAttributeArgumentAst || lastAst.Parent is NamedAttributeArgumentAst))
if (completionContext.TokenAtCursor.TokenFlags == TokenFlags.MemberName)
{
result = GetResultForAttributeArgument(completionContext, ref replacementIndex, ref replacementLength);
if (lastAst is NamedAttributeArgumentAst || lastAst.Parent is NamedAttributeArgumentAst)
{
result = GetResultForAttributeArgument(completionContext, ref replacementIndex, ref replacementLength);
}
else if (lastAst is VariableExpressionAst && lastAst.Parent is ParameterAst paramAst && paramAst.Attributes.Count > 0)
{
foreach (AttributeBaseAst attribute in paramAst.Attributes)
{
if (IsCursorWithinOrJustAfterExtent(completionContext.CursorPosition, attribute.Extent))
{
result = GetResultForAttributeArgument(completionContext, ref replacementIndex, ref replacementLength);
break;
}
}
}
if (result is not null)
{
return result;
@@ -7154,7 +7154,7 @@ namespace System.Management.Automation.Language
ParserStrings.UnexpectedAttribute,
lastAttribute.TypeName.FullName);
return new ErrorExpressionAst(ExtentOf(token, lastAttribute));
return new ErrorExpressionAst(ExtentOf(token, lastAttribute), attributes);
}
expr = new AttributedExpressionAst(ExtentOf(lastAttribute, child), lastAttribute, child);
@@ -901,6 +901,36 @@ ConstructorTestClass(int i, bool b)
$diffs | Should -BeNullOrEmpty
}
It 'Should complete attribute argument in incomplete param block' {
$res = TabExpansion2 -inputScript 'param([ValidatePattern('
$Expected = ([ValidatePattern].GetProperties() | Where-Object {$_.CanWrite}).Name -join ','
$res.CompletionMatches.CompletionText -join ',' | Should -BeExactly $Expected
}
It 'Should complete attribute argument in incomplete param block on new line' {
$TestString = @'
param([ValidatePattern(
^)])
'@
$CursorIndex = $TestString.IndexOf('^')
$res = TabExpansion2 -cursorColumn $CursorIndex -inputScript $TestString.Remove($CursorIndex, 1)
$Expected = ([ValidatePattern].GetProperties() | Where-Object {$_.CanWrite}).Name -join ','
$res.CompletionMatches.CompletionText -join ',' | Should -BeExactly $Expected
}
It 'Should complete attribute argument with partially written name in incomplete param block' {
$TestString = 'param([ValidatePattern(op^)]'
$CursorIndex = $TestString.IndexOf('^')
$res = TabExpansion2 -cursorColumn $CursorIndex -inputScript $TestString.Remove($CursorIndex, 1)
$res.CompletionMatches[0].CompletionText | Should -BeExactly 'Options'
}
It 'Should complete attribute argument for incomplete standalone attribute' {
$res = TabExpansion2 -inputScript '[ValidatePattern('
$Expected = ([ValidatePattern].GetProperties() | Where-Object {$_.CanWrite}).Name -join ','
$res.CompletionMatches.CompletionText -join ',' | Should -BeExactly $Expected
}
It 'Should complete argument for second parameter' {
$res = TabExpansion2 -inputScript 'Get-ChildItem -Path $HOME -ErrorAction '
$res.CompletionMatches[0].CompletionText | Should -BeExactly Break