@@ -24,11 +24,11 @@ public class Helper
2424
2525 private CommandInvocationIntrinsics invokeCommand ;
2626 private IOutputWriter outputWriter ;
27- private Object getCommandLock = new object ( ) ;
2827 private readonly static Version minSupportedPSVersion = new Version ( 3 , 0 ) ;
2928 private Dictionary < string , Dictionary < string , object > > ruleArguments ;
3029 private PSVersionTable psVersionTable ;
31- private Dictionary < CommandLookupKey , CommandInfo > commandInfoCache ;
30+
31+ private readonly Lazy < CommandInfoCache > _commandInfoCacheLazy ;
3232
3333 #endregion
3434
@@ -100,14 +100,20 @@ internal set
100100 private string [ ] functionScopes = new string [ ] { "global:" , "local:" , "script:" , "private:" } ;
101101
102102 private string [ ] variableScopes = new string [ ] { "global:" , "local:" , "script:" , "private:" , "variable:" , ":" } ;
103+
104+ /// <summary>
105+ /// Store of command info objects for commands. Memoizes results.
106+ /// </summary>
107+ private CommandInfoCache CommandInfoCache => _commandInfoCacheLazy . Value ;
108+
103109 #endregion
104110
105111 /// <summary>
106112 /// Initializes the Helper class.
107113 /// </summary>
108114 private Helper ( )
109115 {
110-
116+ _commandInfoCacheLazy = new Lazy < CommandInfoCache > ( ( ) => new CommandInfoCache ( pssaHelperInstance : this ) ) ;
111117 }
112118
113119 /// <summary>
@@ -123,7 +129,7 @@ private Helper()
123129 /// </param>
124130 public Helper (
125131 CommandInvocationIntrinsics invokeCommand ,
126- IOutputWriter outputWriter )
132+ IOutputWriter outputWriter ) : this ( )
127133 {
128134 this . invokeCommand = invokeCommand ;
129135 this . outputWriter = outputWriter ;
@@ -140,10 +146,6 @@ public void Initialize()
140146 KeywordBlockDictionary = new Dictionary < String , List < Tuple < int , int > > > ( StringComparer . OrdinalIgnoreCase ) ;
141147 VariableAnalysisDictionary = new Dictionary < Ast , VariableAnalysis > ( ) ;
142148 ruleArguments = new Dictionary < string , Dictionary < string , object > > ( StringComparer . OrdinalIgnoreCase ) ;
143- if ( commandInfoCache == null )
144- {
145- commandInfoCache = new Dictionary < CommandLookupKey , CommandInfo > ( ) ;
146- }
147149
148150 IEnumerable < CommandInfo > aliases = this . invokeCommand . GetCommands ( "*" , CommandTypes . Alias , true ) ;
149151
@@ -677,7 +679,6 @@ private CommandInfo GetCommandInfoInternal(string cmdName, CommandTypes? command
677679 }
678680
679681 /// <summary>
680-
681682 /// Legacy method, new callers should use <see cref="GetCommandInfo"/> instead.
682683 /// Given a command's name, checks whether it exists. It does not use the passed in CommandTypes parameter, which is a bug.
683684 /// But existing method callers are already depending on this behaviour and therefore this could not be simply fixed.
@@ -689,30 +690,7 @@ private CommandInfo GetCommandInfoInternal(string cmdName, CommandTypes? command
689690 [ Obsolete ]
690691 public CommandInfo GetCommandInfoLegacy ( string name , CommandTypes ? commandType = null )
691692 {
692- if ( string . IsNullOrWhiteSpace ( name ) )
693- {
694- return null ;
695- }
696-
697- // check if it is an alias
698- string cmdletName = Helper . Instance . GetCmdletNameFromAlias ( name ) ;
699- if ( string . IsNullOrWhiteSpace ( cmdletName ) )
700- {
701- cmdletName = name ;
702- }
703-
704- var key = new CommandLookupKey ( name , commandType ) ;
705- lock ( getCommandLock )
706- {
707- if ( commandInfoCache . ContainsKey ( key ) )
708- {
709- return commandInfoCache [ key ] ;
710- }
711-
712- var commandInfo = GetCommandInfoInternal ( cmdletName , commandType ) ;
713- commandInfoCache . Add ( key , commandInfo ) ;
714- return commandInfo ;
715- }
693+ return CommandInfoCache . GetCommandInfoLegacy ( commandOrAliasName : name , commandTypes : commandType ) ;
716694 }
717695
718696 /// <summary>
@@ -723,23 +701,7 @@ public CommandInfo GetCommandInfoLegacy(string name, CommandTypes? commandType =
723701 /// <returns></returns>
724702 public CommandInfo GetCommandInfo ( string name , CommandTypes ? commandType = null )
725703 {
726- if ( string . IsNullOrWhiteSpace ( name ) )
727- {
728- return null ;
729- }
730-
731- var key = new CommandLookupKey ( name , commandType ) ;
732- lock ( getCommandLock )
733- {
734- if ( commandInfoCache . ContainsKey ( key ) )
735- {
736- return commandInfoCache [ key ] ;
737- }
738-
739- var commandInfo = GetCommandInfoInternal ( name , commandType ) ;
740- commandInfoCache . Add ( key , commandInfo ) ;
741- return commandInfo ;
742- }
704+ return CommandInfoCache . GetCommandInfo ( name , commandTypes : commandType ) ;
743705 }
744706
745707 /// <summary>
0 commit comments