Skip to content

Commit 650189e

Browse files
authored
Fix completion that relies on pseudobinding in script blocks (PowerShell#25122)
1 parent f913924 commit 650189e

File tree

3 files changed

+20
-4
lines changed

3 files changed

+20
-4
lines changed

src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1406,7 +1406,6 @@ private CommandProcessorBase PrepareFromAst(ExecutionContext context, out string
14061406
}
14071407

14081408
ast.Visit(exportVisitor);
1409-
14101409
CommandProcessorBase commandProcessor = null;
14111410

14121411
resolvedCommandName = _commandAst.GetCommandName();

src/System.Management.Automation/engine/Modules/ScriptAnalysis.cs

+15-3
Original file line numberDiff line numberDiff line change
@@ -277,10 +277,22 @@ public override AstVisitAction VisitAssignmentStatement(AssignmentStatementAst a
277277
// - Exporting module members
278278
public override AstVisitAction VisitCommand(CommandAst commandAst)
279279
{
280-
string commandName =
281-
commandAst.GetCommandName() ??
282-
GetSafeValueVisitor.GetSafeValue(commandAst.CommandElements[0], null, GetSafeValueVisitor.SafeValueContext.ModuleAnalysis) as string;
280+
string commandName = commandAst.GetCommandName();
281+
if (commandName is null)
282+
{
283+
// GetCommandName only works if the name is a string constant. GetSafeValueVistor can evaluate some safe dynamic expressions
284+
try
285+
{
286+
commandName = GetSafeValueVisitor.GetSafeValue(commandAst.CommandElements[0], null, GetSafeValueVisitor.SafeValueContext.ModuleAnalysis) as string;
287+
}
288+
catch (ParseException)
289+
{
290+
// The script is invalid so we can't use GetSafeValue to get the name either.
291+
}
292+
}
283293

294+
// We couldn't get the name of the command. Either it's an anonymous scriptblock: & {"Some script"}
295+
// Or it's a dynamic expression we couldn't safely resolve.
284296
if (commandName == null)
285297
return AstVisitAction.SkipChildren;
286298

test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1

+5
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,11 @@ using `
837837
$res.CompletionMatches.CompletionText | Should -Contain "GetType"
838838
}
839839

840+
It 'Should complete variable member inferred from command inside scriptblock' {
841+
$res = TabExpansion2 -inputScript '& {(New-Guid).'
842+
$res.CompletionMatches.Count | Should -BeGreaterThan 0
843+
}
844+
840845
It 'Should not complete void instance members' {
841846
$res = TabExpansion2 -inputScript '([void]("")).'
842847
$res.CompletionMatches | Should -BeNullOrEmpty

0 commit comments

Comments
 (0)