2
2
// Licensed under the MIT License.
3
3
4
4
using System ;
5
+ using System . Collections ;
5
6
using System . Collections . Generic ;
7
+ using System . Linq ;
6
8
using Data = Microsoft . PowerShell . CrossCompatibility . Data ;
7
9
8
10
namespace Microsoft . PowerShell . CrossCompatibility . Query
@@ -14,6 +16,10 @@ public class RuntimeData
14
16
{
15
17
private readonly Lazy < IReadOnlyDictionary < string , IReadOnlyDictionary < Version , ModuleData > > > _modules ;
16
18
19
+ private readonly Lazy < IReadOnlyDictionary < string , IReadOnlyList < CommandData > > > _nonAliasCommands ;
20
+
21
+ private readonly Lazy < IReadOnlyDictionary < string , IReadOnlyList < CommandData > > > _aliases ;
22
+
17
23
private readonly Lazy < IReadOnlyDictionary < string , IReadOnlyList < CommandData > > > _commands ;
18
24
19
25
private readonly Lazy < NativeCommandLookupTable > _nativeCommands ;
@@ -28,7 +34,9 @@ public RuntimeData(Data.RuntimeData runtimeData)
28
34
Common = new CommonPowerShellData ( runtimeData . Common ) ;
29
35
30
36
_modules = new Lazy < IReadOnlyDictionary < string , IReadOnlyDictionary < Version , ModuleData > > > ( ( ) => CreateModuleTable ( runtimeData . Modules ) ) ;
31
- _commands = new Lazy < IReadOnlyDictionary < string , IReadOnlyList < CommandData > > > ( ( ) => CreateCommandLookupTable ( Modules ) ) ;
37
+ _nonAliasCommands = new Lazy < IReadOnlyDictionary < string , IReadOnlyList < CommandData > > > ( ( ) => CreateNonAliasCommandLookupTable ( Modules ) ) ;
38
+ _aliases = new Lazy < IReadOnlyDictionary < string , IReadOnlyList < CommandData > > > ( ( ) => CreateAliasLookupTable ( runtimeData . Modules , NonAliasCommands ) ) ;
39
+ _commands = new Lazy < IReadOnlyDictionary < string , IReadOnlyList < CommandData > > > ( ( ) => new DualLookupTable < string , IReadOnlyList < CommandData > > ( NonAliasCommands , Aliases ) ) ;
32
40
_nativeCommands = new Lazy < NativeCommandLookupTable > ( ( ) => NativeCommandLookupTable . Create ( runtimeData . NativeCommands ) ) ;
33
41
}
34
42
@@ -58,22 +66,26 @@ public RuntimeData(Data.RuntimeData runtimeData)
58
66
/// </summary>
59
67
public CommonPowerShellData Common { get ; }
60
68
61
- private static IReadOnlyDictionary < string , IReadOnlyDictionary < Version , ModuleData > > CreateModuleTable ( IDictionary < string , JsonDictionary < Version , Data . ModuleData > > modules )
69
+ internal IReadOnlyDictionary < string , IReadOnlyList < CommandData > > NonAliasCommands => _nonAliasCommands . Value ;
70
+
71
+ internal IReadOnlyDictionary < string , IReadOnlyList < CommandData > > Aliases => _aliases . Value ;
72
+
73
+ private IReadOnlyDictionary < string , IReadOnlyDictionary < Version , ModuleData > > CreateModuleTable ( IDictionary < string , JsonDictionary < Version , Data . ModuleData > > modules )
62
74
{
63
75
var moduleDict = new Dictionary < string , IReadOnlyDictionary < Version , ModuleData > > ( modules . Count , StringComparer . OrdinalIgnoreCase ) ;
64
76
foreach ( KeyValuePair < string , JsonDictionary < Version , Data . ModuleData > > moduleVersions in modules )
65
77
{
66
78
var moduleVersionDict = new Dictionary < Version , ModuleData > ( moduleVersions . Value . Count ) ;
67
79
foreach ( KeyValuePair < Version , Data . ModuleData > module in moduleVersions . Value )
68
80
{
69
- moduleVersionDict [ module . Key ] = new ModuleData ( name : moduleVersions . Key , version : module . Key , moduleData : module . Value ) ;
81
+ moduleVersionDict [ module . Key ] = new ModuleData ( name : moduleVersions . Key , version : module . Key , parent : this , moduleData : module . Value ) ;
70
82
}
71
83
moduleDict [ moduleVersions . Key ] = moduleVersionDict ;
72
84
}
73
85
return moduleDict ;
74
86
}
75
87
76
- private static IReadOnlyDictionary < string , IReadOnlyList < CommandData > > CreateCommandLookupTable (
88
+ private static IReadOnlyDictionary < string , IReadOnlyList < CommandData > > CreateNonAliasCommandLookupTable (
77
89
IReadOnlyDictionary < string , IReadOnlyDictionary < Version , ModuleData > > modules )
78
90
{
79
91
var commandTable = new Dictionary < string , IReadOnlyList < CommandData > > ( StringComparer . OrdinalIgnoreCase ) ;
@@ -106,23 +118,94 @@ private static IReadOnlyDictionary<string, IReadOnlyList<CommandData>> CreateCom
106
118
( ( List < CommandData > ) commandTable [ function . Key ] ) . Add ( function . Value ) ;
107
119
}
108
120
}
121
+ }
122
+ }
109
123
110
- if ( module . Aliases != null )
124
+ return commandTable ;
125
+ }
126
+
127
+ private static IReadOnlyDictionary < string , IReadOnlyList < CommandData > > CreateAliasLookupTable (
128
+ IReadOnlyDictionary < string , JsonDictionary < Version , Data . ModuleData > > modules ,
129
+ IReadOnlyDictionary < string , IReadOnlyList < CommandData > > commands )
130
+ {
131
+ var aliasTable = new Dictionary < string , IReadOnlyList < CommandData > > ( ) ;
132
+ foreach ( KeyValuePair < string , JsonDictionary < Version , Data . ModuleData > > module in modules )
133
+ {
134
+ foreach ( KeyValuePair < Version , Data . ModuleData > moduleVersion in module . Value )
135
+ {
136
+ if ( moduleVersion . Value . Aliases == null )
111
137
{
112
- foreach ( KeyValuePair < string , CommandData > alias in module . Aliases )
113
- {
114
- if ( ! commandTable . ContainsKey ( alias . Key ) )
115
- {
116
- commandTable . Add ( alias . Key , new List < CommandData > ( ) ) ;
117
- }
138
+ continue ;
139
+ }
118
140
119
- ( ( List < CommandData > ) commandTable [ alias . Key ] ) . Add ( alias . Value ) ;
141
+ foreach ( KeyValuePair < string , string > alias in moduleVersion . Value . Aliases )
142
+ {
143
+ if ( commands . TryGetValue ( alias . Value , out IReadOnlyList < CommandData > aliasedCommands ) )
144
+ {
145
+ aliasTable [ alias . Key ] = aliasedCommands ;
120
146
}
121
147
}
122
148
}
123
149
}
150
+ return aliasTable ;
151
+ }
124
152
125
- return commandTable ;
153
+ private class DualLookupTable < K , V > : IReadOnlyDictionary < K , V >
154
+ {
155
+ private readonly IReadOnlyDictionary < K , V > _firstTable ;
156
+
157
+ private readonly IReadOnlyDictionary < K , V > _secondTable ;
158
+
159
+ public DualLookupTable ( IReadOnlyDictionary < K , V > firstTable , IReadOnlyDictionary < K , V > secondTable )
160
+ {
161
+ _firstTable = firstTable ;
162
+ _secondTable = secondTable ;
163
+ }
164
+
165
+ public V this [ K key ]
166
+ {
167
+ get
168
+ {
169
+ if ( _firstTable . TryGetValue ( key , out V firstValue ) )
170
+ {
171
+ return firstValue ;
172
+ }
173
+
174
+ if ( _secondTable . TryGetValue ( key , out V secondValue ) )
175
+ {
176
+ return secondValue ;
177
+ }
178
+
179
+ throw new KeyNotFoundException ( ) ;
180
+ }
181
+ }
182
+
183
+ public IEnumerable < K > Keys => _firstTable . Keys . Concat ( _secondTable . Keys ) ;
184
+
185
+ public IEnumerable < V > Values => _firstTable . Values . Concat ( _secondTable . Values ) ;
186
+
187
+ public int Count => _firstTable . Count + _secondTable . Count ;
188
+
189
+ public bool ContainsKey ( K key )
190
+ {
191
+ return _firstTable . ContainsKey ( key ) || _secondTable . ContainsKey ( key ) ;
192
+ }
193
+
194
+ public IEnumerator < KeyValuePair < K , V > > GetEnumerator ( )
195
+ {
196
+ return _firstTable . Concat ( _secondTable ) . GetEnumerator ( ) ;
197
+ }
198
+
199
+ public bool TryGetValue ( K key , out V value )
200
+ {
201
+ return _firstTable . TryGetValue ( key , out value )
202
+ || _secondTable . TryGetValue ( key , out value ) ;
203
+ }
204
+
205
+ IEnumerator IEnumerable . GetEnumerator ( )
206
+ {
207
+ return GetEnumerator ( ) ;
208
+ }
126
209
}
127
210
}
128
211
}
0 commit comments