diff --git a/src/Features/Core/Portable/AddParameter/AbstractAddParameterCodeFixProvider.cs b/src/Features/Core/Portable/AddParameter/AbstractAddParameterCodeFixProvider.cs index a41afda552db0245146b20ff44dcc192a28ae096..32d76043b22fa89d137e2924a381f6a099bb0b29 100644 --- a/src/Features/Core/Portable/AddParameter/AbstractAddParameterCodeFixProvider.cs +++ b/src/Features/Core/Portable/AddParameter/AbstractAddParameterCodeFixProvider.cs @@ -65,6 +65,11 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) } } + /// + /// If the diagnostic is on a argument, the argument is considered to be the argument to fix. + /// There are some exceptions to this rule. Returning null indicates that the fixer needs + /// to find the relevant argument by itself. + /// private TArgumentSyntax TryGetRelevantArgument( SyntaxNode initialNode, SyntaxNode node, Diagnostic diagnostic) { @@ -139,6 +144,52 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) RegisterFixForMethodOverloads(context, arguments, insertionData); } + private ImmutableArray> GetArgumentInsertPositionForMethodCandidates( + TArgumentSyntax argumentOpt, + SemanticModel semanticModel, + ISyntaxFactsService syntaxFacts, + SeparatedSyntaxList arguments, + ImmutableArray methodCandidates) + { + var comparer = syntaxFacts.StringComparer; + var methodsAndArgumentToAdd = ArrayBuilder>.GetInstance(); + + foreach (var method in methodCandidates.OrderBy(m => m.Parameters.Length)) + { + if (method.IsNonImplicitAndFromSource()) + { + var isNamedArgument = !string.IsNullOrWhiteSpace(syntaxFacts.GetNameForArgument(argumentOpt)); + + if (isNamedArgument || NonParamsParameterCount(method) < arguments.Count) + { + var argumentToAdd = DetermineFirstArgumentToAdd( + semanticModel, syntaxFacts, comparer, method, + arguments, argumentOpt); + + if (argumentToAdd != null) + { + if (argumentOpt != null && argumentToAdd != argumentOpt) + { + // We were trying to fix a specific argument, but the argument we want + // to fix is something different. That means there was an error earlier + // than this argument. Which means we're looking at a non-viable + // constructor or method. Skip this one. + continue; + } + + methodsAndArgumentToAdd.Add(new ArgumentInsertPositionData( + method, argumentToAdd, arguments.IndexOf(argumentToAdd))); + } + } + } + } + + return methodsAndArgumentToAdd.ToImmutableAndFree(); + } + + private int NonParamsParameterCount(IMethodSymbol method) + => method.IsParams() ? method.Parameters.Length - 1 : method.Parameters.Length; + private void RegisterFixForMethodOverloads( CodeFixContext context, SeparatedSyntaxList arguments, @@ -230,52 +281,6 @@ private static string GetCodeFixTitle(IMethodSymbol methodToUpdate, IEnumerable< return title; } - private ImmutableArray> GetArgumentInsertPositionForMethodCandidates( - TArgumentSyntax argumentOpt, - SemanticModel semanticModel, - ISyntaxFactsService syntaxFacts, - SeparatedSyntaxList arguments, - ImmutableArray methodCandidates) - { - var comparer = syntaxFacts.StringComparer; - var methodsAndArgumentToAdd = ArrayBuilder>.GetInstance(); - - foreach (var method in methodCandidates.OrderBy(m => m.Parameters.Length)) - { - if (method.IsNonImplicitAndFromSource()) - { - var isNamedArgument = !string.IsNullOrWhiteSpace(syntaxFacts.GetNameForArgument(argumentOpt)); - - if (isNamedArgument || NonParamsParameterCount(method) < arguments.Count) - { - var argumentToAdd = DetermineFirstArgumentToAdd( - semanticModel, syntaxFacts, comparer, method, - arguments, argumentOpt); - - if (argumentToAdd != null) - { - if (argumentOpt != null && argumentToAdd != argumentOpt) - { - // We were trying to fix a specific argument, but the argument we want - // to fix is something different. That means there was an error earlier - // than this argument. Which means we're looking at a non-viable - // constructor or method. Skip this one. - continue; - } - - methodsAndArgumentToAdd.Add(new ArgumentInsertPositionData( - method, argumentToAdd, arguments.IndexOf(argumentToAdd))); - } - } - } - } - - return methodsAndArgumentToAdd.ToImmutableAndFree(); - } - - private int NonParamsParameterCount(IMethodSymbol method) - => method.IsParams() ? method.Parameters.Length - 1 : method.Parameters.Length; - private async Task FixAsync( Document invocationDocument, IMethodSymbol method,