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