Skip to content

Commit cb93f89

Browse files
Use existing method to invert condition - fixes #226
I believe this will generally yield more readable code than parenthesizing the whole expression
1 parent 2c056d7 commit cb93f89

4 files changed

Lines changed: 35 additions & 20 deletions

File tree

ICSharpCode.CodeConverter/CSharp/MethodBodyVisitor.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ public override SyntaxList<StatementSyntax> VisitDoLoopBlock(VBSyntax.DoLoopBloc
635635
statements
636636
));
637637
return SingleStatement(SyntaxFactory.WhileStatement(
638-
SyntaxFactory.PrefixUnaryExpression(SyntaxKind.LogicalNotExpression, (ExpressionSyntax)stmt.Condition.Accept(_nodesVisitor)),
638+
((ExpressionSyntax)stmt.Condition.Accept(_nodesVisitor)).InvertCondition(),
639639
statements
640640
));
641641
}
@@ -652,7 +652,7 @@ public override SyntaxList<StatementSyntax> VisitDoLoopBlock(VBSyntax.DoLoopBloc
652652
}
653653

654654
if (isUntilStmt) {
655-
conditionExpression = SyntaxFactory.PrefixUnaryExpression(SyntaxKind.LogicalNotExpression, conditionExpression);
655+
conditionExpression = conditionExpression.InvertCondition();
656656
}
657657

658658
return SingleStatement(SyntaxFactory.DoStatement(statements, conditionExpression));

ICSharpCode.CodeConverter/CSharp/NodesVisitor.cs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1337,11 +1337,7 @@ public override CSharpSyntaxNode VisitTypeOfExpression(VBSyntax.TypeOfExpression
13371337
(ExpressionSyntax)node.Expression.Accept(TriviaConvertingVisitor),
13381338
(TypeSyntax)node.Type.Accept(TriviaConvertingVisitor)
13391339
);
1340-
if (node.IsKind(VBasic.SyntaxKind.TypeOfIsNotExpression))
1341-
return SyntaxFactory.PrefixUnaryExpression(
1342-
SyntaxKind.LogicalNotExpression,
1343-
SyntaxFactory.ParenthesizedExpression(expr));
1344-
return expr;
1340+
return node.IsKind(VBasic.SyntaxKind.TypeOfIsNotExpression) ? expr.InvertCondition() : expr;
13451341
}
13461342

13471343
public override CSharpSyntaxNode VisitUnaryExpression(VBSyntax.UnaryExpressionSyntax node)
@@ -1350,18 +1346,13 @@ public override CSharpSyntaxNode VisitUnaryExpression(VBSyntax.UnaryExpressionSy
13501346
if (node.IsKind(VBasic.SyntaxKind.AddressOfExpression))
13511347
return expr;
13521348
var kind = VBasic.VisualBasicExtensions.Kind(node).ConvertToken(TokenContext.Local);
1349+
SyntaxKind csTokenKind = CSharpUtil.GetExpressionOperatorTokenKind(kind);
13531350
return SyntaxFactory.PrefixUnaryExpression(
13541351
kind,
1355-
SyntaxFactory.Token(CSharpUtil.GetExpressionOperatorTokenKind(kind)),
1356-
MaybeParenthesize(expr, kind)
1352+
SyntaxFactory.Token(csTokenKind),
1353+
expr.AddParensIfRequired()
13571354
);
13581355
}
1359-
private ExpressionSyntax MaybeParenthesize(ExpressionSyntax expr, SyntaxKind operatorKind)
1360-
{
1361-
return expr is BinaryExpressionSyntax && operatorKind == SyntaxKind.LogicalNotExpression
1362-
? SyntaxFactory.ParenthesizedExpression(expr)
1363-
: expr;
1364-
}
13651356

13661357
public override CSharpSyntaxNode VisitBinaryExpression(VBSyntax.BinaryExpressionSyntax node)
13671358
{

ICSharpCode.CodeConverter/Util/CSharpUtil.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ static class CSharpUtil
1313
/// Inverts a boolean condition. Note: The condition object can be frozen (from AST) it's cloned internally.
1414
/// </summary>
1515
/// <param name="condition">The condition to invert.</param>
16-
public static ExpressionSyntax InvertCondition(ExpressionSyntax condition)
16+
public static ExpressionSyntax InvertCondition(this ExpressionSyntax condition)
1717
{
1818
return InvertConditionInternal(condition);
1919
}
@@ -51,8 +51,7 @@ static ExpressionSyntax InvertConditionInternal(ExpressionSyntax condition)
5151
return SyntaxFactory.PrefixUnaryExpression(SyntaxKind.LogicalNotExpression, SyntaxFactory.ParenthesizedExpression(condition));
5252
}
5353

54-
if (condition is ConditionalExpressionSyntax) {
55-
var cEx = condition as ConditionalExpressionSyntax;
54+
if (condition is ConditionalExpressionSyntax cEx) {
5655
return cEx.WithCondition(InvertCondition(cEx.Condition));
5756
}
5857

@@ -63,7 +62,7 @@ static ExpressionSyntax InvertConditionInternal(ExpressionSyntax condition)
6362
return SyntaxFactory.LiteralExpression(SyntaxKind.TrueLiteralExpression);
6463
}
6564

66-
return SyntaxFactory.PrefixUnaryExpression(SyntaxKind.LogicalNotExpression, AddParensIfRequired(condition, false));
65+
return SyntaxFactory.PrefixUnaryExpression(SyntaxKind.LogicalNotExpression, condition.AddParensIfRequired());
6766
}
6867

6968
public static SyntaxKind GetExpressionOperatorTokenKind(SyntaxKind op)
@@ -133,7 +132,7 @@ public static SyntaxKind GetExpressionOperatorTokenKind(SyntaxKind op)
133132
/// When negating an expression this is required, otherwise you would end up with
134133
/// a or b -> !a or b
135134
/// </summary>
136-
public static ExpressionSyntax AddParensIfRequired(ExpressionSyntax expression, bool parenthesesRequiredForUnaryExpressions = true)
135+
public static ExpressionSyntax AddParensIfRequired(this ExpressionSyntax expression, bool parenthesesRequiredForUnaryExpressions = false)
137136
{
138137
if ((expression is BinaryExpressionSyntax) ||
139138
(expression is AssignmentExpressionSyntax) ||

Tests/CSharp/StatementTests.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,31 @@ private void TestMethod()
760760
}");
761761
}
762762

763+
[Fact]
764+
public void UntilStatement()
765+
{
766+
//Bug: comment on statement in do loop gets moved to end of conditional
767+
TestConversionVisualBasicToCSharpWithoutComments(@"Class TestClass
768+
Private Sub TestMethod()
769+
Dim charIndex As Integer
770+
' allow only digits and letters
771+
Do
772+
charIndex = rand.Next(48, 123)
773+
Loop Until (charIndex >= 48 AndAlso charIndex <= 57) OrElse (charIndex >= 65 AndAlso charIndex <= 90) OrElse (charIndex >= 97 AndAlso charIndex <= 122)
774+
End Sub
775+
End Class", @"class TestClass
776+
{
777+
private void TestMethod()
778+
{
779+
int charIndex;
780+
// allow only digits and letters
781+
do
782+
charIndex = rand.Next(48, 123);
783+
while ((charIndex < 48 || charIndex > 57) && (charIndex < 65 || charIndex > 90) && (charIndex < 97 || charIndex > 122));
784+
}
785+
}");
786+
}
787+
763788
[Fact]
764789
public void SimpleDoStatement()
765790
{

0 commit comments

Comments
 (0)