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 > > ( Aliases , NonAliasCommands ) ) ;
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,89 @@ 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
+ foreach ( KeyValuePair < string , string > alias in moduleVersion . Value . Aliases )
111
137
{
112
- foreach ( KeyValuePair < string , CommandData > alias in module . Aliases )
138
+ if ( commands . TryGetValue ( alias . Value , out IReadOnlyList < CommandData > aliasedCommands ) )
113
139
{
114
- if ( ! commandTable . ContainsKey ( alias . Key ) )
115
- {
116
- commandTable . Add ( alias . Key , new List < CommandData > ( ) ) ;
117
- }
118
-
119
- ( ( List < CommandData > ) commandTable [ alias . Key ] ) . Add ( alias . Value ) ;
140
+ aliasTable [ alias . Key ] = aliasedCommands ;
120
141
}
121
142
}
122
143
}
123
144
}
145
+ return aliasTable ;
146
+ }
124
147
125
- return commandTable ;
148
+ private class DualLookupTable < K , V > : IReadOnlyDictionary < K , V >
149
+ {
150
+ private readonly IReadOnlyDictionary < K , V > _firstTable ;
151
+
152
+ private readonly IReadOnlyDictionary < K , V > _secondTable ;
153
+
154
+ public DualLookupTable ( IReadOnlyDictionary < K , V > firstTable , IReadOnlyDictionary < K , V > secondTable )
155
+ {
156
+ _firstTable = firstTable ;
157
+ _secondTable = secondTable ;
158
+ }
159
+
160
+ public V this [ K key ]
161
+ {
162
+ get
163
+ {
164
+ if ( _firstTable . TryGetValue ( key , out V firstValue ) )
165
+ {
166
+ return firstValue ;
167
+ }
168
+
169
+ if ( _secondTable . TryGetValue ( key , out V secondValue ) )
170
+ {
171
+ return secondValue ;
172
+ }
173
+
174
+ throw new KeyNotFoundException ( ) ;
175
+ }
176
+ }
177
+
178
+ public IEnumerable < K > Keys => _firstTable . Keys . Concat ( _secondTable . Keys ) ;
179
+
180
+ public IEnumerable < V > Values => _firstTable . Values . Concat ( _secondTable . Values ) ;
181
+
182
+ public int Count => _firstTable . Count + _secondTable . Count ;
183
+
184
+ public bool ContainsKey ( K key )
185
+ {
186
+ return _firstTable . ContainsKey ( key ) || _secondTable . ContainsKey ( key ) ;
187
+ }
188
+
189
+ public IEnumerator < KeyValuePair < K , V > > GetEnumerator ( )
190
+ {
191
+ return _firstTable . Concat ( _secondTable ) . GetEnumerator ( ) ;
192
+ }
193
+
194
+ public bool TryGetValue ( K key , out V value )
195
+ {
196
+ return _firstTable . TryGetValue ( key , out value )
197
+ || _secondTable . TryGetValue ( key , out value ) ;
198
+ }
199
+
200
+ IEnumerator IEnumerable . GetEnumerator ( )
201
+ {
202
+ return GetEnumerator ( ) ;
203
+ }
126
204
}
127
205
}
128
206
}
0 commit comments