Skip to content

Commit b9c993c

Browse files
committed
add symbols for classes
1 parent 948dffe commit b9c993c

File tree

4 files changed

+204
-12
lines changed

4 files changed

+204
-12
lines changed

src/PowerShellEditorServices/Services/Symbols/SymbolType.cs

+31-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,36 @@ internal enum SymbolType
4141
/// <summary>
4242
/// The symbol is a hashtable key
4343
/// </summary>
44-
HashtableKey
44+
HashtableKey,
45+
46+
/// <summary>
47+
/// The symbol is a class
48+
/// </summary>
49+
Class,
50+
51+
/// <summary>
52+
/// The symbol is a interface
53+
/// </summary>
54+
Interface,
55+
56+
/// <summary>
57+
/// The symbol is a enum
58+
/// </summary>
59+
Enum,
60+
61+
/// <summary>
62+
/// The symbol is a class property
63+
/// </summary>
64+
Property,
65+
66+
/// <summary>
67+
/// The symbol is a class method
68+
/// </summary>
69+
Method,
70+
71+
/// <summary>
72+
/// The symbol is a class constructor
73+
/// </summary>
74+
Constructor
4575
}
4676
}

src/PowerShellEditorServices/Services/Symbols/Vistors/FindSymbolsVisitor.cs

+135-6
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,9 @@
77
namespace Microsoft.PowerShell.EditorServices.Services.Symbols
88
{
99
/// <summary>
10-
/// The visitor used to find all the symbols (function and class defs) in the AST.
10+
/// The visitor used to find all the symbols (variables, functions and class defs etc) in the AST.
1111
/// </summary>
12-
/// <remarks>
13-
/// Requires PowerShell v3 or higher
14-
/// </remarks>
15-
internal class FindSymbolsVisitor : AstVisitor
12+
internal class FindSymbolsVisitor : AstVisitor2
1613
{
1714
public List<SymbolReference> SymbolReferences { get; }
1815

@@ -26,6 +23,12 @@ internal class FindSymbolsVisitor : AstVisitor
2623
/// or a decision to continue if it wasn't found</returns>
2724
public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst functionDefinitionAst)
2825
{
26+
// Extent for constructors and method trigger both this and VisitFunctionMember(). Covered in the latter.
27+
// This will not exclude nested functions as they have ScriptBlockAst as parent
28+
if (functionDefinitionAst.Parent is FunctionMemberAst) {
29+
return AstVisitAction.Continue;
30+
}
31+
2932
IScriptExtent nameExtent = new ScriptExtent()
3033
{
3134
Text = functionDefinitionAst.Name,
@@ -49,7 +52,7 @@ public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst fun
4952
}
5053

5154
/// <summary>
52-
/// Checks to see if this variable expression is the symbol we are looking for.
55+
/// Checks to see if this variable expression is the symbol we are looking for.
5356
/// </summary>
5457
/// <param name="variableExpressionAst">A VariableExpressionAst object in the script's AST</param>
5558
/// <returns>A decision to stop searching if the right symbol was found,
@@ -80,6 +83,132 @@ private static bool IsAssignedAtScriptScope(VariableExpressionAst variableExpres
8083
parent = parent.Parent;
8184
return parent is null || parent.Parent is null || parent.Parent.Parent is null;
8285
}
86+
87+
/// <summary>
88+
/// Adds class, enum and interface AST to symbol reference list
89+
/// </summary>
90+
public override AstVisitAction VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst)
91+
{
92+
IScriptExtent nameExtent = new ScriptExtent()
93+
{
94+
Text = typeDefinitionAst.Name,
95+
StartLineNumber = typeDefinitionAst.Extent.StartLineNumber,
96+
EndLineNumber = typeDefinitionAst.Extent.EndLineNumber,
97+
StartColumnNumber = typeDefinitionAst.Extent.StartColumnNumber,
98+
EndColumnNumber = typeDefinitionAst.Extent.EndColumnNumber,
99+
File = typeDefinitionAst.Extent.File
100+
};
101+
102+
SymbolType symbolType = typeDefinitionAst switch
103+
{
104+
{ IsEnum: true } => SymbolType.Enum,
105+
{ IsInterface: true } => SymbolType.Interface,
106+
_ => SymbolType.Class,
107+
};
108+
109+
SymbolReferences.Add(
110+
new SymbolReference(
111+
symbolType,
112+
nameExtent));
113+
114+
return AstVisitAction.Continue;
115+
}
116+
117+
/// <summary>
118+
/// Adds class method and constructor AST to symbol reference list
119+
/// </summary>
120+
public override AstVisitAction VisitFunctionMember(FunctionMemberAst functionMemberAst)
121+
{
122+
IScriptExtent nameExtent = new ScriptExtent()
123+
{
124+
Text = GetMethodOverloadName(functionMemberAst),
125+
StartLineNumber = functionMemberAst.Extent.StartLineNumber,
126+
EndLineNumber = functionMemberAst.Extent.EndLineNumber,
127+
StartColumnNumber = functionMemberAst.Extent.StartColumnNumber,
128+
EndColumnNumber = functionMemberAst.Extent.EndColumnNumber,
129+
File = functionMemberAst.Extent.File
130+
};
131+
132+
SymbolType symbolType =
133+
functionMemberAst.IsConstructor ?
134+
SymbolType.Constructor : SymbolType.Method;
135+
136+
SymbolReferences.Add(
137+
new SymbolReference(
138+
symbolType,
139+
nameExtent));
140+
141+
return AstVisitAction.Continue;
142+
}
143+
144+
/// <summary>
145+
/// Gets the method or constructor name with parameters for current overload.
146+
/// </summary>
147+
/// <param name="functionMemberAst">A FunctionMemberAst object in the script's AST</param>
148+
/// <returns>Function member name with parameter types and names</returns>
149+
private static string GetMethodOverloadName(FunctionMemberAst functionMemberAst) {
150+
if (functionMemberAst.Parameters.Count > 0)
151+
{
152+
List<string> parameters = new(functionMemberAst.Parameters.Count);
153+
foreach (ParameterAst param in functionMemberAst.Parameters)
154+
{
155+
parameters.Add(param.Extent.Text);
156+
}
157+
158+
string paramString = string.Join(", ", parameters);
159+
return string.Concat(functionMemberAst.Name, "(", paramString, ")");
160+
}
161+
else
162+
{
163+
return string.Concat(functionMemberAst.Name, "()");
164+
}
165+
}
166+
167+
/// <summary>
168+
/// Adds class property AST to symbol reference list
169+
/// </summary>
170+
public override AstVisitAction VisitPropertyMember(PropertyMemberAst propertyMemberAst)
171+
{
172+
IScriptExtent nameExtent = new ScriptExtent()
173+
{
174+
Text = propertyMemberAst.Name,
175+
StartLineNumber = propertyMemberAst.Extent.StartLineNumber,
176+
EndLineNumber = propertyMemberAst.Extent.EndLineNumber,
177+
StartColumnNumber = propertyMemberAst.Extent.StartColumnNumber,
178+
EndColumnNumber = propertyMemberAst.Extent.EndColumnNumber,
179+
File = propertyMemberAst.Extent.File
180+
};
181+
182+
SymbolReferences.Add(
183+
new SymbolReference(
184+
SymbolType.Property,
185+
nameExtent));
186+
187+
return AstVisitAction.Continue;
188+
}
189+
190+
/// <summary>
191+
/// Adds DSC configuration AST to symbol reference list
192+
/// </summary>
193+
public override AstVisitAction VisitConfigurationDefinition(ConfigurationDefinitionAst configurationDefinitionAst)
194+
{
195+
IScriptExtent nameExtent = new ScriptExtent()
196+
{
197+
Text = configurationDefinitionAst.InstanceName.Extent.Text,
198+
StartLineNumber = configurationDefinitionAst.Extent.StartLineNumber,
199+
EndLineNumber = configurationDefinitionAst.Extent.EndLineNumber,
200+
StartColumnNumber = configurationDefinitionAst.Extent.StartColumnNumber,
201+
EndColumnNumber = configurationDefinitionAst.Extent.EndColumnNumber,
202+
File = configurationDefinitionAst.Extent.File
203+
};
204+
205+
SymbolReferences.Add(
206+
new SymbolReference(
207+
SymbolType.Configuration,
208+
nameExtent));
209+
210+
return AstVisitAction.Continue;
211+
}
83212
}
84213

85214
/// <summary>

src/PowerShellEditorServices/Services/TextDocument/Handlers/DocumentSymbolHandler.cs

+14-2
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,12 @@ private static SymbolKind GetSymbolKind(SymbolType symbolType)
129129
return symbolType switch
130130
{
131131
SymbolType.Configuration or SymbolType.Function or SymbolType.Workflow => SymbolKind.Function,
132+
SymbolType.Enum => SymbolKind.Enum,
133+
SymbolType.Interface => SymbolKind.Interface,
134+
SymbolType.Class => SymbolKind.Class,
135+
SymbolType.Constructor => SymbolKind.Constructor,
136+
SymbolType.Method => SymbolKind.Method,
137+
SymbolType.Property => SymbolKind.Property,
132138
_ => SymbolKind.Variable,
133139
};
134140
}
@@ -137,9 +143,15 @@ private static string GetDecoratedSymbolName(ISymbolReference symbolReference)
137143
{
138144
string name = symbolReference.SymbolName;
139145

140-
if (symbolReference.SymbolType is SymbolType.Configuration or
146+
// Append { } for symbols with scriptblock
147+
// Constructors and Methods have overloaded names already
148+
if (symbolReference.SymbolType is
149+
SymbolType.Configuration or
141150
SymbolType.Function or
142-
SymbolType.Workflow)
151+
SymbolType.Workflow or
152+
SymbolType.Enum or
153+
SymbolType.Interface or
154+
SymbolType.Class)
143155
{
144156
name += " { }";
145157
}

src/PowerShellEditorServices/Services/Workspace/Handlers/WorkspaceSymbolsHandler.cs

+24-3
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public override async Task<Container<SymbolInformation>> Handle(WorkspaceSymbolP
6565
symbols.Add(new SymbolInformation
6666
{
6767
ContainerName = containerName,
68-
Kind = foundOccurrence.SymbolType == SymbolType.Variable ? SymbolKind.Variable : SymbolKind.Function,
68+
Kind = GetSymbolKind(foundOccurrence.SymbolType),
6969
Location = location,
7070
Name = GetDecoratedSymbolName(foundOccurrence)
7171
});
@@ -100,16 +100,37 @@ private static string GetDecoratedSymbolName(SymbolReference symbolReference)
100100
{
101101
string name = symbolReference.SymbolName;
102102

103-
if (symbolReference.SymbolType is SymbolType.Configuration or
103+
// Append { } for symbols with scriptblock
104+
// Constructors and Methods have overloaded names already
105+
if (symbolReference.SymbolType is
106+
SymbolType.Configuration or
104107
SymbolType.Function or
105-
SymbolType.Workflow)
108+
SymbolType.Workflow or
109+
SymbolType.Enum or
110+
SymbolType.Interface or
111+
SymbolType.Class)
106112
{
107113
name += " { }";
108114
}
109115

110116
return name;
111117
}
112118

119+
private static SymbolKind GetSymbolKind(SymbolType symbolType)
120+
{
121+
return symbolType switch
122+
{
123+
SymbolType.Configuration or SymbolType.Function or SymbolType.Workflow => SymbolKind.Function,
124+
SymbolType.Enum => SymbolKind.Enum,
125+
SymbolType.Interface => SymbolKind.Interface,
126+
SymbolType.Class => SymbolKind.Class,
127+
SymbolType.Constructor => SymbolKind.Constructor,
128+
SymbolType.Method => SymbolKind.Method,
129+
SymbolType.Property => SymbolKind.Property,
130+
_ => SymbolKind.Variable,
131+
};
132+
}
133+
113134
#endregion
114135
}
115136
}

0 commit comments

Comments
 (0)