diff --git a/src/EditorFeatures/CSharpTest/GenerateFromMembers/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersTests.cs b/src/EditorFeatures/CSharpTest/GenerateFromMembers/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersTests.cs index af80dcb4fb219..9f5ebf5920a23 100644 --- a/src/EditorFeatures/CSharpTest/GenerateFromMembers/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersTests.cs +++ b/src/EditorFeatures/CSharpTest/GenerateFromMembers/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersTests.cs @@ -1,7 +1,9 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Collections.Immutable; using System.Threading.Tasks; using Microsoft.CodeAnalysis.AddConstructorParametersFromMembers; +using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeRefactorings; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; @@ -17,7 +19,11 @@ public class AddConstructorParametersFromMembersTests : AbstractCSharpCodeAction protected override CodeRefactoringProvider CreateCodeRefactoringProvider(Workspace workspace, TestParameters parameters) => new AddConstructorParametersFromMembersCodeRefactoringProvider(); + protected override ImmutableArray MassageActions(ImmutableArray actions) + => FlattenActions(actions); + [WorkItem(308077, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/308077")] + [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestAdd1() { @@ -46,10 +52,11 @@ public Program(int i, string s) this.i = i; this.s = s; } -}"); +}", title: string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)")); } [WorkItem(308077, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/308077")] + [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestAddOptional1() { @@ -78,14 +85,15 @@ public Program(int i, string s = null) this.i = i; this.s = s; } -}", -index: 1); +}", index: 1, title: string.Format(FeaturesResources.Add_optional_parameters_to_0, "Program(int)")); } [WorkItem(308077, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/308077")] + [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestAddToConstructorWithMostMatchingParameters1() { + // behavior change with 33603, now all constructors offered await TestInRegularAndScriptAsync( @"using System.Collections.Generic; @@ -123,13 +131,15 @@ public Program(int i, string s, bool b) : this(i) this.s = s; this.b = b; } -}"); +}", index: 1, title: string.Format(FeaturesResources.Add_to_0, "Program(int, string)")); } [WorkItem(308077, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/308077")] + [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestAddOptionalToConstructorWithMostMatchingParameters1() { + // Behavior change with #33603, now all constructors are offered await TestInRegularAndScriptAsync( @"using System.Collections.Generic; @@ -167,8 +177,7 @@ public Program(int i, string s, bool b = false) : this(i) this.s = s; this.b = b; } -}", -index: 1); +}", index: 3, title: string.Format(FeaturesResources.Add_to_0, "Program(int, string)")); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] @@ -769,5 +778,434 @@ public C(int i, int j) }" ); } + + [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] + public async Task TestMultipleConstructors_FirstofThree() + { + var source = +@" +class C +{ + int [|l|]; + public C(int i) + { + } + public C(int i, int j) + { + } + public C(int i, int j, int k) + { + } +}"; + var expected = +@" +class C +{ + int l; + public C(int i, int l) + { + this.l = l; + } + public C(int i, int j) + { + } + public C(int i, int j, int k) + { + } +}"; + await TestInRegularAndScriptAsync(source, expected, index: 0, title: string.Format(FeaturesResources.Add_to_0, "C(int)")); + } + + [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] + public async Task TestMultipleConstructors_SecondOfThree() + { + var source = +@" +class C +{ + int [|l|]; + public C(int i) + { + } + public C(int i, int j) + { + } + public C(int i, int j, int k) + { + } +}"; + var expected = +@" +class C +{ + int l; + public C(int i) + { + } + public C(int i, int j, int l) + { + this.l = l; + } + public C(int i, int j, int k) + { + } +}"; + await TestInRegularAndScriptAsync(source, expected, index: 1, title: string.Format(FeaturesResources.Add_to_0, "C(int, int)")); + } + + [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] + public async Task TestMultipleConstructors_ThirdOfThree() + { + var source = +@" +class C +{ + int [|l|]; + public C(int i) + { + } + public C(int i, int j) + { + } + public C(int i, int j, int k) + { + } +}"; + + var expected = +@" +class C +{ + int l; + public C(int i) + { + } + public C(int i, int j) + { + } + public C(int i, int j, int k, int l) + { + this.l = l; + } +}"; + await TestInRegularAndScriptAsync(source, expected, index: 2, title: string.Format(FeaturesResources.Add_to_0, "C(int, int, int)")); + } + + [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] + public async Task TestMultipleConstructors_FirstOptionalOfThree() + { + var source = +@" +class C +{ + int [|l|]; + public C(int i) + { + } + public C(int i, int j) + { + } + public C(int i, int j, int k) + { + } +}"; + var expected = +@" +class C +{ + int l; + public C(int i, int l = 0) + { + this.l = l; + } + public C(int i, int j) + { + } + public C(int i, int j, int k) + { + } +}"; + await TestInRegularAndScriptAsync(source, expected, index: 3, title: string.Format(FeaturesResources.Add_to_0, "C(int)")); + } + + [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] + public async Task TestMultipleConstructors_SecondOptionalOfThree() + { + var source = +@" +class C +{ + int [|l|]; + public C(int i) + { + } + public C(int i, int j) + { + } + public C(int i, int j, int k) + { + } +}"; + var expected = +@" +class C +{ + int [|l|]; + public C(int i) + { + } + public C(int i, int j, int l = 0) + { + this.l = l; + } + public C(int i, int j, int k) + { + } +}"; + await TestInRegularAndScriptAsync(source, expected, index: 4, title: string.Format(FeaturesResources.Add_to_0, "C(int, int)")); + } + + [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] + public async Task TestMultipleConstructors_ThirdOptionalOfThree() + { + var source = +@" +class C +{ + int [|l|]; + public C(int i) + { + } + public C(int i, int j) + { + } + public C(int i, int j, int k) + { + } +}"; + var expected = +@" +class C +{ + int [|l|]; + public C(int i) + { + } + public C(int i, int j) + { + } + public C(int i, int j, int k, int l = 0) + { + this.l = l; + } +}"; + await TestInRegularAndScriptAsync(source, expected, index: 5, title: string.Format(FeaturesResources.Add_to_0, "C(int, int, int)")); + } + + [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] + public async Task TestMultipleConstructors_OneMustBeOptional() + { + var source = +@" +class C +{ + int [|l|]; + + // index 0 as required + // index 2 as optional + public C(int i) + { + } + + // index 3 as optional + public C(int i, double j = 0) + { + } + + // index 1 as required + // index 4 as optional + public C(int i, double j, int k) + { + } +}"; + var expected = +@" +class C +{ + int [|l|]; + + // index 0 as required + // index 2 as optional + public C(int i) + { + } + + // index 3 as optional + public C(int i, double j = 0) + { + } + + // index 1 as required + // index 4 as optional + public C(int i, double j, int k, int l) + { + this.l = l; + } +}"; + await TestInRegularAndScriptAsync(source, expected, index: 1, title: string.Format(FeaturesResources.Add_to_0, "C(int, double, int)")); + } + + [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] + public async Task TestMultipleConstructors_OneMustBeOptional2() + { + var source = +@" +class C +{ + int [|l|]; + + // index 0, and 2 as optional + public C(int i) + { + } + + // index 3 as optional + public C(int i, double j = 0) + { + } + + // index 1, and 4 as optional + public C(int i, double j, int k) + { + } +}"; + var expected = +@" +class C +{ + int [|l|]; + + // index 0, and 2 as optional + public C(int i) + { + } + + // index 3 as optional + public C(int i, double j = 0, int l = 0) + { + this.l = l; + } + + // index 1, and 4 as optional + public C(int i, double j, int k) + { + } +}"; + await TestInRegularAndScriptAsync(source, expected, index: 3, title: string.Format(FeaturesResources.Add_to_0, "C(int, double)")); + } + + [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] + public async Task TestMultipleConstructors_AllMustBeOptional() + { + var source = +@" +class C +{ + int [|p|]; + public C(int i = 0) + { + } + public C(double j, int k = 0) + { + } + public C(int l, double m, int n = 0) + { + } +}"; + var expected = +@" +class C +{ + int [|p|]; + public C(int i = 0, int p = 0) + { + this.p = p; + } + public C(double j, int k = 0) + { + } + public C(int l, double m, int n = 0) + { + } +}"; + await TestInRegularAndScriptAsync(source, expected, index: 0, title: string.Format(FeaturesResources.Add_to_0, "C(int)")); + } + + [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] + public async Task TestMultipleConstructors_AllMustBeOptional2() + { + var source = +@" +class C +{ + int [|p|]; + public C(int i = 0) + { + } + public C(double j, int k = 0) + { + } + public C(int l, double m, int n = 0) + { + } +}"; + var expected = +@" +class C +{ + int [|p|]; + public C(int i = 0) + { + } + public C(double j, int k = 0) + { + } + public C(int l, double m, int n = 0, int p = 0) + { + this.p = p; + } +}"; + await TestInRegularAndScriptAsync(source, expected, index: 2, title: string.Format(FeaturesResources.Add_to_0, "C(int, double, int)")); + } + + [WorkItem(33623, "https://github.com/dotnet/roslyn/issues/33623")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] + public async Task TestDeserializationConstructor() + { + await TestMissingAsync( +@" +using System; +using System.Runtime.Serialization; + +class C : ISerializable +{ + int [|i|]; + + private C(SerializationInfo info, StreamingContext context) + { + } +} +"); + } } -} \ No newline at end of file +} diff --git a/src/EditorFeatures/TestUtilities/CodeActions/AbstractCodeActionOrUserDiagnosticTest.cs b/src/EditorFeatures/TestUtilities/CodeActions/AbstractCodeActionOrUserDiagnosticTest.cs index 3e44cbb8b626a..0020db53d5bf4 100644 --- a/src/EditorFeatures/TestUtilities/CodeActions/AbstractCodeActionOrUserDiagnosticTest.cs +++ b/src/EditorFeatures/TestUtilities/CodeActions/AbstractCodeActionOrUserDiagnosticTest.cs @@ -37,6 +37,7 @@ public struct TestParameters internal readonly int index; internal readonly CodeActionPriority? priority; internal readonly bool retainNonFixableDiagnostics; + internal readonly string title; internal TestParameters( ParseOptions parseOptions = null, @@ -45,7 +46,8 @@ internal TestParameters( object fixProviderData = null, int index = 0, CodeActionPriority? priority = null, - bool retainNonFixableDiagnostics = false) + bool retainNonFixableDiagnostics = false, + string title = null) { this.parseOptions = parseOptions; this.compilationOptions = compilationOptions; @@ -54,16 +56,17 @@ internal TestParameters( this.index = index; this.priority = priority; this.retainNonFixableDiagnostics = retainNonFixableDiagnostics; + this.title = title; } public TestParameters WithParseOptions(ParseOptions parseOptions) - => new TestParameters(parseOptions, compilationOptions, options, fixProviderData, index, priority); + => new TestParameters(parseOptions, compilationOptions, options, fixProviderData, index, priority, title: title); public TestParameters WithFixProviderData(object fixProviderData) - => new TestParameters(parseOptions, compilationOptions, options, fixProviderData, index, priority); + => new TestParameters(parseOptions, compilationOptions, options, fixProviderData, index, priority, title: title); public TestParameters WithIndex(int index) - => new TestParameters(parseOptions, compilationOptions, options, fixProviderData, index, priority); + => new TestParameters(parseOptions, compilationOptions, options, fixProviderData, index, priority, title: title); } protected abstract string GetLanguage(); @@ -323,11 +326,12 @@ internal Task TestInRegularAndScriptAsync( CompilationOptions compilationOptions = null, IDictionary options = null, object fixProviderData = null, - ParseOptions parseOptions = null) + ParseOptions parseOptions = null, + string title = null) { return TestInRegularAndScript1Async( initialMarkup, expectedMarkup, index, priority, - new TestParameters(parseOptions, compilationOptions, options, fixProviderData, index)); + new TestParameters(parseOptions, compilationOptions, options, fixProviderData, index, title: title)); } internal async Task TestInRegularAndScript1Async( @@ -524,6 +528,11 @@ internal static Task> VerifyActionAndGetOper Assert.Equal(parameters.priority.Value, action.Priority); } + if (parameters.title != null) + { + Assert.Equal(parameters.title, action.Title); + } + return action.GetOperationsAsync(CancellationToken.None); } diff --git a/src/EditorFeatures/VisualBasicTest/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersTests.vb b/src/EditorFeatures/VisualBasicTest/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersTests.vb index 94aac4825a3ce..14371e68c67d7 100644 --- a/src/EditorFeatures/VisualBasicTest/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersTests.vb +++ b/src/EditorFeatures/VisualBasicTest/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersTests.vb @@ -1,6 +1,8 @@ -' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis.AddConstructorParametersFromMembers +Imports Microsoft.CodeAnalysis.CodeActions Imports Microsoft.CodeAnalysis.CodeRefactorings Imports Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.CodeRefactorings @@ -12,7 +14,12 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.AddConstructorPara Return New AddConstructorParametersFromMembersCodeRefactoringProvider() End Function + Protected Overrides Function MassageActions(actions As ImmutableArray(Of CodeAction)) As ImmutableArray(Of CodeAction) + Return FlattenActions(actions) + End Function + + Public Async Function TestAdd1() As Task Await TestInRegularAndScriptAsync( @@ -30,10 +37,11 @@ End Class", Me.i = i Me.s = s End Sub -End Class") +End Class", title:=String.Format(FeaturesResources.Add_parameters_to_0, "Program(Integer)")) End Function + Public Async Function TestAddOptional1() As Task Await TestInRegularAndScriptAsync( @@ -51,13 +59,14 @@ End Class", Me.i = i Me.s = s End Sub -End Class", -index:=1) +End Class", index:=1, title:=String.Format(FeaturesResources.Add_optional_parameters_to_0, "Program(Integer)")) End Function + Public Async Function TestAddToConstructorWithMostMatchingParameters1() As Task + ' behavior change with 33603, now all constructors offered Await TestInRegularAndScriptAsync( "Class Program [|Private i As Integer @@ -83,12 +92,14 @@ End Class", Me.s = s Me.b = b End Sub -End Class") +End Class", index:=1, title:=String.Format(FeaturesResources.Add_to_0, "Program(Integer, String)")) End Function + Public Async Function TestAddOptionalToConstructorWithMostMatchingParameters1() As Task + ' behavior change with 33603, now all constructors offered Await TestInRegularAndScriptAsync( "Class Program [|Private i As Integer @@ -114,8 +125,7 @@ End Class", Me.s = s Me.b = b End Sub -End Class", -index:=1) +End Class", index:=3, title:=String.Format(FeaturesResources.Add_to_0, "Program(Integer, String)")) End Function @@ -304,5 +314,252 @@ End Class", End Sub End Class") End Function + + + + Public Async Function TestMultipleConstructors_FirstOfThree() As Task + Await TestInRegularAndScriptAsync( +"Class Program + Private [|l|] As Integer + + Public Sub New(i As Integer) + Me.i = i + End Sub + + Public Sub New(i As Integer, j As Integer) + End Sub + + Public Sub New(i As Integer, j As Integer, k As Integer) + End Sub +End Class", +"Class Program + Private [|l|] As Integer + + Public Sub New(i As Integer, l As Integer) + Me.i = i + Me.l = l + End Sub + + Public Sub New(i As Integer, j As Integer) + End Sub + + Public Sub New(i As Integer, j As Integer, k As Integer) + End Sub +End Class", index:=0, title:=String.Format(FeaturesResources.Add_to_0, "Program(Integer)")) + End Function + + + + Public Async Function TestMultipleConstructors_SecondOfThree() As Task + Await TestInRegularAndScriptAsync( +"Class Program + Private [|l|] As Integer + + Public Sub New(i As Integer) + Me.i = i + End Sub + + Public Sub New(i As Integer, j As Integer) + End Sub + + Public Sub New(i As Integer, j As Integer, k As Integer) + End Sub +End Class", +"Class Program + Private [|l|] As Integer + + Public Sub New(i As Integer) + Me.i = i + End Sub + + Public Sub New(i As Integer, j As Integer, l As Integer) + Me.l = l + End Sub + + Public Sub New(i As Integer, j As Integer, k As Integer) + End Sub +End Class", index:=1, title:=String.Format(FeaturesResources.Add_to_0, "Program(Integer, Integer)")) + End Function + + + + Public Async Function TestMultipleConstructors_ThirdOfThree() As Task + Await TestInRegularAndScriptAsync( +"Class Program + Private [|l|] As Integer + + Public Sub New(i As Integer) + Me.i = i + End Sub + + Public Sub New(i As Integer, j As Integer) + End Sub + + Public Sub New(i As Integer, j As Integer, k As Integer) + End Sub +End Class", +"Class Program + Private [|l|] As Integer + + Public Sub New(i As Integer) + Me.i = i + End Sub + + Public Sub New(i As Integer, j As Integer) + End Sub + + Public Sub New(i As Integer, j As Integer, k As Integer, l As Integer) + Me.l = l + End Sub +End Class", index:=2, title:=String.Format(FeaturesResources.Add_to_0, "Program(Integer, Integer, Integer)")) + End Function + + + + Public Async Function TestMultipleConstructors_OneMustBeOptional() As Task + Await TestInRegularAndScriptAsync( +"Class Program + Private [|l|] As Integer + + ' index 0 as required + ' index 2 as optional + Public Sub New(i As Integer) + Me.i = i + End Sub + + ' index 3 as optional + Public Sub New(Optional j As Double = Nothing) + End Sub + + ' index 1 as required + ' index 4 as optional + Public Sub New(i As Integer, j As Double) + End Sub +End Class", +"Class Program + Private [|l|] As Integer + + ' index 0 as required + ' index 2 as optional + Public Sub New(i As Integer) + Me.i = i + End Sub + + ' index 3 as optional + Public Sub New(Optional j As Double = Nothing) + End Sub + + ' index 1 as required + ' index 4 as optional + Public Sub New(i As Integer, j As Double, l As Integer) + Me.l = l + End Sub +End Class", index:=1, title:=String.Format(FeaturesResources.Add_to_0, "Program(Integer, Double)")) + End Function + + + + Public Async Function TestMultipleConstructors_OneMustBeOptional2() As Task + Await TestInRegularAndScriptAsync( +"Class Program + Private [|l|] As Integer + + ' index 0, and 2 as optional + Public Sub New(i As Integer) + Me.i = i + End Sub + + ' index 3 as optional + Public Sub New(Optional j As Double = Nothing) + End Sub + + ' index 1, and 4 as optional + Public Sub New(i As Integer, j As Double) + End Sub +End Class", +"Class Program + Private [|l|] As Integer + + ' index 0, and 2 as optional + Public Sub New(i As Integer) + Me.i = i + End Sub + + ' index 3 as optional + Public Sub New(Optional j As Double = Nothing, Optional l As Integer = Nothing) + Me.l = l + End Sub + + ' index 1, and 4 as optional + Public Sub New(i As Integer, j As Double) + End Sub +End Class", index:=3, title:=String.Format(FeaturesResources.Add_to_0, "Program(Double)")) + End Function + + + + Public Async Function TestMultipleConstructors_AllMustBeOptional1() As Task + Await TestInRegularAndScriptAsync( +"Class Program + Private [|p|] As Integer + + Public Sub New(Optional i As Integer = Nothing) + Me.i = i + End Sub + + Public Sub New(j As Double, Optional k As Double = Nothing) + End Sub + + Public Sub New(l As Integer, m As Integer, Optional n As Integer = Nothing) + End Sub +End Class", +"Class Program + Private p As Integer + + Public Sub New(Optional i As Integer = Nothing, Optional p As Integer = Nothing) + Me.i = i + Me.p = p + End Sub + + Public Sub New(j As Double, Optional k As Double = Nothing) + End Sub + + Public Sub New(l As Integer, m As Integer, Optional n As Integer = Nothing) + End Sub +End Class", index:=0, title:=String.Format(FeaturesResources.Add_to_0, "Program(Integer)")) + End Function + + + + Public Async Function TestMultipleConstructors_AllMustBeOptional2() As Task + Await TestInRegularAndScriptAsync( +"Class Program + Private [|p|] As Integer + + Public Sub New(Optional i As Integer = Nothing) + Me.i = i + End Sub + + Public Sub New(j As Double, Optional k As Double = Nothing) + End Sub + + Public Sub New(l As Integer, m As Integer, Optional n As Integer = Nothing) + End Sub +End Class", +"Class Program + Private p As Integer + + Public Sub New(Optional i As Integer = Nothing) + Me.i = i + End Sub + + Public Sub New(j As Double, Optional k As Double = Nothing) + End Sub + + Public Sub New(l As Integer, m As Integer, Optional n As Integer = Nothing, Optional p As Integer = Nothing) + Me.p = p + End Sub +End Class", index:=2, title:=String.Format(FeaturesResources.Add_to_0, "Program(Integer, Integer, Integer)")) + End Function End Class -End Namespace \ No newline at end of file +End Namespace diff --git a/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.AddConstructorParametersCodeAction.cs b/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.AddConstructorParametersCodeAction.cs index 95e327be5c31e..3384d7843bf0d 100644 --- a/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.AddConstructorParametersCodeAction.cs +++ b/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.AddConstructorParametersCodeAction.cs @@ -19,32 +19,42 @@ internal partial class AddConstructorParametersFromMembersCodeRefactoringProvide { private class AddConstructorParametersCodeAction : CodeAction { - private readonly AddConstructorParametersFromMembersCodeRefactoringProvider _service; private readonly Document _document; - private readonly State _state; + private readonly ConstructorCandidate _constructorCandidate; + private readonly ISymbol _containingType; private readonly ImmutableArray _missingParameters; + /// + /// If there is more than one constructor, the suggested actions will be split into two sub menus, + /// one for regular parameters and one for optional. This boolean is used by the Title property + /// to determine if the code action should be given the complete title or the sub menu title + /// + private readonly bool _useSubMenuName; + public AddConstructorParametersCodeAction( - AddConstructorParametersFromMembersCodeRefactoringProvider service, Document document, - State state, - ImmutableArray missingParameters) + ConstructorCandidate constructorCandidate, + ISymbol containingType, + ImmutableArray missingParameters, + bool useSubMenuName) { - _service = service; _document = document; - _state = state; + _constructorCandidate = constructorCandidate; + _containingType = containingType; _missingParameters = missingParameters; + _useSubMenuName = useSubMenuName; } protected override Task GetChangedDocumentAsync(CancellationToken cancellationToken) { var workspace = _document.Project.Solution.Workspace; var declarationService = _document.GetLanguageService(); - var constructor = declarationService.GetDeclarations(_state.ConstructorToAddTo).Select(r => r.GetSyntax(cancellationToken)).First(); + var constructor = declarationService.GetDeclarations( + _constructorCandidate.Constructor).Select(r => r.GetSyntax(cancellationToken)).First(); var newConstructor = constructor; newConstructor = CodeGenerator.AddParameterDeclarations(newConstructor, _missingParameters, workspace); - newConstructor = CodeGenerator.AddStatements(newConstructor, CreateAssignStatements(_state), workspace) + newConstructor = CodeGenerator.AddStatements(newConstructor, CreateAssignStatements(_constructorCandidate), workspace) .WithAdditionalAnnotations(Formatter.Annotation); var syntaxTree = constructor.SyntaxTree; @@ -53,12 +63,12 @@ protected override Task GetChangedDocumentAsync(CancellationToken canc return Task.FromResult(_document.WithSyntaxRoot(newRoot)); } - private IEnumerable CreateAssignStatements(State state) + private IEnumerable CreateAssignStatements(ConstructorCandidate constructorCandidate) { var factory = _document.GetLanguageService(); for (var i = 0; i < _missingParameters.Length; ++i) { - var memberName = _state.MissingMembers[i].Name; + var memberName = constructorCandidate.MissingMembers[i].Name; var parameterName = _missingParameters[i].Name; yield return factory.ExpressionStatement( factory.AssignmentStatement( @@ -71,14 +81,20 @@ public override string Title { get { - var parameters = _state.ConstructorToAddTo.Parameters.Select(p => p.ToDisplayString(SimpleFormat)); + var parameters = _constructorCandidate.Constructor.Parameters.Select(p => p.ToDisplayString(SimpleFormat)); var parameterString = string.Join(", ", parameters); - var optional = _missingParameters[0].IsOptional; - var signature = $"{_state.ContainingType.Name}({parameterString})"; + var signature = $"{_containingType.Name}({parameterString})"; - return optional - ? string.Format(FeaturesResources.Add_optional_parameters_to_0, signature) - : string.Format(FeaturesResources.Add_parameters_to_0, signature); + if (_useSubMenuName) + { + return string.Format(FeaturesResources.Add_to_0, signature); + } + else + { + return _missingParameters[0].IsOptional + ? string.Format(FeaturesResources.Add_optional_parameters_to_0, signature) + : string.Format(FeaturesResources.Add_parameters_to_0, signature); + } } } } diff --git a/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.ConstructorCandidate.cs b/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.ConstructorCandidate.cs new file mode 100644 index 0000000000000..b8398dd24b72b --- /dev/null +++ b/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.ConstructorCandidate.cs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Immutable; + +namespace Microsoft.CodeAnalysis.AddConstructorParametersFromMembers +{ + internal partial class AddConstructorParametersFromMembersCodeRefactoringProvider + { + private readonly struct ConstructorCandidate + { + public readonly IMethodSymbol Constructor; + public readonly ImmutableArray MissingMembers; + public readonly ImmutableArray MissingParameters; + + public ConstructorCandidate(IMethodSymbol constructor, ImmutableArray missingMembers, ImmutableArray missingParameters) + { + Constructor = constructor; + MissingMembers = missingMembers; + MissingParameters = missingParameters; + } + } + } +} diff --git a/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.State.cs b/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.State.cs index 7aa4bbcaf633e..68ce9aa183882 100644 --- a/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.State.cs +++ b/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.State.cs @@ -2,8 +2,11 @@ using System.Collections.Immutable; using System.Linq; +using System.Threading; +using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.PooledObjects; +using Microsoft.CodeAnalysis.Shared.Utilities; namespace Microsoft.CodeAnalysis.AddConstructorParametersFromMembers { @@ -11,17 +14,18 @@ internal partial class AddConstructorParametersFromMembersCodeRefactoringProvide { private class State { - public IMethodSymbol ConstructorToAddTo { get; private set; } + public ImmutableArray ConstructorCandidates { get; private set; } public INamedTypeSymbol ContainingType { get; private set; } - public ImmutableArray MissingMembers { get; private set; } - public ImmutableArray MissingParameters { get; private set; } - public static State Generate( + public static async Task GenerateAsync( AddConstructorParametersFromMembersCodeRefactoringProvider service, - ImmutableArray selectedMembers) + ImmutableArray selectedMembers, + Document document, + CancellationToken cancellationToken) { var state = new State(); - if (!state.TryInitialize(service, selectedMembers)) + if (!await state.TryInitializeAsync( + service, selectedMembers, document, cancellationToken).ConfigureAwait(false)) { return null; } @@ -29,81 +33,100 @@ public static State Generate( return state; } - private bool TryInitialize( + private async Task TryInitializeAsync( AddConstructorParametersFromMembersCodeRefactoringProvider service, - ImmutableArray selectedMembers) + ImmutableArray selectedMembers, + Document document, + CancellationToken cancellationToken) { - if (!selectedMembers.All(IsWritableInstanceFieldOrProperty)) + ContainingType = selectedMembers[0].ContainingType; + if (!selectedMembers.All(IsWritableInstanceFieldOrProperty) || + ContainingType == null || + ContainingType.TypeKind == TypeKind.Interface) { return false; } - this.ContainingType = selectedMembers[0].ContainingType; - if (this.ContainingType == null || this.ContainingType.TypeKind == TypeKind.Interface) - { - return false; - } + ConstructorCandidates = await GetConstructorCandidatesInfoAsync( + ContainingType, service, selectedMembers, document, cancellationToken).ConfigureAwait(false); - var parameters = service.DetermineParameters(selectedMembers); - // We are trying to add these parameters into an existing constructor's parameter list. - // Comparing parameters based on names to make sure parameter list won't contains duplicate parameters after we - // append the new parameters - this.ConstructorToAddTo = GetDelegatedConstructorBasedOnParameterNames(this.ContainingType, parameters); + return !ConstructorCandidates.IsEmpty; + } - if (this.ConstructorToAddTo == null) - { - return false; - } + /// + /// Try to find all constructors in whose parameters + /// are a subset of the selected members by comparing name. + /// These constructors will not be considered as potential candidates: + /// - if the constructor's parameter list contains 'ref' or 'params' + /// - any constructor that has a params[] parameter + /// - deserialization constructor + /// - implicit default constructor + /// + private async Task> GetConstructorCandidatesInfoAsync( + INamedTypeSymbol containingType, + AddConstructorParametersFromMembersCodeRefactoringProvider service, + ImmutableArray selectedMembers, + Document document, + CancellationToken cancellationToken) + { + var parametersForSelectedMembers = service.DetermineParameters(selectedMembers); + var applicableConstructors = ArrayBuilder.GetInstance(); - var zippedParametersAndSelectedMembers = parameters.Zip(selectedMembers, (parameter, selectedMember) => (parameter, selectedMember)); - var missingParametersBuilder = ArrayBuilder.GetInstance(); - var missingMembersBuilder = ArrayBuilder.GetInstance(); - var constructorParamNames = this.ConstructorToAddTo.Parameters.SelectAsArray(p => p.Name); - foreach ((var parameter, var selectedMember) in zippedParametersAndSelectedMembers) + foreach (var constructor in containingType.InstanceConstructors) { - if (!constructorParamNames.Contains(parameter.Name)) + if (await IsApplicableConstructorAsync( + constructor, document, parametersForSelectedMembers.SelectAsArray(p => p.Name), cancellationToken).ConfigureAwait(false)) { - missingParametersBuilder.Add(parameter); - missingMembersBuilder.Add(selectedMember); + applicableConstructors.Add(CreateConstructorCandidate(parametersForSelectedMembers, selectedMembers, constructor)); } } - this.MissingParameters = missingParametersBuilder.ToImmutableAndFree(); - this.MissingMembers = missingMembersBuilder.ToImmutableAndFree(); - - return MissingParameters.Length != 0; + return applicableConstructors.ToImmutableAndFree(); } - /// - /// Try to find a constructor in whose parameters is the subset of by comparing name. - /// If multiple constructors meet the condition, the one with more parameters will be returned. - /// It will not consider those constructors as potential candidates if the constructor's parameter list - /// contains 'ref' or 'params' - /// - private IMethodSymbol GetDelegatedConstructorBasedOnParameterNames( - INamedTypeSymbol containingType, - ImmutableArray parameters) + private static async Task IsApplicableConstructorAsync(IMethodSymbol constructor, Document document, ImmutableArray parameterNamesForSelectedMembers, CancellationToken cancellationToken) { - var parameterNames = parameters.SelectAsArray(p => p.Name); - return containingType.InstanceConstructors - .Where(constructor => IsApplicableConstructor(constructor, parameterNames)) - .OrderByDescending(constructor => constructor.Parameters.Length) - .FirstOrDefault(); + var constructorParams = constructor.Parameters; + + if (constructorParams.Length == 2) + { + var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); + var deserializationConstructorCheck = new DeserializationConstructorCheck(compilation); + if (deserializationConstructorCheck.IsDeserializationConstructor(constructor)) + { + return false; + } + } + + return constructorParams.All(parameter => parameter.RefKind == RefKind.None) && + !constructor.IsImplicitlyDeclared && + !constructorParams.Any(p => p.IsParams) && + !SelectedMembersAlreadyExistAsParameters(parameterNamesForSelectedMembers, constructorParams); } - private bool IsApplicableConstructor( - IMethodSymbol constructor, - ImmutableArray parametersName) + private static bool SelectedMembersAlreadyExistAsParameters(ImmutableArray parameterNamesForSelectedMembers, ImmutableArray constructorParams) + => constructorParams.Length != 0 && + !parameterNamesForSelectedMembers.Except(constructorParams.Select(p => p.Name)).Any(); + + private static ConstructorCandidate CreateConstructorCandidate(ImmutableArray parametersForSelectedMembers, ImmutableArray selectedMembers, IMethodSymbol constructor) { - var constructorParams = constructor.Parameters; - if (constructorParams.Length == 0) + var missingParametersBuilder = ArrayBuilder.GetInstance(); + var missingMembersBuilder = ArrayBuilder.GetInstance(); + var constructorParamNames = constructor.Parameters.SelectAsArray(p => p.Name); + var zippedParametersAndSelectedMembers = + parametersForSelectedMembers.Zip(selectedMembers, (parameter, selectedMember) => (parameter, selectedMember)); + + foreach (var (parameter, selectedMember) in zippedParametersAndSelectedMembers) { - return !constructor.IsImplicitlyDeclared; + if (!constructorParamNames.Contains(parameter.Name)) + { + missingParametersBuilder.Add(parameter); + missingMembersBuilder.Add(selectedMember); + } } - return constructorParams.All(parameter => parameter.RefKind == RefKind.None) - && !constructorParams.Any(p => p.IsParams) - && parametersName.Except(constructorParams.Select(p => p.Name)).Any(); + return new ConstructorCandidate( + constructor, missingMembersBuilder.ToImmutableAndFree(), missingParametersBuilder.ToImmutableAndFree()); } } } diff --git a/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.cs b/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.cs index 00fb0ff81fb9c..f37d917c34ee1 100644 --- a/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.cs @@ -11,6 +11,7 @@ using Microsoft.CodeAnalysis.CodeRefactorings; using Microsoft.CodeAnalysis.GenerateFromMembers; using Microsoft.CodeAnalysis.Internal.Log; +using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.AddConstructorParametersFromMembers @@ -32,7 +33,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte return; } - var actions = await this.AddConstructorParametersFromMembersAsync(document, textSpan, cancellationToken).ConfigureAwait(false); + var actions = await AddConstructorParametersFromMembersAsync(document, textSpan, cancellationToken).ConfigureAwait(false); context.RegisterRefactorings(actions); } @@ -40,13 +41,18 @@ public async Task> AddConstructorParametersFromMember { using (Logger.LogBlock(FunctionId.Refactoring_GenerateFromMembers_AddConstructorParametersFromMembers, cancellationToken)) { - var info = await this.GetSelectedMemberInfoAsync(document, textSpan, allowPartialSelection: true, cancellationToken).ConfigureAwait(false); + var info = await GetSelectedMemberInfoAsync( + document, + textSpan, + allowPartialSelection: true, + cancellationToken).ConfigureAwait(false); + if (info != null) { - var state = State.Generate(this, info.SelectedMembers); - if (state != null && state.ConstructorToAddTo != null) + var state = await State.GenerateAsync(this, info.SelectedMembers, document, cancellationToken).ConfigureAwait(false); + if (state?.ConstructorCandidates != null && !state.ConstructorCandidates.IsEmpty) { - return CreateCodeActions(document, state).AsImmutableOrNull(); + return CreateCodeActions(document, state); } } @@ -54,27 +60,87 @@ public async Task> AddConstructorParametersFromMember } } - private IEnumerable CreateCodeActions(Document document, State state) + private ImmutableArray CreateCodeActions(Document document, State state) { - var parameters = state.ConstructorToAddTo.Parameters; - if (parameters.Length == 0 || - (parameters.Length > 0 && !parameters.Last().IsOptional)) + var result = ArrayBuilder.GetInstance(); + var containingType = state.ContainingType; + if (state.ConstructorCandidates.Length == 1) { - // return a code action to add required parameters - yield return new AddConstructorParametersCodeAction(this, document, state, state.MissingParameters); + // There will be at most 2 suggested code actions, so no need to use sub menus + var constructorCandidate = state.ConstructorCandidates[0]; + if (CanHaveRequiredParameters(state.ConstructorCandidates[0].MissingParameters)) + { + result.Add(new AddConstructorParametersCodeAction( + document, + constructorCandidate, + containingType, + constructorCandidate.MissingParameters, + useSubMenuName: false)); + } + result.Add(GetOptionalContructorParametersCodeAction( + document, + constructorCandidate, + containingType, + useSubMenuName: false)); } + else + { + // Create sub menus for suggested actions, one for required parameters and one for optional parameters + var requiredParameterCodeActions = ArrayBuilder.GetInstance(); + var optionalParameterCodeActions = ArrayBuilder.GetInstance(); + foreach (var constructorCandidate in state.ConstructorCandidates) + { + if (CanHaveRequiredParameters(constructorCandidate.Constructor.Parameters)) + { + requiredParameterCodeActions.Add(new AddConstructorParametersCodeAction( + document, + constructorCandidate, + containingType, + constructorCandidate.MissingParameters, + useSubMenuName: true)); + } + optionalParameterCodeActions.Add(GetOptionalContructorParametersCodeAction( + document, + constructorCandidate, + containingType, + useSubMenuName: true)); + } - var missingParameters = state.MissingParameters.SelectAsArray(p => CodeGenerationSymbolFactory.CreateParameterSymbol( - attributes: default, - refKind: p.RefKind, - isParams: p.IsParams, - type: p.Type, - name: p.Name, - isOptional: true, - hasDefaultValue: true)); + if (requiredParameterCodeActions.Count > 0) + { + result.Add(new CodeAction.CodeActionWithNestedActions( + FeaturesResources.Add_parameter_to_constructor, + requiredParameterCodeActions.ToImmutableAndFree(), + isInlinable: false)); + } + + result.Add(new CodeAction.CodeActionWithNestedActions( + FeaturesResources.Add_optional_parameter_to_constructor, + optionalParameterCodeActions.ToImmutableAndFree(), + isInlinable: false)); + } + + return result.ToImmutableAndFree(); - // return a code action to add optional parameters - yield return new AddConstructorParametersCodeAction(this, document, state, missingParameters); + // local functions + static bool CanHaveRequiredParameters(ImmutableArray parameters) + => parameters.Length == 0 || !parameters.Last().IsOptional; + + static CodeAction GetOptionalContructorParametersCodeAction(Document document, ConstructorCandidate constructorCandidate, INamedTypeSymbol containingType, bool useSubMenuName) + { + var missingOptionalParameters = constructorCandidate.MissingParameters.SelectAsArray( + p => CodeGenerationSymbolFactory.CreateParameterSymbol( + attributes: default, + refKind: p.RefKind, + isParams: p.IsParams, + type: p.Type, + name: p.Name, + isOptional: true, + hasDefaultValue: true)); + + return new AddConstructorParametersCodeAction( + document, constructorCandidate, containingType, missingOptionalParameters, useSubMenuName); + } } } } diff --git a/src/Features/Core/Portable/FeaturesResources.Designer.cs b/src/Features/Core/Portable/FeaturesResources.Designer.cs index 78c1f442bb88c..0180bbf8b3f6b 100644 --- a/src/Features/Core/Portable/FeaturesResources.Designer.cs +++ b/src/Features/Core/Portable/FeaturesResources.Designer.cs @@ -232,6 +232,15 @@ internal static string Add_null_checks { } } + /// + /// Looks up a localized string similar to Add optional parameter to constructor. + /// + internal static string Add_optional_parameter_to_constructor { + get { + return ResourceManager.GetString("Add_optional_parameter_to_constructor", resourceCulture); + } + } + /// /// Looks up a localized string similar to Add optional parameters to '{0}'. /// @@ -259,6 +268,15 @@ internal static string Add_parameter_to_0_and_overrides_implementations { } } + /// + /// Looks up a localized string similar to Add parameter to constructor. + /// + internal static string Add_parameter_to_constructor { + get { + return ResourceManager.GetString("Add_parameter_to_constructor", resourceCulture); + } + } + /// /// Looks up a localized string similar to Add parameters to '{0}'. /// diff --git a/src/Features/Core/Portable/FeaturesResources.resx b/src/Features/Core/Portable/FeaturesResources.resx index b7822f3ad9de7..764ae035898c3 100644 --- a/src/Features/Core/Portable/FeaturesResources.resx +++ b/src/Features/Core/Portable/FeaturesResources.resx @@ -1599,4 +1599,10 @@ This version used in: {2} Make readonly fields writable {Locked="readonly"} "readonly" is C# keyword and should not be localized. + + Add optional parameter to constructor + + + Add parameter to constructor + \ No newline at end of file diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf index 01a53609c0291..628db4fc4ef85 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf @@ -7,11 +7,21 @@ Přidat název členu + + Add optional parameter to constructor + Add optional parameter to constructor + + Add parameter to '{0}' (and overrides/implementations) Přidat parametr do {0} (a přepsání/implementace) + + Add parameter to constructor + Add parameter to constructor + + Add project reference to '{0}'. Přidat odkaz na projekt do {0} diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf index df5596f9ede1e..002e22c634d2b 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf @@ -7,11 +7,21 @@ Membername hinzufügen + + Add optional parameter to constructor + Add optional parameter to constructor + + Add parameter to '{0}' (and overrides/implementations) Parameter zu "{0}" (und Außerkraftsetzungen/Implementierungen) hinzufügen + + Add parameter to constructor + Add parameter to constructor + + Add project reference to '{0}'. Fügen Sie zu "{0}" einen Projektverweis hinzu. diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf index 70a5d93b3a3c5..031f4151d9416 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf @@ -7,11 +7,21 @@ Agregar nombre de miembro + + Add optional parameter to constructor + Add optional parameter to constructor + + Add parameter to '{0}' (and overrides/implementations) Agregar un parámetro a “{0}” (y reemplazos/implementaciones) + + Add parameter to constructor + Add parameter to constructor + + Add project reference to '{0}'. Agregue referencia de proyecto a '{0}'. diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf index f45a8f1f6bc37..3edb659d743e5 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf @@ -7,11 +7,21 @@ Ajouter le nom du membre + + Add optional parameter to constructor + Add optional parameter to constructor + + Add parameter to '{0}' (and overrides/implementations) Ajouter un paramètre à '{0}' (et aux remplacements/implémentations) + + Add parameter to constructor + Add parameter to constructor + + Add project reference to '{0}'. Ajoutez une référence de projet à '{0}'. diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf index 4ebf58cfd02f3..255432d5ed4df 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf @@ -7,11 +7,21 @@ Aggiungi nome del membro + + Add optional parameter to constructor + Add optional parameter to constructor + + Add parameter to '{0}' (and overrides/implementations) Aggiungi il parametro a '{0}' (e override/implementazioni) + + Add parameter to constructor + Add parameter to constructor + + Add project reference to '{0}'. Aggiunge il riferimento al progetto a '{0}'. diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf index c5c92a1e8e976..742203f80cb9f 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf @@ -7,11 +7,21 @@ メンバー名を追加します + + Add optional parameter to constructor + Add optional parameter to constructor + + Add parameter to '{0}' (and overrides/implementations) パラメーターを '{0}' に追加します (オーバーライド/実装も行います) + + Add parameter to constructor + Add parameter to constructor + + Add project reference to '{0}'. プロジェクト参照を '{0}' に追加します。 diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf index 56d1bd1133321..8ac36ec6728a4 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf @@ -7,11 +7,21 @@ 멤버 이름 추가 + + Add optional parameter to constructor + Add optional parameter to constructor + + Add parameter to '{0}' (and overrides/implementations) '{0}'(및 재정의/구현)에 매개 변수 추가 + + Add parameter to constructor + Add parameter to constructor + + Add project reference to '{0}'. 프로젝트 참조를 '{0}'에 추가합니다. diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf index 2f5bfa07b257f..5081e6b854160 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf @@ -7,11 +7,21 @@ Dodaj nazwę składowej + + Add optional parameter to constructor + Add optional parameter to constructor + + Add parameter to '{0}' (and overrides/implementations) Dodaj parametr do elementu „{0}” (oraz przesłonięć/implementacji) + + Add parameter to constructor + Add parameter to constructor + + Add project reference to '{0}'. Dodaj odwołanie do projektu do elementu „{0}” diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf index bb8cc8b05082b..acec24f45b9e9 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf @@ -7,11 +7,21 @@ Adicionar o nome do membro + + Add optional parameter to constructor + Add optional parameter to constructor + + Add parameter to '{0}' (and overrides/implementations) Adicionar parâmetro ao '{0}' (e substituições/implementações) + + Add parameter to constructor + Add parameter to constructor + + Add project reference to '{0}'. Adicione referência de projeto a "{0}". diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf index b0236f161f99d..f6985c6f595f2 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf @@ -7,11 +7,21 @@ Добавить имя элемента + + Add optional parameter to constructor + Add optional parameter to constructor + + Add parameter to '{0}' (and overrides/implementations) Добавить параметр в "{0}" (а также переопределения или реализации) + + Add parameter to constructor + Add parameter to constructor + + Add project reference to '{0}'. Добавьте ссылку на проект в "{0}". diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf index 4f596d890cb3d..f42fab19bd543 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf @@ -7,11 +7,21 @@ Üye adı Ekle + + Add optional parameter to constructor + Add optional parameter to constructor + + Add parameter to '{0}' (and overrides/implementations) '{0}' öğesine (ve geçersiz kılmalara/uygulamalara) parametre ekle + + Add parameter to constructor + Add parameter to constructor + + Add project reference to '{0}'. {0}' üzerine proje başvurusu ekleyin. diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf index eacc8ffc80462..875b45d026dd9 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf @@ -7,11 +7,21 @@ 添加成员名称 + + Add optional parameter to constructor + Add optional parameter to constructor + + Add parameter to '{0}' (and overrides/implementations) 将参数添加到“{0}”(和重写/实现) + + Add parameter to constructor + Add parameter to constructor + + Add project reference to '{0}'. 将参数引用添加到“{0}”。 diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf index eba3bfd3ba59a..5630b4a012729 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf @@ -7,11 +7,21 @@ 新增成員名稱 + + Add optional parameter to constructor + Add optional parameter to constructor + + Add parameter to '{0}' (and overrides/implementations) 將參數新增至 '{0}' (以及覆寫/執行) + + Add parameter to constructor + Add parameter to constructor + + Add project reference to '{0}'. 加入對 '{0}' 的專案參考。