Skip to content

Commit 1e6e40d

Browse files
committed
correct handling of statement separators and newlines in single line if statements
1 parent ef1b2c6 commit 1e6e40d

File tree

2 files changed

+127
-1
lines changed

2 files changed

+127
-1
lines changed

Rubberduck.Parsing/Grammar/VBAParser.g4

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,8 +416,9 @@ elseBlock :
416416
// 5.4.2.9 Single-line If Statement
417417
singleLineIfStmt : ifWithNonEmptyThen | ifWithEmptyThen;
418418
ifWithNonEmptyThen : IF whiteSpace? booleanExpression whiteSpace? THEN whiteSpace? listOrLabel (whiteSpace singleLineElseClause)?;
419-
ifWithEmptyThen : IF whiteSpace? booleanExpression whiteSpace? THEN endOfStatement? whiteSpace? singleLineElseClause;
419+
ifWithEmptyThen : IF whiteSpace? booleanExpression whiteSpace? THEN whiteSpace? emptyThenStatement? singleLineElseClause;
420420
singleLineElseClause : ELSE whiteSpace? listOrLabel?;
421+
421422
// lineNumberLabel should actually be "statement-label" according to MS VBAL but they only allow lineNumberLabels:
422423
// A <statement-label> that occurs as the first element of a <list-or-label> element has the effect
423424
// as if the <statement-label> was replaced with a <goto-statement> containing the same
@@ -427,7 +428,9 @@ listOrLabel :
427428
lineNumberLabel (whiteSpace? COLON whiteSpace? sameLineStatement?)*
428429
| (COLON whiteSpace?)? sameLineStatement (whiteSpace? COLON whiteSpace? sameLineStatement?)*
429430
;
431+
430432
sameLineStatement : mainBlockStmt;
433+
emptyThenStatement : (COLON whiteSpace?)+;
431434
booleanExpression : expression;
432435

433436
implementsStmt : IMPLEMENTS whiteSpace expression;

RubberduckTests/Grammar/VBAParserTests.cs

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,6 +2002,129 @@ If False Then MsgBox True Else
20022002
AssertTree(parseResult.Item1, parseResult.Item2, "//singleLineIfStmt");
20032003
}
20042004

2005+
[Category("Parser")]
2006+
[Test]
2007+
public void TestSingleLineIfSingleEmptyThenEmptyElse()
2008+
{
2009+
string code = @"
2010+
Sub Test()
2011+
If False Then:: Else:
2012+
End Sub";
2013+
var parseResult = Parse(code);
2014+
AssertTree(parseResult.Item1, parseResult.Item2, "//singleLineIfStmt");
2015+
}
2016+
2017+
public void TestSingleLineIfSingleMultipleEmptyThensEmptyElse()
2018+
{
2019+
string code = @"
2020+
Sub Test()
2021+
If False Then:: _
2022+
:Else:
2023+
End Sub";
2024+
var parseResult = Parse(code);
2025+
AssertTree(parseResult.Item1, parseResult.Item2, "//singleLineIfStmt");
2026+
}
2027+
2028+
public void TestSingleLineIfSingleMultipleEmptyThensElse()
2029+
{
2030+
string code = @"
2031+
Sub Test()
2032+
If False Then:: _
2033+
:Else Bar
2034+
End Sub";
2035+
var parseResult = Parse(code);
2036+
AssertTree(parseResult.Item1, parseResult.Item2, "//singleLineIfStmt");
2037+
}
2038+
2039+
[Category("Parser")]
2040+
[Test]
2041+
public void TestSingleLineIfSingleEmptyMultiLineThenEmptyElse()
2042+
{
2043+
string code = @"
2044+
Sub Test()
2045+
If False Then: _
2046+
: Else:
2047+
End Sub";
2048+
var parseResult = Parse(code);
2049+
AssertTree(parseResult.Item1, parseResult.Item2, "//singleLineIfStmt");
2050+
}
2051+
2052+
[Category("Parser")]
2053+
[Test]
2054+
public void TestSingleLineIfSingleEmptyThenEmptyMultiLineElse()
2055+
{
2056+
string code = @"
2057+
Sub Test()
2058+
If False Then Else _
2059+
:
2060+
End Sub";
2061+
var parseResult = Parse(code);
2062+
AssertTree(parseResult.Item1, parseResult.Item2, "//singleLineIfStmt");
2063+
}
2064+
2065+
[Category("Parser")]
2066+
[Test]
2067+
public void TestSingleLineIfSingleEmptyThenElse()
2068+
{
2069+
string code = @"
2070+
Sub Test()
2071+
If False Then Else _
2072+
: Bar
2073+
End Sub";
2074+
var parseResult = Parse(code);
2075+
AssertTree(parseResult.Item1, parseResult.Item2, "//singleLineIfStmt");
2076+
}
2077+
2078+
[Category("Parser")]
2079+
[Test]
2080+
public void TestSingleLineIfNestedEmptyThenEmptyElse()
2081+
{
2082+
string code = @"
2083+
Sub Test()
2084+
If True Then If False Then If True Then Else
2085+
End Sub";
2086+
var parseResult = Parse(code);
2087+
AssertTree(parseResult.Item1, parseResult.Item2, "//singleLineIfStmt");
2088+
}
2089+
2090+
[Category("Parser")]
2091+
[Test]
2092+
public void TestSingleLineIfNestedThenEmptyElse()
2093+
{
2094+
string code = @"
2095+
Sub Test()
2096+
If True Then If False Then If True Then Bar Else
2097+
End Sub";
2098+
var parseResult = Parse(code);
2099+
AssertTree(parseResult.Item1, parseResult.Item2, "//singleLineIfStmt");
2100+
}
2101+
2102+
[Category("Parser")]
2103+
[Test]
2104+
public void TestSingleLineIfNestedEmptyThenElse()
2105+
{
2106+
string code = @"
2107+
Sub Test()
2108+
If True Then If False Then If True Then Else Bar
2109+
End Sub";
2110+
var parseResult = Parse(code);
2111+
AssertTree(parseResult.Item1, parseResult.Item2, "//singleLineIfStmt");
2112+
}
2113+
2114+
[Category("Parser")]
2115+
[Test]
2116+
public void TestSingleLineIfSingleEmptyMultiLineThenEmptyMultiLineElse()
2117+
{
2118+
string code = @"
2119+
Sub Test()
2120+
If False Then: _
2121+
Else _
2122+
:
2123+
End Sub";
2124+
var parseResult = Parse(code);
2125+
AssertTree(parseResult.Item1, parseResult.Item2, "//singleLineIfStmt");
2126+
}
2127+
20052128
[Category("Parser")]
20062129
[Test]
20072130
public void TestSingleLineIfImplicitGoTo()

0 commit comments

Comments
 (0)