Skip to content

Commit 21472c4

Browse files
Fix Issue #803: Use relational patterns in switch statements
- Modifies `MethodBodyExecutableStatementVisitor` to generate `RelationalPatternSyntax` instead of `VarPattern` with a `when` clause for VB `RelationalCaseClauseSyntax`. - Adds helper `GetRelationalTokenKind` to map VB syntax kinds to the appropriate C# relational operators. - Added corresponding unit test demonstrating the new output. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
1 parent c289dcd commit 21472c4

2 files changed

Lines changed: 85 additions & 4 deletions

File tree

CodeConverter/CSharp/MethodBodyExecutableStatementVisitor.cs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -844,11 +844,16 @@ public override async Task<SyntaxList<StatementSyntax>> VisitSelectBlock(VBSynta
844844
caseSwitchLabelSyntax = WrapInCasePatternSwitchLabelSyntax(node, relational.Value, csRelationalValue, false, operatorKind);
845845
}
846846
else {
847-
var varName = CommonConversions.CsEscapedIdentifier(GetUniqueVariableNameInScope(node, "case"));
848-
ExpressionSyntax csLeft = ValidSyntaxFactory.IdentifierName(varName);
849847
csRelationalValue = CommonConversions.TypeConversionAnalyzer.AddExplicitConversion(relational.Value, csRelationalValue);
850-
var binaryExp = SyntaxFactory.BinaryExpression(operatorKind.ConvertToken(), csLeft, csRelationalValue);
851-
caseSwitchLabelSyntax = VarWhen(varName, binaryExp);
848+
PatternSyntax pattern;
849+
if (operatorKind == VBasic.SyntaxKind.CaseEqualsClause) {
850+
pattern = SyntaxFactory.ConstantPattern(csRelationalValue);
851+
} else if (operatorKind == VBasic.SyntaxKind.CaseNotEqualsClause) {
852+
pattern = SyntaxFactory.UnaryPattern(SyntaxFactory.Token(SyntaxKind.NotKeyword), SyntaxFactory.ConstantPattern(csRelationalValue));
853+
} else {
854+
pattern = SyntaxFactory.RelationalPattern(SyntaxFactory.Token(GetRelationalTokenKind(operatorKind)), csRelationalValue);
855+
}
856+
caseSwitchLabelSyntax = SyntaxFactory.CasePatternSwitchLabel(pattern, null, SyntaxFactory.Token(SyntaxKind.ColonToken));
852857
}
853858
labels.Add(caseSwitchLabelSyntax);
854859
} else if (c is VBSyntax.RangeCaseClauseSyntax range) {
@@ -1201,4 +1206,12 @@ private static SyntaxList<StatementSyntax> SingleStatement(ExpressionSyntax expr
12011206
{
12021207
return SyntaxFactory.SingletonList<StatementSyntax>(SyntaxFactory.ExpressionStatement(expression));
12031208
}
1209+
1210+
private static SyntaxKind GetRelationalTokenKind(VBasic.SyntaxKind caseClauseKind) => caseClauseKind switch {
1211+
VBasic.SyntaxKind.CaseLessThanClause => SyntaxKind.LessThanToken,
1212+
VBasic.SyntaxKind.CaseLessThanOrEqualClause => SyntaxKind.LessThanEqualsToken,
1213+
VBasic.SyntaxKind.CaseGreaterThanOrEqualClause => SyntaxKind.GreaterThanEqualsToken,
1214+
VBasic.SyntaxKind.CaseGreaterThanClause => SyntaxKind.GreaterThanToken,
1215+
_ => throw new ArgumentOutOfRangeException(nameof(caseClauseKind), caseClauseKind, null)
1216+
};
12041217
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using System.Threading.Tasks;
2+
using ICSharpCode.CodeConverter.Tests.TestRunners;
3+
using Xunit;
4+
5+
namespace ICSharpCode.CodeConverter.Tests.CSharp.StatementTests;
6+
7+
public class MethodStatementTests_803 : ConverterTestBase
8+
{
9+
[Fact]
10+
public async Task Issue803_SelectCaseWithRelationalPatternAsync()
11+
{
12+
await TestConversionVisualBasicToCSharpAsync(@"Class TestClass
13+
Private Sub TestMethod(ByVal Breite As Integer)
14+
Dim Rollo_FederUmdrehungen_Berechnen As Integer
15+
Select Case Breite
16+
Case Is < 1000
17+
Rollo_FederUmdrehungen_Berechnen = 12
18+
Case Is < 1200
19+
Rollo_FederUmdrehungen_Berechnen = 15
20+
Case Is < 1600
21+
Rollo_FederUmdrehungen_Berechnen = 19
22+
Case Is < 1800
23+
Rollo_FederUmdrehungen_Berechnen = 25
24+
Case Else
25+
Rollo_FederUmdrehungen_Berechnen = 28
26+
End Select
27+
End Sub
28+
End Class", @"internal partial class TestClass
29+
{
30+
private void TestMethod(int Breite)
31+
{
32+
int Rollo_FederUmdrehungen_Berechnen;
33+
switch (Breite)
34+
{
35+
case < 1000:
36+
{
37+
Rollo_FederUmdrehungen_Berechnen = 12;
38+
break;
39+
}
40+
41+
case < 1200:
42+
{
43+
Rollo_FederUmdrehungen_Berechnen = 15;
44+
break;
45+
}
46+
47+
case < 1600:
48+
{
49+
Rollo_FederUmdrehungen_Berechnen = 19;
50+
break;
51+
}
52+
53+
case < 1800:
54+
{
55+
Rollo_FederUmdrehungen_Berechnen = 25;
56+
break;
57+
}
58+
59+
default:
60+
{
61+
Rollo_FederUmdrehungen_Berechnen = 28;
62+
break;
63+
}
64+
}
65+
}
66+
}");
67+
}
68+
}

0 commit comments

Comments
 (0)