未验证 提交 5d719960 编写于 作者: A Allison Chou 提交者: GitHub

Merge pull request #47657 from allisonchou/ChangeSignatureTargetTypedNew

Add change signature support for target-typed new
......@@ -46,6 +46,47 @@ public B(int a, int x = 10, int y = 11, int z = 12)
}
}
class D : B
{
public D() : base(1, 100, z: 102) { }
}";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[WorkItem(44126, "https://github.com/dotnet/roslyn/issues/44126")]
[WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)]
public async Task AddOptionalParameter_ToConstructor_TargetTypedNew()
{
var markup = @"
class B
{
public B() : this(1) { }
public B$$(int a)
{
B q = new(1);
}
}
class D : B
{
public D() : base(1) { }
}";
var updatedSignature = new[] {
new AddedParameterOrExistingIndex(0),
AddedParameterOrExistingIndex.CreateAdded("System.Int32", "x", CallSiteKind.Value, callSiteValue: "100", isRequired: false, defaultValue: "10"),
AddedParameterOrExistingIndex.CreateAdded("System.Int32", "y", CallSiteKind.Omitted, isRequired: false, defaultValue: "11"),
AddedParameterOrExistingIndex.CreateAdded("System.Int32", "z", CallSiteKind.Value, callSiteValue: "102", isRequired: false, defaultValue: "12")};
var updatedCode = @"
class B
{
public B() : this(1, 100, z: 102) { }
public B(int a, int x = 10, int y = 11, int z = 12)
{
B q = new(1, 100, z: 102);
}
}
class D : B
{
public D() : base(1, 100, z: 102) { }
......
......@@ -1237,7 +1237,7 @@ class C
public void M()
{
_ = new(1, 2);
C _ = new(1, ""y"");
}
}";
var permutation = new[] {
......@@ -1254,11 +1254,9 @@ class C
public void M()
{
_ = new(1, 2);
C _ = new(""y"", 34, 1);
}
}";
// Expect: _ = new(2, 34, 1);
// Tracked by https://github.com/dotnet/roslyn/issues/44126
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
}
......
......@@ -7,7 +7,6 @@
using Microsoft.CodeAnalysis.ChangeSignature;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.Editor.UnitTests.ChangeSignature;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
......
......@@ -377,5 +377,34 @@ class C
state = handler.GetCommandState(new ReorderParametersCommandArgs(textView, textView.TextBuffer));
Assert.True(state.IsUnspecified);
}
[WorkItem(44126, "https://github.com/dotnet/roslyn/issues/44126")]
[WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)]
public async Task RemoveParameters_TargetTypedNew()
{
var markup = @"
public class C
{
public $$C(int a, string b) { }
void M()
{
C c = new(1, ""b"");
}
}";
var updatedSignature = new[] { 1 };
var updatedCode = @"
public class C
{
public C(string b) { }
void M()
{
C c = new(""b"");
}
}";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode);
}
}
}
......@@ -202,6 +202,57 @@ public MyClass(string y, int x)
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[WorkItem(44126, "https://github.com/dotnet/roslyn/issues/44126")]
[WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)]
public async Task ReorderConstructorParametersAndArguments_TargetTypedNew()
{
var markup = @"
using System;
class MyClass2 : MyClass
{
public MyClass2() : base(5, ""test2"")
{
}
}
class MyClass
{
public MyClass() : this(2, ""test"")
{
}
public MyClass(int x, string y)
{
MyClass t = new$$(x, y);
}
}";
var permutation = new[] { 1, 0 };
var updatedCode = @"
using System;
class MyClass2 : MyClass
{
public MyClass2() : base(""test2"", 5)
{
}
}
class MyClass
{
public MyClass() : this(""test"", 2)
{
}
public MyClass(string y, int x)
{
MyClass t = new(y, x);
}
}";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)]
public async Task ReorderAttributeConstructorParametersAndArguments()
{
......
......@@ -53,6 +53,7 @@ internal sealed class CSharpChangeSignatureService : AbstractChangeSignatureServ
SyntaxKind.ThisConstructorInitializer,
SyntaxKind.BaseConstructorInitializer,
SyntaxKind.ObjectCreationExpression,
SyntaxKind.ImplicitObjectCreationExpression,
SyntaxKind.Attribute,
SyntaxKind.NameMemberCref));
......@@ -80,6 +81,7 @@ internal sealed class CSharpChangeSignatureService : AbstractChangeSignatureServ
SyntaxKind.ThisConstructorInitializer,
SyntaxKind.BaseConstructorInitializer,
SyntaxKind.ObjectCreationExpression,
SyntaxKind.ImplicitObjectCreationExpression,
SyntaxKind.Attribute,
SyntaxKind.DelegateDeclaration,
SyntaxKind.NameMemberCref,
......@@ -355,10 +357,26 @@ private static bool InSymbolHeader(SyntaxNode matchingNode, int position)
return parenLambda.WithParameterList(parenLambda.ParameterList.WithParameters(updatedParameters));
}
// Handle references in crefs
if (updatedNode.IsKind(SyntaxKind.NameMemberCref, out NameMemberCrefSyntax? nameMemberCref))
{
if (nameMemberCref.Parameters == null ||
!nameMemberCref.Parameters.Parameters.Any())
{
return nameMemberCref;
}
var newParameters = UpdateDeclaration(nameMemberCref.Parameters.Parameters, signaturePermutation, CreateNewCrefParameterSyntax);
var newCrefParameterList = nameMemberCref.Parameters.WithParameters(newParameters);
return nameMemberCref.WithParameters(newCrefParameterList);
}
var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);
// Update reference site argument lists
if (updatedNode.IsKind(SyntaxKind.InvocationExpression, out InvocationExpressionSyntax? invocation))
{
var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var symbolInfo = semanticModel.GetSymbolInfo((InvocationExpressionSyntax)originalNode, cancellationToken);
return invocation.WithArgumentList(
......@@ -373,16 +391,16 @@ private static bool InSymbolHeader(SyntaxNode matchingNode, int position)
cancellationToken).ConfigureAwait(false));
}
if (updatedNode.IsKind(SyntaxKind.ObjectCreationExpression, out ObjectCreationExpressionSyntax? objCreation))
// Handles both ObjectCreationExpressionSyntax and ImplicitObjectCreationExpressionSyntax
if (updatedNode is BaseObjectCreationExpressionSyntax objCreation)
{
var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var symbolInfo = semanticModel.GetSymbolInfo((ObjectCreationExpressionSyntax)originalNode, cancellationToken);
if (objCreation.ArgumentList == null)
{
return updatedNode;
}
var symbolInfo = semanticModel.GetSymbolInfo((BaseObjectCreationExpressionSyntax)originalNode, cancellationToken);
return objCreation.WithArgumentList(
await UpdateArgumentListAsync(
declarationSymbol,
......@@ -398,7 +416,6 @@ private static bool InSymbolHeader(SyntaxNode matchingNode, int position)
if (updatedNode.IsKind(SyntaxKind.ThisConstructorInitializer, out ConstructorInitializerSyntax? constructorInit) ||
updatedNode.IsKind(SyntaxKind.BaseConstructorInitializer, out constructorInit))
{
var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var symbolInfo = semanticModel.GetSymbolInfo((ConstructorInitializerSyntax)originalNode, cancellationToken);
return constructorInit.WithArgumentList(
......@@ -415,7 +432,6 @@ private static bool InSymbolHeader(SyntaxNode matchingNode, int position)
if (updatedNode.IsKind(SyntaxKind.ElementAccessExpression, out ElementAccessExpressionSyntax? elementAccess))
{
var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var symbolInfo = semanticModel.GetSymbolInfo((ElementAccessExpressionSyntax)originalNode, cancellationToken);
return elementAccess.WithArgumentList(
......@@ -432,7 +448,6 @@ private static bool InSymbolHeader(SyntaxNode matchingNode, int position)
if (updatedNode.IsKind(SyntaxKind.Attribute, out AttributeSyntax? attribute))
{
var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var symbolInfo = semanticModel.GetSymbolInfo((AttributeSyntax)originalNode, cancellationToken);
if (attribute.ArgumentList == null)
......@@ -452,21 +467,6 @@ private static bool InSymbolHeader(SyntaxNode matchingNode, int position)
cancellationToken).ConfigureAwait(false));
}
// Handle references in crefs
if (updatedNode.IsKind(SyntaxKind.NameMemberCref, out NameMemberCrefSyntax? nameMemberCref))
{
if (nameMemberCref.Parameters == null ||
!nameMemberCref.Parameters.Parameters.Any())
{
return nameMemberCref;
}
var newParameters = UpdateDeclaration(nameMemberCref.Parameters.Parameters, signaturePermutation, CreateNewCrefParameterSyntax);
var newCrefParameterList = nameMemberCref.Parameters.WithParameters(newParameters);
return nameMemberCref.WithParameters(newCrefParameterList);
}
Debug.Assert(false, "Unknown reference location");
return null;
}
......@@ -572,13 +572,10 @@ private static bool IsParamsArrayExpanded(SemanticModel semanticModel, SyntaxNod
}
else
{
#pragma warning disable IDE0007 // Use implicit type - Using 'var' causes "error CS8506: No best type was found for the switch expression"
// TODO: File a bug on IDE0007 analyzer
BaseArgumentListSyntax? argumentList = node switch
#pragma warning restore IDE0007 // Use implicit type
{
InvocationExpressionSyntax invocation => invocation.ArgumentList,
ObjectCreationExpressionSyntax objectCreation => objectCreation.ArgumentList,
BaseObjectCreationExpressionSyntax objectCreation => objectCreation.ArgumentList,
ConstructorInitializerSyntax constructorInitializer => constructorInitializer.ArgumentList,
ElementAccessExpressionSyntax elementAccess => elementAccess.ArgumentList,
_ => throw ExceptionUtilities.UnexpectedValue(node.Kind())
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册