4
4
//
5
5
6
6
using System ;
7
+ using System . Collections . Generic ;
8
+ using System . Linq ;
7
9
using System . Management . Automation . Language ;
8
10
9
11
namespace Microsoft . PowerShell . EditorServices
@@ -54,7 +56,7 @@ public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst fun
54
56
} ;
55
57
56
58
if ( symbolRef . SymbolType . Equals ( SymbolType . Function ) &&
57
- nameExtent . Text . Equals ( symbolRef . ScriptRegion . Text , StringComparison . CurrentCultureIgnoreCase ) )
59
+ nameExtent . Text . Equals ( symbolRef . ScriptRegion . Text , StringComparison . CurrentCultureIgnoreCase ) )
58
60
{
59
61
this . FoundDeclaration =
60
62
new SymbolReference (
@@ -76,19 +78,71 @@ public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst fun
76
78
/// or a decision to continue if it wasn't found</returns>
77
79
public override AstVisitAction VisitAssignmentStatement ( AssignmentStatementAst assignmentStatementAst )
78
80
{
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 )
85
82
{
86
83
return AstVisitAction . Continue ;
87
84
}
88
85
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
+ }
92
146
}
93
147
}
94
148
}
0 commit comments