Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CodeConverter/CSharp/MethodBodyExecutableStatementVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,13 @@ public override async Task<SyntaxList<StatementSyntax>> VisitSelectBlock(VBSynta
if (isObjectComparison) {
caseSwitchLabelSyntax = WrapInCasePatternSwitchLabelSyntax(node, relational.Value, csRelationalValue, false, operatorKind);
}
else if (!isStringComparison && _semanticModel.GetConstantValue(relational.Value).HasValue) {
csRelationalValue = CommonConversions.TypeConversionAnalyzer.AddExplicitConversion(relational.Value, csRelationalValue);
var operatorToken = SyntaxFactory.Token(GetRelationalPatternTokenKind(operatorKind));
caseSwitchLabelSyntax = SyntaxFactory.CasePatternSwitchLabel(
SyntaxFactory.RelationalPattern(operatorToken, csRelationalValue),
SyntaxFactory.Token(SyntaxKind.ColonToken));
}
else {
var varName = CommonConversions.CsEscapedIdentifier(GetUniqueVariableNameInScope(node, "case"));
ExpressionSyntax csLeft = ValidSyntaxFactory.IdentifierName(varName);
Expand Down Expand Up @@ -1021,6 +1028,14 @@ private CasePatternSwitchLabelSyntax WrapInCasePatternSwitchLabelSyntax(VBSyntax
_ => throw new ArgumentOutOfRangeException(nameof(caseClauseKind), caseClauseKind, null)
};

private static CS.SyntaxKind GetRelationalPatternTokenKind(VBasic.SyntaxKind caseClauseKind) => caseClauseKind switch {
VBasic.SyntaxKind.CaseLessThanClause => CS.SyntaxKind.LessThanToken,
VBasic.SyntaxKind.CaseLessThanOrEqualClause => CS.SyntaxKind.LessThanEqualsToken,
VBasic.SyntaxKind.CaseGreaterThanOrEqualClause => CS.SyntaxKind.GreaterThanEqualsToken,
VBasic.SyntaxKind.CaseGreaterThanClause => CS.SyntaxKind.GreaterThanToken,
_ => throw new ArgumentOutOfRangeException(nameof(caseClauseKind), caseClauseKind, null)
};

private ExpressionSyntax ComparisonAdjustedForStringComparison(VBSyntax.SelectBlockSyntax node, VBSyntax.ExpressionSyntax vbCase, TypeInfo lhsTypeInfo, ExpressionSyntax csLeft, ExpressionSyntax csRight, TypeInfo rhsTypeInfo, ComparisonKind comparisonKind)
{
var vbEquality = CommonConversions.VisualBasicEqualityComparison;
Expand Down
15 changes: 15 additions & 0 deletions CodeConverter/VB/NodesVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1643,6 +1643,12 @@ public override VisualBasicSyntaxNode VisitThrowExpression(CSSyntax.ThrowExpress

public override VisualBasicSyntaxNode VisitCasePatternSwitchLabel(CSSyntax.CasePatternSwitchLabelSyntax node)
{
if (node.Pattern is CSSyntax.RelationalPatternSyntax relational) {
var value = (ExpressionSyntax)relational.Expression.Accept(TriviaConvertingVisitor);
var (caseClauseKind, tokenKind) = GetRelationalCaseClauseKinds(CS.CSharpExtensions.Kind(relational.OperatorToken));
return SyntaxFactory.RelationalCaseClause(caseClauseKind,
SyntaxFactory.Token(tokenKind), value);
}
var condition = node.WhenClause.Condition.SkipIntoParens();
switch (condition) {
case CSSyntax.BinaryExpressionSyntax bes when node.Pattern.ToString().StartsWith("var", StringComparison.InvariantCulture): //VarPatternSyntax (not available in current library version)
Expand All @@ -1654,6 +1660,15 @@ public override VisualBasicSyntaxNode VisitCasePatternSwitchLabel(CSSyntax.CaseP
throw new NotSupportedException(condition.GetType() + " in switch case");
}
}

private static (SyntaxKind CaseClauseKind, SyntaxKind TokenKind) GetRelationalCaseClauseKinds(CS.SyntaxKind csTokenKind) => csTokenKind switch {
CS.SyntaxKind.LessThanToken => (SyntaxKind.CaseLessThanClause, SyntaxKind.LessThanToken),
CS.SyntaxKind.LessThanEqualsToken => (SyntaxKind.CaseLessThanOrEqualClause, SyntaxKind.LessThanEqualsToken),
CS.SyntaxKind.GreaterThanToken => (SyntaxKind.CaseGreaterThanClause, SyntaxKind.GreaterThanToken),
CS.SyntaxKind.GreaterThanEqualsToken => (SyntaxKind.CaseGreaterThanOrEqualClause, SyntaxKind.GreaterThanEqualsToken),
_ => throw new NotSupportedException($"Relational operator token {csTokenKind} not supported in VB case clause")
};

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation in C# -> VB direction with no test

private INamedTypeSymbol GetStructOrClassSymbol(CS.CSharpSyntaxNode node) {
return (INamedTypeSymbol)_semanticModel.GetDeclaredSymbol(node.Ancestors().First(x => x is CSSyntax.ClassDeclarationSyntax || x is CSSyntax.StructDeclarationSyntax));
}
Expand Down
55 changes: 46 additions & 9 deletions Tests/CSharp/StatementTests/MethodStatementTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1089,13 +1089,13 @@ public static string TimeAgo(int daysAgo)
{
case var @case when 0 <= @case && @case <= 3:
case 4:
case var case1 when case1 >= 5:
case var case2 when case2 < 6:
case var case3 when case3 <= 7:
case >= 5:
case < 6:
case <= 7:
{
return ""this week"";
}
case var case4 when case4 > 0:
case > 0:
{
return daysAgo / 7 + "" weeks ago"";
}
Expand Down Expand Up @@ -1249,15 +1249,15 @@ public void DoesNotThrow()
var rand = new Random();
switch (rand.Next(8))
{
case var @case when @case < 4:
case < 4:
{
break;
}
case 4:
{
break;
}
case var case1 when case1 > 4:
case > 4:
{
break;
}
Expand All @@ -1268,9 +1268,46 @@ public void DoesNotThrow()
}
}
}
}
1 target compilation errors:
CS0825: The contextual keyword 'var' may only appear within a local variable declaration or in script code");
}");
}

[Fact]
public async Task Issue803SelectCaseIsRelationalUsesC9PatternAsync()
{
await TestConversionVisualBasicToCSharpAsync(@"Public Class TestClass
Function Rollo(Breite As Integer) As Integer
Select Case Breite
Case Is < 1000
Return 12
Case Is < 1200
Return 15
Case Else
Return 28
End Select
End Function
End Class", @"
public partial class TestClass
{
public int Rollo(int Breite)
{
switch (Breite)
{
case < 1000:
{
return 12;
}
case < 1200:
{
return 15;
}

default:
{
return 28;
}
}
}
}");
}

[Fact]
Expand Down
Loading