提交 f91cdf99 编写于 作者: C CyrusNajmabadi

better support for params-constructors.

上级 806a34a0
......@@ -181,6 +181,57 @@ void M()
{
new C(1, true);
}
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddParameter)]
public async Task TestParams1()
{
await TestAsync(
@"
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, Trait(Traits.Feature, Traits.Features.CodeActionsAddParameter)]
public async Task TestParams2()
{
await TestMissingAsync(
@"
class C
{
public C(params int[] i) { }
}
class D
{
void M()
{
new [|C|](1, true);
}
}");
}
}
......
......@@ -91,7 +91,7 @@ private Task HandleInvocationExpressionAsync(CodeFixContext context, TInvocation
foreach (var constructor in type.InstanceConstructors.OrderBy(m => m.Parameters.Length))
{
if (IsInSource(constructor) &&
constructor.Parameters.Length < arguments.Count)
NonParamsParameterCount(constructor) < arguments.Count)
{
var argumentToAdd = DetermineFirstArgumentToAdd(
semanticModel, syntaxFacts, comparer, constructor, arguments);
......@@ -111,6 +111,9 @@ private Task HandleInvocationExpressionAsync(CodeFixContext context, TInvocation
}
}
private int NonParamsParameterCount(IMethodSymbol method)
=> method.IsParams() ? method.Parameters.Length - 1 : method.Parameters.Length;
private bool IsInSource(ISymbol symbol)
=> !symbol.IsImplicitlyDeclared &&
symbol.DeclaringSyntaxReferences.Length > 0 &&
......@@ -188,11 +191,11 @@ private static SyntaxNode GetNewMethodDeclaration(IMethodSymbol method, TArgumen
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
private TArgumentSyntax DetermineFirstArgumentToAdd(
SemanticModel semanticModel,
ISyntaxFactsService syntaxFacts,
StringComparer comparer,
IMethodSymbol method,
SeparatedSyntaxList<TArgumentSyntax> arguments)
SemanticModel semanticModel,
ISyntaxFactsService syntaxFacts,
StringComparer comparer,
IMethodSymbol method,
SeparatedSyntaxList<TArgumentSyntax> arguments)
{
var methodParameterNames = new HashSet<string>(comparer);
methodParameterNames.AddRange(method.Parameters.Select(p => p.Name));
......@@ -217,17 +220,28 @@ private static SyntaxNode GetNewMethodDeclaration(IMethodSymbol method, TArgumen
// then this definitely is an argument we could add.
if (i >= method.Parameters.Length)
{
if (method.Parameters.LastOrDefault()?.IsParams == true)
{
// Last parameter is a params. We can't place any parameters past it.
return null;
}
return argument;
}
var argumentTypeInfo = semanticModel.GetTypeInfo(syntaxFacts.GetExpressionOfArgument(argument));
var parameter = method.Parameters[i];
// If this argument already matches the method's parameter, then we don't want
// to add it.
if (!parameter.Type.Equals(argumentTypeInfo.Type) &&
!parameter.Type.Equals(argumentTypeInfo.ConvertedType))
if (!TypeInfoMatchesType(argumentTypeInfo, parameter.Type))
{
if (parameter.IsParams && parameter.Type is IArrayTypeSymbol arrayType)
{
if (TypeInfoMatchesType(argumentTypeInfo, arrayType.ElementType))
{
return null;
}
}
return argument;
}
}
......@@ -236,6 +250,9 @@ private static SyntaxNode GetNewMethodDeclaration(IMethodSymbol method, TArgumen
return null;
}
private bool TypeInfoMatchesType(TypeInfo argumentTypeInfo, ITypeSymbol type)
=> type.Equals(argumentTypeInfo.Type) || type.Equals(argumentTypeInfo.ConvertedType);
private class MyCodeAction : CodeAction.DocumentChangeAction
{
public MyCodeAction(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册