44//
55
66using System ;
7+ using System . Collections . Generic ;
8+ using System . Linq ;
79using System . Management . Automation . Language ;
810
911namespace Microsoft . PowerShell . EditorServices
@@ -54,7 +56,7 @@ public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst fun
5456 } ;
5557
5658 if ( symbolRef . SymbolType . Equals ( SymbolType . Function ) &&
57- nameExtent . Text . Equals ( symbolRef . ScriptRegion . Text , StringComparison . CurrentCultureIgnoreCase ) )
59+ nameExtent . Text . Equals ( symbolRef . ScriptRegion . Text , StringComparison . CurrentCultureIgnoreCase ) )
5860 {
5961 this . FoundDeclaration =
6062 new SymbolReference (
@@ -76,19 +78,71 @@ public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst fun
7678 /// or a decision to continue if it wasn't found</returns>
7779 public override AstVisitAction VisitAssignmentStatement ( AssignmentStatementAst assignmentStatementAst )
7880 {
79- var variableExprAst = assignmentStatementAst . Left as VariableExpressionAst ;
80- if ( variableExprAst == null ||
81- variableName == null ||
82- ! variableExprAst . VariablePath . UserPath . Equals (
83- variableName ,
84- StringComparison . OrdinalIgnoreCase ) )
81+ if ( variableName == null )
8582 {
8683 return AstVisitAction . Continue ;
8784 }
8885
89- // TODO also find instances of set-variable
90- FoundDeclaration = new SymbolReference ( SymbolType . Variable , variableExprAst . Extent ) ;
91- return AstVisitAction . StopVisit ;
86+ // We want to check VariableExpressionAsts from within this AssignmentStatementAst so we visit it.
87+ FindDeclarationVariableExpressionVisitor visitor = new FindDeclarationVariableExpressionVisitor ( symbolRef ) ;
88+ assignmentStatementAst . Left . Visit ( visitor ) ;
89+
90+ if ( visitor . FoundDeclaration != null )
91+ {
92+ FoundDeclaration = visitor . FoundDeclaration ;
93+ return AstVisitAction . StopVisit ;
94+ }
95+ return AstVisitAction . Continue ;
96+ }
97+
98+ /// <summary>
99+ /// The private visitor used to find the variable expression that matches a symbol
100+ /// </summary>
101+ private class FindDeclarationVariableExpressionVisitor : AstVisitor
102+ {
103+ private SymbolReference symbolRef ;
104+ private string variableName ;
105+
106+ public SymbolReference FoundDeclaration { get ; private set ; }
107+
108+ public FindDeclarationVariableExpressionVisitor ( SymbolReference symbolRef )
109+ {
110+ this . symbolRef = symbolRef ;
111+ if ( this . symbolRef . SymbolType == SymbolType . Variable )
112+ {
113+ // converts `$varName` to `varName` or of the form ${varName} to varName
114+ variableName = symbolRef . SymbolName . TrimStart ( '$' ) . Trim ( '{' , '}' ) ;
115+ }
116+ }
117+
118+ /// <summary>
119+ /// Check if the VariableExpressionAst has the same name as that of symbolRef.
120+ /// </summary>
121+ /// <param name="variableExpressionAst">A VariableExpressionAst</param>
122+ /// <returns>A decision to stop searching if the right VariableExpressionAst was found,
123+ /// or a decision to continue if it wasn't found</returns>
124+ public override AstVisitAction VisitVariableExpression ( VariableExpressionAst variableExpressionAst )
125+ {
126+ if ( variableExpressionAst . VariablePath . UserPath . Equals ( variableName , StringComparison . OrdinalIgnoreCase ) )
127+ {
128+ // TODO also find instances of set-variable
129+ FoundDeclaration = new SymbolReference ( SymbolType . Variable , variableExpressionAst . Extent ) ;
130+ return AstVisitAction . StopVisit ;
131+ }
132+ return AstVisitAction . Continue ;
133+ }
134+
135+ public override AstVisitAction VisitMemberExpression ( MemberExpressionAst functionDefinitionAst )
136+ {
137+ // We don't want to discover any variables in member expressisons (`$something.Foo`)
138+ return AstVisitAction . SkipChildren ;
139+ }
140+
141+ public override AstVisitAction VisitIndexExpression ( IndexExpressionAst functionDefinitionAst )
142+ {
143+ // We don't want to discover any variables in index expressions (`$something[0]`)
144+ return AstVisitAction . SkipChildren ;
145+ }
92146 }
93147 }
94148}
0 commit comments