Skip to content

Commit 21b4990

Browse files
committed
Fix bug in Pass Parameter by Value quick fix
1 parent f0b7706 commit 21b4990

File tree

3 files changed

+106
-10
lines changed

3 files changed

+106
-10
lines changed

RetailCoder.VBE/Inspections/ParameterCanBeByValInspection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public override IEnumerable<InspectionResultBase> GetInspectionResults()
4949
&& ((VBAParser.ArgContext)declaration.Context).BYVAL() == null
5050
&& !IsUsedAsByRefParam(declarations, declaration)
5151
&& !declaration.References.Any(reference => reference.IsAssignment))
52-
.Select(issue => new ParameterCanBeByValInspectionResult(this, issue, ((dynamic)issue.Context).unrestrictedIdentifier(), issue.QualifiedName));
52+
.Select(issue => new ParameterCanBeByValInspectionResult(this, issue, issue.Context, issue.QualifiedName));
5353

5454
return issues;
5555
}

RetailCoder.VBE/Inspections/ParameterCanBeByValInspectionResult.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,13 @@ public PassParameterByValueQuickFix(ParserRuleContext context, QualifiedSelectio
3636

3737
public override void Fix()
3838
{
39-
var parameter = Context.Parent.GetText();
40-
var newContent = string.Concat(Tokens.ByVal, " ", parameter.Replace(Tokens.ByRef, string.Empty).Trim());
4139
var selection = Selection.Selection;
40+
var selectionLength = ((VBAParser.ArgContext) Context).BYREF() == null ? 0 : 6;
4241

4342
var module = Selection.QualifiedName.Component.CodeModule;
44-
var lines = module.Lines[selection.StartLine, selection.LineCount];
43+
var lines = module.Lines[selection.StartLine, 1];
4544

46-
var result = lines.Replace(parameter, newContent);
45+
var result = lines.Remove(selection.StartColumn - 1, selectionLength).Insert(selection.StartColumn - 1, Tokens.ByVal + ' ');
4746
module.ReplaceLine(selection.StartLine, result);
4847
}
4948
}

RubberduckTests/Inspections/ParameterCanBeByValInspectionTests.cs

Lines changed: 102 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,63 @@ public void ParameterCanByByVal_ReturnsResult_SomeParams()
192192
Assert.AreEqual(1, inspectionResults.Count());
193193
}
194194

195+
[TestMethod]
196+
[TestCategory("Inspections")]
197+
public void GivenArrayParameter_ReturnsNoResult()
198+
{
199+
const string inputCode =
200+
@"Sub Foo(ByRef arg1() As Variant)
201+
End Sub";
202+
203+
//Arrange
204+
var builder = new MockVbeBuilder();
205+
VBComponent component;
206+
var vbe = builder.BuildFromSingleStandardModule(inputCode, out component);
207+
var mockHost = new Mock<IHostApplication>();
208+
mockHost.SetupAllProperties();
209+
var parser = MockParser.Create(vbe.Object, new RubberduckParserState(vbe.Object, new Mock<ISinks>().Object));
210+
211+
parser.Parse(new CancellationTokenSource());
212+
if (parser.State.Status >= ParserState.Error) { Assert.Inconclusive("Parser Error"); }
213+
214+
var inspection = new ParameterCanBeByValInspection(parser.State);
215+
216+
var results = inspection.GetInspectionResults().ToList();
217+
218+
Assert.AreEqual(0, results.Count);
219+
}
220+
221+
[TestMethod]
222+
[TestCategory("Inspections")]
223+
public void ParameterCanByByVal_ReturnsResult_QuickFixWorks_SubNameStartsWithParamName()
224+
{
225+
const string inputCode =
226+
@"Sub foo(f)
227+
End Sub";
228+
229+
const string expectedCode =
230+
@"Sub foo(ByVal f)
231+
End Sub";
232+
233+
//Arrange
234+
var builder = new MockVbeBuilder();
235+
VBComponent component;
236+
var vbe = builder.BuildFromSingleStandardModule(inputCode, out component);
237+
var project = vbe.Object.VBProjects.Item(0);
238+
var module = project.VBComponents.Item(0).CodeModule;
239+
var mockHost = new Mock<IHostApplication>();
240+
mockHost.SetupAllProperties();
241+
var parser = MockParser.Create(vbe.Object, new RubberduckParserState(vbe.Object, new Mock<ISinks>().Object));
242+
243+
parser.Parse(new CancellationTokenSource());
244+
if (parser.State.Status >= ParserState.Error) { Assert.Inconclusive("Parser Error"); }
245+
246+
var inspection = new ParameterCanBeByValInspection(parser.State);
247+
inspection.GetInspectionResults().First().QuickFixes.First().Fix();
248+
249+
Assert.AreEqual(expectedCode, module.Lines());
250+
}
251+
195252
[TestMethod]
196253
[TestCategory("Inspections")]
197254
public void ParameterCanByByVal_ReturnsResult_QuickFixWorks_PassedByUnspecified()
@@ -256,16 +313,24 @@ public void ParameterCanByByVal_ReturnsResult_QuickFixWorks_PassedByRef()
256313

257314
[TestMethod]
258315
[TestCategory("Inspections")]
259-
public void GivenArrayParameter_ReturnsNoResult()
316+
public void ParameterCanByByVal_ReturnsResult_QuickFixWorks_PassedByUnspecified_MultilineParameter()
260317
{
261318
const string inputCode =
262-
@"Sub Foo(ByRef arg1() As Variant)
319+
@"Sub Foo( _
320+
arg1 As String)
321+
End Sub";
322+
323+
const string expectedCode =
324+
@"Sub Foo( _
325+
ByVal arg1 As String)
263326
End Sub";
264327

265328
//Arrange
266329
var builder = new MockVbeBuilder();
267330
VBComponent component;
268331
var vbe = builder.BuildFromSingleStandardModule(inputCode, out component);
332+
var project = vbe.Object.VBProjects.Item(0);
333+
var module = project.VBComponents.Item(0).CodeModule;
269334
var mockHost = new Mock<IHostApplication>();
270335
mockHost.SetupAllProperties();
271336
var parser = MockParser.Create(vbe.Object, new RubberduckParserState(vbe.Object, new Mock<ISinks>().Object));
@@ -274,10 +339,42 @@ public void GivenArrayParameter_ReturnsNoResult()
274339
if (parser.State.Status >= ParserState.Error) { Assert.Inconclusive("Parser Error"); }
275340

276341
var inspection = new ParameterCanBeByValInspection(parser.State);
277-
278-
var results = inspection.GetInspectionResults().ToList();
342+
inspection.GetInspectionResults().First().QuickFixes.First().Fix();
279343

280-
Assert.AreEqual(0, results.Count);
344+
Assert.AreEqual(expectedCode, module.Lines());
345+
}
346+
347+
[TestMethod]
348+
[TestCategory("Inspections")]
349+
public void ParameterCanByByVal_ReturnsResult_QuickFixWorks_PassedByRef_MultilineParameter()
350+
{
351+
const string inputCode =
352+
@"Sub Foo(ByRef _
353+
arg1 As String)
354+
End Sub";
355+
356+
const string expectedCode =
357+
@"Sub Foo(ByVal _
358+
arg1 As String)
359+
End Sub";
360+
361+
//Arrange
362+
var builder = new MockVbeBuilder();
363+
VBComponent component;
364+
var vbe = builder.BuildFromSingleStandardModule(inputCode, out component);
365+
var project = vbe.Object.VBProjects.Item(0);
366+
var module = project.VBComponents.Item(0).CodeModule;
367+
var mockHost = new Mock<IHostApplication>();
368+
mockHost.SetupAllProperties();
369+
var parser = MockParser.Create(vbe.Object, new RubberduckParserState(vbe.Object, new Mock<ISinks>().Object));
370+
371+
parser.Parse(new CancellationTokenSource());
372+
if (parser.State.Status >= ParserState.Error) { Assert.Inconclusive("Parser Error"); }
373+
374+
var inspection = new ParameterCanBeByValInspection(parser.State);
375+
inspection.GetInspectionResults().First().QuickFixes.First().Fix();
376+
377+
Assert.AreEqual(expectedCode, module.Lines());
281378
}
282379

283380
[TestMethod]

0 commit comments

Comments
 (0)