diff --git a/Engine/CommandLookupKey.cs b/Engine/CommandLookupKey.cs new file mode 100644 index 000000000..bcd7e7097 --- /dev/null +++ b/Engine/CommandLookupKey.cs @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Management.Automation; + +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer +{ + internal struct CommandLookupKey : IEquatable + { + private readonly string Name; + + private readonly CommandTypes CommandTypes; + + internal CommandLookupKey(string name, CommandTypes? commandTypes) + { + Name = name; + CommandTypes = commandTypes ?? CommandTypes.All; + } + + public bool Equals(CommandLookupKey other) + { + return CommandTypes == other.CommandTypes + && Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase); + } + + public override int GetHashCode() + { + // Algorithm from https://stackoverflow.com/questions/1646807/quick-and-simple-hash-code-combinations + unchecked + { + int hash = 17; + hash = hash * 31 + Name.ToUpperInvariant().GetHashCode(); + hash = hash * 31 + CommandTypes.GetHashCode(); + return hash; + } + } + } +} diff --git a/Engine/Helper.cs b/Engine/Helper.cs index c86e2eb55..3d1f4a4ad 100644 --- a/Engine/Helper.cs +++ b/Engine/Helper.cs @@ -28,7 +28,7 @@ public class Helper private readonly static Version minSupportedPSVersion = new Version(3, 0); private Dictionary> ruleArguments; private PSVersionTable psVersionTable; - private Dictionary commandInfoCache; + private Dictionary commandInfoCache; #endregion @@ -142,7 +142,7 @@ public void Initialize() ruleArguments = new Dictionary>(StringComparer.OrdinalIgnoreCase); if (commandInfoCache == null) { - commandInfoCache = new Dictionary(StringComparer.OrdinalIgnoreCase); + commandInfoCache = new Dictionary(); } IEnumerable aliases = this.invokeCommand.GetCommands("*", CommandTypes.Alias, true); @@ -700,15 +700,16 @@ public CommandInfo GetCommandInfoLegacy(string name, CommandTypes? commandType = cmdletName = name; } + var key = new CommandLookupKey(name, commandType); lock (getCommandLock) { - if (commandInfoCache.ContainsKey(cmdletName)) + if (commandInfoCache.ContainsKey(key)) { - return commandInfoCache[cmdletName]; + return commandInfoCache[key]; } var commandInfo = GetCommandInfoInternal(cmdletName, commandType); - commandInfoCache.Add(cmdletName, commandInfo); + commandInfoCache.Add(key, commandInfo); return commandInfo; } } @@ -726,15 +727,16 @@ public CommandInfo GetCommandInfo(string name, CommandTypes? commandType = null) return null; } + var key = new CommandLookupKey(name, commandType); lock (getCommandLock) { - if (commandInfoCache.ContainsKey(name)) + if (commandInfoCache.ContainsKey(key)) { - return commandInfoCache[name]; + return commandInfoCache[key]; } var commandInfo = GetCommandInfoInternal(name, commandType); - + commandInfoCache.Add(key, commandInfo); return commandInfo; } }