mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Filter completion for enum parameter against ValidateRange attributes (#17750)
This commit is contained in:
@@ -1311,6 +1311,28 @@ namespace System.Management.Automation
|
||||
|
||||
return resultType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns only the elements that passed the attribute's validation.
|
||||
/// </summary>
|
||||
/// <param name="elementsToValidate">The objects to validate.</param>
|
||||
internal IEnumerable GetValidatedElements(IEnumerable elementsToValidate)
|
||||
{
|
||||
foreach (var el in elementsToValidate)
|
||||
{
|
||||
try
|
||||
{
|
||||
ValidateElement(el);
|
||||
}
|
||||
catch (ValidationMetadataException)
|
||||
{
|
||||
// Element was not in range - drop
|
||||
continue;
|
||||
}
|
||||
|
||||
yield return el;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1796,9 +1796,16 @@ namespace System.Management.Automation
|
||||
{
|
||||
RemoveLastNullCompletionResult(result);
|
||||
|
||||
string enumString = LanguagePrimitives.EnumSingleTypeConverter.EnumValues(parameterType);
|
||||
string separator = CultureInfo.CurrentUICulture.TextInfo.ListSeparator;
|
||||
string[] enumArray = enumString.Split(separator, StringSplitOptions.RemoveEmptyEntries);
|
||||
IEnumerable enumValues = LanguagePrimitives.EnumSingleTypeConverter.GetEnumValues(parameterType);
|
||||
|
||||
// Exclude values not accepted by ValidateRange-attributes
|
||||
foreach (ValidateArgumentsAttribute att in parameter.Parameter.ValidationAttributes)
|
||||
{
|
||||
if (att is ValidateRangeAttribute rangeAtt)
|
||||
{
|
||||
enumValues = rangeAtt.GetValidatedElements(enumValues);
|
||||
}
|
||||
}
|
||||
|
||||
string wordToComplete = context.WordToComplete ?? string.Empty;
|
||||
string quote = HandleDoubleAndSingleQuote(ref wordToComplete);
|
||||
@@ -1806,18 +1813,19 @@ namespace System.Management.Automation
|
||||
var pattern = WildcardPattern.Get(wordToComplete + "*", WildcardOptions.IgnoreCase);
|
||||
var enumList = new List<string>();
|
||||
|
||||
foreach (string value in enumArray)
|
||||
foreach (Enum value in enumValues)
|
||||
{
|
||||
if (wordToComplete.Equals(value, StringComparison.OrdinalIgnoreCase))
|
||||
string name = value.ToString();
|
||||
if (wordToComplete.Equals(name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
string completionText = quote == string.Empty ? value : quote + value + quote;
|
||||
fullMatch = new CompletionResult(completionText, value, CompletionResultType.ParameterValue, value);
|
||||
string completionText = quote == string.Empty ? name : quote + name + quote;
|
||||
fullMatch = new CompletionResult(completionText, name, CompletionResultType.ParameterValue, name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pattern.IsMatch(value))
|
||||
if (pattern.IsMatch(name))
|
||||
{
|
||||
enumList.Add(value);
|
||||
enumList.Add(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2076,6 +2076,14 @@ namespace System.Management.Automation
|
||||
return string.Join(CultureInfo.CurrentUICulture.TextInfo.ListSeparator, enumHashEntry.names);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all values for the provided enum type.
|
||||
/// </summary>
|
||||
/// <param name="enumType">The enum type to retrieve values from.</param>
|
||||
/// <returns>Array of enum values for the specified type.</returns>
|
||||
internal static Array GetEnumValues(Type enumType)
|
||||
=> EnumSingleTypeConverter.GetEnumHashEntry(enumType).values;
|
||||
|
||||
public override object ConvertFrom(object sourceValue, Type destinationType, IFormatProvider formatProvider, bool ignoreCase)
|
||||
{
|
||||
return EnumSingleTypeConverter.BaseConvertFrom(sourceValue, destinationType, formatProvider, ignoreCase, false);
|
||||
|
||||
@@ -1597,6 +1597,31 @@ class InheritedClassTest : System.Attribute
|
||||
$res.CompletionMatches[1].CompletionText | Should -BeExactly 'Configuration'
|
||||
}
|
||||
|
||||
It 'Tab completion for enum parameter is filtered against <Name>' -TestCases @(
|
||||
@{ Name = 'ValidateRange with enum-values'; Attribute = '[ValidateRange([System.ConsoleColor]::Blue, [System.ConsoleColor]::Cyan)]' }
|
||||
@{ Name = 'ValidateRange with int-values'; Attribute = '[ValidateRange(9, 11)]' }
|
||||
@{ Name = 'multiple ValidateRange-attributes'; Attribute = '[ValidateRange([System.ConsoleColor]::Blue, [System.ConsoleColor]::Cyan)][ValidateRange([System.ConsoleColor]::Gray, [System.ConsoleColor]::Red)]' }
|
||||
) {
|
||||
param($Name, $Attribute)
|
||||
$functionDefinition = 'param ( {0}[consolecolor]$color )' -f $Attribute
|
||||
Set-Item -Path function:baz -Value $functionDefinition
|
||||
$inputStr = 'baz -color '
|
||||
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr.Length
|
||||
$res.CompletionMatches | Should -HaveCount 3
|
||||
$res.CompletionMatches[0].CompletionText | Should -BeExactly 'Blue'
|
||||
$res.CompletionMatches[1].CompletionText | Should -BeExactly 'Cyan'
|
||||
$res.CompletionMatches[2].CompletionText | Should -BeExactly 'Green'
|
||||
}
|
||||
|
||||
It 'Tab completion for enum parameter is filtered with ValidateRange using rangekind' {
|
||||
$functionDefinition = 'param ( [ValidateRange([System.Management.Automation.ValidateRangeKind]::NonPositive)][consolecolor]$color )' -f $Attribute
|
||||
Set-Item -Path function:baz -Value $functionDefinition
|
||||
$inputStr = 'baz -color '
|
||||
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr.Length
|
||||
$res.CompletionMatches | Should -HaveCount 1
|
||||
$res.CompletionMatches[0].CompletionText | Should -BeExactly 'Black' # 0 = NonPositive
|
||||
}
|
||||
|
||||
It "Test [CommandCompletion]::GetNextResult" {
|
||||
$inputStr = "Get-Command -Type Alias,c"
|
||||
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr.Length
|
||||
|
||||
Reference in New Issue
Block a user