From fb9393e0ccc83e381e9deebeb1b1da5a3ee2e8f4 Mon Sep 17 00:00:00 2001 From: MartinGC94 <42123497+MartinGC94@users.noreply.github.com> Date: Mon, 12 Sep 2022 20:34:15 +0200 Subject: [PATCH] Improve pseudo binding for dynamic parameters (#18030) --- .../PseudoParameterBinder.cs | 43 ++++++++++++++++--- .../TabCompletion/TabCompletion.Tests.ps1 | 5 +++ 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs b/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs index 97b39cf39f..a581a11af9 100644 --- a/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs +++ b/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs @@ -1211,9 +1211,6 @@ namespace System.Management.Automation.Language bool implementsDynamicParameters = commandProcessor != null && commandProcessor.CommandInfo.ImplementsDynamicParameters; - var argumentsToGetDynamicParameters = implementsDynamicParameters - ? new List(_commandElements.Count) - : null; if (commandProcessor != null || scriptProcessor != null) { // Pre-processing the arguments -- command arguments @@ -1222,7 +1219,32 @@ namespace System.Management.Automation.Language var parameter = _commandElements[commandIndex] as CommandParameterAst; if (parameter != null) { - argumentsToGetDynamicParameters?.Add(parameter.Extent.Text); + if (implementsDynamicParameters) + { + CommandParameterInternal paramToAdd; + if (parameter.Argument is null) + { + paramToAdd = CommandParameterInternal.CreateParameter(parameter.ParameterName, parameter.Extent.Text); + } + else + { + object value; + if (!SafeExprEvaluator.TrySafeEval(parameter.Argument, context, out value)) + { + value = parameter.Argument.Extent.Text; + } + + paramToAdd = CommandParameterInternal.CreateParameterWithArgument( + parameterAst: null, + parameterName: parameter.ParameterName, + parameterText: parameter.Extent.Text, + argumentAst: null, + value: value, + spaceAfterParameter: false); + } + + commandProcessor.AddParameter(paramToAdd); + } AstPair parameterArg = parameter.Argument != null ? new AstPair(parameter) @@ -1248,7 +1270,11 @@ namespace System.Management.Automation.Language } else if (_commandElements[commandIndex] is ExpressionAst expression) { - valueToAdd = expression.Extent.Text; + if (!SafeExprEvaluator.TrySafeEval(expression, context, out valueToAdd)) + { + valueToAdd = expression.Extent.Text; + } + expressionToAdd = expression; } else @@ -1256,7 +1282,11 @@ namespace System.Management.Automation.Language continue; } - argumentsToGetDynamicParameters?.Add(valueToAdd); + if (implementsDynamicParameters) + { + commandProcessor.AddParameter(CommandParameterInternal.CreateArgument(valueToAdd)); + } + _arguments.Add(new AstPair(null, expressionToAdd)); } } @@ -1267,7 +1297,6 @@ namespace System.Management.Automation.Language _function = false; if (implementsDynamicParameters) { - ParameterBinderController.AddArgumentsToCommandProcessor(commandProcessor, argumentsToGetDynamicParameters.ToArray()); bool retryWithNoArgs = false, alreadyRetried = false; do diff --git a/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 b/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 index 725b47138c..5a93d1307a 100644 --- a/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 +++ b/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 @@ -597,6 +597,11 @@ ConstructorTestClass(int i, bool b) $res.CompletionMatches[0].CompletionText | Should -BeExactly '-Directory' } + it 'Should complete dynamic parameters while providing values to non-string parameters' { + $res = TabExpansion2 -inputScript 'Get-Content -Path $HOME -Verbose:$false -' + $res.CompletionMatches.CompletionText | Should -Contain '-Raw' + } + It 'Should enumerate types when completing member names for Select-Object' { $TestString = '"Hello","World" | select-object ' $res = TabExpansion2 -inputScript $TestString