|
// 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.
#nullable disable
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.ChangeSignature;
using Microsoft.CodeAnalysis.Editor.UnitTests.ChangeSignature;
using Microsoft.CodeAnalysis.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature;
[Trait(Traits.Feature, Traits.Features.ChangeSignature)]
public partial class ChangeSignatureTests : AbstractChangeSignatureTests
{
#region Methods
[Fact]
public async Task ReorderMethodParameters_InvokeBeforeMethodName()
{
var markup = """
using System;
class MyClass
{
public void $$Goo(int x, string y)
{
}
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
using System;
class MyClass
{
public void Goo(string y, int x)
{
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation,
expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0);
}
[Fact]
public async Task ReorderMethodParameters_InvokeInParameterList()
{
var markup = """
using System;
class MyClass
{
public void Goo(int x, $$string y)
{
}
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
using System;
class MyClass
{
public void Goo(string y, int x)
{
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation,
expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 1);
}
[Fact]
public async Task ReorderMethodParameters_InvokeAfterParameterList()
{
var markup = """
using System;
class MyClass
{
public void Goo(int x, string y)$$
{
}
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
using System;
class MyClass
{
public void Goo(string y, int x)
{
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[Fact]
public async Task ReorderMethodParameters_InvokeBeforeMethodDeclaration()
{
var markup = """
using System;
class MyClass
{
$$public void Goo(int x, string y)
{
}
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
using System;
class MyClass
{
public void Goo(string y, int x)
{
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[Fact]
public async Task ReorderMethodParameters_InvokeOnMetadataReference_InIdentifier_ShouldFail()
{
var markup = """
class C
{
static void Main(string[] args)
{
((System.IFormattable)null).ToSt$$ring("test", null);
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, expectedSuccess: false, expectedFailureReason: ChangeSignatureFailureKind.DefinedInMetadata);
}
[Fact]
public async Task ReorderMethodParameters_InvokeOnMetadataReference_AtBeginningOfInvocation_ShouldFail()
{
var markup = """
class C
{
static void Main(string[] args)
{
$$((System.IFormattable)null).ToString("test", null);
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, expectedSuccess: false, expectedFailureReason: ChangeSignatureFailureKind.DefinedInMetadata);
}
[Fact]
public async Task ReorderMethodParameters_InvokeOnMetadataReference_InArgumentsOfInvocation_ShouldFail()
{
var markup = """
class C
{
static void Main(string[] args)
{
((System.IFormattable)null).ToString("test",$$ null);
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, expectedSuccess: false, expectedFailureReason: ChangeSignatureFailureKind.DefinedInMetadata);
}
[Fact]
public async Task ReorderMethodParameters_InvokeOnMetadataReference_AfterInvocation_ShouldFail()
{
var markup = """
class C
{
string s = ((System.IFormattable)null).ToString("test", null)$$;
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, expectedSuccess: false, expectedFailureReason: ChangeSignatureFailureKind.IncorrectKind);
}
[Fact]
public async Task ReorderMethodParameters_InvokeInMethodBody_ViaCommand()
{
var markup = """
using System;
class MyClass
{
public void Goo(int x, string y)
{
$$
}
}
""";
await TestChangeSignatureViaCommandAsync(
LanguageNames.CSharp, markup, expectedSuccess: false);
}
[Fact]
public async Task ReorderMethodParameters_InvokeInMethodBody_ViaSmartTag()
{
var markup = """
using System;
class MyClass
{
public void Goo(int x, string y)
{
[||]
}
}
""";
await TestMissingAsync(markup);
}
[Fact]
public async Task ReorderMethodParameters_InvokeOnReference_BeginningOfIdentifier()
{
var markup = """
using System;
class MyClass
{
public void Goo(int x, string y)
{
$$Bar(x, y);
}
public void Bar(int x, string y)
{
}
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
using System;
class MyClass
{
public void Goo(int x, string y)
{
Bar(y, x);
}
public void Bar(string y, int x)
{
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[Fact]
public async Task ReorderMethodParameters_InvokeOnReference_ArgumentList()
{
var markup = """
using System;
class MyClass
{
public void Goo(int x, string y)
{
$$Bar(x, y);
}
public void Bar(int x, string y)
{
}
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
using System;
class MyClass
{
public void Goo(int x, string y)
{
Bar(y, x);
}
public void Bar(string y, int x)
{
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[Fact]
public async Task ReorderMethodParameters_InvokeOnReference_NestedCalls1()
{
var markup = """
using System;
class MyClass
{
public void Goo(int x, string y)
{
Bar($$Baz(x, y), y);
}
public void Bar(int x, string y)
{
}
public int Baz(int x, string y)
{
return 1;
}
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
using System;
class MyClass
{
public void Goo(int x, string y)
{
Bar(Baz(y, x), y);
}
public void Bar(int x, string y)
{
}
public int Baz(string y, int x)
{
return 1;
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[Fact]
public async Task ReorderMethodParameters_InvokeOnReference_NestedCalls2()
{
var markup = """
using System;
class MyClass
{
public void Goo(int x, string y)
{
Bar$$(Baz(x, y), y);
}
public void Bar(int x, string y)
{
}
public int Baz(int x, string y)
{
return 1;
}
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
using System;
class MyClass
{
public void Goo(int x, string y)
{
Bar(y, Baz(x, y));
}
public void Bar(string y, int x)
{
}
public int Baz(int x, string y)
{
return 1;
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[Fact]
public async Task ReorderMethodParameters_InvokeOnReference_NestedCalls3()
{
var markup = """
using System;
class MyClass
{
public void Goo(int x, string y)
{
Bar(Baz(x, y), $$y);
}
public void Bar(int x, string y)
{
}
public int Baz(int x, string y)
{
return 1;
}
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
using System;
class MyClass
{
public void Goo(int x, string y)
{
Bar(y, Baz(x, y));
}
public void Bar(string y, int x)
{
}
public int Baz(int x, string y)
{
return 1;
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[Fact]
public async Task ReorderMethodParameters_InvokeOnReference_Attribute()
{
var markup = """
using System;
[$$My(1, 2)]
class MyAttribute : Attribute
{
public MyAttribute(int x, int y)
{
}
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
using System;
[My(2, 1)]
class MyAttribute : Attribute
{
public MyAttribute(int y, int x)
{
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[Fact]
public async Task ReorderMethodParameters_InvokeOnReference_OnlyHasCandidateSymbols()
{
var markup = """
class Test
{
void M(int x, string y) { }
void M(int x, double y) { }
void M2() { $$M("s", 1); }
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
class Test
{
void M(string y, int x) { }
void M(int x, double y) { }
void M2() { M(1, "s"); }
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[Fact]
public async Task ReorderMethodParameters_InvokeOnReference_CallToOtherConstructor()
{
var markup = """
class Program
{
public Program(int x, int y) : this(1, 2, 3)$$
{
}
public Program(int x, int y, int z)
{
}
}
""";
var permutation = new[] { 2, 1, 0 };
var updatedCode = """
class Program
{
public Program(int x, int y) : this(3, 2, 1)
{
}
public Program(int z, int y, int x)
{
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[Fact]
public async Task ReorderMethodParameters_InvokeOnReference_CallToBaseConstructor()
{
var markup = """
class B
{
public B(int a, int b)
{
}
}
class D : B
{
public D(int x, int y) : base(1, 2)$$
{
}
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
class B
{
public B(int b, int a)
{
}
}
class D : B
{
public D(int x, int y) : base(2, 1)
{
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
#endregion
#region Indexers
[Fact]
public async Task ReorderIndexerParameters_InvokeAtBeginningOfDeclaration()
{
var markup = """
class Program
{
$$int this[int x, string y]
{
get { return 5; }
set { }
}
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
class Program
{
int this[string y, int x]
{
get { return 5; }
set { }
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation,
expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0);
}
[Fact]
public async Task ReorderIndexerParameters_InParameters()
{
var markup = """
class Program
{
int this[int x, $$string y]
{
get { return 5; }
set { }
}
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
class Program
{
int this[string y, int x]
{
get { return 5; }
set { }
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation,
expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 1);
}
[Fact]
public async Task ReorderIndexerParameters_InvokeAtEndOfDeclaration()
{
var markup = """
class Program
{
int this[int x, string y]$$
{
get { return 5; }
set { }
}
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
class Program
{
int this[string y, int x]
{
get { return 5; }
set { }
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation,
expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0);
}
[Fact]
public async Task ReorderIndexerParameters_InvokeInAccessor()
{
var markup = """
class Program
{
int this[int x, string y]
{
get { return $$5; }
set { }
}
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
class Program
{
int this[string y, int x]
{
get { return 5; }
set { }
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[Fact]
public async Task ReorderIndexerParameters_InvokeOnReference_BeforeTarget()
{
var markup = """
class Program
{
void M(Program p)
{
var t = $$p[5, "test"];
}
int this[int x, string y]
{
get { return 5; }
set { }
}
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
class Program
{
void M(Program p)
{
var t = p["test", 5];
}
int this[string y, int x]
{
get { return 5; }
set { }
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[Fact]
public async Task ReorderIndexerParameters_InvokeOnReference_InArgumentList()
{
var markup = """
class Program
{
void M(Program p)
{
var t = p[5, "test"$$];
}
int this[int x, string y]
{
get { return 5; }
set { }
}
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
class Program
{
void M(Program p)
{
var t = p["test", 5];
}
int this[string y, int x]
{
get { return 5; }
set { }
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation,
expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0);
}
#endregion
#region Delegates
[Fact]
public async Task ReorderDelegateParameters_ObjectCreation1()
{
var markup = """
public class C
{
void T()
{
var d = new $$D((x, y) => { });
}
public delegate void D(int x, int y);
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
public class C
{
void T()
{
var d = new D((y, x) => { });
}
public delegate void D(int y, int x);
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation,
expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0);
}
[Fact]
public async Task ReorderDelegateParameters_ObjectCreation2()
{
var markup = """
public class CD<T>
{
public delegate void D(T t, T u);
}
class Test
{
public void M()
{
var dele = new CD<int>.$$D((int x, int y) => { });
}
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
public class CD<T>
{
public delegate void D(T u, T t);
}
class Test
{
public void M()
{
var dele = new CD<int>.D((int y, int x) => { });
}
}
""";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
#endregion
#region CodeRefactoring
[Fact]
public async Task ReorderMethodParameters_CodeRefactoring_InvokeBeforeMethodName()
{
var markup = """
using System;
class MyClass
{
public void [||]Goo(int x, string y)
{
}
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
using System;
class MyClass
{
public void Goo(string y, int x)
{
}
}
""";
await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: true, updatedSignature: permutation, expectedCode: updatedCode);
}
[Fact]
public async Task ReorderMethodParameters_CodeRefactoring_NotInMethodBody()
{
var markup = """
using System;
class MyClass
{
public void Goo(int x, string y)
{
[||]
}
}
""";
await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false);
}
[Fact]
public async Task ReorderMethodParameters_CodeRefactoring_InLambda()
{
var markup = """
class Program
{
void M(int x)
{
System.Func<int, int, int> f = (a, b)[||] => { return a; };
}
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
class Program
{
void M(int x)
{
System.Func<int, int, int> f = (b, a) => { return a; };
}
}
""";
await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: true, updatedSignature: permutation, expectedCode: updatedCode);
}
[Fact]
public async Task ReorderMethodParameters_CodeRefactoring_NotInLambdaBody()
{
var markup = """
class Program
{
void M(int x)
{
System.Func<int, int, int> f = (a, b) => { [||]return a; };
}
}
""";
await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false);
}
[Fact]
public async Task ReorderMethodParameters_CodeRefactoring_AtCallSite_ViaCommand()
{
var markup = """
class Program
{
void M(int x, int y)
{
M($$5, 6);
}
}
""";
var permutation = new[] { 1, 0 };
var updatedCode = """
class Program
{
void M(int y, int x)
{
M(6, 5);
}
}
""";
await TestChangeSignatureViaCommandAsync(
LanguageNames.CSharp, markup, updatedSignature: permutation,
expectedUpdatedInvocationDocumentCode: updatedCode);
}
[Fact]
public async Task ReorderMethodParameters_CodeRefactoring_AtCallSite_ViaCodeAction()
{
var markup = """
class Program
{
void M(int x, int y)
{
M([||]5, 6);
}
}
""";
await TestMissingAsync(markup);
}
#endregion
}
|