|
7 | 7 | using System.Collections.Concurrent;
|
8 | 8 | using System.Management.Automation.Language;
|
9 | 9 | using Microsoft.PowerShell.EditorServices.Services.TextDocument;
|
10 |
| -using Microsoft.PowerShell.EditorServices.Services.PowerShell.Utility; |
11 | 10 | using Microsoft.PowerShell.EditorServices.Services.Symbols;
|
12 | 11 | using System.Collections.Generic;
|
13 |
| -using Microsoft.PowerShell.EditorServices.Utility; |
14 | 12 |
|
15 | 13 | namespace Microsoft.PowerShell.EditorServices.Services;
|
16 | 14 |
|
@@ -68,233 +66,31 @@ internal void EnsureInitialized()
|
68 | 66 | return;
|
69 | 67 | }
|
70 | 68 |
|
71 |
| - _parent.ScriptAst.Visit(new ReferenceVisitor(this)); |
| 69 | + _parent.ScriptAst.Visit(new SymbolVisitor(_parent, AddReference)); |
72 | 70 | }
|
73 | 71 |
|
74 | 72 | private static bool ExtentIsEmpty(IScriptExtent e) => string.IsNullOrEmpty(e.File) &&
|
75 | 73 | e.StartLineNumber == 0 && e.StartColumnNumber == 0 &&
|
76 | 74 | e.EndLineNumber == 0 && e.EndColumnNumber == 0 &&
|
77 | 75 | string.IsNullOrEmpty(e.Text);
|
78 | 76 |
|
79 |
| - private void AddReference(SymbolType type, string name, IScriptExtent nameExtent, IScriptExtent extent, bool isDeclaration = false) |
| 77 | + private AstVisitAction AddReference(SymbolReference symbol) |
80 | 78 | {
|
81 | 79 | // We have to exclude implicit things like `$this` that don't actually exist.
|
82 |
| - if (ExtentIsEmpty(extent)) |
| 80 | + if (ExtentIsEmpty(symbol.ScriptRegion)) |
83 | 81 | {
|
84 |
| - return; |
| 82 | + return AstVisitAction.Continue; |
85 | 83 | }
|
86 | 84 |
|
87 |
| - SymbolReference symbol = new(type, name, nameExtent, extent, _parent, isDeclaration); |
88 | 85 | _symbolReferences.AddOrUpdate(
|
89 |
| - name, |
| 86 | + symbol.SymbolName, |
90 | 87 | _ => new ConcurrentBag<SymbolReference> { symbol },
|
91 | 88 | (_, existing) =>
|
92 | 89 | {
|
93 | 90 | existing.Add(symbol);
|
94 | 91 | return existing;
|
95 | 92 | });
|
96 |
| - } |
97 |
| - |
98 |
| - // TODO: Reconstruct this to take an action lambda that returns a visit action and accepts a |
99 |
| - // symbol. Then ReferenceTable can add a reference and find symbol can just stop. |
100 |
| - // |
101 |
| - // TODO: Have a symbol name and a separate display name, the first minimally the text so the |
102 |
| - // buckets work, the second usually a more complete signature for e.g. outline view. |
103 |
| - private sealed class ReferenceVisitor : AstVisitor2 |
104 |
| - { |
105 |
| - private readonly ReferenceTable _references; |
106 |
| - |
107 |
| - public ReferenceVisitor(ReferenceTable references) => _references = references; |
108 |
| - |
109 |
| - public override AstVisitAction VisitCommand(CommandAst commandAst) |
110 |
| - { |
111 |
| - string? commandName = VisitorUtils.GetCommandName(commandAst); |
112 |
| - if (string.IsNullOrEmpty(commandName)) |
113 |
| - { |
114 |
| - return AstVisitAction.Continue; |
115 |
| - } |
116 |
| - |
117 |
| - _references.AddReference( |
118 |
| - SymbolType.Function, |
119 |
| - CommandHelpers.StripModuleQualification(commandName, out _), |
120 |
| - commandAst.CommandElements[0].Extent, |
121 |
| - commandAst.Extent); |
122 |
| - |
123 |
| - return AstVisitAction.Continue; |
124 |
| - } |
125 |
| - |
126 |
| - public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst functionDefinitionAst) |
127 |
| - { |
128 |
| - SymbolType symbolType = functionDefinitionAst.IsWorkflow |
129 |
| - ? SymbolType.Workflow |
130 |
| - : SymbolType.Function; |
131 |
| - |
132 |
| - // Extent for constructors and method trigger both this and VisitFunctionMember(). Covered in the latter. |
133 |
| - // This will not exclude nested functions as they have ScriptBlockAst as parent |
134 |
| - if (functionDefinitionAst.Parent is FunctionMemberAst) |
135 |
| - { |
136 |
| - return AstVisitAction.Continue; |
137 |
| - } |
138 |
| - |
139 |
| - IScriptExtent nameExtent = VisitorUtils.GetNameExtent(functionDefinitionAst); |
140 |
| - _references.AddReference( |
141 |
| - symbolType, |
142 |
| - functionDefinitionAst.Name, |
143 |
| - nameExtent, |
144 |
| - functionDefinitionAst.Extent, |
145 |
| - isDeclaration: true); |
146 |
| - |
147 |
| - return AstVisitAction.Continue; |
148 |
| - } |
149 |
| - |
150 |
| - public override AstVisitAction VisitCommandParameter(CommandParameterAst commandParameterAst) |
151 |
| - { |
152 |
| - _references.AddReference( |
153 |
| - SymbolType.Parameter, |
154 |
| - commandParameterAst.Extent.Text, |
155 |
| - commandParameterAst.Extent, |
156 |
| - commandParameterAst.Extent, |
157 |
| - isDeclaration: true); |
158 |
| - |
159 |
| - return AstVisitAction.Continue; |
160 |
| - } |
161 |
| - |
162 |
| - public override AstVisitAction VisitVariableExpression(VariableExpressionAst variableExpressionAst) |
163 |
| - { |
164 |
| - // TODO: Consider tracking unscoped variable references only when they declared within |
165 |
| - // the same function definition. |
166 |
| - _references.AddReference( |
167 |
| - SymbolType.Variable, |
168 |
| - $"${variableExpressionAst.VariablePath.UserPath}", |
169 |
| - variableExpressionAst.Extent, |
170 |
| - variableExpressionAst.Extent, // TODO: Maybe parent? |
171 |
| - isDeclaration: variableExpressionAst.Parent is AssignmentStatementAst or ParameterAst); |
172 |
| - |
173 |
| - return AstVisitAction.Continue; |
174 |
| - } |
175 |
| - |
176 |
| - public override AstVisitAction VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst) |
177 |
| - { |
178 |
| - SymbolType symbolType = typeDefinitionAst.IsEnum |
179 |
| - ? SymbolType.Enum |
180 |
| - : SymbolType.Class; |
181 |
| - |
182 |
| - IScriptExtent nameExtent = VisitorUtils.GetNameExtent(typeDefinitionAst); |
183 |
| - _references.AddReference( |
184 |
| - symbolType, |
185 |
| - typeDefinitionAst.Name, |
186 |
| - nameExtent, |
187 |
| - typeDefinitionAst.Extent, |
188 |
| - isDeclaration: true); |
189 |
| - |
190 |
| - return AstVisitAction.Continue; |
191 |
| - } |
192 |
| - |
193 |
| - public override AstVisitAction VisitTypeExpression(TypeExpressionAst typeExpressionAst) |
194 |
| - { |
195 |
| - _references.AddReference( |
196 |
| - SymbolType.Type, |
197 |
| - typeExpressionAst.TypeName.Name, |
198 |
| - typeExpressionAst.Extent, |
199 |
| - typeExpressionAst.Extent); |
200 | 93 |
|
201 |
| - return AstVisitAction.Continue; |
202 |
| - } |
203 |
| - |
204 |
| - public override AstVisitAction VisitTypeConstraint(TypeConstraintAst typeConstraintAst) |
205 |
| - { |
206 |
| - _references.AddReference( |
207 |
| - SymbolType.Type, |
208 |
| - typeConstraintAst.TypeName.Name, |
209 |
| - typeConstraintAst.Extent, |
210 |
| - typeConstraintAst.Extent); |
211 |
| - |
212 |
| - return AstVisitAction.Continue; |
213 |
| - } |
214 |
| - |
215 |
| - public override AstVisitAction VisitFunctionMember(FunctionMemberAst functionMemberAst) |
216 |
| - { |
217 |
| - SymbolType symbolType = functionMemberAst.IsConstructor |
218 |
| - ? SymbolType.Constructor |
219 |
| - : SymbolType.Method; |
220 |
| - |
221 |
| - IScriptExtent nameExtent = VisitorUtils.GetNameExtent( |
222 |
| - functionMemberAst, |
223 |
| - useQualifiedName: false, |
224 |
| - includeReturnType: false); |
225 |
| - |
226 |
| - _references.AddReference( |
227 |
| - symbolType, |
228 |
| - functionMemberAst.Name, // We bucket all the overloads. |
229 |
| - nameExtent, |
230 |
| - functionMemberAst.Extent, |
231 |
| - isDeclaration: true); |
232 |
| - |
233 |
| - return AstVisitAction.Continue; |
234 |
| - } |
235 |
| - |
236 |
| - public override AstVisitAction VisitPropertyMember(PropertyMemberAst propertyMemberAst) |
237 |
| - { |
238 |
| - SymbolType symbolType = |
239 |
| - propertyMemberAst.Parent is TypeDefinitionAst typeAst && typeAst.IsEnum |
240 |
| - ? SymbolType.EnumMember : SymbolType.Property; |
241 |
| - |
242 |
| - IScriptExtent nameExtent = VisitorUtils.GetNameExtent(propertyMemberAst, false, false); |
243 |
| - _references.AddReference( |
244 |
| - symbolType, |
245 |
| - nameExtent.Text, |
246 |
| - nameExtent, |
247 |
| - propertyMemberAst.Extent, |
248 |
| - isDeclaration: true); |
249 |
| - |
250 |
| - return AstVisitAction.Continue; |
251 |
| - } |
252 |
| - |
253 |
| - public override AstVisitAction VisitMemberExpression(MemberExpressionAst memberExpressionAst) |
254 |
| - { |
255 |
| - string? memberName = memberExpressionAst.Member is StringConstantExpressionAst stringConstant ? stringConstant.Value : null; |
256 |
| - if (string.IsNullOrEmpty(memberName)) |
257 |
| - { |
258 |
| - return AstVisitAction.Continue; |
259 |
| - } |
260 |
| - |
261 |
| - _references.AddReference( |
262 |
| - SymbolType.Property, |
263 |
| - memberName, |
264 |
| - memberExpressionAst.Member.Extent, |
265 |
| - memberExpressionAst.Extent); |
266 |
| - |
267 |
| - return AstVisitAction.Continue; |
268 |
| - } |
269 |
| - |
270 |
| - public override AstVisitAction VisitInvokeMemberExpression(InvokeMemberExpressionAst methodCallAst) |
271 |
| - { |
272 |
| - string? memberName = methodCallAst.Member is StringConstantExpressionAst stringConstant ? stringConstant.Value : null; |
273 |
| - if (string.IsNullOrEmpty(memberName)) |
274 |
| - { |
275 |
| - return AstVisitAction.Continue; |
276 |
| - } |
277 |
| - |
278 |
| - _references.AddReference( |
279 |
| - SymbolType.Method, |
280 |
| - memberName, |
281 |
| - methodCallAst.Member.Extent, |
282 |
| - methodCallAst.Extent); |
283 |
| - |
284 |
| - return AstVisitAction.Continue; |
285 |
| - } |
286 |
| - |
287 |
| - public override AstVisitAction VisitConfigurationDefinition(ConfigurationDefinitionAst configurationDefinitionAst) |
288 |
| - { |
289 |
| - IScriptExtent nameExtent = VisitorUtils.GetNameExtent(configurationDefinitionAst); |
290 |
| - _references.AddReference( |
291 |
| - SymbolType.Configuration, |
292 |
| - nameExtent.Text, |
293 |
| - nameExtent, |
294 |
| - configurationDefinitionAst.Extent, |
295 |
| - isDeclaration: true); |
296 |
| - |
297 |
| - return AstVisitAction.Continue; |
298 |
| - } |
| 94 | + return AstVisitAction.Continue; |
299 | 95 | }
|
300 | 96 | }
|
0 commit comments