55using  Rubberduck . Parsing . Grammar ; 
66using  Rubberduck . Parsing . Symbols ; 
77using  Rubberduck . VBEditor ; 
8- using  static   Rubberduck . Parsing . Grammar . VBAParser ; 
8+ using  System . Linq ; 
99
1010namespace  Rubberduck . Inspections . QuickFixes 
1111{ 
@@ -24,80 +24,34 @@ public PassParameterByReferenceQuickFix(Declaration target, QualifiedSelection s
2424
2525        public  override  void  Fix ( ) 
2626        { 
27-             var  argCtxt  =  GetArgContextForIdentifier ( Context ,  _target . IdentifierName ) ; 
27+             var  argCtxt  =  GetArgContextForIdentifier ( Context . Parent . Parent ,  _target . IdentifierName ) ; 
2828
29-             var  terminalNodeImpl  =  GetByValNodeForArgCtx ( argCtxt ) ; 
29+             var  terminalNode  =  argCtxt . BYVAL ( ) ; 
3030
31-             var  replacementLine  =  GenerateByRefReplacementLine ( terminalNodeImpl ) ; 
31+             var  replacementLine  =  GenerateByRefReplacementLine ( terminalNode ) ; 
3232
33-             ReplaceModuleLine ( terminalNodeImpl . Symbol . Line ,  replacementLine ) ; 
33+             ReplaceModuleLine ( terminalNode . Symbol . Line ,  replacementLine ) ; 
3434
3535        } 
36-         private  ArgContext  GetArgContextForIdentifier ( ParserRuleContext  context ,  string  identifier ) 
36+         private  VBAParser . ArgContext  GetArgContextForIdentifier ( RuleContext  context ,  string  identifier ) 
3737        { 
38-             var  procStmtCtx  =  ( ParserRuleContext ) context . Parent . Parent ; 
39-             var  procStmtCtxChildren  =  procStmtCtx . children ; 
40-             for  ( int  idx  =  0 ;  idx  <  procStmtCtxChildren . Count ;  idx ++ ) 
41-             { 
42-                 if  ( procStmtCtxChildren [ idx ]  is  ArgListContext ) 
43-                 { 
44-                     var  argListContext  =  ( ArgListContext ) procStmtCtxChildren [ idx ] ; 
45-                     var  arg  =  argListContext . children ; 
46-                     for  ( int  idxArgListCtx  =  0 ;  idxArgListCtx  <  arg . Count ;  idxArgListCtx ++ ) 
47-                     { 
48-                         if  ( arg [ idxArgListCtx ]  is  ArgContext ) 
49-                         { 
50-                             var  name  =  GetIdentifierNameFor ( ( ArgContext ) arg [ idxArgListCtx ] ) ; 
51-                             if  ( name . Equals ( identifier ) ) 
52-                             { 
53-                                 return  ( ArgContext ) arg [ idxArgListCtx ] ; 
54-                             } 
55-                         } 
56-                     } 
57-                 } 
58-             } 
59-             return  null ; 
60-         } 
61-         private  string  GetIdentifierNameFor ( ArgContext  argCtxt ) 
62-         { 
63-             var  argCtxtChild  =  argCtxt . children ; 
64-             var  idRef  =  GetUnRestrictedIdentifierCtx ( argCtxt ) ; 
65-             return  idRef . GetText ( ) ; 
38+             var  argList  =  GetArgListForContext ( context ) ; 
39+             return  argList . arg ( ) . SingleOrDefault ( parameter => 
40+                     Identifier . GetName ( parameter ) . Equals ( identifier ) 
41+                     ||  Identifier . GetName ( parameter ) . Equals ( "["  +  identifier  +  "]" ) ) ; 
6642        } 
67-         private  UnrestrictedIdentifierContext   GetUnRestrictedIdentifierCtx ( ArgContext   argCtxt ) 
43+         private  string   GenerateByRefReplacementLine ( ITerminalNode   terminalNode ) 
6844        { 
69-             var  argCtxtChild  =  argCtxt . children ; 
70-             for  ( int  idx  =  0 ;  idx  <  argCtxtChild . Count ;  idx ++ ) 
71-             { 
72-                 if  ( argCtxtChild [ idx ]  is  UnrestrictedIdentifierContext ) 
73-                 { 
74-                     return  ( UnrestrictedIdentifierContext ) argCtxtChild [ idx ] ; 
75-                 } 
76-             } 
77-             return  null ; 
78-         } 
79-         private  TerminalNodeImpl  GetByValNodeForArgCtx ( ArgContext  argCtxt ) 
80-         { 
81-             var  argCtxtChild  =  argCtxt . children ; 
82-             for  ( int  idx  =  0 ;  idx  <  argCtxtChild . Count ;  idx ++ ) 
83-             { 
84-                 if  ( argCtxtChild [ idx ]  is  TerminalNodeImpl ) 
85-                 { 
86-                     var  candidate  =  ( TerminalNodeImpl ) argCtxtChild [ idx ] ; 
87-                     if  ( candidate . Symbol . Text . Equals ( Tokens . ByVal ) ) 
88-                     { 
89-                         return  candidate ; 
90-                     } 
91-                 } 
92-             } 
93-             return  null ; 
45+             var  module  =  Selection . QualifiedName . Component . CodeModule ; 
46+             var  byValTokenLine  =  module . GetLines ( terminalNode . Symbol . Line ,  1 ) ; 
47+ 
48+             return  ReplaceAtIndex ( byValTokenLine ,  Tokens . ByVal ,  Tokens . ByRef ,  terminalNode . Symbol . Column ) ; 
9449        } 
95-         private  string   GenerateByRefReplacementLine ( TerminalNodeImpl   terminalNodeImpl ) 
50+         private  void   ReplaceModuleLine ( int   lineNumber ,   string   replacementLine ) 
9651        { 
9752            var  module  =  Selection . QualifiedName . Component . CodeModule ; 
98-             var  byValTokenLine  =  module . GetLines ( terminalNodeImpl . Symbol . Line ,  1 ) ; 
99- 
100-             return  ReplaceAtIndex ( byValTokenLine ,  Tokens . ByVal ,  Tokens . ByRef ,  terminalNodeImpl . Symbol . Column ) ; 
53+             module . DeleteLines ( lineNumber ) ; 
54+             module . InsertLines ( lineNumber ,  replacementLine ) ; 
10155        } 
10256        private  string  ReplaceAtIndex ( string  input ,  string  toReplace ,  string  replacement ,  int  startIndex ) 
10357        { 
@@ -107,11 +61,29 @@ private string ReplaceAtIndex(string input, string toReplace, string replacement
10761            var  tokenToBeReplaced  =  input . Substring ( startIndex ,  stopIndex  -  startIndex  +  1 ) ; 
10862            return  prefix  +  tokenToBeReplaced . Replace ( toReplace ,  replacement )  +  suffix ; 
10963        } 
110-         private  void   ReplaceModuleLine ( int   lineNumber ,   string   replacementLine ) 
64+         private  VBAParser . ArgListContext   GetArgListForContext ( RuleContext   context ) 
11165        { 
112-             var  module  =  Selection . QualifiedName . Component . CodeModule ; 
113-             module . DeleteLines ( lineNumber ) ; 
114-             module . InsertLines ( lineNumber ,  replacementLine ) ; 
66+             if  ( context  is  VBAParser . SubStmtContext ) 
67+             { 
68+                 return  ( ( VBAParser . SubStmtContext ) context ) . argList ( ) ; 
69+             } 
70+             else  if  ( context  is  VBAParser . FunctionStmtContext ) 
71+             { 
72+                 return  ( ( VBAParser . FunctionStmtContext ) context ) . argList ( ) ; 
73+             } 
74+             else  if  ( context  is  VBAParser . PropertyLetStmtContext ) 
75+             { 
76+                 return  ( ( VBAParser . PropertyLetStmtContext ) context ) . argList ( ) ; 
77+             } 
78+             else  if  ( context  is  VBAParser . PropertyGetStmtContext ) 
79+             { 
80+                 return  ( ( VBAParser . PropertyGetStmtContext ) context ) . argList ( ) ; 
81+             } 
82+             else  if  ( context  is  VBAParser . PropertySetStmtContext ) 
83+             { 
84+                 return  ( ( VBAParser . PropertySetStmtContext ) context ) . argList ( ) ; 
85+             } 
86+             return  null ; 
11587        } 
11688    } 
11789} 
0 commit comments