@@ -25,7 +25,7 @@ internal class IterativeVariableRename
2525 internal FunctionDefinitionAst TargetFunction ;
2626 internal RenameSymbolOptions options ;
2727
28- public IterativeVariableRename ( string NewName , int StartLineNumber , int StartColumnNumber , Ast ScriptAst , RenameSymbolOptions options = null )
28+ public IterativeVariableRename ( string NewName , int StartLineNumber , int StartColumnNumber , Ast ScriptAst , RenameSymbolOptions options = null )
2929 {
3030 this . NewName = NewName ;
3131 this . StartLineNumber = StartLineNumber ;
@@ -185,38 +185,75 @@ internal static Ast GetAstParentScope(Ast node)
185185 {
186186 Ast parent = node ;
187187 // Walk backwards up the tree looking for a ScriptBLock of a FunctionDefinition
188- parent = Utilities . GetAstParentOfType ( parent , typeof ( ScriptBlockAst ) , typeof ( FunctionDefinitionAst ) , typeof ( ForEachStatementAst ) , typeof ( ForStatementAst ) ) ;
188+ parent = Utilities . GetAstParentOfType ( parent , typeof ( ScriptBlockAst ) , typeof ( FunctionDefinitionAst ) , typeof ( ForEachStatementAst ) , typeof ( ForStatementAst ) ) ;
189189 if ( parent is ScriptBlockAst && parent . Parent != null && parent . Parent is FunctionDefinitionAst )
190190 {
191191 parent = parent . Parent ;
192192 }
193193 // Check if the parent of the VariableExpressionAst is a ForEachStatementAst then check if the variable names match
194194 // if so this is probably a variable defined within a foreach loop
195- else if ( parent is ForEachStatementAst ForEachStmnt && node is VariableExpressionAst VarExp &&
196- ForEachStmnt . Variable . VariablePath . UserPath == VarExp . VariablePath . UserPath ) {
195+ else if ( parent is ForEachStatementAst ForEachStmnt && node is VariableExpressionAst VarExp &&
196+ ForEachStmnt . Variable . VariablePath . UserPath == VarExp . VariablePath . UserPath )
197+ {
197198 parent = ForEachStmnt ;
198199 }
199200 // Check if the parent of the VariableExpressionAst is a ForStatementAst then check if the variable names match
200201 // if so this is probably a variable defined within a foreach loop
201- else if ( parent is ForStatementAst ForStmnt && node is VariableExpressionAst ForVarExp &&
202+ else if ( parent is ForStatementAst ForStmnt && node is VariableExpressionAst ForVarExp &&
202203 ForStmnt . Initializer is AssignmentStatementAst AssignStmnt && AssignStmnt . Left is VariableExpressionAst VarExpStmnt &&
203- VarExpStmnt . VariablePath . UserPath == ForVarExp . VariablePath . UserPath ) {
204+ VarExpStmnt . VariablePath . UserPath == ForVarExp . VariablePath . UserPath )
205+ {
204206 parent = ForStmnt ;
205207 }
206208
207209 return parent ;
208210 }
209211
212+ internal static bool IsVariableExpressionAssignedInTargetScope ( VariableExpressionAst node , Ast scope )
213+ {
214+ bool r = false ;
215+ 216+ List < VariableExpressionAst > VariableAssignments = node . FindAll ( ast =>
217+ {
218+ return ast is VariableExpressionAst VarDef &&
219+ VarDef . Parent is AssignmentStatementAst or ParameterAst &&
220+ VarDef . VariablePath . UserPath . ToLower ( ) == node . VariablePath . UserPath . ToLower ( ) &&
221+ // Look Backwards from the node above
222+ ( VarDef . Extent . EndLineNumber < node . Extent . StartLineNumber ||
223+ ( VarDef . Extent . EndColumnNumber <= node . Extent . StartColumnNumber &&
224+ VarDef . Extent . EndLineNumber <= node . Extent . StartLineNumber ) ) &&
225+ // Must be within the the designated scope
226+ VarDef . Extent . StartLineNumber >= scope . Extent . StartLineNumber ;
227+ } , true ) . Cast < VariableExpressionAst > ( ) . ToList ( ) ;
228+ 229+ if ( VariableAssignments . Count > 0 )
230+ {
231+ r = true ;
232+ }
233+ // Node is probably the first Assignment Statement within scope
234+ if ( node . Parent is AssignmentStatementAst && node . Extent . StartLineNumber >= scope . Extent . StartLineNumber )
235+ {
236+ r = true ;
237+ }
238+ 239+ return r ;
240+ }
241+ 210242 internal static bool WithinTargetsScope ( Ast Target , Ast Child )
211243 {
212244 bool r = false ;
213245 Ast childParent = Child . Parent ;
214246 Ast TargetScope = GetAstParentScope ( Target ) ;
215247 while ( childParent != null )
216248 {
217- if ( childParent is FunctionDefinitionAst )
249+ if ( childParent is FunctionDefinitionAst FuncDefAst )
218250 {
219- break ;
251+ if ( Child is VariableExpressionAst VarExpAst && ! IsVariableExpressionAssignedInTargetScope ( VarExpAst , FuncDefAst ) )
252+ {
253+ 254+ } else {
255+ break ;
256+ }
220257 }
221258 if ( childParent == TargetScope )
222259 {
0 commit comments