Skip to content

Commit 788dc2d

Browse files
authored
Merge pull request #1862 from comintern/next
"If Foo Then Bar Else" fix. Closes #1858
2 parents a83be73 + e4775ab commit 788dc2d

File tree

5 files changed

+122
-11
lines changed

5 files changed

+122
-11
lines changed

Rubberduck.SmartIndenter/AbsoluteCodeLine.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@ internal class AbsoluteCodeLine
1919
private static readonly Regex ProcedureEndRegex = new Regex(@"^End\s(Sub|Function|Property)");
2020
private static readonly Regex TypeEnumStartRegex = new Regex(@"^(Public\s|Private\s)?(Enum\s|Type\s)");
2121
private static readonly Regex TypeEnumEndRegex = new Regex(@"^End\s(Enum|Type)");
22-
private static readonly Regex InProcedureInRegex = new Regex(@"^(Else)?If\s.*\sThen|^Else$|^Case\s|^With|^For\s|^Do$|^Do\s|^While$|^While\s|^Select Case");
23-
private static readonly Regex InProcedureOutRegex = new Regex(@"^If\s.*\sThen\s|^Else$|^ElseIf\s.*\sThen|^Case\s|^End With|^Next\s|^Next$|^Loop$|^Loop\s|^Wend$|^End If$|^End Select");
22+
private static readonly Regex InProcedureInRegex = new Regex(@"^(Else)?If\s.*\sThen$|^(Else)?If\s.*\sThen\s.*\sElse$|^Else$|^Case\s|^With|^For\s|^Do$|^Do\s|^While$|^While\s|^Select Case");
23+
private static readonly Regex InProcedureOutRegex = new Regex(@"^(Else)?If\s.*\sThen\s.*(?<!\sElse)$|^Else$|ElseIf\s.*\sThen$|^Case\s|^End With|^Next\s|^Next$|^Loop$|^Loop\s|^Wend$|^End If$|^End Select");
2424
private static readonly Regex DeclarationRegex = new Regex(@"^(Dim|Const|Static|Public|Private)\s.*\sAs\s");
2525
private static readonly Regex PrecompilerInRegex = new Regex(@"^#(Else)?If\s.+Then$|^#Else$");
2626
private static readonly Regex PrecompilerOutRegex = new Regex(@"^#ElseIf\s.+Then|^#Else$|#End\sIf$");
27-
private static readonly Regex SingleLineIfRegex = new Regex(@"^If\s.*\sThen\s.*$");
27+
private static readonly Regex SingleLineIfRegex = new Regex(@"^If\s.*\sThen\s.*(?<!\sElse)$");
28+
private static readonly Regex SingleLineElseIfRegex = new Regex(@"^ElseIf\s.*\sThen\s.*(?<!\sElse)$");
2829

2930
private readonly IIndenterSettings _settings;
3031
private uint _lineNumber;
@@ -86,8 +87,14 @@ private void ExtractEndOfLineComment()
8687
}
8788

8889
public string Original { get; private set; }
90+
8991
public string EndOfLineComment { get; private set; }
9092

93+
public IEnumerable<string> Segments
94+
{
95+
get { return _segments; }
96+
}
97+
9198
public string ContinuationRebuildText
9299
{
93100
get
@@ -155,7 +162,7 @@ public int NextLineIndents
155162
var adjust = _settings.IndentCase && _segments.Any(s => s.TrimStart().StartsWith("Select Case")) ? 1 : 0;
156163
var ins = _segments.Count(s => InProcedureInRegex.IsMatch(s.Trim())) + (IsProcedureStart && _settings.IndentEntireProcedureBody ? 1 : 0) + adjust;
157164

158-
ins -= _segments.Count(s => SingleLineIfRegex.IsMatch(s));
165+
ins += _segments.Count(s => SingleLineElseIfRegex.IsMatch(s));
159166
ins -= MultipleCaseAdjustment();
160167

161168
if (_settings.IndentCompilerDirectives && PrecompilerInRegex.IsMatch(_segments[0].Trim()))

Rubberduck.SmartIndenter/LogicalCodeLine.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ public int NextLineIndents
3535
get
3636
{
3737
RebuildContinuedLine();
38-
return _rebuilt.NextLineIndents;
38+
return _rebuilt.Segments.Count() < 2
39+
? _rebuilt.NextLineIndents
40+
: _rebuilt.Segments.Select(s => new AbsoluteCodeLine(s, _settings)).Select(a => a.NextLineIndents).Sum();
3941
}
4042
}
4143

@@ -44,7 +46,12 @@ public int Outdents
4446
get
4547
{
4648
RebuildContinuedLine();
47-
return _rebuilt.Outdents;
49+
if (_rebuilt.Segments.Count() < 2)
50+
{
51+
return _rebuilt.Outdents;
52+
}
53+
var baseSegment = new AbsoluteCodeLine(_rebuilt.Segments.First(), _settings);
54+
return baseSegment.Outdents;
4855
}
4956
}
5057

RubberduckTests/SmartIndenter/LineContinuationTests.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ public void RemsWithLineContinuationsWork()
261261
Assert.IsTrue(code.SequenceEqual(actual));
262262
}
263263

264-
[TestMethod, Ignore] // Broken in VB6 SmartIndenter. Should be same fix as IfThenElseOnSameLineWorks()
264+
[TestMethod] // Broken in VB6 SmartIndenter.
265265
[TestCategory("Indenter")]
266266
public void DoWhileOnTwoLinesWorks()
267267
{
@@ -274,12 +274,11 @@ public void DoWhileOnTwoLinesWorks()
274274
"End Sub"
275275
};
276276

277-
//TODO: Not sure if this is what should be expected...
278277
var expected = new[]
279278
{
280279
"Public Sub Test()",
281280
" Do _",
282-
" While X < 10: X = X + 1: Loop",
281+
" While X < 10: X = X + 1: Loop",
283282
" Debug.Print X",
284283
"End Sub"
285284
};
@@ -289,7 +288,7 @@ public void DoWhileOnTwoLinesWorks()
289288
Assert.IsTrue(expected.SequenceEqual(actual));
290289
}
291290

292-
[TestMethod] // Broken in VB6 SmartIndenter.
291+
[TestMethod] // Broken in VB6 SmartIndenter.
293292
[TestCategory("Indenter")]
294293
public void ContinuedIfThenWorks()
295294
{

RubberduckTests/SmartIndenter/MiscAndCornerCaseTests.cs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,104 @@ public void ElseIfStatementWorks()
8181
Assert.IsTrue(expected.SequenceEqual(actual));
8282
}
8383

84+
//https://github.com/rubberduck-vba/Rubberduck/issues/1858
85+
[TestMethod]
86+
[TestCategory("Indenter")]
87+
public void MultipleElseIfStatementWorks()
88+
{
89+
var code = new[]
90+
{
91+
"Public Sub Test()",
92+
"If Foo And Bar Then",
93+
"Call Foobar",
94+
"ElseIf Not Foo Then",
95+
"Call Baz",
96+
"ElseIf Not Bar Then",
97+
"Call NoBaz",
98+
"Else",
99+
"MsgBox \"No Foos or Bars\"",
100+
"End If",
101+
"End Sub"
102+
};
103+
104+
var expected = new[]
105+
{
106+
"Public Sub Test()",
107+
" If Foo And Bar Then",
108+
" Call Foobar",
109+
" ElseIf Not Foo Then",
110+
" Call Baz",
111+
" ElseIf Not Bar Then",
112+
" Call NoBaz",
113+
" Else",
114+
" MsgBox \"No Foos or Bars\"",
115+
" End If",
116+
"End Sub"
117+
};
118+
119+
var indenter = new Indenter(null, () => IndenterSettingsTests.GetMockIndenterSettings());
120+
var actual = indenter.Indent(code, string.Empty);
121+
Assert.IsTrue(expected.SequenceEqual(actual));
122+
}
123+
124+
//https://github.com/rubberduck-vba/Rubberduck/issues/1858
125+
[TestMethod]
126+
[TestCategory("Indenter")]
127+
public void IfThenElseStatementWorks()
128+
{
129+
var code = new[]
130+
{
131+
"Public Sub Test()",
132+
"If Foo And Bar Then Foobar Else",
133+
"Baz",
134+
"End If",
135+
"End Sub"
136+
};
137+
138+
var expected = new[]
139+
{
140+
"Public Sub Test()",
141+
" If Foo And Bar Then Foobar Else",
142+
" Baz",
143+
" End If",
144+
"End Sub"
145+
};
146+
147+
var indenter = new Indenter(null, () => IndenterSettingsTests.GetMockIndenterSettings());
148+
var actual = indenter.Indent(code, string.Empty);
149+
Assert.IsTrue(expected.SequenceEqual(actual));
150+
}
151+
152+
//https://github.com/rubberduck-vba/Rubberduck/issues/1858
153+
[TestMethod]
154+
[TestCategory("Indenter")]
155+
public void ElseIfThenElseStatementWorks()
156+
{
157+
var code = new[]
158+
{
159+
"Public Sub Test()",
160+
"If Foo Then NotFoobar",
161+
"ElseIf Foo And Bar Then Foobar Else",
162+
"Baz",
163+
"End If",
164+
"End Sub"
165+
};
166+
167+
var expected = new[]
168+
{
169+
"Public Sub Test()",
170+
" If Foo Then NotFoobar",
171+
" ElseIf Foo And Bar Then Foobar Else",
172+
" Baz",
173+
" End If",
174+
"End Sub"
175+
};
176+
177+
var indenter = new Indenter(null, () => IndenterSettingsTests.GetMockIndenterSettings());
178+
var actual = indenter.Indent(code, string.Empty);
179+
Assert.IsTrue(expected.SequenceEqual(actual));
180+
}
181+
84182
[TestMethod]
85183
[TestCategory("Indenter")]
86184
public void SingleLineElseIfStatementWorks()

RubberduckTests/SmartIndenter/MultiSegmentLineTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public void UnmatchedEnumsNotIndent()
6868
Assert.IsTrue(code.SequenceEqual(actual));
6969
}
7070

71-
[TestMethod, Ignore] // Broken in VB6 SmartIndenter. Should be same fix as DoWhileOnTwoLinesWorks()
71+
[TestMethod] // Broken in VB6 SmartIndenter.
7272
[TestCategory("Indenter")]
7373
public void IfThenElseOnSameLineWorks()
7474
{

0 commit comments

Comments
 (0)