From f303e993dbfd8db76f2f64efae6213bc1f1af707 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 12 Apr 2026 23:38:03 +0000 Subject: [PATCH 1/3] Fix #1244: Avoid unnecessary code blocks in switch case sections Only wrap switch case statements in a Block when a local variable declaration is present. Otherwise emit statements directly, eliminating the extra level of braces and indentation. https://claude.ai/code/session_01AkwUvu3XuCdj3D4axoX4UX --- CodeConverter/CSharp/MethodBodyExecutableStatementVisitor.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CodeConverter/CSharp/MethodBodyExecutableStatementVisitor.cs b/CodeConverter/CSharp/MethodBodyExecutableStatementVisitor.cs index bc48a7dc..e2f30868 100644 --- a/CodeConverter/CSharp/MethodBodyExecutableStatementVisitor.cs +++ b/CodeConverter/CSharp/MethodBodyExecutableStatementVisitor.cs @@ -883,7 +883,10 @@ public override async Task> VisitSelectBlock(VBSynta if (!DefinitelyExits(csBlockStatements.LastOrDefault())) { csBlockStatements.Add(SyntaxFactory.BreakStatement()); } - var list = SingleStatement(SyntaxFactory.Block(csBlockStatements)); + var hasLocalDeclaration = csBlockStatements.Any(s => s.IsKind(SyntaxKind.LocalDeclarationStatement)); + var list = hasLocalDeclaration + ? SingleStatement(SyntaxFactory.Block(csBlockStatements)) + : SyntaxFactory.List(csBlockStatements); sections.Add(SyntaxFactory.SwitchSection(SyntaxFactory.List(labels), list)); } From 2fa30bffbf940e02ee361a72e7d7e511ff32bc21 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 12 Apr 2026 23:47:18 +0000 Subject: [PATCH 2/3] Update tests to reflect issue #1244 fix: remove unnecessary braces in switch cases Update all existing Select Case tests to reflect the new output format (no block braces when no local variable is declared). Add two new tests: one verifying no blocks are emitted for cases without local declarations, and one verifying blocks are still emitted when local variables are present. https://claude.ai/code/session_01AkwUvu3XuCdj3D4axoX4UX --- .../CSharp/ExpressionTests/ExpressionTests.cs | 282 +++++++----------- .../CSharp/MemberTests/PropertyMemberTests.cs | 14 +- .../ExpressionTests.cs | 48 +-- .../ExitableMethodExecutableStatementTests.cs | 44 +-- .../StatementTests/MethodStatementTests.cs | 187 ++++++------ Tests/CSharp/TypeCastTests.cs | 8 +- .../ConvertVbLibraryOnly/VbLibrary/AClass.cs | 8 +- .../Prefix.VbLibrary/AClass.cs | 8 +- .../ConvertWholeSolution/VbLibrary/AClass.cs | 8 +- 9 files changed, 252 insertions(+), 355 deletions(-) diff --git a/Tests/CSharp/ExpressionTests/ExpressionTests.cs b/Tests/CSharp/ExpressionTests/ExpressionTests.cs index 64727cbc..cdb9d2d0 100644 --- a/Tests/CSharp/ExpressionTests/ExpressionTests.cs +++ b/Tests/CSharp/ExpressionTests/ExpressionTests.cs @@ -421,17 +421,13 @@ public void Main() switch (e1) { case 0: - { - break; - } + break; } switch (e2) { case (int)E.A: - { - break; - } + break; } } @@ -464,16 +460,12 @@ public static void Main() switch (1) { case 1: - { - Console.WriteLine(""a""); - break; - } + Console.WriteLine(""a""); + break; case var @case when @case == 1: - { - Console.WriteLine(""b""); - break; - } + Console.WriteLine(""b""); + break; } @@ -2039,10 +2031,8 @@ public static void Main() switch (x) { case (int)E.A: - { - Console.WriteLine(""z""); - break; - } + Console.WriteLine(""z""); + break; } } }"); @@ -2088,26 +2078,18 @@ public void OnLoad(UserInterface? ui) switch (ui) { case object _ when ui is null: - { - activity = 1; - break; - } + activity = 1; + break; case UserInterface.Spectrum: - { - activity = 2; - break; - } + activity = 2; + break; case UserInterface.Wisdom: - { - activity = 3; - break; - } + activity = 3; + break; default: - { - activity = 4; - break; - } + activity = 4; + break; } } }"); @@ -2206,160 +2188,128 @@ public int OnLoad() switch (x) { case 0: - { - continue; - } + continue; case 1: + x = 1; + break; + case 2: + return 2; + case 3: + throw new Exception(); + case 4: + if (true) { - x = 1; - break; + x = 4; } - case 2: + else { - return 2; + return x; } - case 3: + + break; + case 5: + if (true) { - throw new Exception(); + return x; } - case 4: + else { - if (true) - { - x = 4; - } - else - { - return x; - } + x = 5; + } - break; + break; + case 6: + if (true) + { + return x; } - case 5: + else if (false) { - if (true) - { - return x; - } - else - { - x = 5; - } - - break; + x = 6; } - case 6: + else { - if (true) - { - return x; - } - else if (false) - { - x = 6; - } - else - { - return x; - } - - break; + return x; } + + break; case 7: + if (true) { - if (true) - { - return x; - } - - break; + return x; } + + break; case 8: + if (true) + return x; + break; + case 9: + if (true) + x = 9; + break; + case 10: + if (true) + return x; + else + x = 10; + break; + case 11: + if (true) + x = 11; + else + return x; + break; + case 12: + if (true) + return x; + else + return x; + case 13: + if (true) { - if (true) - return x; - break; + return x; } - case 9: + else if (false) { - if (true) - x = 9; - break; + continue; } - case 10: + else if (false) { - if (true) - return x; - else - x = 10; - break; + throw new Exception(); } - case 11: + else if (false) { - if (true) - x = 11; - else - return x; break; } - case 12: + else { - if (true) - return x; - else - return x; + return x; } - case 13: + case 14: + if (true) { - if (true) - { - return x; - } - else if (false) - { - continue; - } - else if (false) - { - throw new Exception(); - } - else if (false) - { - break; - } - else - { - return x; - } + return x; } - case 14: + else if (false) + { + return x; + } + else if (false) { - if (true) - { - return x; - } - else if (false) - { - return x; - } - else if (false) - { - break; - } - break; } + break; + default: + if (true) + { + return x; + } + else { - if (true) - { - return x; - } - else - { - return x; - } + return x; } } } @@ -2402,31 +2352,21 @@ public void S() switch (o) { case var @case when Operators.ConditionalCompareObjectEqual(@case, 1, false): - { - j = 1; - break; - } + j = 1; + break; case var case1 when Operators.ConditionalCompareObjectEqual(case1, 2, false): - { - j = 2; - break; - } + j = 2; + break; case var case2 when Operators.ConditionalCompareObjectLessEqual(3, case2, false) && Operators.ConditionalCompareObjectLessEqual(case2, 4, false): - { - j = 3; - break; - } + j = 3; + break; case var case3 when Operators.ConditionalCompareObjectGreater(case3, 4, false): - { - j = 4; - break; - } + j = 4; + break; default: - { - j = -1; - break; - } + j = -1; + break; } } } diff --git a/Tests/CSharp/MemberTests/PropertyMemberTests.cs b/Tests/CSharp/MemberTests/PropertyMemberTests.cs index 790859d7..b534794a 100644 --- a/Tests/CSharp/MemberTests/PropertyMemberTests.cs +++ b/Tests/CSharp/MemberTests/PropertyMemberTests.cs @@ -323,18 +323,12 @@ public void ReturnWhatever(MyEnum m) switch (m) { case (MyEnum)(-1): - { - return; - } + return; case MyEnum.First: - { - return; - } + return; case (MyEnum)3: - { - set_MyProp(4, enumerableThing.ToArray()[(int)m]); - return; - } + set_MyProp(4, enumerableThing.ToArray()[(int)m]); + return; } } }"); diff --git a/Tests/CSharp/MissingSemanticModelInfo/ExpressionTests.cs b/Tests/CSharp/MissingSemanticModelInfo/ExpressionTests.cs index 32b73591..c81956ee 100644 --- a/Tests/CSharp/MissingSemanticModelInfo/ExpressionTests.cs +++ b/Tests/CSharp/MissingSemanticModelInfo/ExpressionTests.cs @@ -232,22 +232,16 @@ public PositionEnum PositionEnumFromString(string pS, MissingType missing) { case ""NONE"": case ""0"": - { - tPos = 0; - break; - } + tPos = 0; + break; case ""LEFTTOP"": case ""1"": - { - tPos = (PositionEnum)1; - break; - } + tPos = (PositionEnum)1; + break; default: - { - Ratio = (float)Conversion.Val(pS); - break; - } + Ratio = (float)Conversion.Val(pS); + break; } return tPos; } @@ -257,21 +251,15 @@ public string PositionEnumStringFromConstant(PositionEnum pS) switch (pS) { case 0: - { - tS = ""NONE""; - break; - } + tS = ""NONE""; + break; case (PositionEnum)1: - { - tS = ""LEFTTOP""; - break; - } + tS = ""LEFTTOP""; + break; default: - { - tS = ((int)pS).ToString(); - break; - } + tS = ((int)pS).ToString(); + break; } return tS; } @@ -306,16 +294,12 @@ public void PositionEnumFromString(char c) switch (c) { case '.': - { - Console.WriteLine(1); - break; - } + Console.WriteLine(1); + break; case ',': - { - Console.WriteLine(2); - break; - } + Console.WriteLine(2); + break; } } }") ; diff --git a/Tests/CSharp/StatementTests/ExitableMethodExecutableStatementTests.cs b/Tests/CSharp/StatementTests/ExitableMethodExecutableStatementTests.cs index 7ff85d15..ab9be87d 100644 --- a/Tests/CSharp/StatementTests/ExitableMethodExecutableStatementTests.cs +++ b/Tests/CSharp/StatementTests/ExitableMethodExecutableStatementTests.cs @@ -357,9 +357,7 @@ public int Add(int x) switch (x) { case 1: - { - break; - } + break; } return 3; } @@ -406,10 +404,8 @@ public void Test() switch (CurVal) { case 6: - { - exitFor = true; - break; - } + exitFor = true; + break; } if (exitFor) @@ -465,15 +461,11 @@ public void Test() switch (CurVal) { case 6: - { - exitFor = true; - break; - } + exitFor = true; + break; case 7: - { - exitFor = true; - break; - } + exitFor = true; + break; } if (exitFor) @@ -631,9 +623,7 @@ public void Test() switch (CurVal) { case 6: - { - continue; - } + continue; } Console.WriteLine(); } @@ -697,10 +687,8 @@ public void Test() switch (CurVal) { case 6: - { - continueFor = breakFor = true; - break; - } + continueFor = breakFor = true; + break; } if (breakFor) @@ -722,15 +710,11 @@ public void Test() switch (CurVal) { case 7: - { - continueFor1 = breakFor1 = true; - break; - } + continueFor1 = breakFor1 = true; + break; case 8: - { - exitFor1 = exitFor = true; - break; - } + exitFor1 = exitFor = true; + break; } if (breakFor1) diff --git a/Tests/CSharp/StatementTests/MethodStatementTests.cs b/Tests/CSharp/StatementTests/MethodStatementTests.cs index bc20f218..468e227c 100644 --- a/Tests/CSharp/StatementTests/MethodStatementTests.cs +++ b/Tests/CSharp/StatementTests/MethodStatementTests.cs @@ -1046,21 +1046,15 @@ private void TestMethod(int number) case 0: case 1: case 2: - { - Console.Write(""number is 0, 1, 2""); - break; - } + Console.Write(""number is 0, 1, 2""); + break; case 5: - { - Console.Write(""section 5""); - break; - } + Console.Write(""section 5""); + break; default: - { - Console.Write(""default section""); - break; - } + Console.Write(""default section""); + break; } } }"); @@ -1092,18 +1086,12 @@ public static string TimeAgo(int daysAgo) case var case1 when case1 >= 5: case var case2 when case2 < 6: case var case3 when case3 <= 7: - { - return ""this week""; - } + return ""this week""; case var case4 when case4 > 0: - { - return daysAgo / 7 + "" weeks ago""; - } + return daysAgo / 7 + "" weeks ago""; default: - { - return ""in the future""; - } + return ""in the future""; } } } @@ -1137,22 +1125,14 @@ public static string TimeAgo(string x) { case var @case when @case == (Strings.UCase(""a"") ?? """"): case var case1 when case1 == (Strings.UCase(""b"") ?? """"): - { - return ""ab""; - } + return ""ab""; case var case2 when case2 == (Strings.UCase(""c"") ?? """"): - { - return ""c""; - } + return ""c""; case ""d"": - { - return ""d""; - } + return ""d""; default: - { - return ""e""; - } + return ""e""; } } } @@ -1195,26 +1175,18 @@ public bool CanDoWork(object Something) switch (true) { case object _ when DateTime.Today.DayOfWeek == DayOfWeek.Saturday | DateTime.Today.DayOfWeek == DayOfWeek.Sunday: - { - // we do not work on weekends - return false; - } + // we do not work on weekends + return false; case object _ when !IsSqlAlive(): - { - // Database unavailable - return false; - } + // Database unavailable + return false; case object _ when Something is int: - { - // Do something with the Integer - return true; - } + // Do something with the Integer + return true; default: - { - // Do something else - return false; - } + // Do something else + return false; } } @@ -1250,22 +1222,14 @@ public void DoesNotThrow() switch (rand.Next(8)) { case var @case when @case < 4: - { - break; - } + break; case 4: - { - break; - } + break; case var case1 when case1 > 4: - { - break; - } + break; default: - { - throw new Exception(); - } + throw new Exception(); } } } @@ -1299,18 +1263,12 @@ internal partial class Issue579SelectCaseWithCaseInsensitiveTextCompare switch (astr_Temp ?? """") { case var @case when CultureInfo.CurrentCulture.CompareInfo.Compare(@case, ""Test"", CompareOptions.IgnoreCase | CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth) == 0: - { - return true; - } + return true; case var case1 when CultureInfo.CurrentCulture.CompareInfo.Compare(case1, astr_Temp ?? """", CompareOptions.IgnoreCase | CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth) == 0: - { - return false; - } + return false; default: - { - return default; - } + return default; } } } @@ -1342,14 +1300,10 @@ internal partial class Issue707SelectCaseAsyncClass { case var @case when @case == """": case var case1 when case1 == """": - { - return false; - } + return false; default: - { - return true; - } + return true; } } } @@ -1477,13 +1431,9 @@ internal static string prtWhere(EWhere aWhere) switch (aWhere) { case EWhere.None: - { - return "" ""; - } + return "" ""; case EWhere.Bottom: - { - return ""_ ""; - } + return ""_ ""; } return default; @@ -1519,14 +1469,10 @@ private object Test3(DataRow CurRow) switch (CurCol.DataType) { case var @case when @case == typeof(string): - { - return false; - } + return false; default: - { - return true; - } + return true; } } @@ -1537,6 +1483,71 @@ private object Test3(DataRow CurRow) CS0825: The contextual keyword 'var' may only appear within a local variable declaration or in script code"); } + [Fact] + public async Task Issue1244_SelectCaseWithoutLocalDeclarationDoesNotWrapInBlockAsync() + { + await TestConversionVisualBasicToCSharpAsync(@"Class TestClass + Private Shared Function d1mach(i As Integer) As Double + Select Case i + Case 1 + Return 2.2250738585072014E-308 ' the smallest positive magnitude. + Case 2 + Return Double.MaxValue ' the largest magnitude. + End Select + Return 0 + End Function +End Class", @" +internal partial class TestClass +{ + private static double d1mach(int i) + { + switch (i) + { + case 1: + return 2.2250738585072014E-308d; // the smallest positive magnitude. + case 2: + return double.MaxValue; // the largest magnitude. + } + + return 0d; + } +}"); + } + + [Fact] + public async Task Issue1244_SelectCaseWithLocalDeclarationWrapsInBlockAsync() + { + await TestConversionVisualBasicToCSharpAsync(@"Class TestClass + Private Shared Function Describe(i As Integer) As String + Select Case i + Case 1 + Dim msg As String = ""one"" + Return msg + Case 2 + Return ""two"" + End Select + Return Nothing + End Function +End Class", @" +internal partial class TestClass +{ + private static string Describe(int i) + { + switch (i) + { + case 1: + { + string msg = ""one""; + return msg; + } + case 2: + return ""two""; + } + + return default; + } +}"); + } [Fact] public async Task ExitMethodBlockStatementsAsync() diff --git a/Tests/CSharp/TypeCastTests.cs b/Tests/CSharp/TypeCastTests.cs index 83c59f19..c8a04979 100644 --- a/Tests/CSharp/TypeCastTests.cs +++ b/Tests/CSharp/TypeCastTests.cs @@ -1381,14 +1381,10 @@ private void Q() switch (""a"") { case var @case when ""x"" <= @case && @case <= ""y"": - { - break; - } + break; case ""b"": - { - break; - } + break; } } } diff --git a/Tests/TestData/MultiFileCharacterization/VBToCSResults/ConvertVbLibraryOnly/VbLibrary/AClass.cs b/Tests/TestData/MultiFileCharacterization/VBToCSResults/ConvertVbLibraryOnly/VbLibrary/AClass.cs index abab8381..c613f97e 100644 --- a/Tests/TestData/MultiFileCharacterization/VBToCSResults/ConvertVbLibraryOnly/VbLibrary/AClass.cs +++ b/Tests/TestData/MultiFileCharacterization/VBToCSResults/ConvertVbLibraryOnly/VbLibrary/AClass.cs @@ -35,13 +35,9 @@ private void UseEnumFromOtherFileInSolution(AnEnum m) switch (m) { case (AnEnum)(-1): - { - return; - } + return; case AnEnum.AnEnumMember: - { - return; - } + return; } } } diff --git a/Tests/TestData/MultiFileCharacterization/VBToCSResults/ConvertWholeSolution/Prefix.VbLibrary/AClass.cs b/Tests/TestData/MultiFileCharacterization/VBToCSResults/ConvertWholeSolution/Prefix.VbLibrary/AClass.cs index dbc22d4d..6149bae2 100644 --- a/Tests/TestData/MultiFileCharacterization/VBToCSResults/ConvertWholeSolution/Prefix.VbLibrary/AClass.cs +++ b/Tests/TestData/MultiFileCharacterization/VBToCSResults/ConvertWholeSolution/Prefix.VbLibrary/AClass.cs @@ -35,13 +35,9 @@ private void UseEnumFromOtherFileInSolution(AnEnum m) switch (m) { case (AnEnum)(-1): - { - return; - } + return; case AnEnum.AnEnumMember: - { - return; - } + return; } } } diff --git a/Tests/TestData/MultiFileCharacterization/VBToCSResults/ConvertWholeSolution/VbLibrary/AClass.cs b/Tests/TestData/MultiFileCharacterization/VBToCSResults/ConvertWholeSolution/VbLibrary/AClass.cs index abab8381..c613f97e 100644 --- a/Tests/TestData/MultiFileCharacterization/VBToCSResults/ConvertWholeSolution/VbLibrary/AClass.cs +++ b/Tests/TestData/MultiFileCharacterization/VBToCSResults/ConvertWholeSolution/VbLibrary/AClass.cs @@ -35,13 +35,9 @@ private void UseEnumFromOtherFileInSolution(AnEnum m) switch (m) { case (AnEnum)(-1): - { - return; - } + return; case AnEnum.AnEnumMember: - { - return; - } + return; } } } From b8c8164195ca3b889d3dbc49ab6d56ae1660c5d4 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 14 Apr 2026 08:07:13 +0000 Subject: [PATCH 3/3] =?UTF-8?q?Fix=20Issue1244=20test:=20Return=20Nothing?= =?UTF-8?q?=20in=20String-returning=20function=20=E2=86=92=20return=20null?= =?UTF-8?q?,=20not=20return=20default?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit String is a reference type so Nothing converts to null (not default). Confirmed by ParameterTests.cs:35 which has the same pattern. https://claude.ai/code/session_01AkwUvu3XuCdj3D4axoX4UX --- Tests/CSharp/StatementTests/MethodStatementTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/CSharp/StatementTests/MethodStatementTests.cs b/Tests/CSharp/StatementTests/MethodStatementTests.cs index 468e227c..b1735c75 100644 --- a/Tests/CSharp/StatementTests/MethodStatementTests.cs +++ b/Tests/CSharp/StatementTests/MethodStatementTests.cs @@ -1544,7 +1544,7 @@ private static string Describe(int i) return ""two""; } - return default; + return null; } }"); }