Skip to content

Commit

Permalink
Dedupe multiple exit/continue variables
Browse files Browse the repository at this point in the history
  • Loading branch information
GrahamTheCoder committed Oct 1, 2022
1 parent 3f4d292 commit b76d7cd
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 18 deletions.
32 changes: 22 additions & 10 deletions CodeConverter/CSharp/PerScopeState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,8 @@ public IEnumerable<StatementSyntax> ConvertExit(VBasic.SyntaxKind vbBlockKeyword
var scopesToExit = _hoistedNodesPerScope.Where(x => x.ExitableKind != VBasic.SyntaxKind.None).TakeWhile(x => x.ExitableKind != vbBlockKeywordKind && x.IsBreakableInCs).ToArray();
var assignmentExpression = CommonConversions.Literal(true);
foreach (var scope in scopesToExit) {
var exitScopeVar = new AdditionalDeclaration("exit" + VBasic.SyntaxFactory.Token(vbBlockKeywordKind), CommonConversions.Literal(false), SyntaxFactory.ParseTypeName("bool"));
var ifTrueBreak = new PostIfTrueBlock(exitScopeVar.IdentifierName, SyntaxFactory.BreakStatement());
scope.HoistedNodes.Add(exitScopeVar);
scope.HoistedNodes.Add(ifTrueBreak);
string prefix = "exit";
var exitScopeVar = HoistConditionalBreakOrContinue(scope, prefix, vbBlockKeywordKind, SyntaxFactory.BreakStatement());
assignmentExpression = SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, exitScopeVar.IdentifierName, assignmentExpression);
}
if (scopesToExit.Any()) yield return SyntaxFactory.ExpressionStatement(assignmentExpression);
Expand All @@ -212,12 +210,11 @@ public IEnumerable<StatementSyntax> ConvertContinue(VBasic.SyntaxKind vbBlockKey
var assignmentExpression = CommonConversions.Literal(true);
int i = 0;
foreach (var scope in scopesToExit) {
var continueScopeVar = new AdditionalDeclaration("continue" + VBasic.SyntaxFactory.Token(vbBlockKeywordKind), CommonConversions.Literal(false), SyntaxFactory.ParseTypeName("bool"));
StatementSyntax stmt = i++ == scopesToExit.Length - 1 ? SyntaxFactory.ContinueStatement() : SyntaxFactory.BreakStatement();
var ifTrue = new PostIfTrueBlock(continueScopeVar.IdentifierName, stmt);
scope.HoistedNodes.Add(continueScopeVar);
scope.HoistedNodes.Add(ifTrue);
assignmentExpression = SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, continueScopeVar.IdentifierName, assignmentExpression);
bool isContinue = i++ == scopesToExit.Length - 1;
string prefix = isContinue ? "continue" : "break";
StatementSyntax stmt = isContinue ? SyntaxFactory.ContinueStatement() : SyntaxFactory.BreakStatement();
var scopeVar = HoistConditionalBreakOrContinue(scope, prefix, vbBlockKeywordKind, stmt);
assignmentExpression = SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, scopeVar.IdentifierName, assignmentExpression);
}

if (scopesToExit.Any()) {
Expand All @@ -227,4 +224,19 @@ public IEnumerable<StatementSyntax> ConvertContinue(VBasic.SyntaxKind vbBlockKey
yield return SyntaxFactory.ContinueStatement();
}
}

private static AdditionalDeclaration HoistConditionalBreakOrContinue(ScopeState scope, string prefix, Microsoft.CodeAnalysis.VisualBasic.SyntaxKind vbBlockKeywordKind, StatementSyntax stmt)
{
prefix += VBasic.SyntaxFactory.Token(vbBlockKeywordKind);
var scopeVar = scope.HoistedNodes.OfType<AdditionalDeclaration>().FirstOrDefault(n => n.Prefix == prefix);
if (scopeVar is null) {
scopeVar = new AdditionalDeclaration(prefix, CommonConversions.Literal(false), SyntaxFactory.ParseTypeName("bool"));
var ifTrue = new PostIfTrueBlock(scopeVar.IdentifierName, stmt);
scope.HoistedNodes.Add(scopeVar);
scope.HoistedNodes.Add(ifTrue);
return scopeVar;
}

return scopeVar;
}
}
116 changes: 108 additions & 8 deletions Tests/CSharp/StatementTests/ExitableMethodExecutableStatementTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,8 @@ For Each CurVal As Integer In LstTmp
Select Case CurVal
Case 6
Exit For
Case 7
Exit For
End Select
Console.WriteLine()
Next
Expand Down Expand Up @@ -467,6 +469,11 @@ public void Test()
exitFor = true;
break;
}
case 7:
{
exitFor = true;
break;
}
}
if (exitFor)
Expand All @@ -490,10 +497,22 @@ For Each appRole In applicationRoles
Dim objectUnit = appRole
While objectUnit IsNot Nothing
If appRole < 10 Then
If appRole < 5 Then
If appRole < 3 Then
Return True
Else If appRole < 4 Then
Continue While ' Continue While
Else If appRole < 5 Then
Exit For ' Exit For
Else If appRole < 6 Then
Continue For ' Continue For
Else If appRole < 7 Then
Exit For ' Exit For
Else If appRole < 8 Then
Exit While ' Exit While
Else If appRole < 9 Then
Continue While ' Continue While
Else
Continue For
Continue For ' Continue For
End If
End IF
objectUnit = objectUnit.ToString
Expand All @@ -511,19 +530,47 @@ public object Test(object applicationRoles)
{
var objectUnit = appRole;
bool continueFor = false;
bool exitFor = false;
while (objectUnit is not null)
{
if (Conversions.ToBoolean(Operators.ConditionalCompareObjectLess(appRole, 10, false)))
{
if (Conversions.ToBoolean(Operators.ConditionalCompareObjectLess(appRole, 5, false)))
if (Conversions.ToBoolean(Operators.ConditionalCompareObjectLess(appRole, 3, false)))
{
return true;
}
else if (Conversions.ToBoolean(Operators.ConditionalCompareObjectLess(appRole, 4, false)))
{
continue; // Continue While
}
else if (Conversions.ToBoolean(Operators.ConditionalCompareObjectLess(appRole, 5, false)))
{
exitFor = true;
break; // Exit For
}
else if (Conversions.ToBoolean(Operators.ConditionalCompareObjectLess(appRole, 6, false)))
{
continueFor = true;
break; // Continue For
}
else if (Conversions.ToBoolean(Operators.ConditionalCompareObjectLess(appRole, 7, false)))
{
exitFor = true;
break; // Exit For
}
else if (Conversions.ToBoolean(Operators.ConditionalCompareObjectLess(appRole, 8, false)))
{
break; // Exit While
}
else if (Conversions.ToBoolean(Operators.ConditionalCompareObjectLess(appRole, 9, false)))
{
continue; // Continue While
}
else
{
continueFor = true;
break;
}
} // Continue For
}
objectUnit = objectUnit.ToString();
}
Expand All @@ -532,6 +579,11 @@ public object Test(object applicationRoles)
{
continue;
}
if (exitFor)
{
break;
}
}
return default;
Expand Down Expand Up @@ -611,6 +663,14 @@ Case 6
Continue For
End Select
End While
While CurVal < 4
Select Case CurVal
Case 7
Continue For
Case 8
Exit For
End Select
End While
Console.WriteLine()
Next
System.Console.WriteLine(i_Total.ToString())
Expand All @@ -630,20 +690,55 @@ public void Test()
foreach (int CurVal in LstTmp)
{
i_Total += CurVal;
bool continueFor1 = false;
bool continueFor = false;
while (CurVal < 3)
{
bool continueFor = false;
bool breakFor = false;
switch (CurVal)
{
case 6:
{
continueFor1 = continueFor = true;
continueFor = breakFor = true;
break;
}
}
if (breakFor)
{
break;
}
}
if (continueFor)
{
continue;
}
bool continueFor1 = false;
bool exitFor1 = false;
while (CurVal < 4)
{
bool breakFor1 = false;
bool exitFor = false;
switch (CurVal)
{
case 7:
{
continueFor1 = breakFor1 = true;
break;
}
case 8:
{
exitFor1 = exitFor = true;
break;
}
}
if (breakFor1)
{
break;
}
if (continueFor)
if (exitFor)
{
break;
}
Expand All @@ -653,6 +748,11 @@ public void Test()
{
continue;
}
if (exitFor1)
{
break;
}
Console.WriteLine();
}
Console.WriteLine(i_Total.ToString());
Expand Down

0 comments on commit b76d7cd

Please sign in to comment.