未验证 提交 78a8d1ae 编写于 作者: J Julien Couvreur 提交者: GitHub

ChangeSignature: enable on local functions (#25404)

上级 90b0d0c5
...@@ -564,7 +564,7 @@ private void AddMemberModifiersIfRequired(ISymbol symbol) ...@@ -564,7 +564,7 @@ private void AddMemberModifiersIfRequired(ISymbol symbol)
if (format.MemberOptions.IncludesOption(SymbolDisplayMemberOptions.IncludeModifiers) && if (format.MemberOptions.IncludesOption(SymbolDisplayMemberOptions.IncludeModifiers) &&
(containingType == null || (containingType == null ||
(containingType.TypeKind != TypeKind.Interface && !IsEnumMember(symbol)))) (containingType.TypeKind != TypeKind.Interface && !IsEnumMember(symbol) && !IsLocalFunction(symbol))))
{ {
var isConst = symbol is IFieldSymbol && ((IFieldSymbol)symbol).IsConst; var isConst = symbol is IFieldSymbol && ((IFieldSymbol)symbol).IsConst;
if (symbol.IsStatic && !isConst) if (symbol.IsStatic && !isConst)
......
// 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;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.PooledObjects;
...@@ -287,12 +288,22 @@ private void AddAccessibilityIfRequired(ISymbol symbol) ...@@ -287,12 +288,22 @@ private void AddAccessibilityIfRequired(ISymbol symbol)
if (format.MemberOptions.IncludesOption(SymbolDisplayMemberOptions.IncludeAccessibility) && if (format.MemberOptions.IncludesOption(SymbolDisplayMemberOptions.IncludeAccessibility) &&
(containingType == null || (containingType == null ||
(containingType.TypeKind != TypeKind.Interface && !IsEnumMember(symbol)))) (containingType.TypeKind != TypeKind.Interface && !IsEnumMember(symbol) & !IsLocalFunction(symbol))))
{ {
AddAccessibility(symbol); AddAccessibility(symbol);
} }
} }
private static bool IsLocalFunction(ISymbol symbol)
{
if (symbol.Kind != SymbolKind.Method)
{
return false;
}
return ((IMethodSymbol)symbol).MethodKind == MethodKind.LocalFunction;
}
private void AddAccessibility(ISymbol symbol) private void AddAccessibility(ISymbol symbol)
{ {
switch (symbol.DeclaredAccessibility) switch (symbol.DeclaredAccessibility)
......
...@@ -5854,6 +5854,47 @@ void M() ...@@ -5854,6 +5854,47 @@ void M()
SymbolDisplayPartKind.Punctuation); // ) SymbolDisplayPartKind.Punctuation); // )
} }
[Fact]
[CompilerTrait(CompilerFeature.LocalFunctions)]
public void LocalFunctionForChangeSignature()
{
SymbolDisplayFormat changeSignatureFormat = new SymbolDisplayFormat(
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes,
extensionMethodStyle: SymbolDisplayExtensionMethodStyle.StaticMethod,
memberOptions:
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeExplicitInterface |
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeRef);
var srcTree = SyntaxFactory.ParseSyntaxTree(@"
class C
{
void M()
{
void Local() {}
}
}");
var root = srcTree.GetRoot();
var comp = CreateCompilation(srcTree);
var semanticModel = comp.GetSemanticModel(srcTree);
var local = root.DescendantNodes()
.Where(n => n.Kind() == SyntaxKind.LocalFunctionStatement)
.Single();
var localSymbol = Assert.IsType<LocalFunctionSymbol>(
semanticModel.GetDeclaredSymbol(local));
Verify(localSymbol.ToDisplayParts(changeSignatureFormat),
"void Local",
SymbolDisplayPartKind.Keyword, // void
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.MethodName // Local
);
}
[Fact] [Fact]
[CompilerTrait(CompilerFeature.LocalFunctions)] [CompilerTrait(CompilerFeature.LocalFunctions)]
public void LocalFunction2() public void LocalFunction2()
......
...@@ -9,6 +9,70 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature ...@@ -9,6 +9,70 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature
{ {
public partial class ChangeSignatureTests : AbstractChangeSignatureTests public partial class ChangeSignatureTests : AbstractChangeSignatureTests
{ {
[WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)]
public async Task ReorderLocalFunctionParametersAndArguments_OnDeclaration()
{
var markup = @"
using System;
class MyClass
{
public void M()
{
Goo(1, 2);
void $$Goo(int x, string y)
{
}
}
}";
var permutation = new[] { 1, 0 };
var updatedCode = @"
using System;
class MyClass
{
public void M()
{
Goo(2, 1);
void Goo(string y, int x)
{
}
}
}";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)]
public async Task ReorderLocalFunctionParametersAndArguments_OnInvocation()
{
var markup = @"
using System;
class MyClass
{
public void M()
{
$$Goo(1, null);
void Goo(int x, string y)
{
}
}
}";
var permutation = new[] { 1, 0 };
var updatedCode = @"
using System;
class MyClass
{
public void M()
{
Goo(null, 1);
void Goo(string y, int x)
{
}
}
}";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] [WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)]
public async Task ReorderMethodParameters() public async Task ReorderMethodParameters()
{ {
......
...@@ -28,7 +28,8 @@ internal sealed class CSharpChangeSignatureService : AbstractChangeSignatureServ ...@@ -28,7 +28,8 @@ internal sealed class CSharpChangeSignatureService : AbstractChangeSignatureServ
SyntaxKind.IndexerDeclaration, SyntaxKind.IndexerDeclaration,
SyntaxKind.DelegateDeclaration, SyntaxKind.DelegateDeclaration,
SyntaxKind.SimpleLambdaExpression, SyntaxKind.SimpleLambdaExpression,
SyntaxKind.ParenthesizedLambdaExpression); SyntaxKind.ParenthesizedLambdaExpression,
SyntaxKind.LocalFunctionStatement);
private static readonly ImmutableArray<SyntaxKind> _declarationAndInvocableKinds = private static readonly ImmutableArray<SyntaxKind> _declarationAndInvocableKinds =
_declarationKinds.Concat(ImmutableArray.Create( _declarationKinds.Concat(ImmutableArray.Create(
...@@ -56,6 +57,7 @@ internal sealed class CSharpChangeSignatureService : AbstractChangeSignatureServ ...@@ -56,6 +57,7 @@ internal sealed class CSharpChangeSignatureService : AbstractChangeSignatureServ
private static readonly ImmutableArray<SyntaxKind> _updatableNodeKinds = ImmutableArray.Create( private static readonly ImmutableArray<SyntaxKind> _updatableNodeKinds = ImmutableArray.Create(
SyntaxKind.MethodDeclaration, SyntaxKind.MethodDeclaration,
SyntaxKind.LocalFunctionStatement,
SyntaxKind.ConstructorDeclaration, SyntaxKind.ConstructorDeclaration,
SyntaxKind.IndexerDeclaration, SyntaxKind.IndexerDeclaration,
SyntaxKind.InvocationExpression, SyntaxKind.InvocationExpression,
...@@ -253,35 +255,42 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode) ...@@ -253,35 +255,42 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode)
if (updatedNode.IsKind(SyntaxKind.MethodDeclaration)) if (updatedNode.IsKind(SyntaxKind.MethodDeclaration))
{ {
var method = updatedNode as MethodDeclarationSyntax; var method = (MethodDeclarationSyntax)updatedNode;
var updatedParameters = PermuteDeclaration(method.ParameterList.Parameters, signaturePermutation); var updatedParameters = PermuteDeclaration(method.ParameterList.Parameters, signaturePermutation);
return method.WithParameterList(method.ParameterList.WithParameters(updatedParameters).WithAdditionalAnnotations(changeSignatureFormattingAnnotation)); return method.WithParameterList(method.ParameterList.WithParameters(updatedParameters).WithAdditionalAnnotations(changeSignatureFormattingAnnotation));
} }
if (updatedNode.IsKind(SyntaxKind.LocalFunctionStatement))
{
var localFunction = (LocalFunctionStatementSyntax)updatedNode;
var updatedParameters = PermuteDeclaration(localFunction.ParameterList.Parameters, signaturePermutation);
return localFunction.WithParameterList(localFunction.ParameterList.WithParameters(updatedParameters).WithAdditionalAnnotations(changeSignatureFormattingAnnotation));
}
if (updatedNode.IsKind(SyntaxKind.ConstructorDeclaration)) if (updatedNode.IsKind(SyntaxKind.ConstructorDeclaration))
{ {
var constructor = updatedNode as ConstructorDeclarationSyntax; var constructor = (ConstructorDeclarationSyntax)updatedNode;
var updatedParameters = PermuteDeclaration(constructor.ParameterList.Parameters, signaturePermutation); var updatedParameters = PermuteDeclaration(constructor.ParameterList.Parameters, signaturePermutation);
return constructor.WithParameterList(constructor.ParameterList.WithParameters(updatedParameters).WithAdditionalAnnotations(changeSignatureFormattingAnnotation)); return constructor.WithParameterList(constructor.ParameterList.WithParameters(updatedParameters).WithAdditionalAnnotations(changeSignatureFormattingAnnotation));
} }
if (updatedNode.IsKind(SyntaxKind.IndexerDeclaration)) if (updatedNode.IsKind(SyntaxKind.IndexerDeclaration))
{ {
var indexer = updatedNode as IndexerDeclarationSyntax; var indexer = (IndexerDeclarationSyntax)updatedNode;
var updatedParameters = PermuteDeclaration(indexer.ParameterList.Parameters, signaturePermutation); var updatedParameters = PermuteDeclaration(indexer.ParameterList.Parameters, signaturePermutation);
return indexer.WithParameterList(indexer.ParameterList.WithParameters(updatedParameters).WithAdditionalAnnotations(changeSignatureFormattingAnnotation)); return indexer.WithParameterList(indexer.ParameterList.WithParameters(updatedParameters).WithAdditionalAnnotations(changeSignatureFormattingAnnotation));
} }
if (updatedNode.IsKind(SyntaxKind.DelegateDeclaration)) if (updatedNode.IsKind(SyntaxKind.DelegateDeclaration))
{ {
var delegateDeclaration = updatedNode as DelegateDeclarationSyntax; var delegateDeclaration = (DelegateDeclarationSyntax)updatedNode;
var updatedParameters = PermuteDeclaration(delegateDeclaration.ParameterList.Parameters, signaturePermutation); var updatedParameters = PermuteDeclaration(delegateDeclaration.ParameterList.Parameters, signaturePermutation);
return delegateDeclaration.WithParameterList(delegateDeclaration.ParameterList.WithParameters(updatedParameters).WithAdditionalAnnotations(changeSignatureFormattingAnnotation)); return delegateDeclaration.WithParameterList(delegateDeclaration.ParameterList.WithParameters(updatedParameters).WithAdditionalAnnotations(changeSignatureFormattingAnnotation));
} }
if (updatedNode.IsKind(SyntaxKind.AnonymousMethodExpression)) if (updatedNode.IsKind(SyntaxKind.AnonymousMethodExpression))
{ {
var anonymousMethod = updatedNode as AnonymousMethodExpressionSyntax; var anonymousMethod = (AnonymousMethodExpressionSyntax)updatedNode;
// Delegates may omit parameters in C# // Delegates may omit parameters in C#
if (anonymousMethod.ParameterList == null) if (anonymousMethod.ParameterList == null)
...@@ -295,7 +304,7 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode) ...@@ -295,7 +304,7 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode)
if (updatedNode.IsKind(SyntaxKind.SimpleLambdaExpression)) if (updatedNode.IsKind(SyntaxKind.SimpleLambdaExpression))
{ {
var lambda = updatedNode as SimpleLambdaExpressionSyntax; var lambda = (SimpleLambdaExpressionSyntax)updatedNode;
if (signaturePermutation.UpdatedConfiguration.ToListOfParameters().Any()) if (signaturePermutation.UpdatedConfiguration.ToListOfParameters().Any())
{ {
...@@ -315,7 +324,7 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode) ...@@ -315,7 +324,7 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode)
if (updatedNode.IsKind(SyntaxKind.ParenthesizedLambdaExpression)) if (updatedNode.IsKind(SyntaxKind.ParenthesizedLambdaExpression))
{ {
var lambda = updatedNode as ParenthesizedLambdaExpressionSyntax; var lambda = (ParenthesizedLambdaExpressionSyntax)updatedNode;
var updatedParameters = PermuteDeclaration(lambda.ParameterList.Parameters, signaturePermutation); var updatedParameters = PermuteDeclaration(lambda.ParameterList.Parameters, signaturePermutation);
return lambda.WithParameterList(lambda.ParameterList.WithParameters(updatedParameters)); return lambda.WithParameterList(lambda.ParameterList.WithParameters(updatedParameters));
} }
...@@ -324,10 +333,10 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode) ...@@ -324,10 +333,10 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode)
if (updatedNode.IsKind(SyntaxKind.InvocationExpression)) if (updatedNode.IsKind(SyntaxKind.InvocationExpression))
{ {
var invocation = updatedNode as InvocationExpressionSyntax; var invocation = (InvocationExpressionSyntax)updatedNode;
var semanticModel = document.GetSemanticModelAsync(cancellationToken).WaitAndGetResult(cancellationToken); var semanticModel = document.GetSemanticModelAsync(cancellationToken).WaitAndGetResult(cancellationToken);
var symbolInfo = semanticModel.GetSymbolInfo(originalNode as InvocationExpressionSyntax, cancellationToken); var symbolInfo = semanticModel.GetSymbolInfo((InvocationExpressionSyntax)originalNode, cancellationToken);
var methodSymbol = symbolInfo.Symbol as IMethodSymbol; var methodSymbol = symbolInfo.Symbol as IMethodSymbol;
var isReducedExtensionMethod = false; var isReducedExtensionMethod = false;
...@@ -342,7 +351,7 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode) ...@@ -342,7 +351,7 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode)
if (updatedNode.IsKind(SyntaxKind.ObjectCreationExpression)) if (updatedNode.IsKind(SyntaxKind.ObjectCreationExpression))
{ {
var objCreation = updatedNode as ObjectCreationExpressionSyntax; var objCreation = (ObjectCreationExpressionSyntax)updatedNode;
var newArguments = PermuteArgumentList(document, declarationSymbol, objCreation.ArgumentList.Arguments, signaturePermutation); var newArguments = PermuteArgumentList(document, declarationSymbol, objCreation.ArgumentList.Arguments, signaturePermutation);
return objCreation.WithArgumentList(objCreation.ArgumentList.WithArguments(newArguments).WithAdditionalAnnotations(changeSignatureFormattingAnnotation)); return objCreation.WithArgumentList(objCreation.ArgumentList.WithArguments(newArguments).WithAdditionalAnnotations(changeSignatureFormattingAnnotation));
} }
...@@ -350,21 +359,21 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode) ...@@ -350,21 +359,21 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode)
if (updatedNode.IsKind(SyntaxKind.ThisConstructorInitializer) || if (updatedNode.IsKind(SyntaxKind.ThisConstructorInitializer) ||
updatedNode.IsKind(SyntaxKind.BaseConstructorInitializer)) updatedNode.IsKind(SyntaxKind.BaseConstructorInitializer))
{ {
var objCreation = updatedNode as ConstructorInitializerSyntax; var objCreation = (ConstructorInitializerSyntax)updatedNode;
var newArguments = PermuteArgumentList(document, declarationSymbol, objCreation.ArgumentList.Arguments, signaturePermutation); var newArguments = PermuteArgumentList(document, declarationSymbol, objCreation.ArgumentList.Arguments, signaturePermutation);
return objCreation.WithArgumentList(objCreation.ArgumentList.WithArguments(newArguments).WithAdditionalAnnotations(changeSignatureFormattingAnnotation)); return objCreation.WithArgumentList(objCreation.ArgumentList.WithArguments(newArguments).WithAdditionalAnnotations(changeSignatureFormattingAnnotation));
} }
if (updatedNode.IsKind(SyntaxKind.ElementAccessExpression)) if (updatedNode.IsKind(SyntaxKind.ElementAccessExpression))
{ {
var elementAccess = updatedNode as ElementAccessExpressionSyntax; var elementAccess = (ElementAccessExpressionSyntax)updatedNode;
var newArguments = PermuteArgumentList(document, declarationSymbol, elementAccess.ArgumentList.Arguments, signaturePermutation); var newArguments = PermuteArgumentList(document, declarationSymbol, elementAccess.ArgumentList.Arguments, signaturePermutation);
return elementAccess.WithArgumentList(elementAccess.ArgumentList.WithArguments(newArguments).WithAdditionalAnnotations(changeSignatureFormattingAnnotation)); return elementAccess.WithArgumentList(elementAccess.ArgumentList.WithArguments(newArguments).WithAdditionalAnnotations(changeSignatureFormattingAnnotation));
} }
if (updatedNode.IsKind(SyntaxKind.Attribute)) if (updatedNode.IsKind(SyntaxKind.Attribute))
{ {
var attribute = updatedNode as AttributeSyntax; var attribute = (AttributeSyntax)updatedNode;
var newArguments = PermuteAttributeArgumentList(document, declarationSymbol, attribute.ArgumentList.Arguments, signaturePermutation); var newArguments = PermuteAttributeArgumentList(document, declarationSymbol, attribute.ArgumentList.Arguments, signaturePermutation);
return attribute.WithArgumentList(attribute.ArgumentList.WithArguments(newArguments).WithAdditionalAnnotations(changeSignatureFormattingAnnotation)); return attribute.WithArgumentList(attribute.ArgumentList.WithArguments(newArguments).WithAdditionalAnnotations(changeSignatureFormattingAnnotation));
} }
...@@ -373,7 +382,7 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode) ...@@ -373,7 +382,7 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode)
if (updatedNode.IsKind(SyntaxKind.NameMemberCref)) if (updatedNode.IsKind(SyntaxKind.NameMemberCref))
{ {
var nameMemberCref = updatedNode as NameMemberCrefSyntax; var nameMemberCref = (NameMemberCrefSyntax)updatedNode;
if (nameMemberCref.Parameters == null || if (nameMemberCref.Parameters == null ||
!nameMemberCref.Parameters.Parameters.Any()) !nameMemberCref.Parameters.Parameters.Any())
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册