|
// 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.CodeStyle;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.GenerateConstructorFromMembers;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings;
using Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics.NamingStyles;
using Microsoft.CodeAnalysis.PickMembers;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.GenerateConstructorFromMembers;
[Trait(Traits.Feature, Traits.Features.CodeActionsGenerateConstructorFromMembers)]
public sealed class GenerateConstructorFromMembersTests : AbstractCSharpCodeActionTest
{
protected override CodeRefactoringProvider CreateCodeRefactoringProvider(EditorTestWorkspace workspace, TestParameters parameters)
=> new CSharpGenerateConstructorFromMembersCodeRefactoringProvider((IPickMembersService)parameters.fixProviderData);
private readonly NamingStylesTestOptionSets options = new(LanguageNames.CSharp);
[Fact]
public async Task TestSingleField()
{
await TestInRegularAndScriptAsync(
"""
using System.Collections.Generic;
class Z
{
[|int a;|]
}
""",
"""
using System.Collections.Generic;
class Z
{
int a;
public Z(int a{|Navigation:)|}
{
this.a = a;
}
}
""");
}
[Fact]
public async Task TestSingleFieldWithCodeStyle()
{
await TestInRegularAndScriptAsync(
"""
using System.Collections.Generic;
class Z
{
[|int a;|]
}
""",
"""
using System.Collections.Generic;
class Z
{
int a;
public Z(int a{|Navigation:)|} => this.a = a;
}
""",
options: Option(CSharpCodeStyleOptions.PreferExpressionBodiedConstructors, CSharpCodeStyleOptions.WhenPossibleWithSilentEnforcement));
}
[Fact]
public async Task TestUseExpressionBodyWhenOnSingleLine_AndIsSingleLine()
{
await TestInRegularAndScriptAsync(
"""
using System.Collections.Generic;
class Z
{
[|int a;|]
}
""",
"""
using System.Collections.Generic;
class Z
{
int a;
public Z(int a{|Navigation:)|} => this.a = a;
}
""",
options: Option(CSharpCodeStyleOptions.PreferExpressionBodiedConstructors, CSharpCodeStyleOptions.WhenOnSingleLineWithSilentEnforcement));
}
[Fact]
public async Task TestUseExpressionBodyWhenOnSingleLine_AndIsNotSingleLine()
{
await TestInRegularAndScriptAsync(
"""
using System.Collections.Generic;
class Z
{
[|int a;
int b;|]
}
""",
"""
using System.Collections.Generic;
class Z
{
int a;
int b;
public Z(int a, int b{|Navigation:)|}
{
this.a = a;
this.b = b;
}
}
""",
options: Option(CSharpCodeStyleOptions.PreferExpressionBodiedConstructors, CSharpCodeStyleOptions.WhenOnSingleLineWithSilentEnforcement));
}
[Fact]
public async Task TestMultipleFields()
{
await TestInRegularAndScriptAsync(
"""
using System.Collections.Generic;
class Z
{
[|int a;
string b;|]
}
""",
"""
using System.Collections.Generic;
class Z
{
int a;
string b;
public Z(int a, string b{|Navigation:)|}
{
this.a = a;
this.b = b;
}
}
""");
}
[Fact]
public async Task TestMultipleFields_VerticalSelection()
{
await TestInRegularAndScriptAsync(
"""
using System.Collections.Generic;
class Z
{[|
int a;
string b;|]
}
""",
"""
using System.Collections.Generic;
class Z
{
int a;
string b;
public Z(int a, string b{|Navigation:)|}
{
this.a = a;
this.b = b;
}
}
""");
}
[Fact]
public async Task TestMultipleFields_VerticalSelectionUpToExcludedField()
{
await TestInRegularAndScriptAsync(
"""
using System.Collections.Generic;
class Z
{
int a;[|
string b;
string c;|]
}
""",
"""
using System.Collections.Generic;
class Z
{
int a;
string b;
string c;
public Z(string b, string c{|Navigation:)|}
{
this.b = b;
this.c = c;
}
}
""");
}
[Fact]
public async Task TestMultipleFields_VerticalSelectionUpToMethod()
{
await TestInRegularAndScriptAsync(
"""
using System.Collections.Generic;
class Z
{
void Goo() { }[|
int a;
string b;|]
}
""",
"""
using System.Collections.Generic;
class Z
{
void Goo() { }
int a;
string b;
public Z(int a, string b{|Navigation:)|}
{
this.a = a;
this.b = b;
}
}
""");
}
[Fact]
public async Task TestMultipleFields_SelectionIncludingClassOpeningBrace()
{
await TestMissingAsync(
"""
using System.Collections.Generic;
class Z
[|{
int a;
string b;|]
}
""");
}
[Fact]
public async Task TestSecondField()
{
await TestInRegularAndScriptAsync(
"""
using System.Collections.Generic;
class Z
{
int a;
[|string b;|]
public Z(int a)
{
this.a = a;
}
}
""",
"""
using System.Collections.Generic;
class Z
{
int a;
string b;
public Z(int a)
{
this.a = a;
}
public Z(string b{|Navigation:)|}
{
this.b = b;
}
}
""");
}
[Fact]
public async Task TestFieldAssigningConstructor()
{
await TestInRegularAndScriptAsync(
"""
using System.Collections.Generic;
class Z
{
[|int a;
string b;|]
public Z(int a)
{
this.a = a;
}
}
""",
"""
using System.Collections.Generic;
class Z
{
int a;
string b;
public Z(int a)
{
this.a = a;
}
public Z(int a, string b{|Navigation:)|}
{
this.a = a;
this.b = b;
}
}
""");
}
[Fact]
public async Task TestFieldAssigningConstructor2()
{
await TestInRegularAndScriptAsync(
"""
using System.Collections.Generic;
class Z
{
[|int a;
string b;|]
public Z(int a)
{
this.a = a;
}
}
""",
"""
using System.Collections.Generic;
class Z
{
int a;
string b;
public Z(int a)
{
this.a = a;
}
public Z(int a, string b{|Navigation:)|}
{
this.a = a;
this.b = b;
}
}
""");
}
[Fact]
public async Task TestDelegatingConstructor()
{
await TestInRegularAndScriptAsync(
"""
using System.Collections.Generic;
class Z
{
[|int a;
string b;|]
public Z(int a)
{
this.a = a;
}
}
""",
"""
using System.Collections.Generic;
class Z
{
int a;
string b;
public Z(int a)
{
this.a = a;
}
public Z(int a, string b{|Navigation:)|} : this(a)
{
this.b = b;
}
}
""",
index: 1);
}
[Fact]
public async Task TestDelegatingConstructorWithNullabilityDifferences()
{
// For this test we have a problem: the existing constructor has different nullability than
// the underlying field. We will still offer to use the delegating constructor even though it has a nullability issue
// the user can then easily fix. If they don't want that, they can also just use the first option.
await TestInRegularAndScriptAsync(
"""
#nullable enable
using System.Collections.Generic;
class Z
{
[|string? a;
int b;|]
public Z(string a)
{
this.a = a;
}
}
""",
"""
#nullable enable
using System.Collections.Generic;
class Z
{
string? a;
int b;
public Z(string a)
{
this.a = a;
}
public Z(string? a, int b{|Navigation:)|} : this(a)
{
this.b = b;
}
}
""",
index: 1);
}
[Fact]
public async Task TestMissingWithExistingConstructor()
{
await TestMissingInRegularAndScriptAsync(
"""
using System.Collections.Generic;
class Z
{
[|int a;
string b;|]
public Z(int a)
{
this.a = a;
}
public Z(int a, string b{|Navigation:)|}
{
this.a = a;
this.b = b;
}
}
""");
}
[Fact]
public async Task TestMultipleProperties()
{
await TestInRegularAndScriptAsync(
"""
class Z
{
[|public int A { get; private set; }
public string B { get; private set; }|]
}
""",
"""
class Z
{
public Z(int a, string b{|Navigation:)|}
{
A = a;
B = b;
}
public int A { get; private set; }
public string B { get; private set; }
}
""");
}
[Fact]
public async Task TestMultiplePropertiesWithQualification()
{
await TestInRegularAndScriptAsync(
"""
class Z
{
[|public int A { get; private set; }
public string B { get; private set; }|]
}
""",
"""
class Z
{
public Z(int a, string b{|Navigation:)|}
{
this.A = a;
this.B = b;
}
public int A { get; private set; }
public string B { get; private set; }
}
""", options: Option(CodeStyleOptions2.QualifyPropertyAccess, true, NotificationOption2.Error));
}
[Fact]
public async Task TestStruct()
{
await TestInRegularAndScriptAsync(
"""
using System.Collections.Generic;
struct S
{
[|int i;|]
}
""",
"""
using System.Collections.Generic;
struct S
{
int i;
public S(int i{|Navigation:)|}
{
this.i = i;
}
}
""");
}
[Fact]
public async Task TestStructInitializingAutoProperty()
{
await TestInRegularAndScriptAsync(
"""
using System.Collections.Generic;
struct S
{
[|int i { get; set; }|]
}
""",
"""
using System.Collections.Generic;
struct S
{
public S(int i{|Navigation:)|}
{
this.i = i;
}
int i { get; set; }
}
""");
}
[Fact]
public async Task TestStructNotInitializingAutoProperty()
{
await TestInRegularAndScriptAsync(
"""
using System.Collections.Generic;
struct S
{
[|int i { get => f; set => f = value; }|]
int j { get; set; }
}
""",
"""
using System.Collections.Generic;
struct S
{
public S(int i{|Navigation:)|} : this()
{
this.i = i;
}
int i { get => f; set => f = value; }
int j { get; set; }
}
""");
}
[Fact]
public async Task TestStruct2()
{
await TestInRegularAndScriptAsync(
"""
using System.Collections.Generic;
struct S
{
int i { get; set; }
[|int y;|]
}
""",
"""
using System.Collections.Generic;
struct S
{
int i { get; set; }
int y;
public S(int y{|Navigation:)|} : this()
{
this.y = y;
}
}
""");
}
[Fact]
public async Task TestStruct3()
{
await TestInRegularAndScriptAsync(
"""
using System.Collections.Generic;
struct S
{
[|int i { get; set; }|]
int y;
}
""",
"""
using System.Collections.Generic;
struct S
{
int i { get; set; }
int y;
public S(int i{|Navigation:)|} : this()
{
this.i = i;
}
}
""");
}
[Fact]
public async Task TestGenericType()
{
await TestInRegularAndScriptAsync(
"""
using System.Collections.Generic;
class Program<T>
{
[|int i;|]
}
""",
"""
using System.Collections.Generic;
class Program<T>
{
int i;
public Program(int i{|Navigation:)|}
{
this.i = i;
}
}
""");
}
[Fact]
public async Task TestSmartTagText1()
{
await TestSmartTagTextAsync(
"""
using System.Collections.Generic;
class Program
{
[|bool b;
HashSet<string> s;|]
}
""",
string.Format(CodeFixesResources.Generate_constructor_0_1, "Program", "bool b, HashSet<string> s"));
}
[Fact]
public async Task TestSmartTagText2()
{
await TestSmartTagTextAsync(
"""
using System.Collections.Generic;
class Program
{
[|bool b;
HashSet<string> s;|]
public Program(bool b)
{
this.b = b;
}
}
""",
string.Format(CodeFixesResources.Generate_field_assigning_constructor_0_1, "Program", "bool b, HashSet<string> s"));
}
[Fact]
public async Task TestSmartTagText3()
{
await TestSmartTagTextAsync(
"""
using System.Collections.Generic;
class Program
{
[|bool b;
HashSet<string> s;|]
public Program(bool b)
{
this.b = b;
}
}
""",
string.Format(FeaturesResources.Generate_delegating_constructor_0_1, "Program", "bool b, HashSet<string> s"),
index: 1);
}
[Fact]
public async Task TestContextualKeywordName()
{
await TestInRegularAndScriptAsync(
"""
class Program
{
[|int yield;|]
}
""",
"""
class Program
{
int yield;
public Program(int yield{|Navigation:)|}
{
this.yield = yield;
}
}
""");
}
[Fact]
public async Task TestGenerateConstructorNotOfferedForDuplicate()
{
await TestMissingInRegularAndScriptAsync(
"""
using System;
class X
{
public X(string v)
{
}
static void Test()
{
new X(new [|string|]());
}
}
""");
}
[Fact]
public async Task Tuple()
{
await TestInRegularAndScriptAsync(
"""
using System.Collections.Generic;
class Z
{
[|(int, string) a;|]
}
""",
"""
using System.Collections.Generic;
class Z
{
(int, string) a;
public Z((int, string) a{|Navigation:)|}
{
this.a = a;
}
}
""");
}
[Fact]
public async Task NullableReferenceType()
{
await TestInRegularAndScriptAsync(
"""
#nullable enable
class Z
{
[|string? a;|]
}
""",
"""
#nullable enable
class Z
{
string? a;
public Z(string? a{|Navigation:)|}
{
this.a = a;
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14219")]
public async Task TestUnderscoreInName1()
{
await TestInRegularAndScriptAsync(
"""
class Program
{
[|int _field;|]
}
""",
"""
class Program
{
int _field;
public Program(int field{|Navigation:)|}
{
_field = field;
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/62162")]
public async Task TestUnderscoreInName_KeepIfNameWithoutUnderscoreIsInvalid()
{
await TestInRegularAndScriptAsync(
"""
class Program
{
[|int _0;|]
}
""",
"""
class Program
{
int _0;
public Program(int _0{|Navigation:)|}
{
this._0 = _0;
}
}
""");
}
[Theory, WorkItem("https://github.com/dotnet/roslyn/issues/62162")]
[InlineData('m')]
[InlineData('s')]
[InlineData('t')]
public async Task TestCommonPatternInName_KeepUnderscoreIfNameWithoutItIsInvalid(char commonPatternChar)
{
await TestInRegularAndScriptAsync(
$@"class Program
{{
[|int {commonPatternChar}_0;|]
}}",
$@"class Program
{{
int {commonPatternChar}_0;
public Program(int _0{{|Navigation:)|}}
{{
{commonPatternChar}_0 = _0;
}}
}}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14219")]
public async Task TestUnderscoreInName_PreferThis()
{
await TestInRegularAndScriptAsync(
"""
class Program
{
[|int _field;|]
}
""",
"""
class Program
{
int _field;
public Program(int field{|Navigation:)|}
{
this._field = field;
}
}
""",
options: Option(CodeStyleOptions2.QualifyFieldAccess, CodeStyleOption2.TrueWithSuggestionEnforcement));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/13944")]
public async Task TestGetter_Only_Auto_Props()
{
await TestInRegularAndScriptAsync(
"""
abstract class Contribution
{
[|public string Title { get; }
public int Number { get; }|]
}
""",
"""
abstract class Contribution
{
protected Contribution(string title, int number{|Navigation:)|}
{
Title = title;
Number = number;
}
public string Title { get; }
public int Number { get; }
}
""",
options: Option(CodeStyleOptions2.QualifyFieldAccess, CodeStyleOption2.TrueWithSuggestionEnforcement));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/13944")]
public async Task TestAbstract_Getter_Only_Auto_Props()
{
await TestMissingInRegularAndScriptAsync(
"""
abstract class Contribution
{
[|public abstract string Title { get; }
public int Number { get; }|]
}
""",
new TestParameters(options: Option(CodeStyleOptions2.QualifyFieldAccess, CodeStyleOption2.TrueWithSuggestionEnforcement)));
}
[Fact]
public async Task TestSingleFieldWithDialog()
{
await TestWithPickMembersDialogAsync(
"""
using System.Collections.Generic;
class Z
{
int a;
[||]
}
""",
"""
using System.Collections.Generic;
class Z
{
int a;
public Z(int a{|Navigation:)|}
{
this.a = a;
}
}
""",
chosenSymbols: ["a"]);
}
[Fact]
public async Task TestSingleFieldWithDialog2()
{
await TestWithPickMembersDialogAsync(
"""
using System.Collections.Generic;
class [||]Z
{
int a;
}
""",
"""
using System.Collections.Generic;
class Z
{
int a;
public Z(int a{|Navigation:)|}
{
this.a = a;
}
}
""",
chosenSymbols: ["a"]);
}
[Fact]
public async Task TestMissingOnClassAttributes()
{
await TestMissingInRegularAndScriptAsync(
"""
using System.Collections.Generic;
[X][||]
class Z
{
int a;
}
""");
}
[Fact]
public async Task TestPickNoFieldWithDialog()
{
await TestWithPickMembersDialogAsync(
"""
using System.Collections.Generic;
class Z
{
int a;
[||]
}
""",
"""
using System.Collections.Generic;
class Z
{
int a;
public Z({|Navigation:)|}
{
}
}
""",
chosenSymbols: []);
}
[Fact]
public async Task TestReorderFieldsWithDialog()
{
await TestWithPickMembersDialogAsync(
"""
using System.Collections.Generic;
class Z
{
int a;
string b;
[||]
}
""",
"""
using System.Collections.Generic;
class Z
{
int a;
string b;
public Z(string b, int a{|Navigation:)|}
{
this.b = b;
this.a = a;
}
}
""",
chosenSymbols: ["b", "a"]);
}
[Fact]
public async Task TestAddNullChecks1()
{
await TestWithPickMembersDialogAsync(
"""
using System;
using System.Collections.Generic;
class Z
{
int a;
string b;
[||]
}
""",
"""
using System;
using System.Collections.Generic;
class Z
{
int a;
string b;
public Z(int a, string b{|Navigation:)|}
{
this.a = a;
this.b = b ?? throw new ArgumentNullException(nameof(b));
}
}
""",
chosenSymbols: ["a", "b"],
optionsCallback: options => options[0].Value = true);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41428")]
public async Task TestAddNullChecksWithNullableReferenceType()
{
await TestWithPickMembersDialogAsync(
"""
using System;
using System.Collections.Generic;
#nullable enable
class Z
{
int a;
string b;
string? c;
[||]
}
""",
"""
using System;
using System.Collections.Generic;
#nullable enable
class Z
{
int a;
string b;
string? c;
public Z(int a, string b, string? c{|Navigation:)|}
{
this.a = a;
this.b = b ?? throw new ArgumentNullException(nameof(b));
this.c = c;
}
}
""",
chosenSymbols: ["a", "b", "c"],
optionsCallback: options => options[0].Value = true);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41428")]
public async Task TestAddNullChecksWithNullableReferenceTypeForGenerics()
{
await TestWithPickMembersDialogAsync(
"""
using System;
using System.Collections.Generic;
#nullable enable
class Z<T> where T : class
{
int a;
string b;
T? c;
[||]
}
""",
"""
using System;
using System.Collections.Generic;
#nullable enable
class Z<T> where T : class
{
int a;
string b;
T? c;
public Z(int a, string b, T? c{|Navigation:)|}
{
this.a = a;
this.b = b ?? throw new ArgumentNullException(nameof(b));
this.c = c;
}
}
""",
chosenSymbols: ["a", "b", "c"],
optionsCallback: options => options[0].Value = true);
}
[Fact]
public async Task TestAddNullChecks2()
{
await TestWithPickMembersDialogAsync(
"""
using System;
using System.Collections.Generic;
class Z
{
int a;
string b;
[||]
}
""",
"""
using System;
using System.Collections.Generic;
class Z
{
int a;
string b;
public Z(int a, string b{|Navigation:)|}
{
if (b is null)
{
throw new ArgumentNullException(nameof(b));
}
this.a = a;
this.b = b;
}
}
""",
chosenSymbols: ["a", "b"],
optionsCallback: options => options[0].Value = true,
parameters: new TestParameters(options:
Option(CSharpCodeStyleOptions.PreferThrowExpression, CodeStyleOption2.FalseWithSilentEnforcement)));
}
[Fact]
public async Task TestAddNullChecks3()
{
await TestWithPickMembersDialogAsync(
"""
using System;
using System.Collections.Generic;
class Z
{
int a;
int? b;
[||]
}
""",
"""
using System;
using System.Collections.Generic;
class Z
{
int a;
int? b;
public Z(int a, int? b{|Navigation:)|}
{
this.a = a;
this.b = b;
}
}
""",
chosenSymbols: ["a", "b"],
optionsCallback: options => options[0].Value = true,
parameters: new TestParameters(options:
Option(CSharpCodeStyleOptions.PreferThrowExpression, CodeStyleOption2.FalseWithSilentEnforcement)));
}
[Fact]
public async Task TestAddNullChecks_CSharp6()
{
await TestWithPickMembersDialogAsync(
"""
using System;
using System.Collections.Generic;
class Z
{
int a;
string b;
[||]
}
""",
"""
using System;
using System.Collections.Generic;
class Z
{
int a;
string b;
public Z(int a, string b{|Navigation:)|}
{
if (b == null)
{
throw new ArgumentNullException(nameof(b));
}
this.a = a;
this.b = b;
}
}
""",
chosenSymbols: ["a", "b"],
optionsCallback: options => options[0].Value = true,
parameters: new TestParameters(
parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6),
options: Option(CSharpCodeStyleOptions.PreferThrowExpression, CodeStyleOption2.FalseWithSilentEnforcement)));
}
[Fact]
public async Task TestMissingOnMember1()
{
await TestMissingInRegularAndScriptAsync(
"""
using System.Collections.Generic;
class Z
{
int a;
string b;
[||]public void M() { }
}
""");
}
[Fact]
public async Task TestMissingOnMember2()
{
await TestMissingInRegularAndScriptAsync(
"""
using System.Collections.Generic;
class Z
{
int a;
string b;
public void M()
{
}[||]
public void N() { }
}
""");
}
[Fact]
public async Task TestMissingOnMember3()
{
await TestMissingInRegularAndScriptAsync(
"""
using System.Collections.Generic;
class Z
{
int a;
string b;
public void M()
{
[||]
}
public void N() { }
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/pull/21067")]
public async Task TestFinalCaretPosition()
{
await TestInRegularAndScriptAsync(
"""
using System.Collections.Generic;
class Z
{
[|int a;|]
}
""",
"""
using System.Collections.Generic;
class Z
{
int a;
public Z(int a{|Navigation:)|}
{
this.a = a;
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20595")]
public async Task ProtectedConstructorShouldBeGeneratedForAbstractClass()
{
await TestInRegularAndScriptAsync(
"""
abstract class C
{
[|public int Prop { get; set; }|]
}
""",
"""
abstract class C
{
protected C(int prop{|Navigation:)|}
{
Prop = prop;
}
public int Prop { get; set; }
}
""",
options: Option(CodeStyleOptions2.QualifyFieldAccess, CodeStyleOption2.TrueWithSuggestionEnforcement));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17643")]
public async Task TestWithDialogNoBackingField()
{
await TestWithPickMembersDialogAsync(
"""
class Program
{
public int F { get; set; }
[||]
}
""",
"""
class Program
{
public int F { get; set; }
public Program(int f{|Navigation:)|}
{
F = f;
}
}
""",
chosenSymbols: null);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25690")]
public async Task TestWithDialogNoIndexer()
{
await TestWithPickMembersDialogAsync(
"""
class Program
{
public int P { get => 0; set { } }
public int this[int index] { get => 0; set { } }
[||]
}
""",
"""
class Program
{
public int P { get => 0; set { } }
public int this[int index] { get => 0; set { } }
public Program(int p{|Navigation:)|}
{
P = p;
}
}
""",
chosenSymbols: null);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
public async Task TestWithDialogSetterOnlyProperty()
{
await TestWithPickMembersDialogAsync(
"""
class Program
{
public int P { get => 0; set { } }
public int S { set { } }
[||]
}
""",
"""
class Program
{
public int P { get => 0; set { } }
public int S { set { } }
public Program(int p, int s{|Navigation:)|}
{
P = p;
S = s;
}
}
""",
chosenSymbols: null);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33601")]
public async Task TestPartialFieldSelection()
{
await TestInRegularAndScriptAsync(
"""
class Z
{
int [|a|];
}
""",
"""
class Z
{
int a;
public Z(int a{|Navigation:)|}
{
this.a = a;
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33601")]
public async Task TestPartialFieldSelection2()
{
await TestInRegularAndScriptAsync(
"""
class Z
{
int [|a|]bcdefg;
}
""",
"""
class Z
{
int abcdefg;
public Z(int abcdefg{|Navigation:)|}
{
this.abcdefg = abcdefg;
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33601")]
public async Task TestPartialFieldSelection3()
{
await TestInRegularAndScriptAsync(
"""
class Z
{
int abcdef[|g|];
}
""",
"""
class Z
{
int abcdefg;
public Z(int abcdefg{|Navigation:)|}
{
this.abcdefg = abcdefg;
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33601")]
public async Task TestPartialFieldSelectionBeforeIdentifier()
{
await TestInRegularAndScript1Async(
"""
class Z
{
int [||]a;
}
""",
"""
class Z
{
int a;
public Z(int a{|Navigation:)|}
{
this.a = a;
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33601")]
public async Task TestPartialFieldSelectionAfterIdentifier()
{
await TestInRegularAndScript1Async(
"""
class Z
{
int a[||];
}
""",
"""
class Z
{
int a;
public Z(int a{|Navigation:)|}
{
this.a = a;
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33601")]
public async Task TestPartialFieldSelectionIdentifierNotSelected()
{
await TestMissingAsync(
"""
class Z
{
in[|t|] a;
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33601")]
public async Task TestPartialFieldSelectionIdentifierNotSelected2()
{
await TestMissingAsync(
"""
class Z
{
int a [|= 3|];
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33601")]
public async Task TestMultiplePartialFieldSelection()
{
await TestInRegularAndScriptAsync(
"""
class Z
{
int [|a;
int b|];
}
""",
"""
class Z
{
int a;
int b;
public Z(int a, int b{|Navigation:)|}
{
this.a = a;
this.b = b;
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33601")]
public async Task TestMultiplePartialFieldSelection2()
{
await TestInRegularAndScriptAsync(
"""
class Z
{
int [|a = 2;
int|] b;
}
""",
"""
class Z
{
int a = 2;
int b;
public Z(int a{|Navigation:)|}
{
this.a = a;
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33601")]
public async Task TestMultiplePartialFieldSelection3_1()
{
await TestInRegularAndScriptAsync(
"""
class Z
{
int [|a|] = 2, b = 3;
}
""",
"""
class Z
{
int a = 2, b = 3;
public Z(int a{|Navigation:)|}
{
this.a = a;
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33601")]
public async Task TestMultiplePartialFieldSelection3_2()
{
await TestInRegularAndScriptAsync(
"""
class Z
{
int [|a = 2, b|] = 3;
}
""",
"""
class Z
{
int a = 2, b = 3;
public Z(int a, int b{|Navigation:)|}
{
this.a = a;
this.b = b;
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33601")]
public async Task TestMultiplePartialFieldSelection4()
{
await TestMissingAsync(
"""
class Z
{
int a = [|2|], b = 3;
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36741")]
public async Task TestNoFieldNamingStyle()
{
await TestInRegularAndScriptAsync(
"""
class Z
{
int [|a|] = 2;
}
""",
"""
class Z
{
int a = 2;
public Z(int p_a{|Navigation:)|}
{
a = p_a;
}
}
""", options: options.ParameterNamesAreCamelCaseWithPUnderscorePrefix);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36741")]
public async Task TestCommonFieldNamingStyle()
{
await TestInRegularAndScriptAsync(
"""
class Z
{
int [|s_a|] = 2;
}
""",
"""
class Z
{
int s_a = 2;
public Z(int p_a{|Navigation:)|}
{
s_a = p_a;
}
}
""", options: options.ParameterNamesAreCamelCaseWithPUnderscorePrefix);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36741")]
public async Task TestSpecifiedNamingStyle()
{
await TestInRegularAndScriptAsync(
"""
class Z
{
int [|field_a|] = 2;
}
""",
"""
class Z
{
int field_a = 2;
public Z(int p_a_End{|Navigation:)|}
{
field_a = p_a_End;
}
}
""", options: options.MergeStyles(options.FieldNamesAreCamelCaseWithFieldUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36741")]
public async Task TestSpecifiedAndCommonFieldNamingStyle()
{
await TestInRegularAndScriptAsync(
"""
class Z
{
int [|field_s_a|] = 2;
}
""",
"""
class Z
{
int field_s_a = 2;
public Z(int p_a_End{|Navigation:)|}
{
field_s_a = p_a_End;
}
}
""", options: options.MergeStyles(options.FieldNamesAreCamelCaseWithFieldUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36741")]
public async Task TestSpecifiedAndCommonFieldNamingStyle2()
{
await TestInRegularAndScriptAsync(
"""
class Z
{
int [|s_field_a|] = 2;
}
""",
"""
class Z
{
int s_field_a = 2;
public Z(int p_a_End{|Navigation:)|}
{
s_field_a = p_a_End;
}
}
""", options: options.MergeStyles(options.FieldNamesAreCamelCaseWithFieldUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36741")]
public async Task TestBaseNameEmpty()
{
await TestMissingAsync(
"""
class Z
{
int [|field__End|] = 2;
}
""", new TestParameters(options: options.MergeStyles(options.FieldNamesAreCamelCaseWithFieldUnderscorePrefixAndUnderscoreEndSuffix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix)));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36741")]
public async Task TestSomeBaseNamesEmpty()
{
await TestInRegularAndScriptAsync(
"""
class Z
{
int [|s_field_a = 2;
int field__End |]= 3;
}
""",
"""
class Z
{
int s_field_a = 2;
int field__End = 3;
public Z(int p_a{|Navigation:)|}
{
s_field_a = p_a;
}
}
""", options: options.MergeStyles(options.FieldNamesAreCamelCaseWithFieldUnderscorePrefixAndUnderscoreEndSuffix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45808")]
public async Task TestUnsafeField()
{
await TestInRegularAndScriptAsync(
"""
class Z
{
[|unsafe int* a;|]
}
""",
"""
class Z
{
unsafe int* a;
public unsafe Z(int* a{|Navigation:)|}
{
this.a = a;
}
}
""", compilationOptions: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: true));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45808")]
public async Task TestUnsafeFieldInUnsafeClass()
{
await TestInRegularAndScriptAsync(
"""
unsafe class Z
{
[|int* a;|]
}
""",
"""
unsafe class Z
{
int* a;
public Z(int* a{|Navigation:)|}
{
this.a = a;
}
}
""", compilationOptions: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: true));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/53467")]
public async Task TestMissingWhenTypeNotInCompilation()
{
await TestMissingAsync(
"""
<Workspace>
<Project Language="C#" AssemblyName="Assembly1">
<Document>
using System;
using System.Collections.Generic;
#nullable enable
<![CDATA[ class Z<T> where T : class ]]>
{
int a;
string b;
T? c;
[||]
}
</Document>
</Project>
</Workspace>
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29198")]
public async Task TestWithSelectedGetPropertyThatReturnsField1()
{
await TestInRegularAndScriptAsync(
"""
class Program
{
private int _value;
[|public int Goo
{
get { return _value; }
}|]
}
""",
"""
class Program
{
private int _value;
public Program(int value{|Navigation:)|}
{
_value = value;
}
public int Goo
{
get { return _value; }
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29198")]
public async Task TestWithSelectedGetPropertyThatReturnsField2()
{
await TestInRegularAndScriptAsync(
"""
class Program
{
private int _value;
[|public int Goo
{
get { return this._value; }
}|]
}
""",
"""
class Program
{
private int _value;
public Program(int value{|Navigation:)|}
{
_value = value;
}
public int Goo
{
get { return this._value; }
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29198")]
public async Task TestWithSelectedGetPropertyThatReturnsField3()
{
await TestInRegularAndScriptAsync(
"""
class Program
{
private int _value;
[|public int Goo
{
get => this._value;
}|]
}
""",
"""
class Program
{
private int _value;
public Program(int value{|Navigation:)|}
{
_value = value;
}
public int Goo
{
get => this._value;
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29198")]
public async Task TestWithSelectedGetPropertyThatReturnsField4()
{
await TestInRegularAndScriptAsync(
"""
class Program
{
private int _value;
[|public int Goo => this._value;|]
}
""",
"""
class Program
{
private int _value;
public Program(int value{|Navigation:)|}
{
_value = value;
}
public int Goo => this._value;
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29198")]
public async Task TestWithSelectedGetPropertyThatReturnsField5()
{
await TestInRegularAndScriptAsync(
"""
class Program
{
[|private int _value;
public int Goo
{
get { return _value; }
}|]
}
""",
"""
class Program
{
private int _value;
public Program(int value{|Navigation:)|}
{
_value = value;
}
public int Goo
{
get { return _value; }
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29198")]
public async Task TestWithSelectedGetPropertyThatReturnsField6()
{
await TestInRegularAndScriptAsync(
"""
class Program
{
private int _value;
[|public int Goo
{
get { return _value; }
set { _value = value; }
}|]
}
""",
"""
class Program
{
private int _value;
public Program(int goo{|Navigation:)|}
{
Goo = goo;
}
public int Goo
{
get { return _value; }
set { _value = value; }
}
}
""");
}
}
|