From fbb8069d4d6e0c1127d38026a8509d8c16861fd4 Mon Sep 17 00:00:00 2001 From: MartinGC94 Date: Fri, 14 Apr 2023 18:03:29 +0200 Subject: [PATCH 1/2] Fix dynamic parameter completion --- .../CommandCompletion/CompletionCompleters.cs | 13 ++++++++++++- .../CommandCompletion/PseudoParameterBinder.cs | 11 +++++++++-- .../Host/TabCompletion/TabCompletion.Tests.ps1 | 14 ++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs b/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs index 7d7ecf9ab91..23976a9136f 100644 --- a/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs +++ b/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs @@ -707,7 +707,18 @@ private static List GetParameterCompletionResults(string param break; } - Diagnostics.Assert(matchedParameterName != null, "we should find matchedParameterName from the BoundArguments"); + if (matchedParameterName is null) + { + // The pseudo binder has skipped a parameter + // This will happen when completing parameters for commands with dynamic parameters. + result = GetParameterCompletionResults( + parameterName, + bindingInfo.ValidParameterSetsFlags, + bindingInfo.UnboundParameters, + withColon); + return result; + } + MergedCompiledCommandParameter param = bindingInfo.BoundParameters[matchedParameterName]; WildcardPattern pattern = WildcardPattern.Get(parameterName + "*", WildcardOptions.IgnoreCase); diff --git a/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs b/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs index a581a11af92..4201be16f93 100644 --- a/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs +++ b/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs @@ -982,7 +982,7 @@ internal PseudoBindingInfo DoPseudoParameterBinding(CommandAst command, Type pip executionContext.LanguageMode = PSLanguageMode.ConstrainedLanguage; } - _bindingEffective = PrepareCommandElements(executionContext); + _bindingEffective = PrepareCommandElements(executionContext, paramAstAtCursor); } finally { @@ -1189,7 +1189,7 @@ private void InitializeMembers() _duplicateParameters.Clear(); } - private bool PrepareCommandElements(ExecutionContext context) + private bool PrepareCommandElements(ExecutionContext context, CommandParameterAst paramAtCursor) { int commandIndex = 0; bool dotSource = _commandAst.InvocationOperator == TokenKind.Dot; @@ -1216,6 +1216,13 @@ private bool PrepareCommandElements(ExecutionContext context) // Pre-processing the arguments -- command arguments for (commandIndex++; commandIndex < _commandElements.Count; commandIndex++) { + if (implementsDynamicParameters && _commandElements[commandIndex] == paramAtCursor) + { + // Commands with dynamic parameters will try to bind the command elements. + // A partially complete parameter will most likely cause a binding error and negatively affect the results. + continue; + } + var parameter = _commandElements[commandIndex] as CommandParameterAst; if (parameter != null) { diff --git a/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 b/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 index d7c98b1589d..9e981f11866 100644 --- a/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 +++ b/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 @@ -883,6 +883,20 @@ class InheritedClassTest : System.Attribute $res.CompletionMatches.CompletionText | Should -Contain '-ProgressAction' } + It 'Should complete dynamic parameters with partial input' { + # See issue: #19498 + try + { + Push-Location function: + $res = TabExpansion2 -inputScript 'Get-ChildItem -LiteralPath $PSHOME -File' + $res.CompletionMatches[0].CompletionText | Should -Be '-File' + } + finally + { + Pop-Location + } + } + Context "Script name completion" { BeforeAll { Setup -f 'install-powershell.ps1' -Content "" From 03ab9b1dd703b12e5826c60859cdeaa44afabde0 Mon Sep 17 00:00:00 2001 From: MartinGC94 Date: Tue, 16 May 2023 21:47:32 +0200 Subject: [PATCH 2/2] Fix test --- test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 b/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 index 9e981f11866..710abd5dbae 100644 --- a/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 +++ b/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 @@ -888,8 +888,8 @@ class InheritedClassTest : System.Attribute try { Push-Location function: - $res = TabExpansion2 -inputScript 'Get-ChildItem -LiteralPath $PSHOME -File' - $res.CompletionMatches[0].CompletionText | Should -Be '-File' + $res = TabExpansion2 -inputScript 'Get-ChildItem -LiteralPath $PSHOME -Fi' + $res.CompletionMatches[1].CompletionText | Should -Be '-File' } finally {