|
4 | 4 | using System.Linq;
|
5 | 5 | using Antlr4.Runtime;
|
6 | 6 | using Rubberduck.Parsing;
|
| 7 | +using Rubberduck.Parsing.Grammar; |
7 | 8 | using Rubberduck.Parsing.Symbols;
|
8 | 9 | using Rubberduck.Parsing.VBA;
|
9 | 10 | using Rubberduck.VBEditor;
|
@@ -162,10 +163,74 @@ private static string RemoveExtraComma(string str, int numParams, int indexRemov
|
162 | 163 |
|
163 | 164 | public static void Remove(this ICodeModule module, IdentifierReference target)
|
164 | 165 | {
|
165 |
| - var parent = target.Context.Parent as ParserRuleContext; |
| 166 | + var parent = (ParserRuleContext)target.Context.Parent; |
| 167 | + if (target.IsAssignment) |
| 168 | + { |
| 169 | + // target is LHS of assignment; need to know if there's a procedure call in RHS |
| 170 | + var letStmt = parent as VBAParser.LetStmtContext; |
| 171 | + var setStmt = parent as VBAParser.SetStmtContext; |
| 172 | + |
| 173 | + string argList; |
| 174 | + if (HasProcedureCall(letStmt, out argList) || HasProcedureCall(setStmt, out argList)) |
| 175 | + { |
| 176 | + // need to remove LHS only; RHS expression may have side-effects |
| 177 | + var original = parent.GetText(); |
| 178 | + var replacement = ReplaceStringAtIndex(original, target.IdentifierName + " = ", string.Empty, 0); |
| 179 | + if (argList != null) |
| 180 | + { |
| 181 | + var atIndex = replacement.IndexOf(argList, StringComparison.OrdinalIgnoreCase); |
| 182 | + var plainArgs = " " + argList.Substring(1, argList.Length - 2); |
| 183 | + replacement = ReplaceStringAtIndex(replacement, argList, plainArgs, atIndex); |
| 184 | + } |
| 185 | + module.ReplaceLine(parent.Start.Line, replacement); |
| 186 | + return; |
| 187 | + } |
| 188 | + } |
| 189 | + |
166 | 190 | module.Remove(parent.GetSelection(), parent);
|
167 | 191 | }
|
168 | 192 |
|
| 193 | + private static bool HasProcedureCall(VBAParser.LetStmtContext context, out string argList) |
| 194 | + { |
| 195 | + if (context == null) |
| 196 | + { |
| 197 | + argList = null; |
| 198 | + return false; |
| 199 | + } |
| 200 | + return HasProcedureCall(context.expression(), out argList); |
| 201 | + } |
| 202 | + |
| 203 | + private static bool HasProcedureCall(VBAParser.SetStmtContext context, out string argList) |
| 204 | + { |
| 205 | + if (context == null) |
| 206 | + { |
| 207 | + argList = null; |
| 208 | + return false; |
| 209 | + } |
| 210 | + return HasProcedureCall(context.expression(), out argList); |
| 211 | + } |
| 212 | + |
| 213 | + private static bool HasProcedureCall(VBAParser.ExpressionContext context, out string argList) |
| 214 | + { |
| 215 | + // bug: what if complex expression has multiple arg lists? |
| 216 | + argList = GetArgListString(context.FindChildren<VBAParser.ArgListContext>().FirstOrDefault()) |
| 217 | + ?? GetArgListString(context.FindChildren<VBAParser.ArgumentListContext>().FirstOrDefault()); |
| 218 | + |
| 219 | + return !(context is VBAParser.LiteralExprContext |
| 220 | + || context is VBAParser.NewExprContext |
| 221 | + || context is VBAParser.BuiltInTypeExprContext); |
| 222 | + } |
| 223 | + |
| 224 | + private static string GetArgListString(VBAParser.ArgListContext context) |
| 225 | + { |
| 226 | + return context == null ? null : context.GetText(); |
| 227 | + } |
| 228 | + |
| 229 | + private static string GetArgListString(VBAParser.ArgumentListContext context) |
| 230 | + { |
| 231 | + return context == null ? null : "(" + context.GetText() + ")"; |
| 232 | + } |
| 233 | + |
169 | 234 | public static void Remove(this ICodeModule module, IEnumerable<IdentifierReference> targets)
|
170 | 235 | {
|
171 | 236 | foreach (var target in targets.OrderByDescending(e => e.Selection))
|
|
0 commit comments