|
// 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.Collections.Immutable;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.AddParameter;
using Microsoft.CodeAnalysis.CSharp.Shared.Extensions;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
using Xunit.Abstractions;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddParameter;
[Trait(Traits.Feature, Traits.Features.CodeActionsAddParameter)]
public class AddParameterTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor
{
public AddParameterTests(ITestOutputHelper logger)
: base(logger)
{
}
internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace)
=> (null, new CSharpAddParameterCodeFixProvider());
protected override ImmutableArray<CodeAction> MassageActions(ImmutableArray<CodeAction> actions)
=> FlattenActions(actions);
[Fact]
public async Task TestMissingWithImplicitConstructor()
{
await TestMissingAsync(
"""
class C
{
}
class D
{
void M()
{
new [|C|](1);
}
}
""");
}
[Fact]
public async Task TestOnEmptyConstructor()
{
await TestInRegularAndScriptAsync(
"""
class C
{
public C() { }
}
class D
{
void M()
{
new [|C|](1);
}
}
""",
"""
class C
{
public C(int v) { }
}
class D
{
void M()
{
new C(1);
}
}
""");
}
[Fact]
public async Task TestNamedArg()
{
await TestInRegularAndScriptAsync(
"""
class C
{
public C() { }
}
class D
{
void M()
{
new C([|p|]: 1);
}
}
""",
"""
class C
{
public C(int p) { }
}
class D
{
void M()
{
new C(p: 1);
}
}
""");
}
[Fact]
public async Task TestMissingWithConstructorWithSameNumberOfParams()
{
await TestMissingAsync(
"""
class C
{
public C(bool b) { }
}
class D
{
void M()
{
new [|C|](1);
}
}
""");
}
[Fact]
public async Task TestAddBeforeMatchingArg()
{
await TestInRegularAndScriptAsync(
"""
class C
{
public C(int i) { }
}
class D
{
void M()
{
new [|C|](true, 1);
}
}
""",
"""
class C
{
public C(bool v, int i) { }
}
class D
{
void M()
{
new C(true, 1);
}
}
""");
}
[Fact]
public async Task TestAddAfterMatchingConstructorParam()
{
await TestInRegularAndScriptAsync(
"""
class C
{
public C(int i) { }
}
class D
{
void M()
{
new [|C|](1, true);
}
}
""",
"""
class C
{
public C(int i, bool v) { }
}
class D
{
void M()
{
new C(1, true);
}
}
""");
}
[Fact]
public async Task TestParams1()
{
await TestInRegularAndScriptAsync(
"""
class C
{
public C(params int[] i) { }
}
class D
{
void M()
{
new C([|true|], 1);
}
}
""",
"""
class C
{
public C(bool v, params int[] i) { }
}
class D
{
void M()
{
new C(true, 1);
}
}
""");
}
[Fact]
public async Task TestParams2()
{
await TestMissingAsync(
"""
class C
{
public C(params int[] i) { }
}
class D
{
void M()
{
new [|C|](1, true);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20708")]
public async Task TestMultiLineParameters1()
{
await TestInRegularAndScriptAsync(
"""
class C
{
public C(int i,
/* goo */ int j)
{
}
private void Goo()
{
new [|C|](true, 0, 0);
}
}
""",
"""
class C
{
public C(bool v,
int i,
/* goo */ int j)
{
}
private void Goo()
{
new C(true, 0, 0);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20708")]
public async Task TestMultiLineParameters2()
{
await TestInRegularAndScriptAsync(
"""
class C
{
public C(int i,
/* goo */ int j)
{
}
private void Goo()
{
new [|C|](0, true, 0);
}
}
""",
"""
class C
{
public C(int i,
bool v,
/* goo */ int j)
{
}
private void Goo()
{
new C(0, true, 0);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20708")]
public async Task TestMultiLineParameters3()
{
await TestInRegularAndScriptAsync(
"""
class C
{
public C(int i,
/* goo */ int j)
{
}
private void Goo()
{
new [|C|](0, 0, true);
}
}
""",
"""
class C
{
public C(int i,
/* goo */ int j,
bool v)
{
}
private void Goo()
{
new C(0, 0, true);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20708")]
public async Task TestMultiLineParameters4()
{
await TestInRegularAndScriptAsync(
"""
class C
{
public C(
int i,
/* goo */ int j)
{
}
private void Goo()
{
new [|C|](true, 0, 0);
}
}
""",
"""
class C
{
public C(
bool v,
int i,
/* goo */ int j)
{
}
private void Goo()
{
new C(true, 0, 0);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20708")]
public async Task TestMultiLineParameters5()
{
await TestInRegularAndScriptAsync(
"""
class C
{
public C(
int i,
/* goo */ int j)
{
}
private void Goo()
{
new [|C|](0, true, 0);
}
}
""",
"""
class C
{
public C(
int i,
bool v,
/* goo */ int j)
{
}
private void Goo()
{
new C(0, true, 0);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20708")]
public async Task TestMultiLineParameters6()
{
await TestInRegularAndScriptAsync(
"""
class C
{
public C(
int i,
/* goo */ int j)
{
}
private void Goo()
{
new [|C|](0, 0, true);
}
}
""",
"""
class C
{
public C(
int i,
/* goo */ int j,
bool v)
{
}
private void Goo()
{
new C(0, 0, true);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20973")]
public async Task TestNullArg1()
{
await TestInRegularAndScriptAsync(
"""
class C
{
public C(int i) { }
}
class D
{
void M()
{
new [|C|](null, 1);
}
}
""",
"""
class C
{
public C(object value, int i) { }
}
class D
{
void M()
{
new C(null, 1);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20973")]
public async Task TestNullArg2()
{
await TestInRegularAndScriptAsync(
"""
class C
{
public C(string s) { }
}
class D
{
void M()
{
new [|C|](null, 1);
}
}
""",
"""
class C
{
public C(string s, int v) { }
}
class D
{
void M()
{
new C(null, 1);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20973")]
public async Task TestDefaultArg1()
{
await TestInRegularAndScriptAsync(
"""
class C
{
public C(int i) { }
}
class D
{
void M()
{
new [|C|](default, 1);
}
}
""",
"""
class C
{
public C(int i, int v) { }
}
class D
{
void M()
{
new C(default, 1);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20973")]
public async Task TestDefaultArg2()
{
await TestInRegularAndScriptAsync(
"""
class C
{
public C(string s) { }
}
class D
{
void M()
{
new [|C|](default, 1);
}
}
""",
"""
class C
{
public C(string s, int v) { }
}
class D
{
void M()
{
new C(default, 1);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocationInstanceMethod1()
{
await TestInRegularAndScriptAsync(
"""
class C
{
void M1()
{
}
void M2()
{
int i=0;
[|M1|](i);
}
}
""",
"""
class C
{
void M1(int i)
{
}
void M2()
{
int i=0;
M1(i);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocationInheritedMethodGetFixed()
{
await TestInRegularAndScriptAsync(
"""
class Base
{
protected void M1()
{
}
}
class C1 : Base
{
void M2()
{
int i = 0;
[|M1|](i);
}
}
""",
"""
class Base
{
protected void M1(int i)
{
}
}
class C1 : Base
{
void M2()
{
int i = 0;
M1(i);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocationInheritedMethodInMetadatGetsNotFixed()
{
await TestMissingAsync(
"""
class C1
{
void M2()
{
int i = 0;
[|GetHashCode|](i);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocationLocalFunction()
{
await TestInRegularAndScriptAsync(
"""
class C1
{
void M1()
{
int Local() => 1;
[|Local|](2);
}
}
""",
"""
class C1
{
void M1()
{
int Local(int v) => 1;
Local(2);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
[Trait("TODO", "Fix broken")]
public async Task TestInvocationLambda1()
{
await TestMissingInRegularAndScriptAsync(
"""
using System;
class C1
{
void M1()
{
Action a = () => { };
[|a|](2);
}
}
""");
//Should be Action<int> a = (int v) => { };
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocationStaticMethod()
{
await TestInRegularAndScriptAsync(
"""
class C1
{
static void M1()
{
}
void M2()
{
[|M1|](1);
}
}
""",
"""
class C1
{
static void M1(int v)
{
}
void M2()
{
M1(1);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocationExtensionMethod()
{
var code =
"""
namespace N {
static class Extensions
{
public static void ExtensionM1(this object o)
{
}
}
class C1
{
void M1()
{
new object().[|ExtensionM1|](1);
}
}}
""";
var fix =
"""
namespace N {
static class Extensions
{
public static void ExtensionM1(this object o, int v)
{
}
}
class C1
{
void M1()
{
new object().ExtensionM1(1);
}
}}
""";
await TestInRegularAndScriptAsync(code, fix);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocationExtensionMethod_StaticInvocationStyle()
{
// error CS1501: No overload for method 'ExtensionM1' takes 2 arguments
var code =
"""
namespace N {
static class Extensions
{
public static void ExtensionM1(this object o)
{
}
}
class C1
{
void M1()
{
Extensions.[|ExtensionM1|](new object(), 1);
}
}}
""";
var fix =
"""
namespace N {
static class Extensions
{
public static void ExtensionM1(this object o, int v)
{
}
}
class C1
{
void M1()
{
Extensions.ExtensionM1(new object(), 1);
}
}}
""";
await TestInRegularAndScriptAsync(code, fix);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocationOverride()
{
var code = """
class Base
{
protected virtual void M1() { }
}
class C1 : Base
{
protected override void M1() { }
void M2()
{
[|M1|](1);
}
}
""";
var fix_DeclarationOnly = """
class Base
{
protected virtual void M1() { }
}
class C1 : Base
{
protected override void M1(int v) { }
void M2()
{
M1(1);
}
}
""";
var fix_All = """
class Base
{
protected virtual void M1(int v) { }
}
class C1 : Base
{
protected override void M1(int v) { }
void M2()
{
M1(1);
}
}
""";
await TestInRegularAndScriptAsync(code, fix_DeclarationOnly, index: 0);
await TestInRegularAndScriptAsync(code, fix_All, index: 1);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocationExplicitInterface()
{
var code = """
interface I1
{
void M1();
}
class C1 : I1
{
void I1.M1() { }
void M2()
{
((I1)this).[|M1|](1);
}
}
""";
var fix_DeclarationOnly = """
interface I1
{
void M1(int v);
}
class C1 : I1
{
void I1.M1() { }
void M2()
{
((I1)this).M1(1);
}
}
""";
var fix_All = """
interface I1
{
void M1(int v);
}
class C1 : I1
{
void I1.M1(int v) { }
void M2()
{
((I1)this).M1(1);
}
}
""";
await TestInRegularAndScriptAsync(code, fix_DeclarationOnly, index: 0);
await TestInRegularAndScriptAsync(code, fix_All, index: 1);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocationImplicitInterface()
{
var code =
"""
interface I1
{
void M1();
}
class C1 : I1
{
public void M1() { }
void M2()
{
[|M1|](1);
}
}
""";
var fix_DeclarationOnly = """
interface I1
{
void M1();
}
class C1 : I1
{
public void M1(int v) { }
void M2()
{
M1(1);
}
}
""";
var fix_All = """
interface I1
{
void M1(int v);
}
class C1 : I1
{
public void M1(int v) { }
void M2()
{
M1(1);
}
}
""";
await TestInRegularAndScriptAsync(code, fix_DeclarationOnly, index: 0);
await TestInRegularAndScriptAsync(code, fix_All, index: 1);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocationImplicitInterfaces()
{
var code =
"""
interface I1
{
void M1();
}
interface I2
{
void M1();
}
class C1 : I1, I2
{
public void M1() { }
void M2()
{
[|M1|](1);
}
}
""";
var fix_DeclarationOnly = """
interface I1
{
void M1();
}
interface I2
{
void M1();
}
class C1 : I1, I2
{
public void M1(int v) { }
void M2()
{
M1(1);
}
}
""";
var fix_All = """
interface I1
{
void M1(int v);
}
interface I2
{
void M1(int v);
}
class C1 : I1, I2
{
public void M1(int v) { }
void M2()
{
M1(1);
}
}
""";
await TestInRegularAndScriptAsync(code, fix_DeclarationOnly, index: 0);
await TestInRegularAndScriptAsync(code, fix_All, index: 1);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
[Trait("TODO", "Fix broken")]
public async Task TestInvocationGenericMethod()
{
await TestInRegularAndScriptAsync(
"""
class C1
{
void M1<T>(T arg) { }
void M2()
{
[|M1|](1, 2);
}
}
""",
"""
class C1
{
void M1<T>(T arg, int v) { }
void M2()
{
M1(1, 2);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocationRecursion()
{
await TestInRegularAndScriptAsync(
"""
class C1
{
void M1()
{
[|M1|](1);
}
}
""",
"""
class C1
{
void M1(int v)
{
M1(1);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocationOverloads1()
{
var code =
"""
class C1
{
void M1(string s) { }
void M1(int i) { }
void M2()
{
[|M1|](1, 2);
}
}
""";
var fix0 =
"""
class C1
{
void M1(string s) { }
void M1(int i, int v) { }
void M2()
{
M1(1, 2);
}
}
""";
var fix1 =
"""
class C1
{
void M1(int v, string s) { }
void M1(int i) { }
void M2()
{
M1(1, 2);
}
}
""";
await TestInRegularAndScriptAsync(code, fix0, 0);
await TestInRegularAndScriptAsync(code, fix1, 1);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocationOverloads2()
{
var code =
"""
class C1
{
void M1(string s1, string s2) { }
void M1(string s) { }
void M1(int i) { }
void M2()
{
M1(1, [|2|]);
}
}
""";
var fix0 =
"""
class C1
{
void M1(string s1, string s2) { }
void M1(string s) { }
void M1(int i, int v) { }
void M2()
{
M1(1, 2);
}
}
""";
var fix1 =
"""
class C1
{
void M1(string s1, string s2) { }
void M1(int v, string s) { }
void M1(int i) { }
void M2()
{
M1(1, 2);
}
}
""";
await TestInRegularAndScriptAsync(code, fix0, 0);
await TestInRegularAndScriptAsync(code, fix1, 1);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocationTuple1()
{
var code =
"""
class C1
{
void M1((int, int) t1)
{
}
void M2()
{
[|M1|]((0, 0), (1, "1"));
}
}
""";
var fix0 =
"""
class C1
{
void M1((int, int) t1, (int, string) value)
{
}
void M2()
{
M1((0, 0), (1, "1"));
}
}
""";
await TestInRegularAndScriptAsync(code, fix0, 0);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocationTuple2()
{
var code =
"""
class C1
{
void M1((int, int) t1)
{
}
void M2()
{
var tup = (1, "1");
[|M1|]((0, 0), tup);
}
}
""";
var fix0 =
"""
class C1
{
void M1((int, int) t1, (int, string) tup)
{
}
void M2()
{
var tup = (1, "1");
M1((0, 0), tup);
}
}
""";
await TestInRegularAndScriptAsync(code, fix0, 0);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocationTuple3()
{
var code =
"""
class C1
{
void M1((int, int) t1)
{
}
void M2()
{
var tup = (i: 1, s: "1");
[|M1|]((0, 0), tup);
}
}
""";
var fix0 =
"""
class C1
{
void M1((int, int) t1, (int i, string s) tup)
{
}
void M2()
{
var tup = (i: 1, s: "1");
M1((0, 0), tup);
}
}
""";
await TestInRegularAndScriptAsync(code, fix0, 0);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_Missing_TypeArguments_AddingTypeArgumentAndParameter()
{
// error CS0305: Using the generic method 'C1.M1<T>(T)' requires 1 type arguments
var code =
"""
class C1
{
void M1<T>(T i) { }
void M2()
{
[|M1|]<int, bool>(1, true);
}
}
""";
// Could be fixed as void M1<T, T1>(T i, T1 v) { }
await TestMissingInRegularAndScriptAsync(code);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_Missing_TypeArguments_AddingTypeArgument()
{
// error CS0308: The non-generic method 'C1.M1(int)' cannot be used with type arguments
var code =
"""
class C1
{
void M1(int i) { }
void M2()
{
[|M1<bool>|](1, true);
}
}
""";
// Could be fixed as void M1<T>(int i, T v) { }
await TestMissingInRegularAndScriptAsync(code);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
[Trait("TODO", "Fix missing")]
public async Task TestInvocation_Missing_ExplicitInterfaceImplementation()
{
// error CS0539: 'C1.M1(int)' in explicit interface declaration is not a member of interface
var code =
"""
interface I1
{
void M1();
}
class C1 : I1
{
void I1.M1() { }
void I1.[|M1|](int i) { }
}
""";
// Could apply argument to interface method: void M1(int i);
await TestMissingAsync(code);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_OverloadResolutionFailure()
{
// error CS1503: Argument 1: cannot convert from 'double' to 'int'
var code =
"""
class C1
{
void M1(int i1, int i2) { }
void M1(double d) { }
void M2()
{
M1([|1.0|], 1);
}
}
""";
var fix0 =
"""
class C1
{
void M1(int i1, int i2) { }
void M1(double d, int v) { }
void M2()
{
M1(1.0, 1);
}
}
""";
await TestInRegularAndScriptAsync(code, fix0);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_LambdaExpressionParameter()
{
// error CS1660: Cannot convert lambda expression to type 'int' because it is not a delegate type
var code =
"""
class C1
{
void M1(int i1, int i2) { }
void M1(System.Action a) { }
void M2()
{
M1([|()=> { }|], 1);
}
}
""";
var fix =
"""
class C1
{
void M1(int i1, int i2) { }
void M1(System.Action a, int v) { }
void M2()
{
M1(()=> { }, 1);
}
}
""";
await TestInRegularAndScriptAsync(code, fix);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_NamedParameter()
{
// error CS1739: The best overload for 'M1' does not have a parameter named 'i2'
var code =
"""
class C1
{
void M1(int i1) { }
void M2()
{
M1([|i2|]: 1);
}
}
""";
var fix =
"""
class C1
{
void M1(int i1, int i2) { }
void M2()
{
M1(i2: 1);
}
}
""";
await TestInRegularAndScriptAsync(code, fix);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocationAddTypeParameter_AddTypeParameterIfUserSpecifiesOne_OnlyTypeArgument()
{
var code =
"""
class C1
{
void M1() { }
void M2()
{
[|M1|]<bool>();
}
}
""";
// Could be fixed as void M1<T>() { }
await TestMissingInRegularAndScriptAsync(code);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocationAddTypeParameter_AddTypeParameterIfUserSpecifiesOne_TypeArgumentAndParameterArgument()
{
var code =
"""
class C1
{
void M1() { }
void M2()
{
[|M1|]<bool>(true);
}
}
""";
// Could be fixed to void M1<T>(T v) { }
await TestMissingInRegularAndScriptAsync(code);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_ExisitingTypeArgumentIsNotGeneralized()
{
var code =
"""
class C1
{
void M1<T>(T v) { }
void M2()
{
[|M1|](true, true);
}
}
""";
var fix0 =
"""
class C1
{
void M1<T>(T v, bool v1) { }
void M2()
{
M1(true, true);
}
}
""";
await TestInRegularAndScriptAsync(code, fix0);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_AddParameterToMethodWithParams()
{
// error CS1503: Argument 1: cannot convert from 'bool' to 'int'
var code =
"""
class C1
{
static void M1(params int[] nums) { }
static void M2()
{
M1([|true|], 4);
}
}
""";
var fix0 =
"""
class C1
{
static void M1(bool v, params int[] nums) { }
static void M2()
{
M1(true, 4);
}
}
""";
await TestInRegularAndScriptAsync(code, fix0);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_Cascading_FixingVirtualFixesOverrideToo()
{
// error CS1501: No overload for method 'M1' takes 1 arguments
var code =
"""
class BaseClass
{
protected virtual void M1() { }
}
class Derived1: BaseClass
{
protected override void M1() { }
}
class Test: BaseClass
{
void M2()
{
[|M1|](1);
}
}
""";
var fix_DeclarationOnly =
"""
class BaseClass
{
protected virtual void M1(int v) { }
}
class Derived1: BaseClass
{
protected override void M1() { }
}
class Test: BaseClass
{
void M2()
{
M1(1);
}
}
""";
var fix_All =
"""
class BaseClass
{
protected virtual void M1(int v) { }
}
class Derived1: BaseClass
{
protected override void M1(int v) { }
}
class Test: BaseClass
{
void M2()
{
M1(1);
}
}
""";
await TestInRegularAndScriptAsync(code, fix_DeclarationOnly, index: 0);
await TestInRegularAndScriptAsync(code, fix_All, index: 1);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_Cascading_PartialMethods()
{
var code =
"""
<Workspace>
<Project Language="C#" AssemblyName="Assembly1" CommonReferences="true">
<Document>
namespace N1
{
partial class C1
{
partial void PartialM();
}
}
</Document>
<Document>
namespace N1
{
partial class C1
{
partial void PartialM() { }
void M1()
{
[|PartialM|](1);
}
}
}
</Document>
</Project>
</Workspace>
""";
var fix0 =
"""
<Workspace>
<Project Language="C#" AssemblyName="Assembly1" CommonReferences="true">
<Document>
namespace N1
{
partial class C1
{
partial void PartialM(int v);
}
}
</Document>
<Document>
namespace N1
{
partial class C1
{
partial void PartialM(int v) { }
void M1()
{
PartialM(1);
}
}
}
</Document>
</Project>
</Workspace>
""";
await TestInRegularAndScriptAsync(code, fix0);
}
[Fact]
public async Task TestInvocation_Cascading_ExtendedPartialMethods()
{
var code =
"""
<Workspace>
<Project Language="C#" AssemblyName="Assembly1" CommonReferences="true">
<Document>
namespace N1
{
partial class C1
{
public partial void PartialM();
}
}
</Document>
<Document>
namespace N1
{
partial class C1
{
public partial void PartialM() { }
void M1()
{
[|PartialM|](1);
}
}
}
</Document>
</Project>
</Workspace>
""";
var fix0 =
"""
<Workspace>
<Project Language="C#" AssemblyName="Assembly1" CommonReferences="true">
<Document>
namespace N1
{
partial class C1
{
public partial void PartialM(int v);
}
}
</Document>
<Document>
namespace N1
{
partial class C1
{
public partial void PartialM(int v) { }
void M1()
{
PartialM(1);
}
}
}
</Document>
</Project>
</Workspace>
""";
await TestInRegularAndScriptAsync(code, fix0);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_Cascading_PartialMethodsInSameDocument()
{
var code =
"""
namespace N1
{
partial class C1
{
partial void PartialM();
}
partial class C1
{
partial void PartialM() { }
void M1()
{
[|PartialM|](1);
}
}
}
""";
var fix0 =
"""
namespace N1
{
partial class C1
{
partial void PartialM(int v);
}
partial class C1
{
partial void PartialM(int v) { }
void M1()
{
PartialM(1);
}
}
}
""";
await TestInRegularAndScriptAsync(code, fix0);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_Cascading_BaseNotInSource()
{
// error CS1501: No overload for method 'M' takes 1 arguments
var code =
"""
<Workspace>
<Project Language="C#" CommonReferences="true">
<MetadataReferenceFromSource Language="C#" CommonReferences="true">
<Document FilePath="ReferencedDocument">
namespace N
{
public class BaseClass
{
public virtual void M() { }
}
}
</Document>
</MetadataReferenceFromSource>
<Document FilePath="TestDocument">
namespace N
{
public class Derived: BaseClass
{
public void M2()
{
[|M|](1);
}
}
}
</Document>
</Project>
</Workspace>
""";
await TestMissingAsync(code);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_Cascading_RootNotInSource()
{
// error CS1501: No overload for method 'M' takes 1 arguments
var code =
"""
<Workspace>
<Project Language="C#" CommonReferences="true">
<MetadataReferenceFromSource Language="C#" CommonReferences="true">
<Document FilePath="ReferencedDocument">namespace N
{
public class BaseClass
{
public virtual void M() { }
}
}</Document>
</MetadataReferenceFromSource>
<Document FilePath="TestDocument">namespace N
{
public class Derived: BaseClass
{
public override void M() { }
}
public class DerivedDerived: Derived
{
public void M2()
{
[|M|](1);
}
}
}</Document>
</Project>
</Workspace>
""";
var fixedDocumentWithoutConflictAnnotation = """
namespace N
{
public class Derived: BaseClass
{
public override void M(int v) { }
}
public class DerivedDerived: Derived
{
public void M2()
{
M(1);
}
}
}
""";
var fixedDocumentWithConflictAnnotation = """
namespace N
{
public class Derived: BaseClass
{
public override void M({|Conflict:int v|}) { }
}
public class DerivedDerived: Derived
{
public void M2()
{
M(1);
}
}
}
""";
await TestInRegularAndScriptAsync(code, fixedDocumentWithoutConflictAnnotation, index: 0);
await TestInRegularAndScriptAsync(code, fixedDocumentWithConflictAnnotation, index: 1);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_Cascading_ManyReferencesInManyProjects()
{
// error CS1501: No overload for method 'M' takes 1 arguments
var code =
"""
<Workspace>
<Project Language="C#" CommonReferences="true" AssemblyName="A1">
<Document FilePath="ReferencedDocument">
namespace N
{
public class BaseClass
{
public virtual void M() { }
}
}
</Document>
</Project>
<Project Language="C#" CommonReferences="true" AssemblyName="A2">
<ProjectReference>A1</ProjectReference>
<Document>
namespace N
{
public class Derived1: BaseClass
{
public override void M() { }
}
}
</Document>
</Project>
<Project Language="C#" CommonReferences="true" AssemblyName="A3">
<ProjectReference>A1</ProjectReference>
<Document>
namespace N
{
public class Derived2: BaseClass
{
public override void M() { }
}
}
</Document>
</Project>
<Project Language="C#" CommonReferences="true" AssemblyName="A4">
<ProjectReference>A3</ProjectReference>
<Document>
namespace N
{
public class T
{
public void Test() {
new Derived2().[|M|](1);
}
}
}
</Document>
</Project>
</Workspace>
""";
var fix_All =
"""
<Workspace>
<Project Language="C#" CommonReferences="true" AssemblyName="A1">
<Document FilePath="ReferencedDocument">
namespace N
{
public class BaseClass
{
public virtual void M(int v) { }
}
}
</Document>
</Project>
<Project Language="C#" CommonReferences="true" AssemblyName="A2">
<ProjectReference>A1</ProjectReference>
<Document>
namespace N
{
public class Derived1: BaseClass
{
public override void M(int v) { }
}
}
</Document>
</Project>
<Project Language="C#" CommonReferences="true" AssemblyName="A3">
<ProjectReference>A1</ProjectReference>
<Document>
namespace N
{
public class Derived2: BaseClass
{
public override void M(int v) { }
}
}
</Document>
</Project>
<Project Language="C#" CommonReferences="true" AssemblyName="A4">
<ProjectReference>A3</ProjectReference>
<Document>
namespace N
{
public class T
{
public void Test() {
new Derived2().M(1);
}
}
}
</Document>
</Project>
</Workspace>
""";
await TestInRegularAndScriptAsync(code, fix_All, index: 1);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_Cascading_OfferFixCascadingForImplicitInterface()
{
// error CS1501: No overload for method 'M1' takes 1 arguments
var code =
"""
interface I1
{
void M1();
}
class C: I1
{
public void M1() { }
void MTest()
{
[|M1|](1);
}
}
""";
var fix_DeclarationOnly =
"""
interface I1
{
void M1();
}
class C: I1
{
public void M1(int v) { }
void MTest()
{
M1(1);
}
}
""";
var fix_All =
"""
interface I1
{
void M1(int v);
}
class C: I1
{
public void M1(int v) { }
void MTest()
{
M1(1);
}
}
""";
await TestInRegularAndScriptAsync(code, fix_DeclarationOnly, index: 0);
await TestInRegularAndScriptAsync(code, fix_All, index: 1);
}
#if !CODE_STYLE
// CodeStyle layer does not support cross language application of fixes.
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_Cascading_CrossLanguage()
{
var code =
"""
<Workspace>
<Project Language="Visual Basic" CommonReferences="true" AssemblyName="VB1">
<Document FilePath="ReferencedDocument">
Namespace N
Public Class BaseClass
Public Overridable Sub M()
End Sub
End Class
End Namespace
</Document>
</Project>
<Project Language="C#" CommonReferences="true" AssemblyName="A2">
<ProjectReference>VB1</ProjectReference>
<Document>
namespace N
{
public class Derived: BaseClass
{
public override void M() { }
}
public class T
{
public void Test() {
new Derived().[|M|](1);
}
}
}
</Document>
</Project>
</Workspace>
""";
var fix =
"""
<Workspace>
<Project Language="Visual Basic" CommonReferences="true" AssemblyName="VB1">
<Document FilePath="ReferencedDocument">
Namespace N
Public Class BaseClass
Public Overridable Sub M(v As Integer)
End Sub
End Class
End Namespace
</Document>
</Project>
<Project Language="C#" CommonReferences="true" AssemblyName="A2">
<ProjectReference>VB1</ProjectReference>
<Document>
namespace N
{
public class Derived: BaseClass
{
public override void M(int v) { }
}
public class T
{
public void Test() {
new Derived().M(1);
}
}
}
</Document>
</Project>
</Workspace>
""";
await TestInRegularAndScriptAsync(code, fix, index: 1);
}
#endif
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_InvocationStyles_Positional_MoreThanOneArgumentToMuch()
{
var code =
"""
class C
{
void M() { }
void Test()
{
[|M|](1, 2, 3, 4);
}
}
""";
var fix0 =
"""
class C
{
void M(int v) { }
void Test()
{
M(1, 2, 3, 4);
}
}
""";
await TestActionCountAsync(code, 1);
await TestInRegularAndScriptAsync(code, fix0, index: 0);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_InvocationStyles_Positional_WithOptionalParam()
{
// error CS1501: No overload for method 'M' takes 2 arguments
var code =
"""
class C
{
void M(int i = 1) { }
void Test()
{
[|M|](1, 2);
}
}
""";
var fix0 =
"""
class C
{
void M(int i = 1, int v = 0) { }
void Test()
{
M(1, 2);
}
}
""";
await TestInRegularAndScriptAsync(code, fix0, index: 0);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_InvocationStyles_Named_WithOptionalParam()
{
// error CS1739: The best overload for 'M' does not have a parameter named 'i3'
var code =
"""
class C
{
void M(int i1, int i2 = 1) { }
void Test()
{
M(1, i2: 2, [|i3|]: 3);
}
}
""";
var fix0 =
"""
class C
{
void M(int i1, int i2 = 1, int i3 = 0) { }
void Test()
{
M(1, i2: 2, i3: 3);
}
}
""";
await TestInRegularAndScriptAsync(code, fix0, index: 0);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_InvocationStyles_Positional_WithParams()
{
// error CS1503: Argument 1: cannot convert from 'string' to 'int'
var code =
"""
class C
{
void M(params int[] ints) { }
void Test()
{
M([|"text"|]);
}
}
""";
var fix0 =
"""
class C
{
void M(string v, params int[] ints) { }
void Test()
{
M("text");
}
}
""";
await TestInRegularAndScriptAsync(code, fix0, index: 0);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_InvocationStyles_Named_WithTypemissmatch()
{
// error CS1503: Argument 1: cannot convert from 'string' to 'int'
var code =
"""
class C
{
void M(int i) { }
void Test()
{
M(i: [|"text"|]);
}
}
""";
await TestMissingInRegularAndScriptAsync(code);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_InvocationStyles_NamedAndPositional1()
{
// error CS1739: The best overload for 'M' does not have a parameter named 'i2'
var code =
"""
class C
{
void M(int i1, string s) { }
void Test()
{
M(1, s: "text", [|i2|]: 0);
}
}
""";
var fix0 =
"""
class C
{
void M(int i1, string s, int i2) { }
void Test()
{
M(1, s: "text", i2: 0);
}
}
""";
await TestInRegularAndScriptAsync(code, fix0, index: 0);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_InvocationStyles_NamedAndPositional2()
{
// CS1744 is not yet a supported diagnostic (just declaring the diagnostic as supported does not work)
// error CS1744: Named argument 's' specifies a parameter for which a positional argument has already been given
var code =
"""
class C
{
void M(string s) { }
void Test()
{
M(1, [|s|]: "text");
}
}
""";
await TestMissingInRegularAndScriptAsync(code);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_InvocationStyles_Incomplete_1()
{
// error CS1501: No overload for method 'M' takes 1 arguments
var code =
"""
class C
{
void M() { }
void Test()
{
[|M|](1
}
}
""";
var fix0 =
"""
class C
{
void M(int v) { }
void Test()
{
M(1
}
}
""";
await TestInRegularAndScriptAsync(code, fix0, index: 0);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_InvocationStyles_Incomplete_2()
{
// error CS1503: Argument 1: cannot convert from 'string' to 'int'
var code =
"""
class C
{
void M(int v) { }
void Test()
{
[|M|]("text", 1
""";
var fix0 =
"""
class C
{
void M(string v1, int v) { }
void Test()
{
M("text", 1
""";
await TestInRegularAndScriptAsync(code, fix0, index: 0);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_InvocationStyles_RefParameter()
{
// error CS1501: No overload for method 'M' takes 1 arguments
var code =
"""
class C
{
void M() { }
void Test()
{
int i = 0;
[|M|](ref i);
}
}
""";
var fix0 =
"""
class C
{
void M(ref int i) { }
void Test()
{
int i = 0;
M(ref i);
}
}
""";
await TestInRegularAndScriptAsync(code, fix0, index: 0);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_InvocationStyles_OutParameter_WithTypeDeclarationOutsideArgument()
{
// error CS1501: No overload for method 'M' takes 1 arguments
var code =
"""
class C
{
void M() { }
void Test()
{
int i = 0;
[|M|](out i);
}
}
""";
var fix0 =
"""
class C
{
void M(out int i) { }
void Test()
{
int i = 0;
M(out i);
}
}
""";
await TestInRegularAndScriptAsync(code, fix0, index: 0);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_InvocationStyles_OutParameter_WithTypeDeclarationInArgument()
{
// error CS1501: No overload for method 'M' takes 1 arguments
var code =
"""
class C
{
void M() { }
void Test()
{
[|M|](out int i);
}
}
""";
var fix0 =
"""
class C
{
void M(out int i) { }
void Test()
{
M(out int i);
}
}
""";
await TestInRegularAndScriptAsync(code, fix0, index: 0);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_InvocationStyles_OutParameter_WithVarTypeDeclarationInArgument()
{
// error CS1501: No overload for method 'M' takes 1 arguments
var code =
"""
class C
{
void M() { }
void Test()
{
[|M|](out var i);
}
}
""";
var fix0 =
"""
class C
{
void M(out object i) { }
void Test()
{
M(out var i);
}
}
""";
await TestInRegularAndScriptAsync(code, fix0, index: 0);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")]
public async Task TestInvocation_Indexer_NotSupported()
{
// Could be fixed by allowing ElementAccessExpression next to InvocationExpression
// in AbstractAddParameterCodeFixProvider.RegisterCodeFixesAsync.
// error CS1501: No overload for method 'this' takes 2 arguments
var code =
"""
public class C {
public int this[int i]
{
get => 1;
set {}
}
public void Test() {
var i = [|this[0,0]|];
}
}
""";
await TestMissingAsync(code);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29061")]
public async Task TestThis_DoNotOfferToFixTheConstructorWithTheDiagnosticOnIt()
{
// error CS1729: 'C' does not contain a constructor that takes 1 arguments
var code =
"""
public class C {
public C(): [|this|](1)
{ }
}
""";
await TestMissingAsync(code);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29061")]
public async Task TestThis_Fix_IfACandidateIsAvailable()
{
// error CS1729: 'C' does not contain a constructor that takes 2 arguments
var code =
"""
class C
{
public C(int i) { }
public C(): [|this|](1, 1)
{ }
}
""";
var fix0 =
"""
class C
{
public C(int i, int v) { }
public C(): this(1, 1)
{ }
}
""";
await TestInRegularAndScriptAsync(code, fix0, index: 0);
await TestActionCountAsync(code, 1);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29061")]
public async Task TestBase_Fix_IfACandidateIsAvailable()
{
// error CS1729: 'B' does not contain a constructor that takes 1 arguments
var code =
"""
public class B
{
B() { }
}
public class C : B
{
public C(int i) : [|base|](i) { }
}
""";
var fix0 =
"""
public class B
{
B(int i) { }
}
public class C : B
{
public C(int i) : base(i) { }
}
""";
await TestInRegularAndScriptAsync(code, fix0, index: 0);
await TestActionCountAsync(code, 1);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29753")]
public async Task LocalFunction_AddParameterToLocalFunctionWithOneParameter()
{
// CS1501 No overload for method takes 2 arguments
var code =
"""
class Rsrp
{
public void M()
{
[|Local|]("ignore this", true);
void Local(string whatever)
{
}
}
}
""";
var fix0 =
"""
class Rsrp
{
public void M()
{
Local("ignore this", true);
void Local(string whatever, bool v)
{
}
}
}
""";
await TestInRegularAndScriptAsync(code, fix0, index: 0);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29752")]
public async Task LocalFunction_AddNamedParameterToLocalFunctionWithOneParameter()
{
// CS1739: The best overload for 'Local' does not have a parameter named 'mynewparameter'
var code =
"""
class Rsrp
{
public void M()
{
Local("ignore this", [|mynewparameter|]: true);
void Local(string whatever)
{
}
}
}
""";
var fix0 =
"""
class Rsrp
{
public void M()
{
Local("ignore this", mynewparameter: true);
void Local(string whatever, bool mynewparameter)
{
}
}
}
""";
await TestInRegularAndScriptAsync(code, fix0, index: 0);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39270")]
public async Task TestWithArgThatHasImplicitConversionToParamType1()
{
await TestInRegularAndScriptAsync(
"""
class BaseClass { }
class MyClass : BaseClass
{
void TestFunc()
{
MyClass param1 = new MyClass();
int newparam = 1;
[|MyFunc|](param1, newparam);
}
void MyFunc(BaseClass param1) { }
}
""",
"""
class BaseClass { }
class MyClass : BaseClass
{
void TestFunc()
{
MyClass param1 = new MyClass();
int newparam = 1;
MyFunc(param1, newparam);
}
void MyFunc(BaseClass param1, int newparam) { }
}
""");
}
[Fact]
public async Task TestOnExtensionGetEnumerator()
{
var code =
"""
using System.Collections.Generic;
namespace N {
static class Extensions
{
public static IEnumerator<int> GetEnumerator(this object o)
{
}
}
class C1
{
void M1()
{
new object().[|GetEnumerator|](1);
foreach (var a in new object());
}
}}
""";
var fix =
"""
using System.Collections.Generic;
namespace N {
static class Extensions
{
public static IEnumerator<int> GetEnumerator(this object o, int v)
{
}
}
class C1
{
void M1()
{
new object().GetEnumerator(1);
foreach (var a in new object());
}
}}
""";
await TestInRegularAndScriptAsync(code, fix);
}
[Fact]
public async Task TestOnExtensionGetAsyncEnumerator()
{
var code =
"""
using System.Collections.Generic;
using System.Threading.Tasks;
namespace N {
static class Extensions
{
public static IAsyncEnumerator<int> GetAsyncEnumerator(this object o)
{
}
}
class C1
{
async Task M1()
{
new object().[|GetAsyncEnumerator|](1);
await foreach (var a in new object());
}
}}
""" + IAsyncEnumerable;
var fix =
"""
using System.Collections.Generic;
using System.Threading.Tasks;
namespace N {
static class Extensions
{
public static IAsyncEnumerator<int> GetAsyncEnumerator(this object o, int v)
{
}
}
class C1
{
async Task M1()
{
new object().GetAsyncEnumerator(1);
await foreach (var a in new object());
}
}}
""" + IAsyncEnumerable;
await TestInRegularAndScriptAsync(code, fix);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44271")]
public async Task TopLevelStatement()
{
await TestInRegularAndScriptAsync("""
[|local|](1, 2, 3);
void local(int x, int y)
{
}
""",
"""
[|local|](1, 2, 3);
void local(int x, int y, int v)
{
}
""", parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp9));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44271")]
public async Task TopLevelStatement_Nested()
{
await TestInRegularAndScriptAsync("""
void outer()
{
[|local|](1, 2, 3);
void local(int x, int y)
{
}
}
""",
"""
void outer()
{
local(1, 2, 3);
void local(int x, int y, int v)
{
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42559")]
public async Task TestAddParameter_ImplicitObjectCreation()
{
await TestInRegularAndScriptAsync("""
class C
{
C(int i) { }
void M()
{
C c = [||]new(1, 2);
}
}
""",
"""
class C
{
C(int i, int v) { }
void M()
{
C c = new(1, 2);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48042")]
public async Task TestNamedArgOnExtensionMethod()
{
await TestInRegularAndScriptAsync(
"""
namespace r
{
static class AbcExtensions
{
public static Abc Act(this Abc state, bool p = true) => state;
}
class Abc {
void Test()
=> new Abc().Act([|param3|]: 123);
}
}
""",
"""
namespace r
{
static class AbcExtensions
{
public static Abc Act(this Abc state, bool p = true, int param3 = 0) => state;
}
class Abc {
void Test()
=> new Abc().Act(param3: 123);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/54408")]
public async Task TestPositionalRecord()
{
await TestInRegularAndScriptAsync("""
var b = "B";
var r = [|new R(1, b)|];
record R(int A);
namespace System.Runtime.CompilerServices
{
public static class IsExternalInit { }
}
""", """
var b = "B";
var r = new R(1, b);
record R(int A, string b);
namespace System.Runtime.CompilerServices
{
public static class IsExternalInit { }
}
""", parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp9));
}
[Fact]
public async Task Test_PrimaryConstructor_Class()
{
await TestInRegularAndScriptAsync("""
var b = "B";
var r = [|new R(1, b)|];
class R(int A);
""", """
var b = "B";
var r = new R(1, b);
class R(int A, string b);
""", parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp12));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/54408")]
public async Task TestPositionalRecordStruct()
{
await TestInRegularAndScriptAsync("""
var b = "B";
var r = [|new R(1, b)|];
record struct R(int A);
namespace System.Runtime.CompilerServices
{
public static class IsExternalInit { }
}
""", """
var b = "B";
var r = new R(1, b);
record struct R(int A, string b);
namespace System.Runtime.CompilerServices
{
public static class IsExternalInit { }
}
""", parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp9));
}
[Fact]
public async Task Test_PrimaryConstructor_Struct()
{
await TestInRegularAndScriptAsync("""
var b = "B";
var r = [|new R(1, b)|];
struct R(int A);
""", """
var b = "B";
var r = new R(1, b);
struct R(int A, string b);
""", parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp12));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56952")]
public async Task TestRecordsNamingConventions()
{
await TestInRegularAndScript1Async("""
[|new Test("repro")|];
record Test();
""", """
new Test("repro");
record Test(string V);
""");
}
[Fact]
public async Task TestNamingConventions_PrimaryConstructor_Class()
{
await TestInRegularAndScript1Async("""
[|new Test("repro")|];
class Test();
""", """
new Test("repro");
class Test(string v);
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56952")]
public async Task TestRecordsNamingConventions_RecordStruct()
{
await TestInRegularAndScript1Async("""
[|new Test("repro")|];
record struct Test();
""", """
new Test("repro");
record struct Test(string V);
""");
}
[Fact]
public async Task TestNamingConventions_PrimaryConstructor_Struct()
{
await TestInRegularAndScript1Async("""
[|new Test("repro")|];
struct Test();
""", """
new Test("repro");
struct Test(string v);
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61715")]
public async Task TestMethodGroup1()
{
await TestInRegularAndScript1Async("""
public class Example
{
public void Add(int x)
{
}
public void DoSomething()
{
}
public void Main()
{
[|DoSomething|](Add);
}
}
""", """
public class Example
{
public void Add(int x)
{
}
public void DoSomething(System.Action<int> add)
{
}
public void Main()
{
DoSomething(Add);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61715")]
public async Task TestMethodGroup2()
{
await TestInRegularAndScript1Async("""
public class Example
{
public void Add(int x, string y)
{
}
public void DoSomething()
{
}
public void Main()
{
[|DoSomething|](Add);
}
}
""", """
public class Example
{
public void Add(int x, string y)
{
}
public void DoSomething(System.Action<int, string> add)
{
}
public void Main()
{
DoSomething(Add);
}
}
""");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61715")]
public async Task TestMethodGroup3()
{
await TestInRegularAndScript1Async("""
public class Example
{
public int Add(int x, string y)
{
return 0;
}
public void DoSomething()
{
}
public void Main()
{
[|DoSomething|](Add);
}
}
""", """
public class Example
{
public int Add(int x, string y)
{
return 0;
}
public void DoSomething(System.Func<int, string, int> add)
{
}
public void Main()
{
DoSomething(Add);
}
}
""");
}
}
|