Skip to content

Commit 4d61b8b

Browse files
committed
Handle array declarations in move closer to usage. Closes #3258
1 parent 2a47a4d commit 4d61b8b

File tree

2 files changed

+154
-11
lines changed

2 files changed

+154
-11
lines changed

Rubberduck.Refactorings/MoveCloserToUsage/MoveCloserToUsageRefactoring.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using Antlr4.Runtime.Misc;
66
using Rubberduck.Common;
77
using Rubberduck.Interaction;
8+
using Rubberduck.Parsing;
89
using Rubberduck.Parsing.Grammar;
910
using Rubberduck.Parsing.Rewriter;
1011
using Rubberduck.Parsing.Symbols;
@@ -152,7 +153,11 @@ private void UpdateOtherModules()
152153

153154
private void InsertNewDeclaration()
154155
{
155-
var newVariable = $"Dim {_target.IdentifierName} As {_target.AsTypeName}{Environment.NewLine}";
156+
var subscripts = _target.Context.GetDescendent<VBAParser.SubscriptsContext>()?.GetText() ?? string.Empty;
157+
var identifier = _target.IsArray ? $"{_target.IdentifierName}({subscripts})" : _target.IdentifierName;
158+
var newVariable = _target.AsTypeContext is null
159+
? $"{Tokens.Dim} {identifier} {Tokens.As} {Tokens.Variant}{Environment.NewLine}"
160+
: $"{Tokens.Dim} {identifier} {Tokens.As} {_target.AsTypeNameWithoutArrayDesignator}{Environment.NewLine}";
156161

157162
var firstReference = _target.References.OrderBy(r => r.Selection.StartLine).First();
158163

RubberduckTests/Refactoring/MoveCloserToUsageTests.cs

Lines changed: 148 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ Private Sub Foo()
308308
Dim bat As Boolean
309309
bat = True
310310
End Sub";
311-
311+
312312
var vbe = MockVbeBuilder.BuildFromSingleStandardModule(inputCode, out var component, selection);
313313
using (var state = MockParser.CreateAndParse(vbe.Object))
314314
{
@@ -428,7 +428,7 @@ Private Sub Foo()
428428
Dim bay As Date
429429
bay = #1/13/2004#
430430
End Sub";
431-
431+
432432
var vbe = MockVbeBuilder.BuildFromSingleStandardModule(inputCode, out var component, selection);
433433
using (var state = MockParser.CreateAndParse(vbe.Object))
434434
{
@@ -470,7 +470,7 @@ bay As Date
470470
Dim bar As Integer
471471
bar = 3
472472
End Sub";
473-
473+
474474
var vbe = MockVbeBuilder.BuildFromSingleStandardModule(inputCode, out var component, selection);
475475
using (var state = MockParser.CreateAndParse(vbe.Object))
476476
{
@@ -687,7 +687,7 @@ End Sub
687687
Sub Baz(ByVal bat As Boolean)
688688
End Sub";
689689
var selection = new Selection(1, 1);
690-
690+
691691
var vbe = MockVbeBuilder.BuildFromSingleStandardModule(inputCode, out var component, selection);
692692
using (var state = MockParser.CreateAndParse(vbe.Object))
693693
{
@@ -728,8 +728,8 @@ End Sub
728728
Sub Baz(ByVal bat As Boolean, ByVal bas As Boolean, ByVal bac As Boolean)
729729
End Sub";
730730
var selection = new Selection(1, 1);
731-
732-
var vbe = MockVbeBuilder.BuildFromSingleStandardModule(inputCode, out var component, selection);
731+
732+
var vbe = MockVbeBuilder.BuildFromSingleStandardModule(inputCode, out var component, selection);
733733
using (var state = MockParser.CreateAndParse(vbe.Object))
734734
{
735735

@@ -761,7 +761,7 @@ Private Sub Foo(): Baz True, True, bar: End Sub
761761
@"Private Sub Foo(): Dim bar As Boolean
762762
Baz True, True, bar: End Sub
763763
Private Sub Baz(ByVal bat As Boolean, ByVal bas As Boolean, ByVal bac As Boolean): End Sub";
764-
764+
765765
var vbe = MockVbeBuilder.BuildFromSingleStandardModule(inputCode, out var component, selection);
766766
using (var state = MockParser.CreateAndParse(vbe.Object))
767767
{
@@ -806,7 +806,7 @@ End Sub
806806
Public Sub SomeSub(ByVal someParam As Long)
807807
Debug.Print someParam
808808
End Sub";
809-
809+
810810
var vbe = MockVbeBuilder.BuildFromSingleStandardModule(inputCode, out var component, selection);
811811
using (var state = MockParser.CreateAndParse(vbe.Object))
812812
{
@@ -845,7 +845,7 @@ Public Sub Test(): Dim foo As Long
845845
Public Sub SomeSub(ByVal someParam As Long)
846846
Debug.Print someParam
847847
End Sub";
848-
848+
849849
var vbe = MockVbeBuilder.BuildFromSingleStandardModule(inputCode, out var component, selection);
850850
using (var state = MockParser.CreateAndParse(vbe.Object))
851851
{
@@ -871,7 +871,7 @@ public void IntroduceFieldRefactoring_PassInTarget_Nonvariable()
871871
Private Sub Foo()
872872
bar = True
873873
End Sub";
874-
874+
875875
var vbe = MockVbeBuilder.BuildFromSingleStandardModule(inputCode, out var component);
876876
using (var state = MockParser.CreateAndParse(vbe.Object))
877877
{
@@ -1044,5 +1044,143 @@ Dim foo As Class1
10441044
Assert.AreEqual(expected, actual);
10451045
}
10461046
}
1047+
1048+
[Test]
1049+
[Category("Refactorings")]
1050+
[Category("Move Closer")]
1051+
public void MoveCloserToUsageRefactoring_DynamicArray()
1052+
{
1053+
//Input
1054+
const string inputCode =
1055+
@"Private bar() As Boolean
1056+
Private Sub Foo()
1057+
ReDim bar(0)
1058+
bar(0) = True
1059+
End Sub";
1060+
var selection = new Selection(1, 1);
1061+
1062+
//Expectation
1063+
const string expectedCode =
1064+
@"Private Sub Foo()
1065+
Dim bar() As Boolean
1066+
ReDim bar(0)
1067+
bar(0) = True
1068+
End Sub";
1069+
1070+
var vbe = MockVbeBuilder.BuildFromSingleStandardModule(inputCode, out var component, selection);
1071+
using (var state = MockParser.CreateAndParse(vbe.Object))
1072+
{
1073+
1074+
var qualifiedSelection = new QualifiedSelection(new QualifiedModuleName(component), selection);
1075+
1076+
var refactoring = new MoveCloserToUsageRefactoring(vbe.Object, state, null);
1077+
refactoring.Refactor(qualifiedSelection);
1078+
1079+
var rewriter = state.GetRewriter(component);
1080+
Assert.AreEqual(expectedCode, rewriter.GetText());
1081+
}
1082+
}
1083+
1084+
[Test]
1085+
[Category("Refactorings")]
1086+
[Category("Move Closer")]
1087+
public void MoveCloserToUsageRefactoring_FixedArray()
1088+
{
1089+
//Input
1090+
const string inputCode =
1091+
@"Private bar(0) As Boolean
1092+
Private Sub Foo()
1093+
bar(0) = True
1094+
End Sub";
1095+
var selection = new Selection(1, 1);
1096+
1097+
//Expectation
1098+
const string expectedCode =
1099+
@"Private Sub Foo()
1100+
Dim bar(0) As Boolean
1101+
bar(0) = True
1102+
End Sub";
1103+
1104+
var vbe = MockVbeBuilder.BuildFromSingleStandardModule(inputCode, out var component, selection);
1105+
using (var state = MockParser.CreateAndParse(vbe.Object))
1106+
{
1107+
1108+
var qualifiedSelection = new QualifiedSelection(new QualifiedModuleName(component), selection);
1109+
1110+
var refactoring = new MoveCloserToUsageRefactoring(vbe.Object, state, null);
1111+
refactoring.Refactor(qualifiedSelection);
1112+
1113+
var rewriter = state.GetRewriter(component);
1114+
Assert.AreEqual(expectedCode, rewriter.GetText());
1115+
}
1116+
}
1117+
1118+
[Test]
1119+
[Category("Refactorings")]
1120+
[Category("Move Closer")]
1121+
public void MoveCloserToUsageRefactoring_FixedArrayBounded()
1122+
{
1123+
//Input
1124+
const string inputCode =
1125+
@"Private bar(1 To 42) As Boolean
1126+
Private Sub Foo()
1127+
bar(1) = True
1128+
End Sub";
1129+
var selection = new Selection(1, 1);
1130+
1131+
//Expectation
1132+
const string expectedCode =
1133+
@"Private Sub Foo()
1134+
Dim bar(1 To 42) As Boolean
1135+
bar(1) = True
1136+
End Sub";
1137+
1138+
var vbe = MockVbeBuilder.BuildFromSingleStandardModule(inputCode, out var component, selection);
1139+
using (var state = MockParser.CreateAndParse(vbe.Object))
1140+
{
1141+
1142+
var qualifiedSelection = new QualifiedSelection(new QualifiedModuleName(component), selection);
1143+
1144+
var refactoring = new MoveCloserToUsageRefactoring(vbe.Object, state, null);
1145+
refactoring.Refactor(qualifiedSelection);
1146+
1147+
var rewriter = state.GetRewriter(component);
1148+
Assert.AreEqual(expectedCode, rewriter.GetText());
1149+
}
1150+
}
1151+
1152+
[Test]
1153+
[Category("Refactorings")]
1154+
[Category("Move Closer")]
1155+
public void MoveCloserToUsageRefactoring_MultiDimensionalArray()
1156+
{
1157+
//Input
1158+
const string inputCode =
1159+
@"Private bar(1, 1) As Boolean
1160+
Private Sub Foo()
1161+
bar(0, 0) = True
1162+
End Sub";
1163+
var selection = new Selection(1, 1);
1164+
1165+
//Expectation
1166+
const string expectedCode =
1167+
@"Private Sub Foo()
1168+
Dim bar(1, 1) As Boolean
1169+
bar(0, 0) = True
1170+
End Sub";
1171+
1172+
var vbe = MockVbeBuilder.BuildFromSingleStandardModule(inputCode, out var component, selection);
1173+
using (var state = MockParser.CreateAndParse(vbe.Object))
1174+
{
1175+
1176+
var qualifiedSelection = new QualifiedSelection(new QualifiedModuleName(component), selection);
1177+
1178+
var refactoring = new MoveCloserToUsageRefactoring(vbe.Object, state, null);
1179+
refactoring.Refactor(qualifiedSelection);
1180+
1181+
var rewriter = state.GetRewriter(component);
1182+
Assert.AreEqual(expectedCode, rewriter.GetText());
1183+
}
1184+
}
10471185
}
10481186
}

0 commit comments

Comments
 (0)