1
+ // Copyright (c) Microsoft Corporation. All rights reserved.
2
+ // Licensed under the MIT License.
3
+
4
+ using System . Management . Automation . Language ;
5
+
6
+ namespace Microsoft . Windows . PowerShell . ScriptAnalyzer
7
+ {
8
+ /// <summary>
9
+ /// Provides an efficient way to find the position in the AST corresponding to a given script position.
10
+ /// </summary>
11
+ #if ! ( PSV3 || PSV4 )
12
+ internal class FindAstPositionVisitor : AstVisitor2
13
+ #else
14
+ internal class FindAstPositionVisitor : AstVisitor
15
+ #endif
16
+ {
17
+ private IScriptPosition searchPosition ;
18
+
19
+ /// <summary>
20
+ /// Contains the position in the AST corresponding to the provided <see cref="IScriptPosition"/> upon completion of the <see cref="Ast.Visit(AstVisitor)"/> method.
21
+ /// </summary>
22
+ public Ast AstPosition { get ; private set ; }
23
+
24
+ /// <summary>
25
+ /// Initializes a new instance of the <see cref="FindAstPositionVisitor"/> class with the postition to search for.
26
+ /// </summary>
27
+ /// <param name="position">The script position to search for.</param>
28
+ public FindAstPositionVisitor ( IScriptPosition position )
29
+ {
30
+ this . searchPosition = position ;
31
+ }
32
+
33
+ public override AstVisitAction VisitArrayExpression ( ArrayExpressionAst arrayExpressionAst )
34
+ {
35
+ return Visit ( arrayExpressionAst ) ;
36
+ }
37
+
38
+ public override AstVisitAction VisitArrayLiteral ( ArrayLiteralAst arrayLiteralAst )
39
+ {
40
+ return Visit ( arrayLiteralAst ) ;
41
+ }
42
+
43
+ public override AstVisitAction VisitAssignmentStatement ( AssignmentStatementAst assignmentStatementAst )
44
+ {
45
+ return Visit ( assignmentStatementAst ) ;
46
+ }
47
+
48
+ public override AstVisitAction VisitAttribute ( AttributeAst attributeAst )
49
+ {
50
+ return Visit ( attributeAst ) ;
51
+ }
52
+
53
+ public override AstVisitAction VisitAttributedExpression ( AttributedExpressionAst attributedExpressionAst )
54
+ {
55
+ return Visit ( attributedExpressionAst ) ;
56
+ }
57
+
58
+ public override AstVisitAction VisitBinaryExpression ( BinaryExpressionAst binaryExpressionAst )
59
+ {
60
+ return Visit ( binaryExpressionAst ) ;
61
+ }
62
+
63
+ public override AstVisitAction VisitBlockStatement ( BlockStatementAst blockStatementAst )
64
+ {
65
+ return Visit ( blockStatementAst ) ;
66
+ }
67
+
68
+ public override AstVisitAction VisitBreakStatement ( BreakStatementAst breakStatementAst )
69
+ {
70
+ return Visit ( breakStatementAst ) ;
71
+ }
72
+
73
+ public override AstVisitAction VisitCatchClause ( CatchClauseAst catchClauseAst )
74
+ {
75
+ return Visit ( catchClauseAst ) ;
76
+ }
77
+
78
+ public override AstVisitAction VisitCommand ( CommandAst commandAst )
79
+ {
80
+ return Visit ( commandAst ) ;
81
+ }
82
+
83
+ public override AstVisitAction VisitCommandExpression ( CommandExpressionAst commandExpressionAst )
84
+ {
85
+ return Visit ( commandExpressionAst ) ;
86
+ }
87
+
88
+ public override AstVisitAction VisitCommandParameter ( CommandParameterAst commandParameterAst )
89
+ {
90
+ return Visit ( commandParameterAst ) ;
91
+ }
92
+
93
+ public override AstVisitAction VisitConstantExpression ( ConstantExpressionAst constantExpressionAst )
94
+ {
95
+ return Visit ( constantExpressionAst ) ;
96
+ }
97
+
98
+ public override AstVisitAction VisitContinueStatement ( ContinueStatementAst continueStatementAst )
99
+ {
100
+ return Visit ( continueStatementAst ) ;
101
+ }
102
+
103
+ public override AstVisitAction VisitConvertExpression ( ConvertExpressionAst convertExpressionAst )
104
+ {
105
+ return Visit ( convertExpressionAst ) ;
106
+ }
107
+
108
+ public override AstVisitAction VisitDataStatement ( DataStatementAst dataStatementAst )
109
+ {
110
+ return Visit ( dataStatementAst ) ;
111
+ }
112
+
113
+ public override AstVisitAction VisitDoUntilStatement ( DoUntilStatementAst doUntilStatementAst )
114
+ {
115
+ return Visit ( doUntilStatementAst ) ;
116
+ }
117
+
118
+ public override AstVisitAction VisitDoWhileStatement ( DoWhileStatementAst doWhileStatementAst )
119
+ {
120
+ return Visit ( doWhileStatementAst ) ;
121
+ }
122
+
123
+ public override AstVisitAction VisitErrorExpression ( ErrorExpressionAst errorExpressionAst )
124
+ {
125
+ return Visit ( errorExpressionAst ) ;
126
+ }
127
+
128
+ public override AstVisitAction VisitErrorStatement ( ErrorStatementAst errorStatementAst )
129
+ {
130
+ return Visit ( errorStatementAst ) ;
131
+ }
132
+
133
+ public override AstVisitAction VisitExitStatement ( ExitStatementAst exitStatementAst )
134
+ {
135
+ return Visit ( exitStatementAst ) ;
136
+ }
137
+
138
+ public override AstVisitAction VisitExpandableStringExpression ( ExpandableStringExpressionAst expandableStringExpressionAst )
139
+ {
140
+ return Visit ( expandableStringExpressionAst ) ;
141
+ }
142
+
143
+ public override AstVisitAction VisitFileRedirection ( FileRedirectionAst fileRedirectionAst )
144
+ {
145
+ return Visit ( fileRedirectionAst ) ;
146
+ }
147
+
148
+ public override AstVisitAction VisitForEachStatement ( ForEachStatementAst forEachStatementAst )
149
+ {
150
+ return Visit ( forEachStatementAst ) ;
151
+ }
152
+
153
+ public override AstVisitAction VisitForStatement ( ForStatementAst forStatementAst )
154
+ {
155
+ return Visit ( forStatementAst ) ;
156
+ }
157
+
158
+ public override AstVisitAction VisitFunctionDefinition ( FunctionDefinitionAst functionDefinitionAst )
159
+ {
160
+ return Visit ( functionDefinitionAst ) ;
161
+ }
162
+
163
+ public override AstVisitAction VisitHashtable ( HashtableAst hashtableAst )
164
+ {
165
+ return Visit ( hashtableAst ) ;
166
+ }
167
+
168
+ public override AstVisitAction VisitIfStatement ( IfStatementAst ifStatementAst )
169
+ {
170
+ return Visit ( ifStatementAst ) ;
171
+ }
172
+
173
+ public override AstVisitAction VisitIndexExpression ( IndexExpressionAst indexExpressionAst )
174
+ {
175
+ return Visit ( indexExpressionAst ) ;
176
+ }
177
+
178
+ public override AstVisitAction VisitInvokeMemberExpression ( InvokeMemberExpressionAst invokeMemberExpressionAst )
179
+ {
180
+ return Visit ( invokeMemberExpressionAst ) ;
181
+ }
182
+
183
+ public override AstVisitAction VisitMemberExpression ( MemberExpressionAst memberExpressionAst )
184
+ {
185
+ return Visit ( memberExpressionAst ) ;
186
+ }
187
+
188
+ public override AstVisitAction VisitMergingRedirection ( MergingRedirectionAst mergingRedirectionAst )
189
+ {
190
+ return Visit ( mergingRedirectionAst ) ;
191
+ }
192
+
193
+ public override AstVisitAction VisitNamedAttributeArgument ( NamedAttributeArgumentAst namedAttributeArgumentAst )
194
+ {
195
+ return Visit ( namedAttributeArgumentAst ) ;
196
+ }
197
+
198
+ public override AstVisitAction VisitNamedBlock ( NamedBlockAst namedBlockAst )
199
+ {
200
+ return Visit ( namedBlockAst ) ;
201
+ }
202
+
203
+ public override AstVisitAction VisitParamBlock ( ParamBlockAst paramBlockAst )
204
+ {
205
+ return Visit ( paramBlockAst ) ;
206
+ }
207
+
208
+ public override AstVisitAction VisitParameter ( ParameterAst parameterAst )
209
+ {
210
+ return Visit ( parameterAst ) ;
211
+ }
212
+
213
+ public override AstVisitAction VisitParenExpression ( ParenExpressionAst parenExpressionAst )
214
+ {
215
+ return Visit ( parenExpressionAst ) ;
216
+ }
217
+
218
+ public override AstVisitAction VisitPipeline ( PipelineAst pipelineAst )
219
+ {
220
+ return Visit ( pipelineAst ) ;
221
+ }
222
+
223
+ public override AstVisitAction VisitReturnStatement ( ReturnStatementAst returnStatementAst )
224
+ {
225
+ return Visit ( returnStatementAst ) ;
226
+ }
227
+
228
+ public override AstVisitAction VisitScriptBlock ( ScriptBlockAst scriptBlockAst )
229
+ {
230
+ return Visit ( scriptBlockAst ) ;
231
+ }
232
+
233
+ public override AstVisitAction VisitScriptBlockExpression ( ScriptBlockExpressionAst scriptBlockExpressionAst )
234
+ {
235
+ return Visit ( scriptBlockExpressionAst ) ;
236
+ }
237
+
238
+ public override AstVisitAction VisitStatementBlock ( StatementBlockAst statementBlockAst )
239
+ {
240
+ return Visit ( statementBlockAst ) ;
241
+ }
242
+
243
+ public override AstVisitAction VisitStringConstantExpression ( StringConstantExpressionAst stringConstantExpressionAst )
244
+ {
245
+ return Visit ( stringConstantExpressionAst ) ;
246
+ }
247
+
248
+ public override AstVisitAction VisitSubExpression ( SubExpressionAst subExpressionAst )
249
+ {
250
+ return Visit ( subExpressionAst ) ;
251
+ }
252
+
253
+ public override AstVisitAction VisitSwitchStatement ( SwitchStatementAst switchStatementAst )
254
+ {
255
+ return Visit ( switchStatementAst ) ;
256
+ }
257
+
258
+ public override AstVisitAction VisitThrowStatement ( ThrowStatementAst throwStatementAst )
259
+ {
260
+ return Visit ( throwStatementAst ) ;
261
+ }
262
+
263
+ public override AstVisitAction VisitTrap ( TrapStatementAst trapStatementAst )
264
+ {
265
+ return Visit ( trapStatementAst ) ;
266
+ }
267
+
268
+ public override AstVisitAction VisitTryStatement ( TryStatementAst tryStatementAst )
269
+ {
270
+ return Visit ( tryStatementAst ) ;
271
+ }
272
+
273
+ public override AstVisitAction VisitTypeConstraint ( TypeConstraintAst typeConstraintAst )
274
+ {
275
+ return Visit ( typeConstraintAst ) ;
276
+ }
277
+
278
+ public override AstVisitAction VisitTypeExpression ( TypeExpressionAst typeExpressionAst )
279
+ {
280
+ return Visit ( typeExpressionAst ) ;
281
+ }
282
+
283
+ public override AstVisitAction VisitUnaryExpression ( UnaryExpressionAst unaryExpressionAst )
284
+ {
285
+ return Visit ( unaryExpressionAst ) ;
286
+ }
287
+
288
+ public override AstVisitAction VisitUsingExpression ( UsingExpressionAst usingExpressionAst )
289
+ {
290
+ return Visit ( usingExpressionAst ) ;
291
+ }
292
+
293
+ public override AstVisitAction VisitVariableExpression ( VariableExpressionAst variableExpressionAst )
294
+ {
295
+ return Visit ( variableExpressionAst ) ;
296
+ }
297
+
298
+ public override AstVisitAction VisitWhileStatement ( WhileStatementAst whileStatementAst )
299
+ {
300
+ return Visit ( whileStatementAst ) ;
301
+ }
302
+
303
+ #if ! ( PSV3 || PSV4 )
304
+ public override AstVisitAction VisitBaseCtorInvokeMemberExpression ( BaseCtorInvokeMemberExpressionAst baseCtorInvokeMemberExpressionAst )
305
+ {
306
+ return Visit ( baseCtorInvokeMemberExpressionAst ) ;
307
+ }
308
+
309
+ public override AstVisitAction VisitConfigurationDefinition ( ConfigurationDefinitionAst configurationDefinitionAst )
310
+ {
311
+ return Visit ( configurationDefinitionAst ) ;
312
+ }
313
+
314
+ public override AstVisitAction VisitDynamicKeywordStatement ( DynamicKeywordStatementAst dynamicKeywordStatementAst )
315
+ {
316
+ return Visit ( dynamicKeywordStatementAst ) ;
317
+ }
318
+
319
+ public override AstVisitAction VisitFunctionMember ( FunctionMemberAst functionMemberAst )
320
+ {
321
+ return Visit ( functionMemberAst ) ;
322
+ }
323
+
324
+ public override AstVisitAction VisitPropertyMember ( PropertyMemberAst propertyMemberAst )
325
+ {
326
+ return Visit ( propertyMemberAst ) ;
327
+ }
328
+
329
+ public override AstVisitAction VisitTypeDefinition ( TypeDefinitionAst typeDefinitionAst )
330
+ {
331
+ return Visit ( typeDefinitionAst ) ;
332
+ }
333
+
334
+ public override AstVisitAction VisitUsingStatement ( UsingStatementAst usingStatementAst )
335
+ {
336
+ return Visit ( usingStatementAst ) ;
337
+ }
338
+ #endif
339
+
340
+ #if ! ( NET452 || PSV6 ) // NET452 includes V3,4,5
341
+ public override AstVisitAction VisitPipelineChain ( PipelineChainAst pipelineChainAst )
342
+ {
343
+ return Visit ( pipelineChainAst ) ;
344
+ }
345
+
346
+ public override AstVisitAction VisitTernaryExpression ( TernaryExpressionAst ternaryExpressionAst )
347
+ {
348
+ return Visit ( ternaryExpressionAst ) ;
349
+ }
350
+ #endif
351
+
352
+ /// <summary>
353
+ /// Traverses the AST based on offests to find the leaf-most node which contains the provided <see cref="IScriptPosition"/>.
354
+ /// This method implements the entire functionality of this visitor. All <see cref="AstVisitor2"/> methods are overridden to simply invoke this one.
355
+ /// </summary>
356
+ /// <param name="ast">Current AST node to process.</param>
357
+ /// <returns>An <see cref="AstVisitAction"/> indicating whether to visit children of the current node.</returns>
358
+ private AstVisitAction Visit ( Ast ast )
359
+ {
360
+ if ( ast . Extent . StartOffset > searchPosition . Offset || ast . Extent . EndOffset <= searchPosition . Offset )
361
+ {
362
+ return AstVisitAction . SkipChildren ;
363
+ }
364
+ AstPosition = ast ;
365
+ return AstVisitAction . Continue ;
366
+ }
367
+
368
+ }
369
+ }
0 commit comments