File: InvertIf\InvertIfTests.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.InvertIf;
using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Testing;
using Roslyn.Test.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.InvertIf;
 
[UseExportProvider, Trait(Traits.Feature, Traits.Features.CodeActionsInvertIf)]
public partial class InvertIfTests
{
    private static Task TestInsideMethodAsync(
        string initial,
        string expected)
    {
        return TestAsync(CreateTreeText(initial), CreateTreeText(expected));
 
        static string CreateTreeText(string initial)
        {
            return $$"""
                class A
                {
                    bool a = true;
                    bool b = true;
                    bool c = true;
                    bool d = true;
 
                    void Goo()
                    {
                        {{initial}}
                    }
                }
                """;
        }
    }
 
    private static async Task TestAsync(string initial, string expected, LanguageVersion languageVersion = LanguageVersion.Latest)
    {
        await new CSharpCodeRefactoringVerifier<CSharpInvertIfCodeRefactoringProvider>.Test
        {
            TestCode = initial,
            FixedCode = expected,
            LanguageVersion = languageVersion,
            CompilerDiagnostics = CompilerDiagnostics.None,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestSingleLine_Identifier()
    {
        await TestInsideMethodAsync(
@"[||]if (a) { a(); } else { b(); }",
@"if (!a) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_IdentifierWithTrivia()
    {
        await TestInsideMethodAsync(
@"[||]if /*0*/(/*1*/a/*2*/)/*3*/ { a(); } else { b(); }",
@"if /*0*/(/*1*/!a/*2*/)/*3*/ { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_NotIdentifier()
    {
        await TestInsideMethodAsync(
@"[||]if (!a) { a(); } else { b(); }",
@"if (a) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_NotIdentifierWithTrivia()
    {
        await TestInsideMethodAsync(
@"[||]if /*0*/(/*1*/!/*1b*/a/*2*/)/*3*/ { a(); } else { b(); }",
@"if /*0*/(/*1*/a/*2*/)/*3*/ { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_EqualsEquals()
    {
        await TestInsideMethodAsync(
@"[||]if (a == b) { a(); } else { b(); }",
@"if (a != b) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_NotEquals()
    {
        await TestInsideMethodAsync(
@"[||]if (a != b) { a(); } else { b(); }",
@"if (a == b) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_GreaterThan()
    {
        await TestInsideMethodAsync(
@"[||]if (a > b) { a(); } else { b(); }",
@"if (a <= b) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_GreaterThanEquals()
    {
        await TestInsideMethodAsync(
@"[||]if (a >= b) { a(); } else { b(); }",
@"if (a < b) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_LessThan()
    {
        await TestInsideMethodAsync(
@"[||]if (a < b) { a(); } else { b(); }",
@"if (a >= b) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_LessThanEquals()
    {
        await TestInsideMethodAsync(
@"[||]if (a <= b) { a(); } else { b(); }",
@"if (a > b) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_DoubleParentheses()
    {
        await TestInsideMethodAsync(
@"[||]if ((a)) { a(); } else { b(); }",
@"if (!a) { b(); } else { a(); }");
    }
 
    [Fact(Skip = "https://github.com/dotnet/roslyn/issues/26427")]
    public async Task TestSingleLine_DoubleParenthesesWithInnerTrivia()
    {
        await TestInsideMethodAsync(
@"[||]if ((/*1*/a/*2*/)) { a(); } else { b(); }",
@"if (/*1*/!a/*2*/) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_DoubleParenthesesWithMiddleTrivia()
    {
        await TestInsideMethodAsync(
@"[||]if (/*1*/(a)/*2*/) { a(); } else { b(); }",
@"if (/*1*/!a/*2*/) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_DoubleParenthesesWithOutsideTrivia()
    {
        await TestInsideMethodAsync(
@"[||]if /*before*/((a))/*after*/ { a(); } else { b(); }",
@"if /*before*/(!a)/*after*/ { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_Is()
    {
        await TestInsideMethodAsync(
@"[||]if (a is Goo) { a(); } else { b(); }",
@"if (a is not Goo) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_MethodCall()
    {
        await TestInsideMethodAsync(
@"[||]if (a.Goo()) { a(); } else { b(); }",
@"if (!a.Goo()) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_Or()
    {
        await TestInsideMethodAsync(
@"[||]if (a || b) { a(); } else { b(); }",
@"if (!a && !b) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_Or2()
    {
        await TestInsideMethodAsync(
@"[||]if (!a || !b) { a(); } else { b(); }",
@"if (a && b) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_Or3()
    {
        await TestInsideMethodAsync(
@"[||]if (!a || b) { a(); } else { b(); }",
@"if (a && !b) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_Or4()
    {
        await TestInsideMethodAsync(
@"[||]if (a | b) { a(); } else { b(); }",
@"if (!a & !b) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_And()
    {
        await TestInsideMethodAsync(
@"[||]if (a && b) { a(); } else { b(); }",
@"if (!a || !b) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_And2()
    {
        await TestInsideMethodAsync(
@"[||]if (!a && !b) { a(); } else { b(); }",
@"if (a || b) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_And3()
    {
        await TestInsideMethodAsync(
@"[||]if (!a && b) { a(); } else { b(); }",
@"if (a || !b) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_And4()
    {
        await TestInsideMethodAsync(
@"[||]if (a & b) { a(); } else { b(); }",
@"if (!a | !b) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_ParenthesizeAndForPrecedence()
    {
        await TestInsideMethodAsync(
@"[||]if (a && b || c) { a(); } else { b(); }",
@"if ((!a || !b) && !c) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_Plus()
    {
        await TestInsideMethodAsync(
@"[||]if (a + b) { a(); } else { b(); }",
@"if (!(a + b)) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_True()
    {
        await TestInsideMethodAsync(
@"[||]if (true) { a(); } else { b(); }",
@"if (false) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_TrueWithTrivia()
    {
        await TestInsideMethodAsync(
@"[||]if (/*1*/true/*2*/) { a(); } else { b(); }",
@"if (/*1*/false/*2*/) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_False()
    {
        await TestInsideMethodAsync(
@"[||]if (false) { a(); } else { b(); }",
@"if (true) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_OtherLiteralExpression()
    {
        await TestInsideMethodAsync(
@"[||]if (literalexpression) { a(); } else { b(); }",
@"if (!literalexpression) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_TrueAndFalse()
    {
        await TestInsideMethodAsync(
@"[||]if (true && false) { a(); } else { b(); }",
@"if (false || true) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_NoCurlyBraces()
    {
        await TestInsideMethodAsync(
@"[||]if (a) a(); else b();",
@"if (!a) b(); else a();");
    }
 
    [Fact]
    public async Task TestSingleLine_CurlyBracesOnIf()
    {
        await TestInsideMethodAsync(
@"[||]if (a) { a(); } else b();",
@"if (!a) b(); else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_CurlyBracesOnElse()
    {
        await TestInsideMethodAsync(
@"[||]if (a) a(); else { b(); }",
@"if (!a) { b(); } else a();");
    }
 
    [Fact]
    public async Task TestSingleLine_IfElseIf()
    {
        await TestInsideMethodAsync(
@"[||]if (a) { a(); } else if (b) { b(); }",
@"if (!a) { if (b) { b(); } } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_IfElseIfElse()
    {
        await TestInsideMethodAsync(
@"[||]if (a) { a(); } else if (b) { b(); } else { c(); }",
@"if (!a) { if (b) { b(); } else { c(); } } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_CompoundConditional()
    {
        await TestInsideMethodAsync(
@"[||]if (((a == b) && (c != d)) || ((e < f) && (!g))) { a(); } else { b(); }",
@"if ((a != b || c == d) && (e >= f || g)) { b(); } else { a(); }");
    }
 
    [Fact]
    public async Task TestSingleLine_Trivia()
    {
        await TestInsideMethodAsync(
@"[||]if /*1*/ (a) /*2*/ { /*3*/ a() /*4*/; /*5*/ } /*6*/ else if /*7*/ (b) /*8*/ { /*9*/ b(); /*10*/ } /*11*/ else /*12*/ { /*13*/ c(); /*14*/} /*15*/",
@"if /*1*/ (!a) /*2*/ { if /*7*/ (b) /*8*/ { /*9*/ b(); /*10*/ } /*11*/ else /*12*/ { /*13*/ c(); /*14*/} /*6*/ } else { /*3*/ a() /*4*/; /*5*/ } /*15*/");
    }
 
    [Fact]
    public async Task TestKeepTriviaWithinExpression_BrokenCode()
    {
        await TestAsync("""
            class A
            {
                void Goo()
                {
                    [||]if (a ||
                    b &&
                    c < // comment
                    d)
                    {
                        a();
                    }
                    else
                    {
                        b();
                    }
                }
            }
            """, """
            class A
            {
                void Goo()
                {
                    if (!a &&
                    (!b ||
                    c >= // comment
                    d))
                    {
                        b();
                    }
                    else
                    {
                        a();
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestKeepTriviaWithinExpression()
    {
        await TestAsync("""
            class A
            {
                void Goo()
                {
                    bool a = true;
                    bool b = true;
                    bool c = true;
                    bool d = true;
            
                    [||]if (a ||
                    b &&
                    c < // comment
                    d)
                    {
                        a();
                    }
                    else
                    {
                        b();
                    }
                }
            }
            """, """
            class A
            {
                void Goo()
                {
                    bool a = true;
                    bool b = true;
                    bool c = true;
                    bool d = true;
            
                    if (!a &&
                    (!b ||
                    c >= // comment
                    d))
                    {
                        b();
                    }
                    else
                    {
                        a();
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestMultiline_IfElseIfElse()
    {
        await TestAsync("""
            class A
            {
                void Goo()
                {
                    [||]if (a)
                    {
                        a();
                    }
                    else if (b)
                    {
                        b();
                    }
                    else
                    {
                        c();
                    }
                }
            }
            """, """
            class A
            {
                void Goo()
                {
                    if (!a)
                    {
                        if (b)
                        {
                            b();
                        }
                        else
                        {
                            c();
                        }
                    }
                    else
                    {
                        a();
                    }
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35525")]
    public async Task TestMultiline_IfElseIfElseSelection1()
    {
        await TestAsync("""
            class A
            {
                void Goo()
                {
                    [|if (a)
                    {
                        a();
                    }
                    else if (b)
                    {
                        b();
                    }
                    else
                    {
                        c();
                    }|]
                }
            }
            """, """
            class A
            {
                void Goo()
                {
                    if (!a)
                    {
                        if (b)
                        {
                            b();
                        }
                        else
                        {
                            c();
                        }
                    }
                    else
                    {
                        a();
                    }
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35525")]
    public async Task TestMultiline_IfElseIfElseSelection2()
    {
        await TestAsync("""
            class A
            {
                void Goo()
                {
                    [|if (a)
                    {
                        a();
                    }|]
                    else if (b)
                    {
                        b();
                    }
                    else
                    {
                        c();
                    }
                }
            }
            """, """
            class A
            {
                void Goo()
                {
                    if (!a)
                    {
                        if (b)
                        {
                            b();
                        }
                        else
                        {
                            c();
                        }
                    }
                    else
                    {
                        a();
                    }
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35525")]
    public async Task TestMultilineMissing_IfElseIfElseSubSelection()
    {
        var code = """
            class A
            {
                void Goo()
                {
                    if (a)
                    {
                        a();
                    }
                    [|else if (b)
                    {
                        b();
                    }
                    else
                    {
                        c();
                    }|]
                }
            }
            """;
 
        await TestAsync(code, code);
    }
 
    [Fact]
    public async Task TestMultiline_IfElse()
    {
        await TestAsync("""
            class A
            {
                void Goo()
                {
                    [||]if (foo) 
                        bar();
                    else
                        if (baz)
                            Quux();
                }
            }
            """, """
            class A
            {
                void Goo()
                {
                    if (!foo)
                    {
                        if (baz)
                            Quux();
                    }
                    else
                        bar();
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestMultiline_OpenCloseBracesSameLine()
    {
        await TestAsync("""
            class A
            {
                void Goo()
                {
                    [||]if (foo) {
                        x();
                        x();
                    } else {
                        y();
                        y();
                    }
                }
            }
            """, """
            class A
            {
                void Goo()
                {
                    if (!foo)
                    {
                        y();
                        y();
                    }
                    else
                    {
                        x();
                        x();
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestMultiline_Trivia()
    {
        await TestAsync("""
            class A
            {
                void Goo()
                { /*1*/
                    [||]if (a) /*2*/
                    { /*3*/
                        /*4*/
                        goo(); /*5*/
                        /*6*/
                    } /*7*/
                    else if (b) /*8*/
                    { /*9*/
                        /*10*/
                        goo(); /*11*/
                        /*12*/
                    } /*13*/
                    else /*14*/
                    { /*15*/
                        /*16*/
                        goo(); /*17*/
                        /*18*/
                    } /*19*/
                    /*20*/
                }
            }
            """, """
            class A
            {
                void Goo()
                { /*1*/
                    if (!a) /*2*/
                    {
                        if (b) /*8*/
                        { /*9*/
                            /*10*/
                            goo(); /*11*/
                            /*12*/
                        } /*13*/
                        else /*14*/
                        { /*15*/
                            /*16*/
                            goo(); /*17*/
                            /*18*/
                        } /*19*/
                    }
                    else
                    { /*3*/
                        /*4*/
                        goo(); /*5*/
                        /*6*/
                    } /*7*/
                    /*20*/
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestOverlapsHiddenPosition1()
    {
        var code = """
            class C
            {
                void F()
                {
            #line hidden
                    [||]if (a)
                    {
                        a();
                    }
                    else
                    {
                        b();
                    }
            #line default
                }
            }
            """;
 
        await TestAsync(code, code);
    }
 
    [Fact]
    public async Task TestOverlapsHiddenPosition2()
    {
        var code = """
            class C
            {
                void F()
                {
                    [||]if (a)
                    {
            #line hidden
                        a();
            #line default
                    }
                    else
                    {
                        b();
                    }
                }
            }
            """;
 
        await TestAsync(code, code);
    }
 
    [Fact]
    public async Task TestOverlapsHiddenPosition3()
    {
        var code = """
            class C
            {
                void F()
                {
                    [||]if (a)
                    {
                        a();
                    }
                    else
                    {
            #line hidden
                        b();
            #line default
                    }
                }
            }
            """;
 
        await TestAsync(code, code);
    }
 
    [Fact]
    public async Task TestOverlapsHiddenPosition4()
    {
        var code = """
            class C
            {
                void F()
                {
                    [||]if (a)
                    {
            #line hidden
                        a();
                    }
                    else
                    {
                        b();
            #line default
                    }
                }
            }
            """;
 
        await TestAsync(code, code);
    }
 
    [Fact]
    public async Task TestOverlapsHiddenPosition5()
    {
        var code = """
            class C
            {
                void F()
                {
                    [||]if (a)
                    {
                        a();
            #line hidden
                    }
                    else
                    {
            #line default
                        b();
                    }
                }
            }
            """;
 
        await TestAsync(code, code);
    }
 
    [Fact]
    public async Task TestOverlapsHiddenPosition6()
    {
        await TestAsync("""
            #line hidden
            class C 
            {
                void F()
                {
            #line default
                    [||]if (a)
                    {
                        a();
                    }
                    else
                    {
                        b();
                    }
                }
            }
            """, """
            #line hidden
            class C 
            {
                void F()
                {
            #line default
                    if (!a)
                    {
                        b();
                    }
                    else
                    {
                        a();
                    }
                }
            }
            """);
 
    }
 
    [Fact]
    public async Task TestOverlapsHiddenPosition7()
    {
        await TestAsync("""
            #line hidden
            class C 
            {
                void F()
                {
            #line default
                    [||]if (a)
                    {
                        a();
                    }
                    else
                    {
                        b();
                    }
            #line hidden
                }
            }
            #line default
            """, """
            #line hidden
            class C 
            {
                void F()
                {
            #line default
                    if (!a)
                    {
                        b();
                    }
                    else
                    {
                        a();
                    }
            #line hidden
                }
            }
            #line default
            """);
    }
 
    [Fact]
    public async Task TestSingleLine_SimplifyToLengthEqualsZero()
    {
        await TestInsideMethodAsync(
@"string x; [||]if (x.Length > 0) { GreaterThanZero(); } else { EqualsZero(); } } } ",
@"string x; if (x.Length == 0) { EqualsZero(); } else { GreaterThanZero(); } } } ");
    }
 
    [Fact]
    public async Task TestSingleLine_SimplifyToLengthEqualsZero2()
    {
        await TestInsideMethodAsync(
@"string[] x; [||]if (x.Length > 0) { GreaterThanZero(); } else { EqualsZero(); } } } ",
@"string[] x; if (x.Length == 0) { EqualsZero(); } else { GreaterThanZero(); } } } ");
    }
 
    [Fact]
    public async Task TestSingleLine_SimplifyToLengthEqualsZero3()
    {
        await TestInsideMethodAsync(
@"string x; [||]if (x.Length > 0x0) { a(); } else { b(); } } } ",
@"string x; if (x.Length == 0x0) { b(); } else { a(); } } } ");
    }
 
    [Fact]
    public async Task TestSingleLine_SimplifyToLengthEqualsZero4()
    {
        await TestInsideMethodAsync(
@"string x; [||]if (0 < x.Length) { a(); } else { b(); } } } ",
@"string x; if (0 == x.Length) { b(); } else { a(); } } } ");
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545986")]
    public async Task TestSingleLine_SimplifyToEqualsZero1()
    {
        await TestInsideMethodAsync(
@"byte x = 1; [||]if (0 < x) { a(); } else { b(); } } } ",
@"byte x = 1; if (0 == x) { b(); } else { a(); } } } ");
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545986")]
    public async Task TestSingleLine_SimplifyToEqualsZero2()
    {
        await TestInsideMethodAsync(
@"ushort x = 1; [||]if (0 < x) { a(); } else { b(); } } } ",
@"ushort x = 1; if (0 == x) { b(); } else { a(); } } } ");
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545986")]
    public async Task TestSingleLine_SimplifyToEqualsZero3()
    {
        await TestInsideMethodAsync(
@"uint x = 1; [||]if (0 < x) { a(); } else { b(); } } } ",
@"uint x = 1; if (0 == x) { b(); } else { a(); } } } ");
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545986")]
    public async Task TestSingleLine_SimplifyToEqualsZero4()
    {
        await TestInsideMethodAsync(
@"ulong x = 1; [||]if (x > 0) { a(); } else { b(); } } } ",
@"ulong x = 1; if (x == 0) { b(); } else { a(); } } } ");
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545986")]
    public async Task TestSingleLine_SimplifyToNotEqualsZero1()
    {
        await TestInsideMethodAsync(
@"ulong x = 1; [||]if (0 == x) { a(); } else { b(); } } } ",
@"ulong x = 1; if (0 != x) { b(); } else { a(); } } } ");
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545986")]
    public async Task TestSingleLine_SimplifyToNotEqualsZero2()
    {
        await TestInsideMethodAsync(
@"ulong x = 1; [||]if (x == 0) { a(); } else { b(); } } } ",
@"ulong x = 1; if (x != 0) { b(); } else { a(); } } } ");
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530505")]
    public async Task TestSingleLine_SimplifyLongLengthEqualsZero()
    {
        await TestInsideMethodAsync(
@"string[] x; [||]if (x.LongLength > 0) { GreaterThanZero(); } else { EqualsZero(); } } } ",
@"string[] x; if (x.LongLength == 0) { EqualsZero(); } else { GreaterThanZero(); } } } ");
    }
 
    [Fact]
    public async Task TestSingleLine_DoesNotSimplifyToLengthEqualsZero()
    {
        await TestInsideMethodAsync(
@"string x; [||]if (x.Length >= 0) { a(); } else { b(); } } } ",
@"string x; if (x.Length < 0) { b(); } else { a(); } } } ");
    }
 
    [Fact]
    public async Task TestSingleLine_DoesNotSimplifyToLengthEqualsZero2()
    {
        await TestInsideMethodAsync(
@"string x; [||]if (x.Length > 0.0f) { GreaterThanZero(); } else { EqualsZero(); } } } ",
@"string x; if (x.Length <= 0.0f) { EqualsZero(); } else { GreaterThanZero(); } } } ");
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29434")]
    public async Task TestIsExpression()
    {
        await TestAsync(
@"class C { void M(object o) { [||]if (o is C) { a(); } else { } } }",
@"class C { void M(object o) { if (o is not C) { } else { a(); } } }");
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43224")]
    public async Task TestEmptyIf()
    {
        await TestAsync(
            @"class C { void M(string s){ [||]if (s == ""a""){}else{ s = ""b""}}}",
            @"class C { void M(string s){ if (s != ""a"") { s = ""b""}}}");
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43224")]
    public async Task TestOnlySingleLineCommentIf()
    {
        await TestAsync("""
            class C 
            {
                void M(string s)
                {
                    [||]if (s == "a")
                    {
                        // A single line comment
                    }
                    else
                    {
                        s = "b"
                    }
                }
            }
            """, """
            class C 
            {
                void M(string s)
                {
                    if (s != "a")
                    {
                        s = "b"
                    }
                    else
                    {
                        // A single line comment
                    }
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43224")]
    public async Task TestOnlyMultilineLineCommentIf()
    {
        await TestAsync("""
            class C 
            { 
                void M(string s)
                {
                    [||]if (s == "a")
                    {
                        /*
                        * This is
                        * a multiline
                        * comment with
                        * two words
                        * per line.
                        */
                    }
                    else
                    {
                        s = "b"
                    }
                }
            }
            """, """
            class C 
            { 
                void M(string s)
                {
                    if (s != "a")
                    {
                        s = "b"
                    }
                    else
                    {
                        /*
                        * This is
                        * a multiline
                        * comment with
                        * two words
                        * per line.
                        */
                    }
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/51359")]
    public async Task TestIsCheck_CSharp6()
    {
        await TestAsync("""
            class C
            {
                int M()
                {
                    [||]if (c is object)
                    {
                        return 1;
                    }
                    else
                    {
                        return 2;
                    }
                }
            }
            """, """
            class C
            {
                int M()
                {
                    if (!(c is object))
                    {
                        return 2;
                    }
                    else
                    {
                        return 1;
                    }
                }
            }
            """, LanguageVersion.CSharp6);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/51359")]
    public async Task TestIsCheck_CSharp8()
    {
        await TestAsync("""
            class C
            {
                int M()
                {
                    [||]if (c is object)
                    {
                        return 1;
                    }
                    else
                    {
                        return 2;
                    }
                }
            }
            """, """
            class C
            {
                int M()
                {
                    if (c is null)
                    {
                        return 2;
                    }
                    else
                    {
                        return 1;
                    }
                }
            }
            """, LanguageVersion.CSharp8);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/51359")]
    public async Task TestIsCheck_CSharp9()
    {
        await TestAsync("""
            class C
            {
                int M()
                {
                    [||]if (c is object)
                    {
                        return 1;
                    }
                    else
                    {
                        return 2;
                    }
                }
            }
            """, """
            class C
            {
                int M()
                {
                    if (c is null)
                    {
                        return 2;
                    }
                    else
                    {
                        return 1;
                    }
                }
            }
            """, LanguageVersion.CSharp9);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/51359")]
    public async Task TestIsNotObjectCheck_CSharp8()
    {
        // Not terrific.  But the starting code is not legal C#8 either.  In this case because we don't even support
        // 'not' patterns wee don't bother diving into the pattern to negate it, and we instead just negate the
        // expression.
        await TestAsync("""
            class C
            {
                int M()
                {
                    [||]if (c is not object)
                    {
                        return 1;
                    }
                    else
                    {
                        return 2;
                    }
                }
            }
            """, """
            class C
            {
                int M()
                {
                    if (c is object)
                    {
                        return 2;
                    }
                    else
                    {
                        return 1;
                    }
                }
            }
            """, LanguageVersion.CSharp8);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/51359")]
    public async Task TestIsNotObjectCheck_CSharp9()
    {
        await TestAsync("""
            class C
            {
                int M()
                {
                    [||]if (c is not object)
                    {
                        return 1;
                    }
                    else
                    {
                        return 2;
                    }
                }
            }
            """, """
            class C
            {
                int M()
                {
                    if (c is not null)
                    {
                        return 2;
                    }
                    else
                    {
                        return 1;
                    }
                }
            }
            """, LanguageVersion.CSharp9);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63311")]
    public async Task TestLiftedNullable_GreaterThan()
    {
        await TestAsync("""
            class C
            {
                void M(int? p)
                {
                    [||]if (p > 10)
                    {
                        System.Console.WriteLine("p is not null and p.Value > 10");
                    }
                }
            }
            """, """
            class C
            {
                void M(int? p)
                {
                    if (!(p > 10))
                    {
                        return;
                    }
                    System.Console.WriteLine("p is not null and p.Value > 10");
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63311")]
    public async Task TestLiftedNullable_GreaterThanOrEqual()
    {
        await TestAsync("""
            class C
            {
                void M(int? p)
                {
                    [||]if (p >= 10)
                    {
                        System.Console.WriteLine("p is not null and p.Value >= 10");
                    }
                }
            }
            """, """
            class C
            {
                void M(int? p)
                {
                    if (!(p >= 10))
                    {
                        return;
                    }
                    System.Console.WriteLine("p is not null and p.Value >= 10");
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63311")]
    public async Task TestLiftedNullable_LessThan()
    {
        await TestAsync("""
            class C
            {
                void M(int? p)
                {
                    [||]if (p < 10)
                    {
                        System.Console.WriteLine("p is not null and p.Value < 10");
                    }
                }
            }
            """, """
            class C
            {
                void M(int? p)
                {
                    if (!(p < 10))
                    {
                        return;
                    }
                    System.Console.WriteLine("p is not null and p.Value < 10");
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63311")]
    public async Task TestLiftedNullable_LessThanOrEqual()
    {
        await TestAsync("""
            class C
            {
                void M(int? p)
                {
                    [||]if (p <= 10)
                    {
                        System.Console.WriteLine("p is not null and p.Value <= 10");
                    }
                }
            }
            """, """
            class C
            {
                void M(int? p)
                {
                    if (!(p <= 10))
                    {
                        return;
                    }
                    System.Console.WriteLine("p is not null and p.Value <= 10");
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63311")]
    public async Task TestNullableReference_GreaterThan()
    {
        await TestAsync("""
            #nullable enable
            using System;
            class C
            {
                void M(C? p)
                {
                    [||]if (p > new C())
                    {
                        Console.WriteLine("Null-handling semantics may actually change depending on the operator implementation");
                    }
                }
 
                public static bool operator <(C? left, C? right) => throw new NotImplementedException();
                public static bool operator >(C? left, C? right) => throw new NotImplementedException();
                public static bool operator <=(C? left, C? right) => throw new NotImplementedException();
                public static bool operator >=(C? left, C? right) => throw new NotImplementedException();
            }
            """, """
            #nullable enable
            using System;
            class C
            {
                void M(C? p)
                {
                    if (p <= new C())
                    {
                        return;
                    }
                    Console.WriteLine("Null-handling semantics may actually change depending on the operator implementation");
                }
 
                public static bool operator <(C? left, C? right) => throw new NotImplementedException();
                public static bool operator >(C? left, C? right) => throw new NotImplementedException();
                public static bool operator <=(C? left, C? right) => throw new NotImplementedException();
                public static bool operator >=(C? left, C? right) => throw new NotImplementedException();
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40585")]
    public async Task TestYieldBreak()
    {
        await TestAsync("""
            using System.Collections;
 
            class Program
            {
                public static IEnumerable Method(bool condition)
                {
                    [||]if (condition)
                    {
                        yield return 1;
                    }
                }
            }
            """, """
            using System.Collections;
 
            class Program
            {
                public static IEnumerable Method(bool condition)
                {
                    if (!condition)
                    {
                        yield break;
                    }
                    yield return 1;
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42715")]
    public async Task PreserveSpacing()
    {
        await TestAsync("""
            class C
            {
                string? M(string s)
                {
                    var l = s.ToLowerCase();
 
                    [||]if (l == "hello")
                    {
                        return null;
                    }
 
                    return l;
 
                }
            }
            """, """
            class C
            {
                string? M(string s)
                {
                    var l = s.ToLowerCase();
 
                    if (l != "hello")
                    {
                        return l;
                    }
 
                    return null;
 
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42715")]
    public async Task PreserveSpacing_WithComments()
    {
        await TestAsync("""
            class C
            {
                string? M(string s)
                {
                    var l = s.ToLowerCase();
 
                    [||]if (l == "hello")
                    {
                        // null 1
                        return null; // null 2
                        // null 3
                    }
 
                    // l 1
                    return l; // l 2
                    // l 3
 
                }
            }
            """, """
            class C
            {
                string? M(string s)
                {
                    var l = s.ToLowerCase();
 
                    if (l != "hello")
                    {
                        // l 1
                        return l; // l 2
                        // null 3
                    }
 
                    // null 1
                    return null; // null 2
                    // l 3
 
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42715")]
    public async Task PreserveSpacing_NoTrivia()
    {
        await TestAsync("""
            class C
            {
                string? M(bool b)
                {[||]if(b){return(true);}return(false);}
            }
            """, """
            class C
            {
                string? M(bool b)
                { if (!b) { return (false); } return (true); }
            }
            """);
    }
}