mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Refactor CompletionCompleters.cs to avoid constructing unnecessary CompletionContext instances (#4048)
This commit is contained in:
+122
-92
@@ -76,7 +76,8 @@ namespace System.Management.Automation
|
||||
}
|
||||
|
||||
var helper = new PowerShellExecutionHelper(PowerShell.Create(RunspaceMode.CurrentRunspace));
|
||||
return CompleteCommand(new CompletionContext { WordToComplete = commandName, Helper = helper, ExecutionContext = helper.CurrentPowerShell.GetContextFromTLS() }, moduleName, commandTypes);
|
||||
var executionContext = helper.CurrentPowerShell.Runspace.ExecutionContext;
|
||||
return CompleteCommand(new CompletionContext { WordToComplete = commandName, Helper = helper, ExecutionContext = executionContext }, moduleName, commandTypes);
|
||||
}
|
||||
|
||||
internal static List<CompletionResult> CompleteCommand(CompletionContext context)
|
||||
@@ -118,7 +119,7 @@ namespace System.Management.Automation
|
||||
var commandInfos = context.Helper.ExecuteCurrentPowerShell(out exceptionThrown);
|
||||
|
||||
// Complete against pseudo commands that work only in the script workflow.
|
||||
// It's for argument completion when RelatedAst is null, don't complete pseudo commands for arguments
|
||||
// If RelatedAst is null then it's for argument completion, because we don't complete pseudo commands for arguments
|
||||
if (lastAst != null)
|
||||
{
|
||||
commandInfos = CompleteWorkflowCommand(commandName, lastAst, commandInfos);
|
||||
@@ -128,11 +129,11 @@ namespace System.Management.Automation
|
||||
{
|
||||
// OrderBy is using stable sorting
|
||||
var sortedCommandInfos = commandInfos.OrderBy(a => a, new CommandNameComparer());
|
||||
commandResults = MakeCommandsUnique(sortedCommandInfos, false, addAmpersandIfNecessary, quote, context);
|
||||
commandResults = MakeCommandsUnique(sortedCommandInfos, /* includeModulePrefix: */ false, addAmpersandIfNecessary, quote);
|
||||
}
|
||||
else
|
||||
{
|
||||
commandResults = MakeCommandsUnique(commandInfos, false, addAmpersandIfNecessary, quote, context);
|
||||
commandResults = MakeCommandsUnique(commandInfos, /* includeModulePrefix: */ false, addAmpersandIfNecessary, quote);
|
||||
}
|
||||
|
||||
if (lastAst != null)
|
||||
@@ -184,11 +185,11 @@ namespace System.Management.Automation
|
||||
if (commandInfos != null && commandInfos.Count > 1)
|
||||
{
|
||||
var sortedCommandInfos = commandInfos.OrderBy(a => a, new CommandNameComparer());
|
||||
commandResults = MakeCommandsUnique(sortedCommandInfos, true, addAmpersandIfNecessary, quote, context);
|
||||
commandResults = MakeCommandsUnique(sortedCommandInfos, /* includeModulePrefix: */ true, addAmpersandIfNecessary, quote);
|
||||
}
|
||||
else
|
||||
{
|
||||
commandResults = MakeCommandsUnique(commandInfos, true, addAmpersandIfNecessary, quote, context);
|
||||
commandResults = MakeCommandsUnique(commandInfos, /* includeModulePrefix: */ true, addAmpersandIfNecessary, quote);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,6 +197,21 @@ namespace System.Management.Automation
|
||||
return commandResults;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct a new instance of CompletionContext with RelatedAst = null.
|
||||
/// For argument completion, we don't want to complete against pseudo commands that only work in the script workflow.
|
||||
/// The way to avoid that is to pass in a CompletionContext with RelatedAst = null.
|
||||
/// </summary>
|
||||
private static CompletionContext NewContextToCompleteCommandAsArgument(CompletionContext context)
|
||||
{
|
||||
return new CompletionContext {
|
||||
WordToComplete = context.WordToComplete,
|
||||
Helper = context.Helper,
|
||||
ExecutionContext = context.ExecutionContext,
|
||||
Options = context.Options
|
||||
};
|
||||
}
|
||||
|
||||
private static readonly HashSet<string> s_keywordsToExcludeFromAddingAmpersand
|
||||
= new HashSet<string>(StringComparer.OrdinalIgnoreCase) { TokenKind.InlineScript.ToString(), TokenKind.Configuration.ToString() };
|
||||
internal static CompletionResult GetCommandNameCompletionResult(string name, object command, bool addAmpersandIfNecessary, string quote)
|
||||
@@ -252,7 +268,7 @@ namespace System.Management.Automation
|
||||
return new CompletionResult(name, listItem, CompletionResultType.Command, syntax);
|
||||
}
|
||||
|
||||
internal static List<CompletionResult> MakeCommandsUnique(IEnumerable<PSObject> commandInfoPsObjs, bool includeModulePrefix, bool addAmpersandIfNecessary, string quote, CompletionContext context)
|
||||
internal static List<CompletionResult> MakeCommandsUnique(IEnumerable<PSObject> commandInfoPsObjs, bool includeModulePrefix, bool addAmpersandIfNecessary, string quote)
|
||||
{
|
||||
List<CompletionResult> results = new List<CompletionResult>();
|
||||
if (commandInfoPsObjs == null || !commandInfoPsObjs.Any())
|
||||
@@ -579,7 +595,7 @@ namespace System.Management.Automation
|
||||
if (result.Count == 0)
|
||||
{
|
||||
result = pseudoBinding.CommandName.Equals("Set-Location", StringComparison.OrdinalIgnoreCase)
|
||||
? new List<CompletionResult>(CompleteFilename(context, true, null))
|
||||
? new List<CompletionResult>(CompleteFilename(context, containerOnly: true, extension: null))
|
||||
: new List<CompletionResult>(CompleteFilename(context));
|
||||
}
|
||||
|
||||
@@ -1325,7 +1341,8 @@ namespace System.Management.Automation
|
||||
{
|
||||
// For argument completion, we don't want to complete against pseudo commands that only work in the script workflow.
|
||||
// The way to avoid that is to pass in a CompletionContext with RelatedAst = null
|
||||
var commandResults = CompleteCommand(new CompletionContext { WordToComplete = context.WordToComplete, Helper = context.Helper, ExecutionContext = context.ExecutionContext });
|
||||
var newContext = NewContextToCompleteCommandAsArgument(context);
|
||||
var commandResults = CompleteCommand(newContext);
|
||||
if (commandResults != null)
|
||||
result.AddRange(commandResults);
|
||||
}
|
||||
@@ -2042,7 +2059,7 @@ namespace System.Management.Automation
|
||||
{
|
||||
if (parameterName.Equals("Module", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
NativeCompletionGetCommand(context.WordToComplete, null, parameterName, result, context);
|
||||
NativeCompletionGetCommand(context, /* moduleName: */ null, parameterName, result);
|
||||
break;
|
||||
}
|
||||
if (parameterName.Equals("Name", StringComparison.OrdinalIgnoreCase))
|
||||
@@ -2053,12 +2070,12 @@ namespace System.Management.Automation
|
||||
{
|
||||
foreach (string module in moduleNames)
|
||||
{
|
||||
NativeCompletionGetCommand(context.WordToComplete, module, parameterName, result, context);
|
||||
NativeCompletionGetCommand(context, module, parameterName, result);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NativeCompletionGetCommand(context.WordToComplete, null, parameterName, result, context);
|
||||
NativeCompletionGetCommand(context, /* moduleName: */ null, parameterName, result);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2073,13 +2090,13 @@ namespace System.Management.Automation
|
||||
}
|
||||
case "Show-Command":
|
||||
{
|
||||
NativeCompletionGetHelpCommand(context.WordToComplete, parameterName, false, result, context);
|
||||
NativeCompletionGetHelpCommand(context, parameterName, /* isHelpRelated: */ false, result);
|
||||
break;
|
||||
}
|
||||
case "help":
|
||||
case "Get-Help":
|
||||
{
|
||||
NativeCompletionGetHelpCommand(context.WordToComplete, parameterName, true, result, context);
|
||||
NativeCompletionGetHelpCommand(context, parameterName, /* isHelpRelated: */ true, result);
|
||||
break;
|
||||
}
|
||||
case "Invoke-Expression":
|
||||
@@ -2088,7 +2105,8 @@ namespace System.Management.Automation
|
||||
{
|
||||
// For argument completion, we don't want to complete against pseudo commands that only work in the script workflow.
|
||||
// The way to avoid that is to pass in a CompletionContext with RelatedAst = null
|
||||
var commandResults = CompleteCommand(new CompletionContext { WordToComplete = context.WordToComplete, Helper = context.Helper, ExecutionContext = context.ExecutionContext });
|
||||
var newContext = NewContextToCompleteCommandAsArgument(context);
|
||||
var commandResults = CompleteCommand(newContext);
|
||||
if (commandResults != null)
|
||||
result.AddRange(commandResults);
|
||||
}
|
||||
@@ -2100,7 +2118,7 @@ namespace System.Management.Automation
|
||||
case "Remove-EventLog":
|
||||
case "Write-EventLog":
|
||||
{
|
||||
NativeCompletionEventLogCommands(context.WordToComplete, parameterName, result, context);
|
||||
NativeCompletionEventLogCommands(context, parameterName, result);
|
||||
break;
|
||||
}
|
||||
case "Get-Job":
|
||||
@@ -2111,7 +2129,7 @@ namespace System.Management.Automation
|
||||
case "Suspend-Job":
|
||||
case "Resume-Job":
|
||||
{
|
||||
NativeCompletionJobCommands(context.WordToComplete, parameterName, result, context);
|
||||
NativeCompletionJobCommands(context, parameterName, result);
|
||||
break;
|
||||
}
|
||||
case "Disable-ScheduledJob":
|
||||
@@ -2119,23 +2137,23 @@ namespace System.Management.Automation
|
||||
case "Get-ScheduledJob":
|
||||
case "Unregister-ScheduledJob":
|
||||
{
|
||||
NativeCompletionScheduledJobCommands(context.WordToComplete, parameterName, result, context);
|
||||
NativeCompletionScheduledJobCommands(context, parameterName, result);
|
||||
break;
|
||||
}
|
||||
case "Get-Module":
|
||||
{
|
||||
bool loadedModulesOnly = boundArguments == null || !boundArguments.ContainsKey("ListAvailable");
|
||||
NativeCompletionModuleCommands(context.WordToComplete, parameterName, loadedModulesOnly, false, result, context);
|
||||
NativeCompletionModuleCommands(context, parameterName, loadedModulesOnly, /* isImportModule: */ false, result);
|
||||
break;
|
||||
}
|
||||
case "Remove-Module":
|
||||
{
|
||||
NativeCompletionModuleCommands(context.WordToComplete, parameterName, true, false, result, context);
|
||||
NativeCompletionModuleCommands(context, parameterName, /* loadedModulesOnly: */ true, /* isImportModule: */ false, result);
|
||||
break;
|
||||
}
|
||||
case "Import-Module":
|
||||
{
|
||||
NativeCompletionModuleCommands(context.WordToComplete, parameterName, false, true, result, context);
|
||||
NativeCompletionModuleCommands(context, parameterName, /* loadedModulesOnly: */ false, /* isImportModule: */ true, result);
|
||||
break;
|
||||
}
|
||||
case "Debug-Process":
|
||||
@@ -2144,7 +2162,7 @@ namespace System.Management.Automation
|
||||
case "Wait-Process":
|
||||
case "Enter-PSHostProcess":
|
||||
{
|
||||
NativeCompletionProcessCommands(context.WordToComplete, parameterName, result, context);
|
||||
NativeCompletionProcessCommands(context, parameterName, result);
|
||||
break;
|
||||
}
|
||||
case "Get-PSDrive":
|
||||
@@ -2152,7 +2170,7 @@ namespace System.Management.Automation
|
||||
{
|
||||
if (parameterName.Equals("PSProvider", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
NativeCompletionProviderCommands(context.WordToComplete, parameterName, result, context);
|
||||
NativeCompletionProviderCommands(context, parameterName, result);
|
||||
}
|
||||
else if (parameterName.Equals("Name", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
@@ -2161,12 +2179,12 @@ namespace System.Management.Automation
|
||||
{
|
||||
foreach (string psProvider in psProviders)
|
||||
{
|
||||
NativeCompletionDriveCommands(context.WordToComplete, psProvider, parameterName, result, context);
|
||||
NativeCompletionDriveCommands(context, psProvider, parameterName, result);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NativeCompletionDriveCommands(context.WordToComplete, null, parameterName, result, context);
|
||||
NativeCompletionDriveCommands(context, /* psProvider: */ null, parameterName, result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2174,12 +2192,12 @@ namespace System.Management.Automation
|
||||
}
|
||||
case "New-PSDrive":
|
||||
{
|
||||
NativeCompletionProviderCommands(context.WordToComplete, parameterName, result, context);
|
||||
NativeCompletionProviderCommands(context, parameterName, result);
|
||||
break;
|
||||
}
|
||||
case "Get-PSProvider":
|
||||
{
|
||||
NativeCompletionProviderCommands(context.WordToComplete, parameterName, result, context);
|
||||
NativeCompletionProviderCommands(context, parameterName, result);
|
||||
break;
|
||||
}
|
||||
case "Get-Service":
|
||||
@@ -2190,7 +2208,7 @@ namespace System.Management.Automation
|
||||
case "Stop-Service":
|
||||
case "Suspend-Service":
|
||||
{
|
||||
NativeCompletionServiceCommands(context.WordToComplete, parameterName, result, context);
|
||||
NativeCompletionServiceCommands(context, parameterName, result);
|
||||
break;
|
||||
}
|
||||
case "Clear-Variable":
|
||||
@@ -2198,43 +2216,43 @@ namespace System.Management.Automation
|
||||
case "Remove-Variable":
|
||||
case "Set-Variable":
|
||||
{
|
||||
NativeCompletionVariableCommands(context.WordToComplete, parameterName, result, context);
|
||||
NativeCompletionVariableCommands(context, parameterName, result);
|
||||
break;
|
||||
}
|
||||
case "Get-Alias":
|
||||
{
|
||||
NativeCompletionAliasCommands(context.WordToComplete, parameterName, result, context);
|
||||
NativeCompletionAliasCommands(context, parameterName, result);
|
||||
break;
|
||||
}
|
||||
case "Get-TraceSource":
|
||||
case "Set-TraceSource":
|
||||
case "Trace-Command":
|
||||
{
|
||||
NativeCompletionTraceSourceCommands(context.WordToComplete, parameterName, result, context);
|
||||
NativeCompletionTraceSourceCommands(context, parameterName, result);
|
||||
break;
|
||||
}
|
||||
case "Push-Location":
|
||||
case "Set-Location":
|
||||
{
|
||||
NativeCompletionSetLocationCommand(context.WordToComplete, parameterName, result, context);
|
||||
NativeCompletionSetLocationCommand(context, parameterName, result);
|
||||
break;
|
||||
}
|
||||
case "Move-Item":
|
||||
case "Copy-Item":
|
||||
{
|
||||
NativeCompletionCopyMoveItemCommand(context.WordToComplete, parameterName, result, context);
|
||||
NativeCompletionCopyMoveItemCommand(context, parameterName, result);
|
||||
break;
|
||||
}
|
||||
case "New-Item":
|
||||
{
|
||||
NativeCompletionNewItemCommand(context.WordToComplete, parameterName, result, context);
|
||||
NativeCompletionNewItemCommand(context, parameterName, result);
|
||||
break;
|
||||
}
|
||||
case "ForEach-Object":
|
||||
{
|
||||
if (parameterName.Equals("MemberName", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
NativeCompletionMemberName(context.WordToComplete, result, commandAst, context);
|
||||
NativeCompletionMemberName(context, result, commandAst);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2249,7 +2267,7 @@ namespace System.Management.Automation
|
||||
{
|
||||
if (parameterName.Equals("Property", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
NativeCompletionMemberName(context.WordToComplete, result, commandAst, context);
|
||||
NativeCompletionMemberName(context, result, commandAst);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2259,7 +2277,7 @@ namespace System.Management.Automation
|
||||
|| parameterName.Equals("ExcludeProperty", StringComparison.OrdinalIgnoreCase)
|
||||
|| parameterName.Equals("ExpandProperty", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
NativeCompletionMemberName(context.WordToComplete, result, commandAst, context);
|
||||
NativeCompletionMemberName(context, result, commandAst);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2286,7 +2304,7 @@ namespace System.Management.Automation
|
||||
|
||||
default:
|
||||
{
|
||||
NativeCompletionPathArgument(context.WordToComplete, parameterName, result, context);
|
||||
NativeCompletionPathArgument(context, parameterName, result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2771,14 +2789,17 @@ namespace System.Management.Automation
|
||||
result.AddRange(namespaceResults.OrderBy(x => x.ListItemText, StringComparer.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
private static void NativeCompletionGetCommand(string commandName, string moduleName, string paramName, List<CompletionResult> result, CompletionContext context)
|
||||
private static void NativeCompletionGetCommand(CompletionContext context, string moduleName, string paramName, List<CompletionResult> result)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(paramName) && paramName.Equals("Name", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
RemoveLastNullCompletionResult(result);
|
||||
|
||||
// Available commands
|
||||
var commandResults = CompleteCommand(new CompletionContext { WordToComplete = commandName, Helper = context.Helper, ExecutionContext = context.ExecutionContext }, moduleName);
|
||||
// For argument completion, we don't want to complete against pseudo commands that only work in the script workflow.
|
||||
// The way to avoid that is to pass in a CompletionContext with RelatedAst = null
|
||||
var newContext = NewContextToCompleteCommandAsArgument(context);
|
||||
var commandResults = CompleteCommand(newContext, moduleName);
|
||||
if (commandResults != null)
|
||||
result.AddRange(commandResults);
|
||||
|
||||
@@ -2788,7 +2809,7 @@ namespace System.Management.Automation
|
||||
// ps1 files and directories. We only complete the files with .ps1 extension for Get-Command, because the -Syntax
|
||||
// may only works on files with .ps1 extension
|
||||
var ps1Extension = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { StringLiterals.PowerShellScriptFileExtension };
|
||||
var moduleFilesResults = new List<CompletionResult>(CompleteFilename(new CompletionContext { WordToComplete = commandName, Helper = context.Helper, ExecutionContext = context.ExecutionContext }, false, ps1Extension));
|
||||
var moduleFilesResults = new List<CompletionResult>(CompleteFilename(context, /* containerOnly: */ false, ps1Extension));
|
||||
if (moduleFilesResults.Count > 0)
|
||||
result.AddRange(moduleFilesResults);
|
||||
}
|
||||
@@ -2800,7 +2821,7 @@ namespace System.Management.Automation
|
||||
RemoveLastNullCompletionResult(result);
|
||||
|
||||
var modules = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
var moduleResults = CompleteModuleName(new CompletionContext { WordToComplete = commandName, Helper = context.Helper, ExecutionContext = context.ExecutionContext }, true);
|
||||
var moduleResults = CompleteModuleName(context, loadedModulesOnly: true);
|
||||
if (moduleResults != null)
|
||||
{
|
||||
foreach (CompletionResult moduleResult in moduleResults)
|
||||
@@ -2813,7 +2834,7 @@ namespace System.Management.Automation
|
||||
}
|
||||
}
|
||||
|
||||
moduleResults = CompleteModuleName(new CompletionContext { WordToComplete = commandName, Helper = context.Helper, ExecutionContext = context.ExecutionContext }, false);
|
||||
moduleResults = CompleteModuleName(context, loadedModulesOnly: false);
|
||||
if (moduleResults != null)
|
||||
{
|
||||
foreach (CompletionResult moduleResult in moduleResults)
|
||||
@@ -2830,28 +2851,31 @@ namespace System.Management.Automation
|
||||
}
|
||||
}
|
||||
|
||||
private static void NativeCompletionGetHelpCommand(string commandName, string paramName, bool isHelpRelated, List<CompletionResult> result, CompletionContext context)
|
||||
private static void NativeCompletionGetHelpCommand(CompletionContext context, string paramName, bool isHelpRelated, List<CompletionResult> result)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(paramName) && paramName.Equals("Name", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
RemoveLastNullCompletionResult(result);
|
||||
|
||||
// Available commands
|
||||
// For argument completion, we don't want to complete against pseudo commands that only work in the script workflow.
|
||||
// The way to avoid that is to pass in a CompletionContext with RelatedAst = null
|
||||
const CommandTypes commandTypes = CommandTypes.Cmdlet | CommandTypes.Function | CommandTypes.Alias | CommandTypes.ExternalScript | CommandTypes.Workflow | CommandTypes.Configuration;
|
||||
var commandResults = CompleteCommand(new CompletionContext { WordToComplete = commandName, Helper = context.Helper, ExecutionContext = context.ExecutionContext }, null, commandTypes);
|
||||
var newContext = NewContextToCompleteCommandAsArgument(context);
|
||||
var commandResults = CompleteCommand(newContext, /* moduleName: */ null, commandTypes);
|
||||
if (commandResults != null)
|
||||
result.AddRange(commandResults);
|
||||
|
||||
// ps1 files and directories
|
||||
var ps1Extension = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { StringLiterals.PowerShellScriptFileExtension };
|
||||
var fileResults = new List<CompletionResult>(CompleteFilename(new CompletionContext { WordToComplete = commandName, Helper = context.Helper, ExecutionContext = context.ExecutionContext }, false, ps1Extension));
|
||||
var fileResults = new List<CompletionResult>(CompleteFilename(context, /* containerOnly: */ false, ps1Extension));
|
||||
if (fileResults.Count > 0)
|
||||
result.AddRange(fileResults);
|
||||
|
||||
if (isHelpRelated)
|
||||
{
|
||||
// Available topics
|
||||
var helpTopicResults = CompleteHelpTopics(new CompletionContext { WordToComplete = commandName, Helper = context.Helper, ExecutionContext = context.ExecutionContext });
|
||||
var helpTopicResults = CompleteHelpTopics(context);
|
||||
if (helpTopicResults != null)
|
||||
result.AddRange(helpTopicResults);
|
||||
}
|
||||
@@ -2860,13 +2884,13 @@ namespace System.Management.Automation
|
||||
}
|
||||
}
|
||||
|
||||
private static void NativeCompletionEventLogCommands(string logName, string paramName, List<CompletionResult> result, CompletionContext context)
|
||||
private static void NativeCompletionEventLogCommands(CompletionContext context, string paramName, List<CompletionResult> result)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(paramName) && paramName.Equals("LogName", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
RemoveLastNullCompletionResult(result);
|
||||
|
||||
logName = logName ?? string.Empty;
|
||||
var logName = context.WordToComplete ?? string.Empty;
|
||||
var quote = HandleDoubleAndSingleQuote(ref logName);
|
||||
|
||||
if (!logName.EndsWith("*", StringComparison.Ordinal))
|
||||
@@ -2911,12 +2935,12 @@ namespace System.Management.Automation
|
||||
}
|
||||
}
|
||||
|
||||
private static void NativeCompletionJobCommands(string wordToComplete, string paramName, List<CompletionResult> result, CompletionContext context)
|
||||
private static void NativeCompletionJobCommands(CompletionContext context, string paramName, List<CompletionResult> result)
|
||||
{
|
||||
if (string.IsNullOrEmpty(paramName))
|
||||
return;
|
||||
|
||||
wordToComplete = wordToComplete ?? string.Empty;
|
||||
var wordToComplete = context.WordToComplete ?? string.Empty;
|
||||
var quote = HandleDoubleAndSingleQuote(ref wordToComplete);
|
||||
|
||||
if (!wordToComplete.EndsWith("*", StringComparison.Ordinal))
|
||||
@@ -2997,12 +3021,12 @@ namespace System.Management.Automation
|
||||
}
|
||||
}
|
||||
|
||||
private static void NativeCompletionScheduledJobCommands(string wordToComplete, string paramName, List<CompletionResult> result, CompletionContext context)
|
||||
private static void NativeCompletionScheduledJobCommands(CompletionContext context, string paramName, List<CompletionResult> result)
|
||||
{
|
||||
if (string.IsNullOrEmpty(paramName))
|
||||
return;
|
||||
|
||||
wordToComplete = wordToComplete ?? string.Empty;
|
||||
var wordToComplete = context.WordToComplete ?? string.Empty;
|
||||
var quote = HandleDoubleAndSingleQuote(ref wordToComplete);
|
||||
|
||||
if (!wordToComplete.EndsWith("*", StringComparison.Ordinal))
|
||||
@@ -3071,7 +3095,7 @@ namespace System.Management.Automation
|
||||
}
|
||||
}
|
||||
|
||||
private static void NativeCompletionModuleCommands(string assemblyOrModuleName, string paramName, bool loadedModulesOnly, bool isImportModule, List<CompletionResult> result, CompletionContext context)
|
||||
private static void NativeCompletionModuleCommands(CompletionContext context, string paramName, bool loadedModulesOnly, bool isImportModule, List<CompletionResult> result)
|
||||
{
|
||||
if (string.IsNullOrEmpty(paramName))
|
||||
{
|
||||
@@ -3093,10 +3117,11 @@ namespace System.Management.Automation
|
||||
StringLiterals.PowerShellCmdletizationFileExtension,
|
||||
StringLiterals.WorkflowFileExtension
|
||||
};
|
||||
var moduleFilesResults = new List<CompletionResult>(CompleteFilename(new CompletionContext { WordToComplete = assemblyOrModuleName, Helper = context.Helper, ExecutionContext = context.ExecutionContext }, false, moduleExtensions));
|
||||
var moduleFilesResults = new List<CompletionResult>(CompleteFilename(context, /* containerOnly: */ false, moduleExtensions));
|
||||
if (moduleFilesResults.Count > 0)
|
||||
result.AddRange(moduleFilesResults);
|
||||
|
||||
var assemblyOrModuleName = context.WordToComplete;
|
||||
if (assemblyOrModuleName.IndexOfAny(Utils.Separators.DirectoryOrDrive) != -1)
|
||||
{
|
||||
// The partial input is a path, then we don't iterate modules under $ENV:PSModulePath
|
||||
@@ -3104,7 +3129,7 @@ namespace System.Management.Automation
|
||||
}
|
||||
}
|
||||
|
||||
var moduleResults = CompleteModuleName(new CompletionContext { WordToComplete = assemblyOrModuleName, Helper = context.Helper, ExecutionContext = context.ExecutionContext }, loadedModulesOnly);
|
||||
var moduleResults = CompleteModuleName(context, loadedModulesOnly);
|
||||
if (moduleResults != null && moduleResults.Count > 0)
|
||||
result.AddRange(moduleResults);
|
||||
|
||||
@@ -3115,7 +3140,7 @@ namespace System.Management.Automation
|
||||
RemoveLastNullCompletionResult(result);
|
||||
|
||||
var moduleExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { ".dll" };
|
||||
var moduleFilesResults = new List<CompletionResult>(CompleteFilename(new CompletionContext { WordToComplete = assemblyOrModuleName, Helper = context.Helper, ExecutionContext = context.ExecutionContext }, false, moduleExtensions));
|
||||
var moduleFilesResults = new List<CompletionResult>(CompleteFilename(context, /* containerOnly: */ false, moduleExtensions));
|
||||
if (moduleFilesResults.Count > 0)
|
||||
result.AddRange(moduleFilesResults);
|
||||
|
||||
@@ -3123,12 +3148,12 @@ namespace System.Management.Automation
|
||||
}
|
||||
}
|
||||
|
||||
private static void NativeCompletionProcessCommands(string wordToComplete, string paramName, List<CompletionResult> result, CompletionContext context)
|
||||
private static void NativeCompletionProcessCommands(CompletionContext context, string paramName, List<CompletionResult> result)
|
||||
{
|
||||
if (string.IsNullOrEmpty(paramName))
|
||||
return;
|
||||
|
||||
wordToComplete = wordToComplete ?? string.Empty;
|
||||
var wordToComplete = context.WordToComplete ?? string.Empty;
|
||||
var quote = HandleDoubleAndSingleQuote(ref wordToComplete);
|
||||
|
||||
if (!wordToComplete.EndsWith("*", StringComparison.Ordinal))
|
||||
@@ -3204,7 +3229,7 @@ namespace System.Management.Automation
|
||||
}
|
||||
}
|
||||
|
||||
private static void NativeCompletionProviderCommands(string providerName, string paramName, List<CompletionResult> result, CompletionContext context)
|
||||
private static void NativeCompletionProviderCommands(CompletionContext context, string paramName, List<CompletionResult> result)
|
||||
{
|
||||
if (string.IsNullOrEmpty(paramName) || !paramName.Equals("PSProvider", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
@@ -3213,7 +3238,7 @@ namespace System.Management.Automation
|
||||
|
||||
RemoveLastNullCompletionResult(result);
|
||||
|
||||
providerName = providerName ?? string.Empty;
|
||||
var providerName = context.WordToComplete ?? string.Empty;
|
||||
var quote = HandleDoubleAndSingleQuote(ref providerName);
|
||||
|
||||
|
||||
@@ -3251,14 +3276,14 @@ namespace System.Management.Automation
|
||||
result.Add(CompletionResult.Null);
|
||||
}
|
||||
|
||||
private static void NativeCompletionDriveCommands(string wordToComplete, string psProvider, string paramName, List<CompletionResult> result, CompletionContext context)
|
||||
private static void NativeCompletionDriveCommands(CompletionContext context, string psProvider, string paramName, List<CompletionResult> result)
|
||||
{
|
||||
if (string.IsNullOrEmpty(paramName) || !paramName.Equals("Name", StringComparison.OrdinalIgnoreCase))
|
||||
return;
|
||||
|
||||
RemoveLastNullCompletionResult(result);
|
||||
|
||||
wordToComplete = wordToComplete ?? string.Empty;
|
||||
var wordToComplete = context.WordToComplete ?? string.Empty;
|
||||
var quote = HandleDoubleAndSingleQuote(ref wordToComplete);
|
||||
|
||||
if (!wordToComplete.EndsWith("*", StringComparison.Ordinal))
|
||||
@@ -3300,12 +3325,12 @@ namespace System.Management.Automation
|
||||
result.Add(CompletionResult.Null);
|
||||
}
|
||||
|
||||
private static void NativeCompletionServiceCommands(string wordToComplete, string paramName, List<CompletionResult> result, CompletionContext context)
|
||||
private static void NativeCompletionServiceCommands(CompletionContext context, string paramName, List<CompletionResult> result)
|
||||
{
|
||||
if (string.IsNullOrEmpty(paramName))
|
||||
return;
|
||||
|
||||
wordToComplete = wordToComplete ?? string.Empty;
|
||||
var wordToComplete = context.WordToComplete ?? string.Empty;
|
||||
var quote = HandleDoubleAndSingleQuote(ref wordToComplete);
|
||||
|
||||
if (!wordToComplete.EndsWith("*", StringComparison.Ordinal))
|
||||
@@ -3383,7 +3408,7 @@ namespace System.Management.Automation
|
||||
}
|
||||
}
|
||||
|
||||
private static void NativeCompletionVariableCommands(string variableName, string paramName, List<CompletionResult> result, CompletionContext context)
|
||||
private static void NativeCompletionVariableCommands(CompletionContext context, string paramName, List<CompletionResult> result)
|
||||
{
|
||||
if (string.IsNullOrEmpty(paramName) || !paramName.Equals("Name", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
@@ -3392,7 +3417,7 @@ namespace System.Management.Automation
|
||||
|
||||
RemoveLastNullCompletionResult(result);
|
||||
|
||||
variableName = variableName ?? string.Empty;
|
||||
var variableName = context.WordToComplete ?? string.Empty;
|
||||
var quote = HandleDoubleAndSingleQuote(ref variableName);
|
||||
if (!variableName.EndsWith("*", StringComparison.Ordinal))
|
||||
{
|
||||
@@ -3437,7 +3462,7 @@ namespace System.Management.Automation
|
||||
result.Add(CompletionResult.Null);
|
||||
}
|
||||
|
||||
private static void NativeCompletionAliasCommands(string commandName, string paramName, List<CompletionResult> result, CompletionContext context)
|
||||
private static void NativeCompletionAliasCommands(CompletionContext context, string paramName, List<CompletionResult> result)
|
||||
{
|
||||
if (string.IsNullOrEmpty(paramName) ||
|
||||
(!paramName.Equals("Definition", StringComparison.OrdinalIgnoreCase) &&
|
||||
@@ -3451,7 +3476,7 @@ namespace System.Management.Automation
|
||||
var powerShellExecutionHelper = context.Helper;
|
||||
if (paramName.Equals("Name", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
commandName = commandName ?? string.Empty;
|
||||
var commandName = context.WordToComplete ?? string.Empty;
|
||||
var quote = HandleDoubleAndSingleQuote(ref commandName);
|
||||
|
||||
if (!commandName.EndsWith("*", StringComparison.Ordinal))
|
||||
@@ -3489,13 +3514,16 @@ namespace System.Management.Automation
|
||||
{
|
||||
// Complete for the parameter Definition
|
||||
// Available commands
|
||||
// For argument completion, we don't want to complete against pseudo commands that only work in the script workflow.
|
||||
// The way to avoid that is to pass in a CompletionContext with RelatedAst = null
|
||||
const CommandTypes commandTypes = CommandTypes.Cmdlet | CommandTypes.Function | CommandTypes.ExternalScript | CommandTypes.Workflow | CommandTypes.Configuration;
|
||||
var commandResults = CompleteCommand(new CompletionContext { WordToComplete = commandName, Helper = powerShellExecutionHelper, ExecutionContext = context.ExecutionContext }, null, commandTypes);
|
||||
var newContext = NewContextToCompleteCommandAsArgument(context);
|
||||
var commandResults = CompleteCommand(newContext, /* moduleName: */ null, commandTypes);
|
||||
if (commandResults != null && commandResults.Count > 0)
|
||||
result.AddRange(commandResults);
|
||||
|
||||
// The parameter Definition takes a file
|
||||
var fileResults = new List<CompletionResult>(CompleteFilename(new CompletionContext { WordToComplete = commandName, Helper = powerShellExecutionHelper, ExecutionContext = context.ExecutionContext }));
|
||||
var fileResults = new List<CompletionResult>(CompleteFilename(context));
|
||||
if (fileResults.Count > 0)
|
||||
result.AddRange(fileResults);
|
||||
}
|
||||
@@ -3503,7 +3531,7 @@ namespace System.Management.Automation
|
||||
result.Add(CompletionResult.Null);
|
||||
}
|
||||
|
||||
private static void NativeCompletionTraceSourceCommands(string traceSourceName, string paramName, List<CompletionResult> result, CompletionContext context)
|
||||
private static void NativeCompletionTraceSourceCommands(CompletionContext context, string paramName, List<CompletionResult> result)
|
||||
{
|
||||
if (string.IsNullOrEmpty(paramName) || !paramName.Equals("Name", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
@@ -3512,7 +3540,7 @@ namespace System.Management.Automation
|
||||
|
||||
RemoveLastNullCompletionResult(result);
|
||||
|
||||
traceSourceName = traceSourceName ?? string.Empty;
|
||||
var traceSourceName = context.WordToComplete ?? string.Empty;
|
||||
var quote = HandleDoubleAndSingleQuote(ref traceSourceName);
|
||||
|
||||
if (!traceSourceName.EndsWith("*", StringComparison.Ordinal))
|
||||
@@ -3550,7 +3578,7 @@ namespace System.Management.Automation
|
||||
result.Add(CompletionResult.Null);
|
||||
}
|
||||
|
||||
private static void NativeCompletionSetLocationCommand(string dirName, string paramName, List<CompletionResult> result, CompletionContext context)
|
||||
private static void NativeCompletionSetLocationCommand(CompletionContext context, string paramName, List<CompletionResult> result)
|
||||
{
|
||||
if (string.IsNullOrEmpty(paramName) ||
|
||||
(!paramName.Equals("Path", StringComparison.OrdinalIgnoreCase) &&
|
||||
@@ -3561,7 +3589,7 @@ namespace System.Management.Automation
|
||||
|
||||
RemoveLastNullCompletionResult(result);
|
||||
|
||||
context.WordToComplete = dirName ?? string.Empty;
|
||||
context.WordToComplete = context.WordToComplete ?? string.Empty;
|
||||
var clearLiteralPath = false;
|
||||
if (paramName.Equals("LiteralPath", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
@@ -3570,7 +3598,7 @@ namespace System.Management.Automation
|
||||
|
||||
try
|
||||
{
|
||||
var fileNameResults = CompleteFilename(context, true, null);
|
||||
var fileNameResults = CompleteFilename(context, containerOnly: true, extension: null);
|
||||
if (fileNameResults != null)
|
||||
result.AddRange(fileNameResults);
|
||||
}
|
||||
@@ -3586,11 +3614,10 @@ namespace System.Management.Automation
|
||||
/// <summary>
|
||||
/// Provides completion results for NewItemCommand
|
||||
/// </summary>
|
||||
/// <param name="itemTypeToComplete">The item provided by user for completion.</param>
|
||||
/// <param name="context">Completion context.</param>
|
||||
/// <param name="paramName">Name of the parameter whose value needs completion.</param>
|
||||
/// <param name="result">List of completion suggestions.</param>
|
||||
/// <param name="context">Completion context.</param>
|
||||
private static void NativeCompletionNewItemCommand(string itemTypeToComplete, string paramName, List<CompletionResult> result, CompletionContext context)
|
||||
private static void NativeCompletionNewItemCommand(CompletionContext context, string paramName, List<CompletionResult> result)
|
||||
{
|
||||
if (string.IsNullOrEmpty(paramName))
|
||||
{
|
||||
@@ -3613,9 +3640,9 @@ namespace System.Management.Automation
|
||||
{
|
||||
if (paramName.Equals("ItemType", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (!String.IsNullOrEmpty(itemTypeToComplete))
|
||||
if (!String.IsNullOrEmpty(context.WordToComplete))
|
||||
{
|
||||
WildcardPattern patternEvaluator = WildcardPattern.Get(itemTypeToComplete + "*", WildcardOptions.IgnoreCase);
|
||||
WildcardPattern patternEvaluator = WildcardPattern.Get(context.WordToComplete + "*", WildcardOptions.IgnoreCase);
|
||||
|
||||
if (patternEvaluator.IsMatch("file"))
|
||||
{
|
||||
@@ -3652,7 +3679,7 @@ namespace System.Management.Automation
|
||||
}
|
||||
}
|
||||
|
||||
private static void NativeCompletionCopyMoveItemCommand(string pathName, string paramName, List<CompletionResult> result, CompletionContext context)
|
||||
private static void NativeCompletionCopyMoveItemCommand(CompletionContext context, string paramName, List<CompletionResult> result)
|
||||
{
|
||||
if (string.IsNullOrEmpty(paramName))
|
||||
{
|
||||
@@ -3661,14 +3688,14 @@ namespace System.Management.Automation
|
||||
|
||||
if (paramName.Equals("LiteralPath", StringComparison.OrdinalIgnoreCase) || paramName.Equals("Path", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
NativeCompletionPathArgument(pathName, paramName, result, context);
|
||||
NativeCompletionPathArgument(context, paramName, result);
|
||||
}
|
||||
else if (paramName.Equals("Destination", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// The parameter Destination for Move-Item and Copy-Item takes literal path
|
||||
RemoveLastNullCompletionResult(result);
|
||||
|
||||
context.WordToComplete = pathName ?? string.Empty;
|
||||
context.WordToComplete = context.WordToComplete ?? string.Empty;
|
||||
var clearLiteralPath = TurnOnLiteralPathOption(context);
|
||||
|
||||
try
|
||||
@@ -3687,7 +3714,7 @@ namespace System.Management.Automation
|
||||
}
|
||||
}
|
||||
|
||||
private static void NativeCompletionPathArgument(string pathName, string paramName, List<CompletionResult> result, CompletionContext context)
|
||||
private static void NativeCompletionPathArgument(CompletionContext context, string paramName, List<CompletionResult> result)
|
||||
{
|
||||
if (string.IsNullOrEmpty(paramName) ||
|
||||
(!paramName.Equals("LiteralPath", StringComparison.OrdinalIgnoreCase) &&
|
||||
@@ -3699,7 +3726,7 @@ namespace System.Management.Automation
|
||||
|
||||
RemoveLastNullCompletionResult(result);
|
||||
|
||||
context.WordToComplete = pathName ?? string.Empty;
|
||||
context.WordToComplete = context.WordToComplete ?? string.Empty;
|
||||
var clearLiteralPath = false;
|
||||
if (paramName.Equals("LiteralPath", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
@@ -3721,7 +3748,7 @@ namespace System.Management.Automation
|
||||
result.Add(CompletionResult.Null);
|
||||
}
|
||||
|
||||
private static void NativeCompletionMemberName(string wordToComplete, List<CompletionResult> result, CommandAst commandAst, CompletionContext context)
|
||||
private static void NativeCompletionMemberName(CompletionContext context, List<CompletionResult> result, CommandAst commandAst)
|
||||
{
|
||||
// Command is something like where-object/foreach-object/format-list/etc. where there is a parameter that is a property name
|
||||
// and we want member names based on the input object, which is either the parameter InputObject, or comes from the pipeline.
|
||||
@@ -3757,7 +3784,7 @@ namespace System.Management.Automation
|
||||
prevType = AstTypeInference.InferTypeOf(pipelineAst.PipelineElements[i - 1], context.TypeInferenceContext, TypeInferenceRuntimePermissions.AllowSafeEval);
|
||||
}
|
||||
|
||||
CompleteMemberByInferredType(context, prevType, result, wordToComplete + "*", filter: IsPropertyMember, isStatic: false);
|
||||
CompleteMemberByInferredType(context, prevType, result, context.WordToComplete + "*", filter: IsPropertyMember, isStatic: false);
|
||||
result.Add(CompletionResult.Null);
|
||||
}
|
||||
|
||||
@@ -4034,12 +4061,13 @@ namespace System.Management.Automation
|
||||
}
|
||||
|
||||
var helper = new PowerShellExecutionHelper(PowerShell.Create(RunspaceMode.CurrentRunspace));
|
||||
return CompleteFilename(new CompletionContext { WordToComplete = fileName, Helper = helper, ExecutionContext = helper.CurrentPowerShell.GetContextFromTLS() });
|
||||
var executionContext = helper.CurrentPowerShell.Runspace.ExecutionContext;
|
||||
return CompleteFilename(new CompletionContext { WordToComplete = fileName, Helper = helper, ExecutionContext = executionContext });
|
||||
}
|
||||
|
||||
internal static IEnumerable<CompletionResult> CompleteFilename(CompletionContext context)
|
||||
{
|
||||
return CompleteFilename(context, false, null);
|
||||
return CompleteFilename(context, containerOnly: false, extension: null);
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly")]
|
||||
@@ -4483,7 +4511,8 @@ namespace System.Management.Automation
|
||||
}
|
||||
|
||||
var helper = new PowerShellExecutionHelper(PowerShell.Create(RunspaceMode.CurrentRunspace));
|
||||
return CompleteVariable(new CompletionContext { WordToComplete = variableName, Helper = helper, ExecutionContext = helper.CurrentPowerShell.GetContextFromTLS() });
|
||||
var executionContext = helper.CurrentPowerShell.Runspace.ExecutionContext;
|
||||
return CompleteVariable(new CompletionContext { WordToComplete = variableName, Helper = helper, ExecutionContext = executionContext });
|
||||
}
|
||||
|
||||
private static readonly string[] s_variableScopes = new string[] { "Global:", "Local:", "Script:", "Private:" };
|
||||
@@ -5860,7 +5889,8 @@ namespace System.Management.Automation
|
||||
: PowerShell.Create(RunspaceMode.CurrentRunspace);
|
||||
|
||||
var helper = new PowerShellExecutionHelper(powershell);
|
||||
return CompleteType(new CompletionContext { WordToComplete = typeName, Helper = helper, ExecutionContext = helper.CurrentPowerShell.GetContextFromTLS() });
|
||||
var executionContext = helper.CurrentPowerShell.Runspace.ExecutionContext;
|
||||
return CompleteType(new CompletionContext { WordToComplete = typeName, Helper = helper, ExecutionContext = executionContext });
|
||||
}
|
||||
|
||||
internal static List<CompletionResult> CompleteType(CompletionContext context, string prefix = "", string suffix = "")
|
||||
|
||||
Reference in New Issue
Block a user