2
2
// Licensed under the MIT License.
3
3
4
4
using System ;
5
+ using System . Collections . Concurrent ;
5
6
using System . Collections . Generic ;
6
7
using System . Management . Automation . Language ;
7
8
@@ -12,48 +13,47 @@ namespace Microsoft.PowerShell.EditorServices.Services.Symbols
12
13
/// </summary>
13
14
internal class FindReferencesVisitor : AstVisitor
14
15
{
15
- private SymbolReference symbolRef ;
16
- private Dictionary < String , List < String > > CmdletToAliasDictionary ;
17
- private Dictionary < String , String > AliasToCmdletDictionary ;
18
- private string symbolRefCommandName ;
19
- private bool needsAliases ;
16
+ private readonly SymbolReference _symbolRef ;
17
+ private readonly ConcurrentDictionary < string , List < string > > _cmdletToAliasDictionary ;
18
+ private readonly ConcurrentDictionary < string , string > _aliasToCmdletDictionary ;
19
+ private readonly string _symbolRefCommandName ;
20
+ private readonly bool _needsAliases ;
20
21
21
22
public List < SymbolReference > FoundReferences { get ; set ; }
22
23
23
24
/// <summary>
24
25
/// Constructor used when searching for aliases is needed
25
26
/// </summary>
26
27
/// <param name="symbolReference">The found symbolReference that other symbols are being compared to</param>
27
- /// <param name="CmdletToAliasDictionary ">Dictionary maping cmdlets to aliases for finding alias references</param>
28
- /// <param name="AliasToCmdletDictionary ">Dictionary maping aliases to cmdlets for finding alias references</param>
28
+ /// <param name="cmdletToAliasDictionary ">Dictionary maping cmdlets to aliases for finding alias references</param>
29
+ /// <param name="aliasToCmdletDictionary ">Dictionary maping aliases to cmdlets for finding alias references</param>
29
30
public FindReferencesVisitor (
30
31
SymbolReference symbolReference ,
31
- Dictionary < String , List < String > > CmdletToAliasDictionary ,
32
- Dictionary < String , String > AliasToCmdletDictionary )
32
+ ConcurrentDictionary < string , List < string > > cmdletToAliasDictionary = default ,
33
+ ConcurrentDictionary < string , string > aliasToCmdletDictionary = default )
33
34
{
34
- this . symbolRef = symbolReference ;
35
- this . FoundReferences = new List < SymbolReference > ( ) ;
36
- this . needsAliases = true ;
37
- this . CmdletToAliasDictionary = CmdletToAliasDictionary ;
38
- this . AliasToCmdletDictionary = AliasToCmdletDictionary ;
39
-
40
- // Try to get the symbolReference's command name of an alias,
41
- // if a command name does not exists (if the symbol isn't an alias to a command)
42
- // set symbolRefCommandName to and empty string value
43
- AliasToCmdletDictionary . TryGetValue ( symbolReference . ScriptRegion . Text , out symbolRefCommandName ) ;
44
- if ( symbolRefCommandName == null ) { symbolRefCommandName = string . Empty ; }
35
+ _symbolRef = symbolReference ;
36
+ FoundReferences = new List < SymbolReference > ( ) ;
45
37
46
- }
38
+ if ( cmdletToAliasDictionary is null || aliasToCmdletDictionary is null )
39
+ {
40
+ _needsAliases = false ;
41
+ return ;
42
+ }
47
43
48
- /// <summary>
49
- /// Constructor used when searching for aliases is not needed
50
- /// </summary>
51
- /// <param name="foundSymbol">The found symbolReference that other symbols are being compared to</param>
52
- public FindReferencesVisitor ( SymbolReference foundSymbol )
53
- {
54
- this . symbolRef = foundSymbol ;
55
- this . FoundReferences = new List < SymbolReference > ( ) ;
56
- this . needsAliases = false ;
44
+ _needsAliases = true ;
45
+ _cmdletToAliasDictionary = cmdletToAliasDictionary ;
46
+ _aliasToCmdletDictionary = aliasToCmdletDictionary ;
47
+
48
+ // Try to get the symbolReference's command name of an alias. If a command name does not
49
+ // exists (if the symbol isn't an alias to a command) set symbolRefCommandName to an
50
+ // empty string.
51
+ aliasToCmdletDictionary . TryGetValue ( symbolReference . ScriptRegion . Text , out _symbolRefCommandName ) ;
52
+
53
+ if ( _symbolRefCommandName == null )
54
+ {
55
+ _symbolRefCommandName = string . Empty ;
56
+ }
57
57
}
58
58
59
59
/// <summary>
@@ -68,50 +68,44 @@ public override AstVisitAction VisitCommand(CommandAst commandAst)
68
68
Ast commandNameAst = commandAst . CommandElements [ 0 ] ;
69
69
string commandName = commandNameAst . Extent . Text ;
70
70
71
- if ( symbolRef . SymbolType . Equals ( SymbolType . Function ) )
71
+ if ( _symbolRef . SymbolType . Equals ( SymbolType . Function ) )
72
72
{
73
- if ( needsAliases )
73
+ if ( _needsAliases )
74
74
{
75
- // Try to get the commandAst's name and aliases,
76
- // if a command does not exists (if the symbol isn't an alias to a command)
77
- // set command to and empty string value string command
78
- // if the aliases do not exist (if the symvol isn't a command that has aliases)
75
+ // Try to get the commandAst's name and aliases.
76
+ //
77
+ // If a command does not exist (if the symbol isn't an alias to a command) set
78
+ // command to an empty string value string command.
79
+ //
80
+ // If the aliases do not exist (if the symbol isn't a command that has aliases)
79
81
// set aliases to an empty List<string>
80
- string command ;
81
- List < string > alaises ;
82
- CmdletToAliasDictionary . TryGetValue ( commandName , out alaises ) ;
83
- AliasToCmdletDictionary . TryGetValue ( commandName , out command ) ;
84
- if ( alaises == null ) { alaises = new List < string > ( ) ; }
82
+ _cmdletToAliasDictionary . TryGetValue ( commandName , out List < string > aliases ) ;
83
+ _aliasToCmdletDictionary . TryGetValue ( commandName , out string command ) ;
84
+ if ( aliases == null ) { aliases = new List < string > ( ) ; }
85
85
if ( command == null ) { command = string . Empty ; }
86
86
87
- if ( symbolRef . SymbolType . Equals ( SymbolType . Function ) )
87
+ // Check if the found symbol's name is the same as the commandAst's name OR
88
+ // if the symbol's name is an alias for this commandAst's name (commandAst is a cmdlet) OR
89
+ // if the symbol's name is the same as the commandAst's cmdlet name (commandAst is a alias)
90
+ if ( commandName . Equals ( _symbolRef . SymbolName , StringComparison . OrdinalIgnoreCase )
91
+ // Note that PowerShell command names and aliases are case insensitive.
92
+ || aliases . Exists ( ( match ) => string . Equals ( match , _symbolRef . ScriptRegion . Text , StringComparison . OrdinalIgnoreCase ) )
93
+ || command . Equals ( _symbolRef . ScriptRegion . Text , StringComparison . OrdinalIgnoreCase )
94
+ || ( ! string . IsNullOrEmpty ( command )
95
+ && command . Equals ( _symbolRefCommandName , StringComparison . OrdinalIgnoreCase ) ) )
88
96
{
89
- // Check if the found symbol's name is the same as the commandAst's name OR
90
- // if the symbol's name is an alias for this commandAst's name (commandAst is a cmdlet) OR
91
- // if the symbol's name is the same as the commandAst's cmdlet name (commandAst is a alias)
92
- if ( commandName . Equals ( symbolRef . SymbolName , StringComparison . CurrentCultureIgnoreCase ) ||
93
- alaises . Contains ( symbolRef . ScriptRegion . Text . ToLower ( ) ) ||
94
- command . Equals ( symbolRef . ScriptRegion . Text , StringComparison . CurrentCultureIgnoreCase ) ||
95
- ( ! string . IsNullOrEmpty ( command ) && command . Equals ( symbolRefCommandName , StringComparison . CurrentCultureIgnoreCase ) ) )
96
- {
97
- this . FoundReferences . Add ( new SymbolReference (
98
- SymbolType . Function ,
99
- commandNameAst . Extent ) ) ;
100
- }
97
+ FoundReferences . Add ( new SymbolReference ( SymbolType . Function , commandNameAst . Extent ) ) ;
101
98
}
102
-
103
99
}
104
100
else // search does not include aliases
105
101
{
106
- if ( commandName . Equals ( symbolRef . SymbolName , StringComparison . CurrentCultureIgnoreCase ) )
102
+ if ( commandName . Equals ( _symbolRef . SymbolName , StringComparison . OrdinalIgnoreCase ) )
107
103
{
108
- this . FoundReferences . Add ( new SymbolReference (
109
- SymbolType . Function ,
110
- commandNameAst . Extent ) ) ;
104
+ FoundReferences . Add ( new SymbolReference ( SymbolType . Function , commandNameAst . Extent ) ) ;
111
105
}
112
106
}
113
-
114
107
}
108
+
115
109
return base . VisitCommand ( commandAst ) ;
116
110
}
117
111
@@ -135,12 +129,10 @@ public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst fun
135
129
File = functionDefinitionAst . Extent . File
136
130
} ;
137
131
138
- if ( symbolRef . SymbolType . Equals ( SymbolType . Function ) &&
139
- nameExtent . Text . Equals ( symbolRef . SymbolName , StringComparison . CurrentCultureIgnoreCase ) )
132
+ if ( _symbolRef . SymbolType . Equals ( SymbolType . Function ) &&
133
+ nameExtent . Text . Equals ( _symbolRef . SymbolName , StringComparison . CurrentCultureIgnoreCase ) )
140
134
{
141
- this . FoundReferences . Add ( new SymbolReference (
142
- SymbolType . Function ,
143
- nameExtent ) ) ;
135
+ FoundReferences . Add ( new SymbolReference ( SymbolType . Function , nameExtent ) ) ;
144
136
}
145
137
return base . VisitFunctionDefinition ( functionDefinitionAst ) ;
146
138
}
@@ -153,12 +145,10 @@ public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst fun
153
145
/// <returns>A visit action that continues the search for references</returns>
154
146
public override AstVisitAction VisitCommandParameter ( CommandParameterAst commandParameterAst )
155
147
{
156
- if ( symbolRef . SymbolType . Equals ( SymbolType . Parameter ) &&
157
- commandParameterAst . Extent . Text . Equals ( symbolRef . SymbolName , StringComparison . CurrentCultureIgnoreCase ) )
148
+ if ( _symbolRef . SymbolType . Equals ( SymbolType . Parameter ) &&
149
+ commandParameterAst . Extent . Text . Equals ( _symbolRef . SymbolName , StringComparison . CurrentCultureIgnoreCase ) )
158
150
{
159
- this . FoundReferences . Add ( new SymbolReference (
160
- SymbolType . Parameter ,
161
- commandParameterAst . Extent ) ) ;
151
+ FoundReferences . Add ( new SymbolReference ( SymbolType . Parameter , commandParameterAst . Extent ) ) ;
162
152
}
163
153
return AstVisitAction . Continue ;
164
154
}
@@ -171,12 +161,10 @@ public override AstVisitAction VisitCommandParameter(CommandParameterAst command
171
161
/// <returns>A visit action that continues the search for references</returns>
172
162
public override AstVisitAction VisitVariableExpression ( VariableExpressionAst variableExpressionAst )
173
163
{
174
- if ( symbolRef . SymbolType . Equals ( SymbolType . Variable ) &&
175
- variableExpressionAst . Extent . Text . Equals ( symbolRef . SymbolName , StringComparison . CurrentCultureIgnoreCase ) )
164
+ if ( _symbolRef . SymbolType . Equals ( SymbolType . Variable )
165
+ && variableExpressionAst . Extent . Text . Equals ( _symbolRef . SymbolName , StringComparison . CurrentCultureIgnoreCase ) )
176
166
{
177
- this . FoundReferences . Add ( new SymbolReference (
178
- SymbolType . Variable ,
179
- variableExpressionAst . Extent ) ) ;
167
+ FoundReferences . Add ( new SymbolReference ( SymbolType . Variable , variableExpressionAst . Extent ) ) ;
180
168
}
181
169
return AstVisitAction . Continue ;
182
170
}
@@ -186,7 +174,7 @@ private static (int, int) GetStartColumnAndLineNumbersFromAst(FunctionDefinition
186
174
{
187
175
int startColumnNumber = ast . Extent . StartColumnNumber ;
188
176
int startLineNumber = ast . Extent . StartLineNumber ;
189
- int astOffset = 0 ;
177
+ int astOffset ;
190
178
191
179
if ( ast . IsFilter )
192
180
{
0 commit comments