Skip to content

Commit b5620bd

Browse files
author
Kapil Borle
committed
Update GetCommandInfo method and cache results
1 parent cab1dcb commit b5620bd

File tree

1 file changed

+45
-13
lines changed

1 file changed

+45
-13
lines changed

Engine/Helper.cs

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public class Helper
3838
private readonly static Version minSupportedPSVersion = new Version(3, 0);
3939
private Dictionary<string, Dictionary<string, object>> ruleArguments;
4040
private PSVersionTable psVersionTable;
41+
private Dictionary<string, CommandInfo> commandInfoCache;
4142

4243
#endregion
4344

@@ -146,6 +147,7 @@ public void Initialize()
146147
KeywordBlockDictionary = new Dictionary<String, List<Tuple<int, int>>>(StringComparer.OrdinalIgnoreCase);
147148
VariableAnalysisDictionary = new Dictionary<Ast, VariableAnalysis>();
148149
ruleArguments = new Dictionary<string, Dictionary<string, object>>(StringComparer.OrdinalIgnoreCase);
150+
commandInfoCache = new Dictionary<string, CommandInfo>(StringComparer.OrdinalIgnoreCase);
149151

150152
IEnumerable<CommandInfo> aliases = this.invokeCommand.GetCommands("*", CommandTypes.Alias, true);
151153

@@ -610,12 +612,16 @@ public bool HasSplattedVariable(CommandAst cmdAst)
610612
/// <returns></returns>
611613
public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanThreePositional = false)
612614
{
613-
if (cmdAst == null || cmdAst.GetCommandName() == null)
615+
if (cmdAst == null)
614616
{
615617
return false;
616618
}
617619

618-
CommandInfo commandInfo = GetCommandInfo(GetCmdletNameFromAlias(cmdAst.GetCommandName())) ?? GetCommandInfo(cmdAst.GetCommandName());
620+
var commandInfo = GetCommandInfo(cmdAst.GetCommandName());
621+
if (commandInfo == null || (commandInfo.CommandType != System.Management.Automation.CommandTypes.Cmdlet))
622+
{
623+
return false;
624+
}
619625

620626
IEnumerable<ParameterMetadata> switchParams = null;
621627

@@ -685,6 +691,23 @@ public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanThreePositio
685691
}
686692

687693

694+
/// <summary>
695+
/// Get a CommandInfo object of the given command name
696+
/// </summary>
697+
/// <returns>Returns null if command does not exists</returns>
698+
private CommandInfo GetCommandInfoInternal(string cmdName, CommandTypes? commandType = null)
699+
{
700+
using (var ps = System.Management.Automation.PowerShell.Create())
701+
{
702+
var cmdInfo = ps.AddCommand("Get-Command")
703+
.AddArgument(cmdName)
704+
.AddParameter("ErrorAction", "SilentlyContinue")
705+
.Invoke<CommandInfo>()
706+
.FirstOrDefault();
707+
return cmdInfo;
708+
}
709+
}
710+
688711
/// <summary>
689712
/// Given a command's name, checks whether it exists
690713
/// </summary>
@@ -693,19 +716,28 @@ public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanThreePositio
693716
/// <returns></returns>
694717
public CommandInfo GetCommandInfo(string name, CommandTypes? commandType = null)
695718
{
696-
CommandTypes defaultCmdType = CommandTypes.Alias
697-
| CommandTypes.Cmdlet
698-
| CommandTypes.ExternalScript
699-
| CommandTypes.Filter
700-
| CommandTypes.Function
701-
| CommandTypes.Script
702-
| CommandTypes.Workflow;
703-
#if !PSV3
704-
defaultCmdType |= CommandTypes.Configuration;
705-
#endif
719+
if (string.IsNullOrWhiteSpace(name))
720+
{
721+
return null;
722+
}
723+
724+
// check if it is an alias
725+
string cmdletName = Helper.Instance.GetCmdletNameFromAlias(name);
726+
if (string.IsNullOrWhiteSpace(cmdletName))
727+
{
728+
cmdletName = name;
729+
}
730+
706731
lock (getCommandLock)
707732
{
708-
return this.invokeCommand.GetCommand(name, commandType ?? defaultCmdType);
733+
if (commandInfoCache.ContainsKey(cmdletName))
734+
{
735+
return commandInfoCache[cmdletName];
736+
}
737+
738+
var commandInfo = GetCommandInfoInternal(cmdletName, commandType);
739+
commandInfoCache.Add(cmdletName, commandInfo);
740+
return commandInfo;
709741
}
710742
}
711743

0 commit comments

Comments
 (0)