Skip to content

Commit 2986360

Browse files
Only cast when switching on enum
1 parent 21b5849 commit 2986360

4 files changed

Lines changed: 59 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
1010

1111
### VB -> C#
1212
* Handle Option Compare Text case insensitive comparisons in switch statements [#579](https://github.com/icsharpcode/CodeConverter/issues/579)
13+
* Fix compilation error when switching with enum cases [#549](https://github.com/icsharpcode/CodeConverter/issues/549)
1314

1415
### C# -> VB
1516

CodeConverter/CSharp/MethodBodyExecutableStatementVisitor.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -660,18 +660,18 @@ public override async Task<SyntaxList<StatementSyntax>> VisitSelectBlock(VBSynta
660660
foreach (var c in block.CaseStatement.Cases) {
661661
if (c is VBSyntax.SimpleCaseClauseSyntax s) {
662662
var originalExpressionSyntax = (ExpressionSyntax)await s.Value.AcceptAsync(_expressionVisitor);
663-
// CSharp requires an explicit cast from the base type (e.g. int) in most cases switching on an enum
663+
var caseTypeInfo = _semanticModel.GetTypeInfo(s.Value);
664664
var typeConversionKind = CommonConversions.TypeConversionAnalyzer.AnalyzeConversion(s.Value);
665665
var correctTypeExpressionSyntax = CommonConversions.TypeConversionAnalyzer.AddExplicitConversion(s.Value, originalExpressionSyntax, typeConversionKind, true, true);
666666
var constantValue = _semanticModel.GetConstantValue(s.Value);
667-
var caseTypeInfo = _semanticModel.GetTypeInfo(s.Value);
668667
var notAlreadyUsed = !constantValue.HasValue || usedConstantValues.Add(constantValue.Value);
669668

670669
// Pass both halves in case we can optimize away the check based on the switch expr
671670
var wrapForStringComparison = isStringComparison && (caseInsensitiveStringComparison ||
672671
vbEquality.VbCoerceToNonNullString(vbExpr, csSwitchExpr, switchExprTypeInfo, true, s.Value, originalExpressionSyntax, caseTypeInfo, false).rhs != originalExpressionSyntax);
673672

674-
var csExpressionToUse = wrapForStringComparison ? originalExpressionSyntax : correctTypeExpressionSyntax.Expr;
673+
// CSharp requires an explicit cast from the base type (e.g. int) in most cases switching on an enum
674+
var csExpressionToUse = wrapForStringComparison || switchExprTypeInfo.ConvertedType?.IsEnumType() == false || caseTypeInfo.Type?.IsEnumType() == true ? originalExpressionSyntax : correctTypeExpressionSyntax.Expr;
675675

676676
var caseSwitchLabelSyntax = !wrapForStringComparison && correctTypeExpressionSyntax.IsConst && notAlreadyUsed
677677
? (SwitchLabelSyntax)SyntaxFactory.CaseSwitchLabel(csExpressionToUse)

Tests/CSharp/StatementTests/StatementTests.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1923,6 +1923,53 @@ private IEnumerable<int> TestMethod(int number)
19231923
yield return i;
19241924
yield break;
19251925
}
1926+
}");
1927+
}
1928+
1929+
[Fact]
1930+
public async Task SwitchIntToEnumAsync()
1931+
{
1932+
await TestConversionVisualBasicToCSharpAsync(@"Module Main
1933+
Public Enum EWhere As Short
1934+
None = 0
1935+
Bottom = 1
1936+
End Enum
1937+
1938+
Friend Function prtWhere(ByVal aWhere As EWhere) As String
1939+
Select Case aWhere
1940+
Case EWhere.None
1941+
Return "" ""
1942+
Case EWhere.Bottom
1943+
Return ""_ ""
1944+
End Select
1945+
1946+
End Function
1947+
End Module", @"
1948+
internal static partial class Main
1949+
{
1950+
public enum EWhere : short
1951+
{
1952+
None = 0,
1953+
Bottom = 1
1954+
}
1955+
1956+
internal static string prtWhere(EWhere aWhere)
1957+
{
1958+
switch (aWhere)
1959+
{
1960+
case EWhere.None:
1961+
{
1962+
return "" "";
1963+
}
1964+
1965+
case EWhere.Bottom:
1966+
{
1967+
return ""_ "";
1968+
}
1969+
}
1970+
1971+
return default;
1972+
}
19261973
}");
19271974
}
19281975
}

Tests/VB/StatementTests.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,7 +1389,9 @@ End Class
13891389
[Fact]
13901390
public async Task YieldAsync()
13911391
{
1392-
await TestConversionCSharpToVisualBasicAsync(@"class TestClass
1392+
await TestConversionCSharpToVisualBasicAsync(@"using System.Collections.Generic;
1393+
1394+
class TestClass
13931395
{
13941396
IEnumerable<int> TestMethod(int number)
13951397
{
@@ -1398,19 +1400,19 @@ IEnumerable<int> TestMethod(int number)
13981400
for (int i = 0; i < number; i++)
13991401
yield return i;
14001402
}
1401-
}", @"Friend Class TestClass
1403+
}", @"Imports System.Collections.Generic
1404+
1405+
Friend Class TestClass
14021406
Private Iterator Function TestMethod(ByVal number As Integer) As IEnumerable(Of Integer)
14031407
If number < 0 Then Return
14041408
14051409
For i As Integer = 0 To number - 1
14061410
Yield i
14071411
Next
14081412
End Function
1409-
End Class
1410-
1411-
1 source compilation errors:
1412-
CS0246: The type or namespace name 'IEnumerable<>' could not be found (are you missing a using directive or an assembly reference?)");
1413+
End Class");
14131414
}
1415+
14141416
[Fact]
14151417
public async Task ObjectCreationExpressionInInvocationExpressionAsync() {
14161418
await TestConversionCSharpToVisualBasicAsync(

0 commit comments

Comments
 (0)