Skip to content

Commit cd8dd7f

Browse files
committed
Break the soon-to-be-only visitor out
1 parent 63b2143 commit cd8dd7f

File tree

3 files changed

+229
-211
lines changed

3 files changed

+229
-211
lines changed

src/PowerShellEditorServices/Services/Symbols/ReferenceTable.cs

Lines changed: 6 additions & 210 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@
77
using System.Collections.Concurrent;
88
using System.Management.Automation.Language;
99
using Microsoft.PowerShell.EditorServices.Services.TextDocument;
10-
using Microsoft.PowerShell.EditorServices.Services.PowerShell.Utility;
1110
using Microsoft.PowerShell.EditorServices.Services.Symbols;
1211
using System.Collections.Generic;
13-
using Microsoft.PowerShell.EditorServices.Utility;
1412

1513
namespace Microsoft.PowerShell.EditorServices.Services;
1614

@@ -68,233 +66,31 @@ internal void EnsureInitialized()
6866
return;
6967
}
7068

71-
_parent.ScriptAst.Visit(new ReferenceVisitor(this));
69+
_parent.ScriptAst.Visit(new SymbolVisitor(_parent, AddReference));
7270
}
7371

7472
private static bool ExtentIsEmpty(IScriptExtent e) => string.IsNullOrEmpty(e.File) &&
7573
e.StartLineNumber == 0 && e.StartColumnNumber == 0 &&
7674
e.EndLineNumber == 0 && e.EndColumnNumber == 0 &&
7775
string.IsNullOrEmpty(e.Text);
7876

79-
private void AddReference(SymbolType type, string name, IScriptExtent nameExtent, IScriptExtent extent, bool isDeclaration = false)
77+
private AstVisitAction AddReference(SymbolReference symbol)
8078
{
8179
// We have to exclude implicit things like `$this` that don't actually exist.
82-
if (ExtentIsEmpty(extent))
80+
if (ExtentIsEmpty(symbol.ScriptRegion))
8381
{
84-
return;
82+
return AstVisitAction.Continue;
8583
}
8684

87-
SymbolReference symbol = new(type, name, nameExtent, extent, _parent, isDeclaration);
8885
_symbolReferences.AddOrUpdate(
89-
name,
86+
symbol.SymbolName,
9087
_ => new ConcurrentBag<SymbolReference> { symbol },
9188
(_, existing) =>
9289
{
9390
existing.Add(symbol);
9491
return existing;
9592
});
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);
20093

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;
29995
}
30096
}

src/PowerShellEditorServices/Services/Symbols/SymbolReference.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ internal record SymbolReference
1717
{
1818
public SymbolType SymbolType { get; }
1919

20+
// TODO: Have a symbol name and a separate display name, the first minimally the text so the
21+
// buckets work, the second usually a more complete signature for e.g. outline view.
2022
public string SymbolName { get; }
2123

2224
public ScriptRegion NameRegion { get; }
@@ -31,6 +33,7 @@ internal record SymbolReference
3133

3234
/// <summary>
3335
/// Constructs and instance of a SymbolReference
36+
/// TODO: Remove this when it becomes unused.
3437
/// </summary>
3538
/// <param name="symbolType">The higher level type of the symbol</param>
3639
/// <param name="symbolName">The name of the symbol</param>
@@ -81,7 +84,8 @@ public SymbolReference(
8184
}
8285

8386
/// <summary>
84-
/// Constructs an instance of a SymbolReference
87+
/// Constructs an instance of a SymbolReference.
88+
/// TODO: Remove this when it becomes unused.
8589
/// </summary>
8690
/// <param name="symbolType">The higher level type of the symbol</param>
8791
/// <param name="scriptExtent">The script extent of the symbol</param>

0 commit comments

Comments
 (0)