File: ConvertIfToSwitch\ConvertIfToSwitchTests.cs
Web Access
Project: src\src\Features\CSharpTest\Microsoft.CodeAnalysis.CSharp.Features.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Features.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.ConvertIfToSwitch;
using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Testing;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeActions.ConvertIfToSwitch;
 
using VerifyCS = CSharpCodeRefactoringVerifier<CSharpConvertIfToSwitchCodeRefactoringProvider>;
 
[UseExportProvider]
[Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
public sealed class ConvertIfToSwitchTests
{
    [Fact]
    public async Task TestUnreachableEndPoint()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (i == 1 || i == 2 || i == 3)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 1:
                        case 2:
                        case 3:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestReachableEndPoint()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (i == 1 || i == 2 || i == 3)
                        M(i);
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 1:
                        case 2:
                        case 3:
                            M(i);
                            break;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestMissingOnSubsequentBlock()
    {
        var code = """
            class C
            {
                int M(int i)
                {
                    $$if (i == 3) return 0;
                    { if (i == 6) return 1; }
                    return 2;
                }
            }
            """;
 
        await VerifyCS.VerifyRefactoringAsync(code, code);
    }
 
    [Fact]
    public async Task TestElseBlock_01()
    {
        var source =
            """
            class C
            {
                int {|#0:M|}(int i)
                {
                    $$if (i == 3) return 0;
                    else { if (i == 6) return 1; }
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                int {|#0:M|}(int i)
                {
                    switch (i)
                    {
                        case 3:
                            return 0;
                        case 6:
                            return 1;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestState =
            {
                Sources = { source },
                ExpectedDiagnostics =
                {
                    // /0/Test0.cs(3,9): error CS0161: 'C.M(int)': not all code paths return a value
                    DiagnosticResult.CompilerError("CS0161").WithLocation(0).WithArguments("C.M(int)"),
                },
            },
            FixedState =
            {
                Sources = { fixedSource },
                ExpectedDiagnostics =
                {
                    // /0/Test0.cs(3,9): error CS0161: 'C.M(int)': not all code paths return a value
                    DiagnosticResult.CompilerError("CS0161").WithLocation(0).WithArguments("C.M(int)"),
                },
            },
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestElseBlock_02()
    {
        var source =
            """
            class C
            {
                int M(int i)
                {
                    $$if (i == 3)
                    {
                        return 0;
                    }
                    else
                    {
                        if (i == 6) return 1;
                        if (i == 7) return 1;
                        return 0;
                    }
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                int M(int i)
                {
                    switch (i)
                    {
                        case 3:
                            return 0;
                        case 6:
                            return 1;
                        case 7:
                            return 1;
                        default:
                            return 0;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestMultipleCases_01()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (i == 1 || 2 == i || i == 3) M(0);
                    else if (i == 4 || 5 == i || i == 6) M(1);
                    else M(2);
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 1:
                        case 2:
                        case 3:
                            M(0);
                            break;
                        case 4:
                        case 5:
                        case 6:
                            M(1);
                            break;
                        default:
                            M(2);
                            break;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestMultipleCases_02_CSharp8()
    {
        var source =
            """
            class C
            {
                void M(object o)
                {
                    $$if (o is string s && s.Length > 0) M(0);
                    else if (o is int i && i > 0) M(1);
                    else return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(object o)
                {
                    switch (o)
                    {
                        case string s when s.Length > 0:
                            M(0);
                            break;
                        case int i when i > 0:
                            M(1);
                            break;
                        default:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            LanguageVersion = LanguageVersion.CSharp8,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestMultipleCases_02_CSharp9()
    {
        var source =
            """
            class C
            {
                void M(object o)
                {
                    $$if (o is string s && s.Length > 0) M(0);
                    else if (o is int i && i > 0) M(1);
                    else return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(object o)
                {
                    switch (o)
                    {
                        case string s when s.Length > 0:
                            M(0);
                            break;
                        case int i when i > 0:
                            M(1);
                            break;
                        default:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            LanguageVersion = LanguageVersion.CSharp9,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestExpressionOrder()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (1 == i || i == 2 || 3 == i)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 1:
                        case 2:
                        case 3:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConstantExpression()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    const int A = 1, B = 2, C = 3;
                    $$if (A == i || B == i || C == i)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    const int A = 1, B = 2, C = 3;
                    switch (i)
                    {
                        case A:
                        case B:
                        case C:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestMissingOnNonConstantExpression()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    int A = 1, B = 2, C = 3;
                    $$if (A == i || B == i || C == i)
                        return;
                }
            }
            """;
 
        await VerifyCS.VerifyRefactoringAsync(source, source);
    }
 
    [Fact]
    public async Task TestMissingOnDifferentOperands()
    {
        var source =
            """
            class C
            {
                void M(int i, int j)
                {
                    $$if (i == 5 || 6 == j) {}
                }
            }
            """;
 
        await VerifyCS.VerifyRefactoringAsync(source, source);
    }
 
    [Fact]
    public async Task TestMissingOnSingleCase()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (i == 5) {}
                }
            }
            """;
 
        await VerifyCS.VerifyRefactoringAsync(source, source);
    }
 
    [Theory, CombinatorialData]
    public async Task TestIsExpression(
        [CombinatorialValues(LanguageVersion.CSharp8, LanguageVersion.CSharp9)] LanguageVersion languageVersion)
    {
        var source =
            """
            class C
            {
                void M(object o)
                {
                    $$if (o is int || o is string || o is C)
                        return;
                }
            }
            """;
        var fixedSource = languageVersion switch
        {
            LanguageVersion.CSharp8 =>
            """
            class C
            {
                void M(object o)
                {
                    switch (o)
                    {
                        case int _:
                        case string _:
                        case C _:
                            return;
                    }
                }
            }
            """,
            LanguageVersion.CSharp9 =>
            """
            class C
            {
                void M(object o)
                {
                    switch (o)
                    {
                        case int:
                        case string:
                        case C:
                            return;
                    }
                }
            }
            """,
            _ => throw ExceptionUtilities.Unreachable(),
        };
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            LanguageVersion = languageVersion,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestIsPatternExpression_01()
    {
        await VerifyCS.VerifyRefactoringAsync(
            """
            class C
            {
                void M(object o)
                {
                    $$if (o is int i)
                            return;
                        else if (o is string s)
                            return;
                }
            }
            """,
            """
            class C
            {
                void M(object o)
                {
                    switch (o)
                    {
                        case int i:
                            return;
                        case string s:
                            return;
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestIsPatternExpression_02_CSharp8()
    {
        var source =
            """
            class C
            {
                void M(object o)
                {
                    $$if (o is string s && s.Length == 5)
                            return;
                        else if (o is int i)
                            return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(object o)
                {
                    switch (o)
                    {
                        case string s when s.Length == 5:
                            return;
                        case int i:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            LanguageVersion = LanguageVersion.CSharp8,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestIsPatternExpression_02_CSharp9()
    {
        var source =
            """
            class C
            {
                void M(object o)
                {
                    $$if (o is string s && s.Length == 5)
                            return;
                        else if (o is int i)
                            return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(object o)
                {
                    switch (o)
                    {
                        case string s when s.Length == 5:
                            return;
                        case int i:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            LanguageVersion = LanguageVersion.CSharp8,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestIsPatternExpression_03()
    {
        await VerifyCS.VerifyRefactoringAsync(
            """
            class C
            {
                void M(object o)
                {
                    $$if (o is string s && (s.Length > 5 && s.Length < 10))
                            return;
                        else if (o is int i)
                            return;
                }
            }
            """,
            """
            class C
            {
                void M(object o)
                {
                    switch (o)
                    {
                        case string s when s.Length > 5 && s.Length < 10:
                            return;
                        case int i:
                            return;
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestIsPatternExpression_04()
    {
        await VerifyCS.VerifyRefactoringAsync(
            """
            class C
            {
                void M(object o)
                {
                    $$if (o is string s && s.Length > 5 && s.Length < 10)
                            return;
                        else if (o is int i)
                            return;
                }
            }
            """,
            """
            class C
            {
                void M(object o)
                {
                    switch (o)
                    {
                        case string s when s.Length > 5 && s.Length < 10:
                            return;
                        case int i:
                            return;
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestComplexExpression_01()
    {
        await VerifyCS.VerifyRefactoringAsync(
            """
            class C
            {
                void M(object o)
                {
                    $$if (o is string s && s.Length > 5 &&
                                             s.Length < 10)
                        {
                            M(o:   0);
 
                        }
                        else if (o is int i)
                        {
                            M(o:   0);
                        }
                }
            }
            """,
            """
            class C
            {
                void M(object o)
                {
                    switch (o)
                    {
                        case string s when s.Length > 5 && s.Length < 10:
                            M(o: 0);
 
                            break;
                        case int i:
                            M(o: 0);
                            break;
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestMissingIfCaretDoesntIntersectWithTheIfKeyword()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    if $$(i == 3) {}
                }
            }
            """;
 
        await VerifyCS.VerifyRefactoringAsync(source, source);
    }
 
    [Fact]
    public async Task TestKeepBlockIfThereIsVariableDeclaration()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (i == 3)
                    {
                        var x = i;
                    }
                    else if (i == 4)
                    {
                    }
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 3:
                            {
                                var x = i;
                                break;
                            }
 
                        case 4:
                            break;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestMissingOnBreak_01()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    while (true)
                    {
                        $$if (i == 5) break;
                    }
                }
            }
            """;
 
        await VerifyCS.VerifyRefactoringAsync(source, source);
    }
 
    [Fact]
    public async Task TestMissingOnBreak_02()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    while (true)
                    {
                        $$if (i == 5) M({|#0:b|}, i);
                        else break;
                    }
                }
            }
            """;
 
        await VerifyCS.VerifyRefactoringAsync(
            source,
            // /0/Test0.cs(7,27): error CS0103: The name 'b' does not exist in the current context
            DiagnosticResult.CompilerError("CS0103").WithLocation(0).WithArguments("b"),
            source);
    }
 
    [Fact]
    public async Task TestNestedBreak()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (i == 1)
                    {
                        while (true)
                        {
                            break;
                        }
                    }
                    else if (i == 2)
                    {
                    }
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 1:
                            while (true)
                            {
                                break;
                            }
                            break;
                        case 2:
                            break;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestSubsequentIfStatements_01()
    {
        var source =
            """
            class C
            {
                int M(int? i)
                {
                    $$if (i == null) return 5;
                    if (i == 0) return 6;
                    return 7;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                int M(int? i)
                {
                    switch (i)
                    {
                        case null:
                            return 5;
                        case 0:
                            return 6;
                        default:
                            return 7;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestSwitchExpression_01()
    {
        var source =
            """
            class C
            {
                int M(int? i)
                {
                    $$if (i == null) return 5;
                    if (i == 0) return 6;
                    return 7;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                int M(int? i)
                {
                    return i switch
                    {
                        null => 5,
                        0 => 6,
                        _ => 7
                    };
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionIndex = 1,
            CodeActionEquivalenceKey = "SwitchExpression",
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestSwitchExpression_02()
    {
        var source =
            """
            class C
            {
                int M(int? i)
                {
                    $$if (i == null) { return 5; }
                    if (i == 0) { return 6; }
                    else { return 7; }
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                int M(int? i)
                {
                    return i switch
                    {
                        null => 5,
                        0 => 6,
                        _ => 7
                    };
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionIndex = 1,
            CodeActionEquivalenceKey = "SwitchExpression",
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestSubsequentIfStatements_02()
    {
        var source =
            """
            class C
            {
                int M(int? i)
                {
                    $$if (i == null) return 5;
                    if (i == 0) {}
                    if (i == 1) return 6;
                    return 7;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                int M(int? i)
                {
                    switch (i)
                    {
                        case null:
                            return 5;
                        case 0:
                            break;
                    }
                    if (i == 1) return 6;
                    return 7;
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestSubsequentIfStatements_03()
    {
        var source =
            """
            class C
            {
                int {|#0:M|}(int? i)
                {
                    while (true)
                    {
                        $$if (i == null) return 5; else if (i == 1) return 1;
                        if (i == 0) break;
                        if (i == 1) return 6;
                        return 7;
                    }
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                int {|#0:M|}(int? i)
                {
                    while (true)
                    {
                        switch (i)
                        {
                            case null:
                                return 5;
                            case 1:
                                return 1;
                        }
                        if (i == 0) break;
                        if (i == 1) return 6;
                        return 7;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestState =
            {
                Sources = { source },
                ExpectedDiagnostics =
                {
                    // /0/Test0.cs(3,9): error CS0161: 'C.M(int?)': not all code paths return a value
                    DiagnosticResult.CompilerError("CS0161").WithLocation(0).WithArguments("C.M(int?)"),
                },
            },
            FixedState =
            {
                Sources = { fixedSource },
                ExpectedDiagnostics =
                {
                    // /0/Test0.cs(3,9): error CS0161: 'C.M(int?)': not all code paths return a value
                    DiagnosticResult.CompilerError("CS0161").WithLocation(0).WithArguments("C.M(int?)"),
                },
            },
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestSubsequentIfStatements_04()
    {
        var source =
            """
            class C
            {
                string M(object i)
                {
                    $$if (i == null || i as string == "") return null;
                    if ((string)i == "0") return i as string;
                    else return i.ToString();
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                string M(object i)
                {
                    switch (i)
                    {
                        case null:
                        case "":
                            return null;
                        case "0":
                            return i as string;
                        default:
                            return i.ToString();
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestSubsequentIfStatements_05()
    {
        var source =
            """
            class C
            {
                int M(int i)
                {
                    $$if (i == 10) return 5;
                    if (i == 20) return 6;
                    if (i == i) return 0;
                    return 7;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                int M(int i)
                {
                    switch (i)
                    {
                        case 10:
                            return 5;
                        case 20:
                            return 6;
                    }
                    if (i == i) return 0;
                    return 7;
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestSubsequentIfStatements_06()
    {
        var source =
            """
            class C
            {
                int M(int i)
                {
                    $$if (i == 10)
                    {
                        return 5;
                    }
                    else if (i == 20)
                    {
                        return 6;
                    }
                    if (i == i) 
                    {
                        return 0;
                    }
                    return 7;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                int M(int i)
                {
                    switch (i)
                    {
                        case 10:
                            return 5;
                        case 20:
                            return 6;
                    }
                    if (i == i) 
                    {
                        return 0;
                    }
                    return 7;
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestSubsequentIfStatements_07()
    {
        var source =
            """
            class C
            {
                int M(int i)
                {
                    $$if (i == 5)
                    {
                        return 4;
                    }
                    else if (i == 1)
                    {
                        return 1;
                    }
 
                    if (i == 10)
                    {
                        return 5;
                    }
                    else if (i == i)
                    {
                        return 6;
                    }
                    else
                    {
                        return 0;
                    }
                    return 7;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                int M(int i)
                {
                    switch (i)
                    {
                        case 5:
                            return 4;
                        case 1:
                            return 1;
                    }
 
                    if (i == 10)
                    {
                        return 5;
                    }
                    else if (i == i)
                    {
                        return 6;
                    }
                    else
                    {
                        return 0;
                    }
                    return 7;
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21109")]
    public async Task TestTrivia1()
    {
        var source =
            """
            class C
            {
                int {|#0:M|}(int x, int z)
                {
            #if TRUE
                    {|#1:Console|}.WriteLine();
            #endif
 
                    $$if (x == 1)
                    {
                        {|#2:Console|}.WriteLine(x + z);
                    }
                    else if (x == 2)
                    {
                        {|#3:Console|}.WriteLine(x + z);
                    }
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                int {|#0:M|}(int x, int z)
                {
            #if TRUE
                    {|#1:Console|}.WriteLine();
            #endif
 
                    switch (x)
                    {
                        case 1:
                            {|#2:Console|}.WriteLine(x + z);
                            break;
                        case 2:
                            {|#3:Console|}.WriteLine(x + z);
                            break;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestState =
            {
                Sources = { source },
                ExpectedDiagnostics =
                {
                    // /0/Test0.cs(3,9): error CS0161: 'C.M(int, int)': not all code paths return a value
                    DiagnosticResult.CompilerError("CS0161").WithLocation(0).WithArguments("C.M(int, int)"),
                    // /0/Test0.cs(6,9): error CS0103: The name 'Console' does not exist in the current context
                    DiagnosticResult.CompilerError("CS0103").WithLocation(1).WithArguments("Console"),
                    // /0/Test0.cs(11,13): error CS0103: The name 'Console' does not exist in the current context
                    DiagnosticResult.CompilerError("CS0103").WithLocation(2).WithArguments("Console"),
                    // /0/Test0.cs(15,13): error CS0103: The name 'Console' does not exist in the current context
                    DiagnosticResult.CompilerError("CS0103").WithLocation(3).WithArguments("Console"),
                },
            },
            FixedState =
            {
                Sources = { fixedSource },
                ExpectedDiagnostics =
                {
                    // /0/Test0.cs(3,9): error CS0161: 'C.M(int, int)': not all code paths return a value
                    DiagnosticResult.CompilerError("CS0161").WithLocation(0).WithArguments("C.M(int, int)"),
                    // /0/Test0.cs(6,9): error CS0103: The name 'Console' does not exist in the current context
                    DiagnosticResult.CompilerError("CS0103").WithLocation(1).WithArguments("Console"),
                    // /0/Test0.cs(11,13): error CS0103: The name 'Console' does not exist in the current context
                    DiagnosticResult.CompilerError("CS0103").WithLocation(2).WithArguments("Console"),
                    // /0/Test0.cs(15,13): error CS0103: The name 'Console' does not exist in the current context
                    DiagnosticResult.CompilerError("CS0103").WithLocation(3).WithArguments("Console"),
                },
            },
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21101")]
    public async Task TestTrivia2()
    {
        var source =
            """
            class C
            {
                int M(int i, string[] args)
                {
                    $$if (/* t0 */args.Length /* t1*/ == /* t2 */ 2)
                        return /* t3 */ 0 /* t4 */; /* t5 */
                    else /* t6 */
                        return /* t7 */ 3 /* t8 */;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                int M(int i, string[] args)
                {
                    switch (/* t0 */args.Length /* t1*/ )
                    {
                        case 2:
                            return /* t3 */ 0 /* t4 */; /* t5 */
                        default:
                            return /* t7 */ 3 /* t8 */;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21360")]
    public async Task TestCompoundLogicalAnd1_CSharp8()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (i == 1 && i == 2)
                        return;
                    else if (i == 10)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 1 when i == 2:
                            return;
                        case 10:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            LanguageVersion = LanguageVersion.CSharp8,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21360")]
    public async Task TestCompoundLogicalAnd1_CSharp9()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (i == 1 && i == 2)
                        return;
                    else if (i == 10)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case {|#0:1 and 2|}:
                            return;
                        case 10:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedState =
            {
                Sources = { fixedSource },
                ExpectedDiagnostics =
                {
                    // /0/Test0.cs(7,18): error CS8120: The switch case is unreachable. It has already been handled by a previous case or it is impossible to match.
                    DiagnosticResult.CompilerError("CS8120").WithLocation(0),
                },
            },
            LanguageVersion = LanguageVersion.CSharp9,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21360")]
    public async Task TestCompoundLogicalAnd2_CSharp8()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (i == 1 && i == 2 && i == 3)
                        return;
                    else if (i == 10)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 1 when i == 2 && i == 3:
                            return;
                        case 10:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            LanguageVersion = LanguageVersion.CSharp8,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21360")]
    public async Task TestCompoundLogicalAnd2_CSharp9()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (i == 1 && i == 2 && i == 3)
                        return;
                    else if (i == 10)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case {|#0:1 and 2 and 3|}:
                            return;
                        case 10:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedState =
            {
                Sources = { fixedSource },
                ExpectedDiagnostics =
                {
                    // /0/Test0.cs(7,18): error CS8120: The switch case is unreachable. It has already been handled by a previous case or it is impossible to match.
                    DiagnosticResult.CompilerError("CS8120").WithLocation(0),
                },
            },
            LanguageVersion = LanguageVersion.CSharp9,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21360")]
    public async Task TestCompoundLogicalAnd3_CSharp8()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (i == 1 && i == 2 && (i == 3))
                        return;
                    else if (i == 10)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 1 when i == 2 && i == 3:
                            return;
                        case 10:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            LanguageVersion = LanguageVersion.CSharp8,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21360")]
    public async Task TestCompoundLogicalAnd3_CSharp9()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (i == 1 && i == 2 && (i == 3))
                        return;
                    else if (i == 10)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case {|#0:1 and 2 and 3|}:
                            return;
                        case 10:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedState =
            {
                Sources = { fixedSource },
                ExpectedDiagnostics =
                {
                    // /0/Test0.cs(7,18): error CS8120: The switch case is unreachable. It has already been handled by a previous case or it is impossible to match.
                    DiagnosticResult.CompilerError("CS8120").WithLocation(0),
                },
            },
            LanguageVersion = LanguageVersion.CSharp9,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21360")]
    public async Task TestCompoundLogicalAnd4()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (i == 1 && (i == 2) && i == 3)
                        return;
                    else if (i == 10)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 1 when i == 2 && i == 3:
                            return;
                        case 10:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            LanguageVersion = LanguageVersion.CSharp8,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21360")]
    public async Task TestCompoundLogicalAnd4_CSharp9()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (i == 1 && (i == 2) && i == 3)
                        return;
                    else if (i == 10)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case {|#0:1 and 2 and 3|}:
                            return;
                        case 10:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedState =
            {
                Sources = { fixedSource },
                ExpectedDiagnostics =
                {
                    // /0/Test0.cs(7,18): error CS8120: The switch case is unreachable. It has already been handled by a previous case or it is impossible to match.
                    DiagnosticResult.CompilerError("CS8120").WithLocation(0),
                },
            },
            LanguageVersion = LanguageVersion.CSharp9,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21360")]
    public async Task TestCompoundLogicalAnd5()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (i == 1 && (i == 2) && (i == 3))
                        return;
                    else if (i == 10)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 1 when i == 2 && i == 3:
                            return;
                        case 10:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21360")]
    public async Task TestCompoundLogicalAnd6()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if ((i == 1) && i == 2 && i == 3)
                        return;
                    else if (i == 10)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 1 when i == 2 && i == 3:
                            return;
                        case 10:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21360")]
    public async Task TestCompoundLogicalAnd7()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if ((i == 1) && i == 2 && (i == 3))
                        return;
                    else if (i == 10)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 1 when i == 2 && i == 3:
                            return;
                        case 10:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21360")]
    public async Task TestCompoundLogicalAnd8()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if ((i == 1) && (i == 2) && i == 3)
                        return;
                    else if (i == 10)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 1 when i == 2 && i == 3:
                            return;
                        case 10:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21360")]
    public async Task TestCompoundLogicalAnd9()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if ((i == 1) && (i == 2) && (i == 3))
                        return;
                    else if (i == 10)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 1 when i == 2 && i == 3:
                            return;
                        case 10:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21360")]
    public async Task TestCompoundLogicalAnd10()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (i == 1 && (i == 2 && i == 3))
                        return;
                    else if (i == 10)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 1 when i == 2 && i == 3:
                            return;
                        case 10:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21360")]
    public async Task TestCompoundLogicalAnd11()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if ((i == 1 && i == 2) && i == 3)
                        return;
                    else if (i == 10)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 1 when i == 2 && i == 3:
                            return;
                        case 10:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21360")]
    public async Task TestCompoundLogicalAnd12()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (((i == 1) && i == 2) && i == 3)
                        return;
                    else if (i == 10)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 1 when i == 2 && i == 3:
                            return;
                        case 10:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21360")]
    public async Task TestCompoundLogicalAnd13()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if ((i == 1 && (i == 2)) && i == 3)
                        return;
                    else if (i == 10)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 1 when i == 2 && i == 3:
                            return;
                        case 10:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21360")]
    public async Task TestCompoundLogicalAnd14()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if ((i == 1 && (i == 2)) && (i == 3))
                        return;
                    else if (i == 10)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 1 when i == 2 && i == 3:
                            return;
                        case 10:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21360")]
    public async Task TestCompoundLogicalAnd15()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if ((i == 1) && ((i == 2) && i == 3))
                        return;
                    else if (i == 10)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 1 when i == 2 && i == 3:
                            return;
                        case 10:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21360")]
    public async Task TestCompoundLogicalAnd16()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if ((i == 1) && (i == 2 && (i == 3)))
                        return;
                    else if (i == 10)
                        return;
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 1 when i == 2 && i == 3:
                            return;
                        case 10:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37035")]
    public async Task TestComplexExpression_02()
    {
        await VerifyCS.VerifyRefactoringAsync(
            """
            class C
            {
                void M(object o)
                {
                    $$if (o is string text &&
                        int.TryParse(text, out var n) &&
                        n < 5 && n > -5)
                    {
                    }
                    else
                    {
                    }
                }
            }
            """,
            """
            class C
            {
                void M(object o)
                {
                    switch (o)
                    {
                        case string text when int.TryParse(text, out var n) && n < 5 && n > -5:
                            break;
                        default:
                            break;
                    }
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42368")]
    public async Task TestRange_CSharp8()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (5 >= i && 1 <= i)
                    {
                        return;
                    }
                    else if (7 >= i && 6 <= i)
                    {
                        return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            LanguageVersion = LanguageVersion.CSharp8,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42368")]
    public async Task TestRange_CSharp9()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (5 >= i && 1 <= i)
                    {
                        return;
                    }
                    else if (7 >= i && 6 <= i)
                    {
                        return;
                    }
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case <= 5 and >= 1:
                            return;
                        case <= 7 and >= 6:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            LanguageVersion = LanguageVersion.CSharp9,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42368")]
    public async Task TestComparison_CSharp8()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (5 >= i || 1 <= i)
                    {
                        return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            LanguageVersion = LanguageVersion.CSharp8,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42368")]
    public async Task TestComparison_CSharp9()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (5 >= i || 1 <= i)
                    {
                        return;
                    }
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case <= 5:
                        case >= 1:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            LanguageVersion = LanguageVersion.CSharp9,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42368")]
    public async Task TestComparison_SwitchExpression_CSharp9()
    {
        var source =
            """
            class C
            {
                int M(int i)
                {
                    $$if (5 >= i || 1 <= i)
                    {
                        return 1;
                    }
                    else
                    {
                        return 2;
                    }
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                int M(int i)
                {
                    return i switch
                    {
                        <= 5 or >= 1 => 1,
                        {|#0:_|} => 2
                    };
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedState =
            {
                Sources = { fixedSource },
                ExpectedDiagnostics =
                {
                    // /0/Test0.cs(8,13): error CS8510: The pattern is unreachable. It has already been handled by a previous arm of the switch expression or it is impossible to match.
                    DiagnosticResult.CompilerError("CS8510").WithLocation(0),
                },
            },
            LanguageVersion = LanguageVersion.CSharp9,
            CodeActionIndex = 1,
            CodeActionEquivalenceKey = "SwitchExpression",
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42368")]
    public async Task TestComplexIf_CSharp8()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (i < 10 || 20 < i || (i >= 30 && 40 >= i) || i == 50)
                    {
                        return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            LanguageVersion = LanguageVersion.CSharp8,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42368")]
    public async Task TestComplexIf_CSharp9()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (i < 10 || 20 < i || (i >= 30 && 40 >= i) || i == 50)
                    {
                        return;
                    }
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case < 10:
                        case > 20:
                        case {|#0:>= 30 and <= 40|}:
                        case {|#1:50|}:
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedState =
            {
                Sources = { fixedSource },
                ExpectedDiagnostics =
                {
                    // /0/Test0.cs(9,18): error CS8120: The switch case is unreachable. It has already been handled by a previous case or it is impossible to match.
                    DiagnosticResult.CompilerError("CS8120").WithLocation(0),
                    // /0/Test0.cs(10,18): error CS8120: The switch case is unreachable. It has already been handled by a previous case or it is impossible to match.
                    DiagnosticResult.CompilerError("CS8120").WithLocation(1),
                },
            },
            LanguageVersion = LanguageVersion.CSharp9,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42368")]
    public async Task TestComplexIf_Precedence_CSharp9()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    $$if (i == 0 || i is < 10 or > 20 && i is >= 30 or <= 40)
                    {
                        return;
                    }
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void M(int i)
                {
                    switch (i)
                    {
                        case 0:
                        case (< 10 or > 20) and (>= 30 or <= 40):
                            return;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            LanguageVersion = LanguageVersion.CSharp9,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestInequality()
    {
        var source =
            """
            class C
            {
                void M(int i)
                {
                    [||]if ((i > 123 && i < 456) && i != 0 || i == 10)
                    {
                        return;
                    }
                }
            }
            """;
 
        var fixedSource =
"""
 class C
 {
     void M(int i)
     {
         switch (i)
         {
             case > 123 and < 456 when i != 0:
             case 10:
                 return;
         }
     }
 }
 """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            LanguageVersion = LanguageVersion.CSharp9,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44278")]
    public async Task TestTopLevelStatement()
    {
        var source = """
            var e = new ET1();
 
            [||]if (e == ET1.A)
            {
            }
            else if (e == ET1.C)
            {
            }
 
            enum ET1
            {
                A,
                B,
                C,
            }
            """;
 
        var fixedSource = """
            var e = new ET1();
 
            switch (e)
            {
                case ET1.A:
                    break;
                case ET1.C:
                    break;
            }
 
            enum ET1
            {
                A,
                B,
                C,
            }
            """;
 
        var test = new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            LanguageVersion = LanguageVersion.CSharp9,
            CodeActionValidationMode = CodeActionValidationMode.None,
        };
 
        test.ExpectedDiagnostics.Add(
            // /0/Test0.cs(2,1): error CS8805: Program using top-level statements must be an executable.
            DiagnosticResult.CompilerError("CS8805").WithSpan(1, 1, 1, 19));
 
        await test.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/46863")]
    public async Task CommentsAtTheEndOfBlocksShouldBePlacedBeforeBreakStatements()
    {
        var source = """
            class C
            {
                void M(int p)
                {
                    [||]if (p == 1)
                    {
                        DoA();
                        // Comment about why A doesn't need something here
                    }
                    else if (p == 2)
                    {
                        DoB();
                        // Comment about why B doesn't need something here
                    }
                }
 
                void DoA() { }
                void DoB() { }
            }
            """;
 
        var fixedSource = """
            class C
            {
                void M(int p)
                {
                    switch (p)
                    {
                        case 1:
                            DoA();
                            // Comment about why A doesn't need something here
                            break;
                        case 2:
                            DoB();
                            // Comment about why B doesn't need something here
                            break;
                    }
                }
 
                void DoA() { }
                void DoB() { }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestMissingOnImplicitCastInRelationalPattern()
    {
        var source =
            """
            class C
            {
                void M(char c)
                {
                    $$if (c >= 128 || c == 'a')
                        System.Console.WriteLine(c);
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            LanguageVersion = LanguageVersion.CSharp9,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestMissingExpressionOnImplicitCastInRelationalPattern()
    {
        var source =
            """
            class C
            {
                int M(char c)
                {
                    $$if (c >= 128 || c == 'a')
                        return 1;
                    else
                        return 2;
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            LanguageVersion = LanguageVersion.CSharp9,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestMissingOnImplicitCastInRangePattern()
    {
        var source =
            """
            class C
            {
                void M(char c)
                {
                    $$if (7 >= c && 6 <= c || c == 'a')
                        System.Console.WriteLine(c);
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            LanguageVersion = LanguageVersion.CSharp9,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestMissingOnImplicitCastInConstantPattern()
    {
        var source =
            """
            class C
            {
                void M(char c)
                {
                    $$if (c == 128 || c == 'a')
                        System.Console.WriteLine(c);
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            LanguageVersion = LanguageVersion.CSharp9,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestExplicitCastInConstantPattern()
    {
        var source =
            """
            class C
            {
                void M(char c)
                {
                    $$if (c == (char)128 || c == 'a')
                        System.Console.WriteLine(c);
                }
            }
            """;
 
        var fixedSource =
            """
            class C
            {
                void M(char c)
                {
                    switch (c)
                    {
                        case (char)128:
                        case 'a':
                            System.Console.WriteLine(c);
                            break;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            LanguageVersion = LanguageVersion.CSharp9,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41131")]
    public async Task MoveTriviaFromElse1()
    {
        var source =
            """
            using System;
 
            class C
            {
                void M()
                {
                    bool? abc = true;
                    $$if (abc == true)
                    {
                        Console.WriteLine(3);
                    }
                    // some comment here
                    else if (abc == false)
                    {
                        Console.WriteLine(4);
                    }
                    else if (abc is null)
                    {
                        Console.WriteLine(14);
                    }
                }
            }
            """;
        var fixedSource =
            """
            using System;
 
            class C
            {
                void M()
                {
                    bool? abc = true;
                    switch (abc)
                    {
                        case true:
                            Console.WriteLine(3);
                            break;
                        // some comment here
                        case false:
                            Console.WriteLine(4);
                            break;
                        case null:
                            Console.WriteLine(14);
                            break;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41131")]
    public async Task MoveTriviaFromElse2()
    {
        var source =
            """
            using System;
 
            class C
            {
                void M()
                {
                    bool? abc = true;
                    $$if (abc == true)
                    {
                        Console.WriteLine(3);
                    }
                    // some comment here
                    else if (abc == false)
                    {
                        Console.WriteLine(4);
                    }
                    // other comment
                    else
                    {
                        Console.WriteLine(14);
                    }
                }
            }
            """;
        var fixedSource =
            """
            using System;
 
            class C
            {
                void M()
                {
                    bool? abc = true;
                    switch (abc)
                    {
                        case true:
                            Console.WriteLine(3);
                            break;
                        // some comment here
                        case false:
                            Console.WriteLine(4);
                            break;
                        // other comment
                        default:
                            Console.WriteLine(14);
                            break;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71295")]
    public async Task TestCodeAfterElseIf()
    {
        var source =
            """
            class C
            {
                void TestThing(int a, int b)
                {
                    $$if (a == 1 && b == 0)
                    {
                        TestThing(0, 1);
                    }
                    else
                    {
                        if (a == 2 && b == 1)
                        {
                            a = b; b = 0;
                        }
                        TestThing(a, b);
                    }
                }
            }
            """;
        var fixedSource =
            """
            class C
            {
                void TestThing(int a, int b)
                {
                    switch (a)
                    {
                        case 1 when b == 0:
                            TestThing(0, 1);
                            break;
                        default:
                            if (a == 2 && b == 1)
                            {
                                a = b; b = 0;
                            }
                            TestThing(a, b);
                            break;
                    }
                }
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = source,
            FixedCode = fixedSource,
            CodeActionValidationMode = CodeActionValidationMode.None,
        }.RunAsync();
    }
}