提交 1d26fc4a 编写于 作者: I Ivan Basov

supporitng tests scenarios with no parameters in the original configuration

上级 60ecc6e2
......@@ -107,6 +107,31 @@ static void M(this object o, string b, int newIntegerParameter, string newString
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)]
public async Task AddParameterToParameterlessMethod()
{
var markup = @"
static class Ext
{
static void $$M()
{
M();
}
}";
var updatedSignature = new[] {
new AddedParameterOrExistingIndex(new AddedParameter("int", "newIntegerParameter", "12345"))};
var updatedCode = @"
static class Ext
{
static void M(int newIntegerParameter)
{
M(12345);
}
}";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)]
public async Task AddAndReorderLocalFunctionParametersAndArguments_OnDeclaration()
{
......
......@@ -87,6 +87,31 @@ Module Program
End Sub
End Module
]]></Text>.NormalizedValue()
Await TestChangeSignatureViaCommandAsync(LanguageNames.VisualBasic, markup, updatedSignature:=permutation, expectedUpdatedInvocationDocumentCode:=updatedCode)
End Function
<WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)>
Public Async Function TestAddParameterToParameterlessMethod() As Task
Dim markup = <Text><![CDATA[
Module Program
Sub $$M()
M()
End Sub
End Module
]]></Text>.NormalizedValue()
Dim permutation = {
New AddedParameterOrExistingIndex(New AddedParameter("Integer", "newIntegerParameter", "12345"))}
Dim updatedCode = <Text><![CDATA[
Module Program
Sub M(newIntegerParameter As Integer)
M(newIntegerParameter:=12345)
End Sub
End Module
]]></Text>.NormalizedValue()
Await TestChangeSignatureViaCommandAsync(LanguageNames.VisualBasic, markup, updatedSignature:=permutation, expectedUpdatedInvocationDocumentCode:=updatedCode)
......
......@@ -8,6 +8,7 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.ChangeSignature;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.FindSymbols;
......@@ -365,7 +366,6 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode)
else
{
// No parameters. Change to a parenthesized lambda expression
var emptyParameterList = SyntaxFactory.ParameterList()
.WithLeadingTrivia(lambda.Parameter.GetLeadingTrivia())
.WithTrailingTrivia(lambda.Parameter.GetTrailingTrivia());
......@@ -440,7 +440,6 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode)
}
// Handle references in crefs
if (updatedNode.IsKind(SyntaxKind.NameMemberCref))
{
var nameMemberCref = (NameMemberCrefSyntax)updatedNode;
......@@ -550,52 +549,11 @@ private static CrefParameterSyntax CreateNewCrefParameterSyntax(AddedParameter a
SignatureChange updatedSignature,
Func<AddedParameter, T> createNewParameterMethod) where T : SyntaxNode
{
var originalParameters = updatedSignature.OriginalConfiguration.ToListOfParameters();
var reorderedParameters = updatedSignature.UpdatedConfiguration.ToListOfParameters();
int numAddedParameters = 0;
var newParameters = new List<T>();
for (var index = 0; index < reorderedParameters.Count; index++)
{
var newParam = reorderedParameters[index];
var pos = originalParameters.IndexOf(p => p.Symbol == newParam.Symbol);
if (pos == -1)
{
// Added parameter
numAddedParameters++;
var newParameter = createNewParameterMethod(newParam as AddedParameter);
newParameters.Add(newParameter);
}
else
{
var param = list[pos];
// copy whitespace trivia from original position
param = TransferLeadingWhitespaceTrivia(param, list[index - numAddedParameters]);
newParameters.Add(param);
}
}
int numSeparatorsToSkip;
if (originalParameters.Count == 0)
{
// ()
// Adding X parameters, need to add X-1 separators.
numSeparatorsToSkip = originalParameters.Count - reorderedParameters.Count + 1;
}
else
{
// (a,b,c)
// Adding X parameters, need to add X separators.
numSeparatorsToSkip = originalParameters.Count - reorderedParameters.Count;
}
return SyntaxFactory.SeparatedList(newParameters, GetSeparators(list, numSeparatorsToSkip));
var permuteDeclarationBase = base.PermuteDeclarationBase<T>(list, updatedSignature, createNewParameterMethod);
return SyntaxFactory.SeparatedList(permuteDeclarationBase.Item1, permuteDeclarationBase.Item2);
}
private static T TransferLeadingWhitespaceTrivia<T>(T newArgument, SyntaxNode oldArgument) where T : SyntaxNode
protected override T TransferLeadingWhitespaceTrivia<T>(T newArgument, SyntaxNode oldArgument)
{
var oldTrivia = oldArgument.GetLeadingTrivia();
var oldOnlyHasWhitespaceTrivia = oldTrivia.All(t => t.IsKind(SyntaxKind.WhitespaceTrivia));
......@@ -647,7 +605,7 @@ private static CrefParameterSyntax CreateNewCrefParameterSyntax(AddedParameter a
return SyntaxFactory.SeparatedList(newArgumentsWithTrivia, GetSeparators(arguments, numSeparatorsToSkip));
}
private static List<T> TransferLeadingWhitespaceTrivia<T, U>(IEnumerable<T> newArguments, SeparatedSyntaxList<U> oldArguments)
private List<T> TransferLeadingWhitespaceTrivia<T, U>(IEnumerable<T> newArguments, SeparatedSyntaxList<U> oldArguments)
where T : SyntaxNode
where U : SyntaxNode
{
......
......@@ -48,6 +48,8 @@ internal abstract class AbstractChangeSignatureService : ILanguageService
protected abstract IEnumerable<AbstractFormattingRule> GetFormattingRules(Document document);
protected abstract T TransferLeadingWhitespaceTrivia<T>(T newArgument, SyntaxNode oldArgument) where T : SyntaxNode;
public async Task<ImmutableArray<ChangeSignatureCodeAction>> GetChangeSignatureCodeActionAsync(Document document, TextSpan span, CancellationToken cancellationToken)
{
var context = await GetContextAsync(document, span.Start, restrictToDeclarations: true, cancellationToken: cancellationToken).ConfigureAwait(false);
......@@ -598,9 +600,63 @@ protected static int GetParameterIndex<TNode>(SeparatedSyntaxList<TNode> paramet
return parameters.Count - 1;
}
protected (IEnumerable<T>, IEnumerable<SyntaxToken>) PermuteDeclarationBase<T>(
SeparatedSyntaxList<T> list,
SignatureChange updatedSignature,
Func<AddedParameter, T> createNewParameterMethod) where T : SyntaxNode
{
var originalParameters = updatedSignature.OriginalConfiguration.ToListOfParameters();
var reorderedParameters = updatedSignature.UpdatedConfiguration.ToListOfParameters();
int numAddedParameters = 0;
var newParameters = new List<T>();
for (var index = 0; index < reorderedParameters.Count; index++)
{
var newParam = reorderedParameters[index];
var pos = originalParameters.IndexOf(p => p.Symbol == newParam.Symbol);
if (pos == -1)
{
// Added parameter
numAddedParameters++;
var newParameter = createNewParameterMethod(newParam as AddedParameter);
newParameters.Add(newParameter);
}
else
{
var param = list[pos];
// copy whitespace trivia from original position
param = TransferLeadingWhitespaceTrivia(param, list[index - numAddedParameters]);
newParameters.Add(param);
}
}
int numSeparatorsToSkip;
if (originalParameters.Count == 0)
{
// ()
// Adding X parameters, need to add X-1 separators.
numSeparatorsToSkip = originalParameters.Count - reorderedParameters.Count + 1;
}
else
{
// (a,b,c)
// Adding X parameters, need to add X separators.
numSeparatorsToSkip = originalParameters.Count - reorderedParameters.Count;
}
return (newParameters, GetSeparators(list, numSeparatorsToSkip));
}
protected List<SyntaxToken> GetSeparators<T>(SeparatedSyntaxList<T> arguments, int numSeparatorsToSkip = 0) where T : SyntaxNode
{
var separators = new List<SyntaxToken>();
if (numSeparatorsToSkip < 0)
{
numSeparatorsToSkip = 0;
}
for (int i = 0; i < arguments.SeparatorCount - numSeparatorsToSkip; i++)
{
......
......@@ -11,6 +11,7 @@ Imports Microsoft.CodeAnalysis.Host.Mef
Imports Microsoft.CodeAnalysis.PooledObjects
Imports System.Composition
Imports Microsoft.CodeAnalysis.Utilities
Imports Microsoft.CodeAnalysis
Namespace Microsoft.CodeAnalysis.VisualBasic.ChangeSignature
<ExportLanguageService(GetType(AbstractChangeSignatureService), LanguageNames.VisualBasic), [Shared]>
......@@ -438,37 +439,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ChangeSignature
parameterList As SeparatedSyntaxList(Of T),
updatedSignature As SignatureChange,
createNewParameterMethod As Func(Of AddedParameter, T)) As SeparatedSyntaxList(Of T)
Dim originalParameterSymbols = updatedSignature.OriginalConfiguration.ToListOfParameters().Select(Function(p) p.Symbol).ToArray()
Dim reorderedParameters = updatedSignature.UpdatedConfiguration.ToListOfParameters()
Dim numSeparatorsToSkip = originalParameterSymbols.Length - reorderedParameters.Count
' The parameter list could be empty if dealing with delegates.
If parameterList.IsEmpty() Then
Return SyntaxFactory.SeparatedList(parameterList, GetSeparators(parameterList, numSeparatorsToSkip))
End If
Dim numAddedParameters = 0
Dim newParameters = New List(Of T)
For Each newParam In reorderedParameters
Dim existingParam = TryCast(newParam, ExistingParameter)
If existingParam IsNot Nothing Then
Dim pos = originalParameterSymbols.IndexOf(existingParam.Symbol)
Dim param = parameterList(pos)
newParameters.Add(param)
Else
' Added parameter
numAddedParameters += 1
Dim newParameter = createNewParameterMethod(DirectCast(newParam, AddedParameter))
newParameters.Add(newParameter)
End If
Next
Return SyntaxFactory.SeparatedList(newParameters, GetSeparators(parameterList, numSeparatorsToSkip))
End Function
Private Shared Function CreateNewArgumentSyntax(addedParameter As AddedParameter) As ArgumentSyntax
Return SyntaxFactory.SimpleArgument(SyntaxFactory.IdentifierName(SyntaxFactory.Identifier(addedParameter.TypeName)))
Dim basePermuteDeclaration = PermuteDeclarationBase(parameterList, updatedSignature, createNewParameterMethod)
Return SyntaxFactory.SeparatedList(basePermuteDeclaration.Item1, basePermuteDeclaration.Item2)
End Function
Private Shared Function CreateNewParameterSyntax(addedParameter As AddedParameter) As ParameterSyntax
......@@ -623,7 +595,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ChangeSignature
SyntaxFactory.List(extraNodeList.AsEnumerable()))
extraDocComments = extraDocComments.WithLeadingTrivia(SyntaxFactory.DocumentationCommentExteriorTrivia("''' ")).
WithTrailingTrivia(node.GetTrailingTrivia()).
WithTrailingTrivia(SyntaxFactory.EndOfLine(document.Project.Solution.Workspace.Options.GetOption(FormattingOptions.NewLine, LanguageNames.CSharp)),
WithTrailingTrivia(SyntaxFactory.EndOfLine(document.Project.Solution.Workspace.Options.GetOption(FormattingOptions.NewLine, LanguageNames.CSharp)),
lastWhiteSpaceTrivia)
Dim newTrivia = SyntaxFactory.Trivia(extraDocComments)
......@@ -696,5 +668,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ChangeSignature
Protected Overrides Function CreateSeparatorSyntaxToken() As SyntaxToken
Return SyntaxFactory.Token(SyntaxKind.CommaToken).WithTrailingTrivia(SyntaxFactory.ElasticSpace)
End Function
Protected Overrides Function TransferLeadingWhitespaceTrivia(Of T As SyntaxNode)(newArgument As T, oldArgument As SyntaxNode) As T
Return newArgument
End Function
End Class
End Namespace
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册