File: ReplacePropertyWithMethods\ReplacePropertyWithMethodsTests.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.CodeRefactorings;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings;
using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions;
using Microsoft.CodeAnalysis.ReplacePropertyWithMethods;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeActions.ReplacePropertyWithMethods;
 
[Trait(Traits.Feature, Traits.Features.CodeActionsReplacePropertyWithMethods)]
public sealed class ReplacePropertyWithMethodsTests : AbstractCSharpCodeActionTest_NoEditor
{
    private OptionsCollection PreferExpressionBodiedMethods
        => new(GetLanguage()) { { CSharpCodeStyleOptions.PreferExpressionBodiedMethods, CSharpCodeStyleOptions.WhenPossibleWithSuggestionEnforcement } };
 
    protected override CodeRefactoringProvider CreateCodeRefactoringProvider(TestWorkspace workspace, TestParameters parameters)
        => new ReplacePropertyWithMethodsCodeRefactoringProvider();
 
    [Fact]
    public async Task TestGetWithBody()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop
                {
                    get
                    {
                        return 0;
                    }
                }
            }
            """,
            """
            class C
            {
                private int GetProp()
                {
                    return 0;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestPublicProperty()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public int [||]Prop
                {
                    get
                    {
                        return 0;
                    }
                }
            }
            """,
            """
            class C
            {
                public int GetProp()
                {
                    return 0;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestAnonyousType1()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public int [||]Prop
                {
                    get
                    {
                        return 0;
                    }
                }
 
                public void M()
                {
                    var v = new { P = this.Prop } }
            }
            """,
            """
            class C
            {
                public int GetProp()
                {
                    return 0;
                }
 
                public void M()
                {
                    var v = new { P = this.GetProp() } }
            }
            """);
    }
 
    [Fact]
    public async Task TestAnonyousType2()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public int [||]Prop
                {
                    get
                    {
                        return 0;
                    }
                }
 
                public void M()
                {
                    var v = new { this.Prop } }
            }
            """,
            """
            class C
            {
                public int GetProp()
                {
                    return 0;
                }
 
                public void M()
                {
                    var v = new { Prop = this.GetProp() } }
            }
            """);
    }
 
    [Fact]
    public async Task TestPassedToRef1()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public int [||]Prop
                {
                    get
                    {
                        return 0;
                    }
                }
 
                public void RefM(ref int i)
                {
                }
 
                public void M()
                {
                    RefM(ref this.Prop);
                }
            }
            """,
            """
            class C
            {
                public int GetProp()
                {
                    return 0;
                }
 
                public void RefM(ref int i)
                {
                }
 
                public void M()
                {
                    RefM(ref this.{|Conflict:GetProp|}());
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestPassedToOut1()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public int [||]Prop
                {
                    get
                    {
                        return 0;
                    }
                }
 
                public void OutM(out int i)
                {
                }
 
                public void M()
                {
                    OutM(out this.Prop);
                }
            }
            """,
            """
            class C
            {
                public int GetProp()
                {
                    return 0;
                }
 
                public void OutM(out int i)
                {
                }
 
                public void M()
                {
                    OutM(out this.{|Conflict:GetProp|}());
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestUsedInAttribute1()
    {
        await TestInRegularAndScriptAsync(
            """
            using System;
 
            class CAttribute : Attribute
            {
                public int [||]Prop
                {
                    get
                    {
                        return 0;
                    }
                }
            }
 
            [C(Prop = 1)]
            class D
            {
            }
            """,
            """
            using System;
 
            class CAttribute : Attribute
            {
                public int GetProp()
                {
                    return 0;
                }
            }
 
            [C({|Conflict:Prop|} = 1)]
            class D
            {
            }
            """);
    }
 
    [Fact]
    public async Task TestSetWithBody1()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop
                {
                    set
                    {
                        var v = value;
                    }
                }
            }
            """,
            """
            class C
            {
                private void SetProp(int value)
                {
                    var v = value;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestSetReference1()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop
                {
                    set
                    {
                        var v = value;
                    }
                }
 
                void M()
                {
                    this.Prop = 1;
                }
            }
            """,
            """
            class C
            {
                private void SetProp(int value)
                {
                    var v = value;
                }
 
                void M()
                {
                    this.SetProp(1);
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestGetterAndSetter()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop
                {
                    get
                    {
                        return 0;
                    }
 
                    set
                    {
                        var v = value;
                    }
                }
            }
            """,
            """
            class C
            {
                private int GetProp()
                {
                    return 0;
                }
 
                private void SetProp(int value)
                {
                    var v = value;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestGetterAndSetterAccessibilityChange()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public int [||]Prop
                {
                    get
                    {
                        return 0;
                    }
 
                    private set
                    {
                        var v = value;
                    }
                }
            }
            """,
            """
            class C
            {
                public int GetProp()
                {
                    return 0;
                }
 
                private void SetProp(int value)
                {
                    var v = value;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestIncrement1()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop
                {
                    get
                    {
                        return 0;
                    }
 
                    set
                    {
                        var v = value;
                    }
                }
 
                void M()
                {
                    this.Prop++;
                }
            }
            """,
            """
            class C
            {
                private int GetProp()
                {
                    return 0;
                }
 
                private void SetProp(int value)
                {
                    var v = value;
                }
 
                void M()
                {
                    this.SetProp(this.GetProp() + 1);
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestDecrement2()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop
                {
                    get
                    {
                        return 0;
                    }
 
                    set
                    {
                        var v = value;
                    }
                }
 
                void M()
                {
                    this.Prop--;
                }
            }
            """,
            """
            class C
            {
                private int GetProp()
                {
                    return 0;
                }
 
                private void SetProp(int value)
                {
                    var v = value;
                }
 
                void M()
                {
                    this.SetProp(this.GetProp() - 1);
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestRecursiveGet()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop
                {
                    get
                    {
                        return this.Prop + 1;
                    }
                }
            }
            """,
            """
            class C
            {
                private int GetProp()
                {
                    return this.GetProp() + 1;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestRecursiveSet()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop
                {
                    set
                    {
                        this.Prop = value + 1;
                    }
                }
            }
            """,
            """
            class C
            {
                private void SetProp(int value)
                {
                    this.SetProp(value + 1);
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestCompoundAssign1()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop
                {
                    get
                    {
                        return 0;
                    }
 
                    set
                    {
                        var v = value;
                    }
                }
 
                void M()
                {
                    this.Prop *= x;
                }
            }
            """,
            """
            class C
            {
                private int GetProp()
                {
                    return 0;
                }
 
                private void SetProp(int value)
                {
                    var v = value;
                }
 
                void M()
                {
                    this.SetProp(this.GetProp() * x);
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestCompoundAssign2()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop
                {
                    get
                    {
                        return 0;
                    }
 
                    set
                    {
                        var v = value;
                    }
                }
 
                void M()
                {
                    this.Prop *= x + y;
                }
            }
            """,
            """
            class C
            {
                private int GetProp()
                {
                    return 0;
                }
 
                private void SetProp(int value)
                {
                    var v = value;
                }
 
                void M()
                {
                    this.SetProp(this.GetProp() * (x + y));
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41159")]
    public async Task TestCompoundAssign3()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                object [||]Prop
                {
                    get
                    {
                        return null;
                    }
 
                    set
                    {
                        var v = value;
                    }
                }
 
                void M()
                {
                    this.Prop ??= x;
                }
            }
            """,
            """
            class C
            {
                private object GetProp()
                {
                    return null;
                }
 
                private void SetProp(object value)
                {
                    var v = value;
                }
 
                void M()
                {
                    this.SetProp(this.GetProp() ?? x);
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41159")]
    public async Task TestCompoundAssign4()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop
                {
                    get
                    {
                        return 0;
                    }
 
                    set
                    {
                        var v = value;
                    }
                }
 
                void M()
                {
                    this.Prop >>= x;
                }
            }
            """,
            """
            class C
            {
                private int GetProp()
                {
                    return 0;
                }
 
                private void SetProp(int value)
                {
                    var v = value;
                }
 
                void M()
                {
                    this.SetProp(this.GetProp() >> x);
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41159")]
    public async Task TestCompoundAssign5()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop
                {
                    get
                    {
                        return 0;
                    }
 
                    set
                    {
                        var v = value;
                    }
                }
 
                void M()
                {
                    this.Prop >>>= x;
                }
            }
            """,
            """
            class C
            {
                private int GetProp()
                {
                    return 0;
                }
 
                private void SetProp(int value)
                {
                    var v = value;
                }
 
                void M()
                {
                    this.SetProp(this.GetProp() >>> x);
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestMissingAccessors()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop { }
 
                void M()
                {
                    var v = this.Prop;
                }
            }
            """,
            """
            class C
            {
 
                void M()
                {
                    var v = this.GetProp();
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestComputedProp()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop => 1;
            }
            """,
            """
            class C
            {
                private int GetProp()
                {
                    return 1;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestComputedPropWithTrailingTrivia()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop => 1; // Comment
            }
            """,
            """
            class C
            {
                private int GetProp()
                {
                    return 1; // Comment
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestIndentation()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Goo
                {
                    get
                    {
                        int count;
                        foreach (var x in y)
                        {
                            count += bar;
                        }
                        return count;
                    }
                }
            }
            """,
            """
            class C
            {
                private int GetGoo()
                {
                    int count;
                    foreach (var x in y)
                    {
                        count += bar;
                    }
                    return count;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestComputedPropWithTrailingTriviaAfterArrow()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public int [||]Prop => /* return 42 */ 42;
            }
            """,
            """
            class C
            {
                public int GetProp()
                {
                    /* return 42 */
                    return 42;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestAbstractProperty()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public abstract int [||]Prop { get; }
 
                public void M()
                {
                    var v = new { P = this.Prop } }
            }
            """,
            """
            class C
            {
                public abstract int GetProp();
 
                public void M()
                {
                    var v = new { P = this.GetProp() } }
            }
            """);
    }
 
    [Fact]
    public async Task TestVirtualProperty()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public virtual int [||]Prop
                {
                    get
                    {
                        return 1;
                    }
                }
 
                public void M()
                {
                    var v = new { P = this.Prop } }
            }
            """,
            """
            class C
            {
                public virtual int GetProp()
                {
                    return 1;
                }
 
                public void M()
                {
                    var v = new { P = this.GetProp() } }
            }
            """);
    }
 
    [Fact]
    public async Task TestInterfaceProperty()
    {
        await TestInRegularAndScriptAsync(
            """
            interface I
            {
                int [||]Prop { get; }
            }
            """,
            """
            interface I
            {
                int GetProp();
            }
            """);
    }
 
    [Fact]
    public async Task TestAutoProperty1()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public int [||]Prop { get; }
            }
            """,
            """
            class C
            {
                private readonly int prop;
 
                public int GetProp()
                {
                    return prop;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestAutoProperty2()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public int [||]Prop { get; }
 
                public C()
                {
                    this.Prop++;
                }
            }
            """,
            """
            class C
            {
                private readonly int prop;
 
                public int GetProp()
                {
                    return prop;
                }
 
                public C()
                {
                    this.prop = this.GetProp() + 1;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestAutoProperty3()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public int [||]Prop { get; }
 
                public C()
                {
                    this.Prop *= x + y;
                }
            }
            """,
            """
            class C
            {
                private readonly int prop;
 
                public int GetProp()
                {
                    return prop;
                }
 
                public C()
                {
                    this.prop = this.GetProp() * (x + y);
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestAutoProperty4()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public int [||]Prop { get; } = 1;
            }
            """,
            """
            class C
            {
                private readonly int prop = 1;
 
                public int GetProp()
                {
                    return prop;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestAutoProperty5()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                private int prop;
 
                public int [||]Prop { get; } = 1;
            }
            """,
            """
            class C
            {
                private int prop;
                private readonly int prop1 = 1;
 
                public int GetProp()
                {
                    return prop1;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestAutoProperty6()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public int [||]PascalCase { get; }
            }
            """,
            """
            class C
            {
                private readonly int pascalCase;
 
                public int GetPascalCase()
                {
                    return pascalCase;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestUniqueName1()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public int [||]Prop
                {
                    get
                    {
                        return 0;
                    }
                }
 
                public abstract int GetProp();
            }
            """,
            """
            class C
            {
                public int GetProp1()
                {
                    return 0;
                }
 
                public abstract int GetProp();
            }
            """);
    }
 
    [Fact]
    public async Task TestUniqueName2()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public int [||]Prop
                {
                    set
                    {
                    }
                }
 
                public abstract void SetProp(int i);
            }
            """,
            """
            class C
            {
                public void SetProp1(int value)
                {
                }
 
                public abstract void SetProp(int i);
            }
            """);
    }
 
    [Fact]
    public async Task TestUniqueName3()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public object [||]Prop
                {
                    set
                    {
                    }
                }
 
                public abstract void SetProp(dynamic i);
            }
            """,
            """
            class C
            {
                public void SetProp1(object value)
                {
                }
 
                public abstract void SetProp(dynamic i);
            }
            """);
    }
 
    [Fact]
    public async Task TestTrivia1()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop { get; set; }
 
                void M()
                {
 
                    Prop++;
                }
            }
            """,
            """
            class C
            {
                private int prop;
 
                private int GetProp()
                {
                    return prop;
                }
 
                private void SetProp(int value)
                {
                    prop = value;
                }
 
                void M()
                {
 
                    SetProp(GetProp() + 1);
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestTrivia2()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop { get; set; }
 
                void M()
                {
                    /* Leading */
                    Prop++; /* Trailing */
                }
            }
            """,
            """
            class C
            {
                private int prop;
 
                private int GetProp()
                {
                    return prop;
                }
 
                private void SetProp(int value)
                {
                    prop = value;
                }
 
                void M()
                {
                    /* Leading */
                    SetProp(GetProp() + 1); /* Trailing */
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestTrivia3()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop { get; set; }
 
                void M()
                {
                    /* Leading */
                    Prop += 1 /* Trailing */ ;
                }
            }
            """,
            """
            class C
            {
                private int prop;
 
                private int GetProp()
                {
                    return prop;
                }
 
                private void SetProp(int value)
                {
                    prop = value;
                }
 
                void M()
                {
                    /* Leading */
                    SetProp(GetProp() + 1 /* Trailing */ );
                }
            }
            """);
    }
 
    [Fact]
    public async Task ReplaceReadInsideWrite1()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop { get; set; }
 
                void M()
                {
                    Prop = Prop + 1;
                }
            }
            """,
            """
            class C
            {
                private int prop;
 
                private int GetProp()
                {
                    return prop;
                }
 
                private void SetProp(int value)
                {
                    prop = value;
                }
 
                void M()
                {
                    SetProp(GetProp() + 1);
                }
            }
            """);
    }
 
    [Fact]
    public async Task ReplaceReadInsideWrite2()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop { get; set; }
 
                void M()
                {
                    Prop *= Prop + 1;
                }
            }
            """,
            """
            class C
            {
                private int prop;
 
                private int GetProp()
                {
                    return prop;
                }
 
                private void SetProp(int value)
                {
                    prop = value;
                }
 
                void M()
                {
                    SetProp(GetProp() * (GetProp() + 1));
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16157")]
    public async Task TestWithConditionalBinding1()
    {
        await TestInRegularAndScriptAsync(
            """
            public class Goo
            {
                public bool [||]Any { get; } // Replace 'Any' with method
 
                public static void Bar()
                {
                    var goo = new Goo();
                    bool f = goo?.Any == true;
                }
            }
            """,
            """
            public class Goo
            {
                private readonly bool any;
 
                public bool GetAny()
                {
                    return any;
                }
 
                public static void Bar()
                {
                    var goo = new Goo();
                    bool f = goo?.GetAny() == true;
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16980")]
    public async Task TestCodeStyle1()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop
                {
                    get
                    {
                        return 0;
                    }
                }
            }
            """,
            """
            class C
            {
                private int GetProp() => 0;
            }
            """, options: PreferExpressionBodiedMethods);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16980")]
    public async Task TestCodeStyle2()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop
                {
                    get
                    {
                        return 0;
                    }
 
                    set
                    {
                        throw e;
                    }
                }
            }
            """,
            """
            class C
            {
                private int GetProp() => 0;
                private void SetProp(int value) => throw e;
            }
            """, options: PreferExpressionBodiedMethods);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16980")]
    public async Task TestCodeStyle3()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop
                {
                    get => 0;
 
                    set => throw e;
                }
            }
            """,
            """
            class C
            {
                private int GetProp() => 0;
                private void SetProp(int value) => throw e;
            }
            """, options: PreferExpressionBodiedMethods);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16980")]
    public async Task TestCodeStyle4()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop => 0;
            }
            """,
            """
            class C
            {
                private int GetProp() => 0;
            }
            """, options: PreferExpressionBodiedMethods);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16980")]
    public async Task TestCodeStyle5()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop { get; }
            }
            """,
            """
            class C
            {
                private readonly int prop;
 
                private int GetProp() => prop;
            }
            """, options: PreferExpressionBodiedMethods);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16980")]
    public async Task TestCodeStyle6()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop { get; set; }
            }
            """,
            """
            class C
            {
                private int prop;
 
                private int GetProp() => prop;
                private void SetProp(int value) => prop = value;
            }
            """, options: PreferExpressionBodiedMethods);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16980")]
    public async Task TestCodeStyle7()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop
                {
                    get
                    {
                        A();
                        return B();
                    }
                }
            }
            """,
            """
            class C
            {
                private int GetProp()
                {
                    A();
                    return B();
                }
            }
            """, options: PreferExpressionBodiedMethods);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18234")]
    public async Task TestDocumentationComment1()
    {
        await TestInRegularAndScriptAsync(
            """
            internal interface ILanguageServiceHost
            {
                /// <summary>
                ///     Gets the active workspace project context that provides access to the language service for the active configured project.
                /// </summary>
                /// <value>
                ///     An value that provides access to the language service for the active configured project.
                /// </value>
                object [||]ActiveProjectContext
                {
                    get;
                }
            }
            """,
            """
            internal interface ILanguageServiceHost
            {
                /// <summary>
                ///     Gets the active workspace project context that provides access to the language service for the active configured project.
                /// </summary>
                /// <returns>
                ///     An value that provides access to the language service for the active configured project.
                /// </returns>
                object GetActiveProjectContext();
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18234")]
    public async Task TestDocumentationComment2()
    {
        await TestInRegularAndScriptAsync(
            """
            internal interface ILanguageServiceHost
            {
                /// <summary>
                ///     Sets the active workspace project context that provides access to the language service for the active configured project.
                /// </summary>
                /// <value>
                ///     An value that provides access to the language service for the active configured project.
                /// </value>
                object [||]ActiveProjectContext
                {
                    set;
                }
            }
            """,
            """
            internal interface ILanguageServiceHost
            {
                /// <summary>
                ///     Sets the active workspace project context that provides access to the language service for the active configured project.
                /// </summary>
                /// <param name="value">
                ///     An value that provides access to the language service for the active configured project.
                /// </param>
                void SetActiveProjectContext(object value);
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18234")]
    public async Task TestDocumentationComment3()
    {
        await TestInRegularAndScriptAsync(
            """
            internal interface ILanguageServiceHost
            {
                /// <summary>
                ///     Gets or sets the active workspace project context that provides access to the language service for the active configured project.
                /// </summary>
                /// <value>
                ///     An value that provides access to the language service for the active configured project.
                /// </value>
                object [||]ActiveProjectContext
                {
                    get; set;
                }
            }
            """,
            """
            internal interface ILanguageServiceHost
            {
                /// <summary>
                ///     Gets or sets the active workspace project context that provides access to the language service for the active configured project.
                /// </summary>
                /// <returns>
                ///     An value that provides access to the language service for the active configured project.
                /// </returns>
                object GetActiveProjectContext();
                void SetActiveProjectContext(object value);
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18234")]
    public async Task TestDocumentationComment4()
    {
        await TestInRegularAndScriptAsync(
            """
            internal interface ILanguageServiceHost
            {
                /// <summary>
                ///     Sets <see cref="ActiveProjectContext"/>.
                /// </summary>
                /// <seealso cref="ActiveProjectContext"/>
                object [||]ActiveProjectContext
                {
                    set;
                }
            }
            internal struct AStruct
            {
                /// <seealso cref="ILanguageServiceHost.ActiveProjectContext"/>
                private int x;
            }
            """,
            """
            internal interface ILanguageServiceHost
            {
                /// <summary>
                ///     Sets <see cref="SetActiveProjectContext(object)"/>.
                /// </summary>
                /// <seealso cref="SetActiveProjectContext(object)"/>
                void SetActiveProjectContext(object value);
            }
            internal struct AStruct
            {
                /// <seealso cref="ILanguageServiceHost.SetActiveProjectContext(object)"/>
                private int x;
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18234")]
    public async Task TestDocumentationComment5()
    {
        await TestInRegularAndScriptAsync(
            """
            internal interface ILanguageServiceHost
            {
                /// <summary>
                ///     Gets or sets <see cref="ActiveProjectContext"/>.
                /// </summary>
                /// <seealso cref="ActiveProjectContext"/>
                object [||]ActiveProjectContext
                {
                    get; set;
                }
            }
            internal struct AStruct
            {
                /// <seealso cref="ILanguageServiceHost.ActiveProjectContext"/>
                private int x;
            }
            """,
            """
            internal interface ILanguageServiceHost
            {
                /// <summary>
                ///     Gets or sets <see cref="GetActiveProjectContext()"/>.
                /// </summary>
                /// <seealso cref="GetActiveProjectContext()"/>
                object GetActiveProjectContext();
                void SetActiveProjectContext(object value);
            }
            internal struct AStruct
            {
                /// <seealso cref="ILanguageServiceHost.GetActiveProjectContext()"/>
                private int x;
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18234")]
    public async Task TestDocumentationComment6()
    {
        await TestInRegularAndScriptAsync(
            """
            internal interface ISomeInterface<T>
            {
                /// <seealso cref="Context"/>
                ISomeInterface<T> [||]Context
                {
                    set;
                }
            }
            internal struct AStruct
            {
                /// <seealso cref="ISomeInterface{T}.Context"/>
                private int x;
            }
            """,
            """
            internal interface ISomeInterface<T>
            {
                /// <seealso cref="SetContext(ISomeInterface{T})"/>
                void SetContext(ISomeInterface<T> value);
            }
            internal struct AStruct
            {
                /// <seealso cref="ISomeInterface{T}.SetContext(ISomeInterface{T})"/>
                private int x;
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19235")]
    public async Task TestWithDirectives1()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop
                {
                    get
                    {
            #if true
                        return 0;
            #else
                        return 1;
            #endif
                    }
                }
            }
            """,
"""
class C
{
    private int GetProp()
    {
#if true
        return 0;
#else
            return 1;
#endif
    }
}
""");
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19235")]
    public async Task TestWithDirectives2()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop
                {
                    get
                    {
            #if true
                        return 0;
            #else
                        return 1;
            #endif
                    }
                }
            }
            """,
"""
class C
{
    private int GetProp() =>
#if true
            0;
#else
            return 1;
#endif
}
""",
options: PreferExpressionBodiedMethods);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19235")]
    public async Task TestWithDirectives3()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop =>
            #if true
                    0;
            #else
                    1;
            #endif
            }
            """,
            """
            class C
            {
                private int GetProp() =>
            #if true
                    0;
            #else
                    1;
            #endif
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19235")]
    public async Task TestWithDirectives4()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int [||]Prop =>
            #if true
                    0;
            #else
                    1;
            #endif
            }
            """,
            """
            class C
            {
                private int GetProp() =>
            #if true
                    0;
            #else
                    1;
            #endif
            }
            """,
options: PreferExpressionBodiedMethods);
    }
 
    [Fact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/440371")]
    public async Task TestExplicitInterfaceImplementation()
    {
        await TestInRegularAndScriptAsync(
            """
            interface IGoo
            {
                int [||]Goo { get; set; }
            }
 
            class C : IGoo
            {
                int IGoo.Goo
                {
                    get
                    {
                        throw new System.NotImplementedException();
                    }
 
                    set
                    {
                        throw new System.NotImplementedException();
                    }
                }
            }
            """,
            """
            interface IGoo
            {
                int GetGoo();
                void SetGoo(int value);
            }
 
            class C : IGoo
            {
                int IGoo.GetGoo()
                {
                    throw new System.NotImplementedException();
                }
 
                void IGoo.SetGoo(int value)
                {
                    throw new System.NotImplementedException();
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38379")]
    public async Task TestUnsafeExpressionBody()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public unsafe void* [||]Pointer => default;
            }
            """,
            """
            class C
            {
                public unsafe void* GetPointer()
                {
                    return default;
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38379")]
    public async Task TestUnsafeAutoProperty()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public unsafe void* [||]Pointer { get; set; }
            }
            """,
            """
            class C
            {
                private unsafe void* pointer;
 
                public unsafe void* GetPointer()
                {
                    return pointer;
                }
 
                public unsafe void SetPointer(void* value)
                {
                    pointer = value;
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38379")]
    public async Task TestUnsafeSafeType()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public unsafe int [||]P
                {
                    get => 0;
                    set {}
                }
            }
            """,
            """
            class C
            {
                public unsafe int GetP()
                {
                    return 0;
                }
 
                public unsafe void SetP(int value)
                { }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22760")]
    public async Task QualifyFieldAccessWhenNecessary1()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public int [||]Value { get; }
 
                public C(int value)
                {
                    Value = value;
                }
            }
            """,
            """
            class C
            {
                private readonly int value;
 
                public int GetValue()
                {
                    return value;
                }
 
                public C(int value)
                {
                    this.value = value;
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22760")]
    public async Task QualifyFieldAccessWhenNecessary2()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public int [||]Value { get; }
 
                public C(int value)
                {
                    this.Value = value;
                }
            }
            """,
            """
            class C
            {
                private readonly int value;
 
                public int GetValue()
                {
                    return value;
                }
 
                public C(int value)
                {
                    this.value = value;
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22760")]
    public async Task QualifyFieldAccessWhenNecessary3()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public static int [||]Value { get; }
 
                public static void Set(int value)
                {
                    Value = value;
                }
            }
            """,
            """
            class C
            {
                private static readonly int value;
 
                public static int GetValue()
                {
                    return value;
                }
 
                public static void Set(int value)
                {
                    C.value = value;
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45171")]
    public async Task TestReferenceInObjectInitializer()
    {
        await TestInRegularAndScriptAsync(
            """
            public class Tweet
            {
                public string [||]Tweet { get; }
            }
 
            class C
            {
                void Main()
                {
                    var t = new Tweet();
                    var t1 = new Tweet
                    {
                        Tweet = t.Tweet
                    };
                }
            }
            """,
            """
            public class Tweet
            {
                private readonly string tweet;
 
                public string GetTweet()
                {
                    return tweet;
                }
            }
 
            class C
            {
                void Main()
                {
                    var t = new Tweet();
                    var t1 = new Tweet
                    {
                        {|Conflict:Tweet|} = t.GetTweet()
                    };
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45171")]
    public async Task TestReferenceInImplicitObjectInitializer()
    {
        await TestInRegularAndScriptAsync(
            """
            public class Tweet
            {
                public string [||]Tweet { get; }
            }
 
            class C
            {
                void Main()
                {
                    var t = new Tweet();
                    Tweet t1 = new()
                    {
                        Tweet = t.Tweet
                    };
                }
            }
            """,
            """
            public class Tweet
            {
                private readonly string tweet;
 
                public string GetTweet()
                {
                    return tweet;
                }
            }
 
            class C
            {
                void Main()
                {
                    var t = new Tweet();
                    Tweet t1 = new()
                    {
                        {|Conflict:Tweet|} = t.GetTweet()
                    };
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45171")]
    public async Task TestReferenceInWithInitializer()
    {
        await TestInRegularAndScriptAsync(
            """
            public class Tweet
            {
                public string [||]Tweet { get; }
            }
 
            class C
            {
                void Main()
                {
                    var t = new Tweet();
                    var t1 = t with
                    {
                        Tweet = t.Tweet
                    };
                }
            }
            """,
            """
            public class Tweet
            {
                private readonly string tweet;
 
                public string GetTweet()
                {
                    return tweet;
                }
            }
 
            class C
            {
                void Main()
                {
                    var t = new Tweet();
                    var t1 = t with
                    {
                        {|Conflict:Tweet|} = t.GetTweet()
                    };
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/57376")]
    public async Task TestInLinkedFile()
    {
        await TestInRegularAndScriptAsync(
            """
            <Workspace>
                <Project Language='C#' CommonReferences='true' AssemblyName='LinkedProj' Name='CSProj.1'>
                    <Document FilePath='C.cs'>
            class C
            {
                int [||]Prop
                {
                    set
                    {
                        var v = value;
                    }
                }
 
                void M()
                {
                    this.Prop = 1;
                }
            }
                    </Document>
                </Project>
                <Project Language='C#' CommonReferences='true' AssemblyName='LinkedProj' Name='CSProj.2'>
                    <Document IsLinkFile='true' LinkProjectName='CSProj.1' LinkFilePath='C.cs'/>
                </Project>
            </Workspace>
            """,
            """
            <Workspace>
                <Project Language='C#' CommonReferences='true' AssemblyName='LinkedProj' Name='CSProj.1'>
                    <Document FilePath='C.cs'>
            class C
            {
                private void SetProp(int value)
                {
                    var v = value;
                }
 
                void M()
                {
                    this.SetProp(1);
                }
            }
                    </Document>
                </Project>
                <Project Language='C#' CommonReferences='true' AssemblyName='LinkedProj' Name='CSProj.2'>
                    <Document IsLinkFile='true' LinkProjectName='CSProj.1' LinkFilePath='C.cs'/>
                </Project>
            </Workspace>
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25367")]
    public async Task TestAccessorAttributes1()
    {
        await TestInRegularAndScriptAsync(
            """
            using System;
            using System.Runtime.CompilerServices;
 
            class Program
            {
                static void Main() { }
 
                private static int [||]SomeValue
                {
                    [MethodImpl(MethodImplOptions.AggressiveInlining)]
                    get => 42;
                }
            }
            """,
            """
            using System;
            using System.Runtime.CompilerServices;
 
            class Program
            {
                static void Main() { }
 
                [MethodImpl(MethodImplOptions.AggressiveInlining)]
                private static int GetSomeValue()
                {
                    return 42;
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25367")]
    public async Task TestAccessorAttributes2()
    {
        await TestInRegularAndScriptAsync(
            """
            using System;
            using System.Runtime.CompilerServices;
 
            class Program
            {
                static void Main() { }
 
                private static int [||]SomeValue
                {
                    [MethodImpl(MethodImplOptions.AggressiveInlining)]
                    get => 42;
 
                    [OtherAttribute]
                    set { }
                }
            }
            """,
            """
            using System;
            using System.Runtime.CompilerServices;
 
            class Program
            {
                static void Main() { }
 
                [MethodImpl(MethodImplOptions.AggressiveInlining)]
                private static int GetSomeValue()
                {
                    return 42;
                }
 
                [OtherAttribute]
                private static void SetSomeValue(int value)
                { }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75135")]
    public async Task TestMatchInPropertyPattern()
    {
        await TestInRegularAndScriptAsync("""
            class C
            {
                public int [||]Property { get { return 0; } }
                public bool M()
                {
                    return this is { Property: 1 };
                }
            }
            """, """
            class C
            {
                public int GetProperty()
                { return 0; }
                public bool M()
                {
                    return this is { {|Conflict:Property|}: 1 };
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75999")]
    public async Task TestInterfacePropertyWithImplementation()
    {
        await TestInRegularAndScriptAsync(
            """
            interface I
            {
                public virtual string [||]Name
                {
                    get
                    {
                        return string.Empty;
                    }
                }
            }
            """,
            """
            interface I
            {
                public virtual string GetName()
                {
                    return string.Empty;
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75186")]
    public async Task DoNotDuplicatePreprocessorDirective1()
    {
        await TestInRegularAndScriptAsync("""
            class A
            {
                #region
                static bool a;
                #endregion
                static bool [||]B => true;
            }
            """, """
            class A
            {
                #region
                static bool a;
                #endregion
                private static bool GetB()
                {
                    return true;
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75186")]
    public async Task DoNotDuplicatePreprocessorDirective2()
    {
        await TestInRegularAndScriptAsync("""
            class A
            {
                #region
                static bool a;
                #endregion
                static bool [||]B { get { return 0; } set { } }
            }
            """, """
            class A
            {
                #region
                static bool a;
                #endregion
                private static bool GetB()
                { return 0; }
 
                private static void SetB(bool value)
                { }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75186")]
    public async Task DoNotDuplicatePreprocessorDirective3()
    {
        await TestInRegularAndScriptAsync("""
            class A
            {
                #region
                static bool a;
                #endregion
                static bool [||]B { get; }
            }
            """, """
            class A
            {
                #region
                static bool a;
                private static readonly bool b;
                #endregion
                private static bool GetB()
                {
                    return b;
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75186")]
    public async Task DoNotDuplicatePreprocessorDirective4()
    {
        await TestInRegularAndScriptAsync("""
            class A
            {
                #region
                static bool a;
                #endregion
                static bool [||]B { get; set; }
            }
            """, """
            class A
            {
                #region
                static bool a;
                private static bool b;
                #endregion
                private static bool GetB()
                {
                    return b;
                }
 
                private static void SetB(bool value)
                {
                    b = value;
                }
            }
            """);
    }
}