Browse Source

Add check to disqualify most invocations early in OptionalParameterCouldBeSkippedIssue.

Simon Lindgren 14 years ago
parent
commit
b6cbd38edd
  1. 24
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/OptionalParameterCouldBeSkippedIssue.cs

24
ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/OptionalParameterCouldBeSkippedIssue.cs

@ -66,15 +66,24 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
(invocation, args) => new InvocationExpression(invocation.Target.Clone(), args)); (invocation, args) => new InvocationExpression(invocation.Target.Clone(), args));
} }
void CheckMethodCall<T> (T node, IEnumerable<Expression> arguments, Func<T, IEnumerable<Expression>, T> generateReplacement) where T: AstNode void CheckMethodCall<T> (T node, IEnumerable<Expression> args, Func<T, IEnumerable<Expression>, T> generateReplacement) where T: AstNode
{ {
// The first two checks are unnecessary, but eliminates the majority of calls early,
// improving performance.
var arguments = args.ToArray();
if (arguments.Length == 0)
return;
var lastArg = arguments[arguments.Length - 1];
if (!(lastArg is PrimitiveExpression || lastArg is NamedArgumentExpression))
return;
var invocationResolveResult = ctx.Resolve(node) as CSharpInvocationResolveResult; var invocationResolveResult = ctx.Resolve(node) as CSharpInvocationResolveResult;
if (invocationResolveResult == null) if (invocationResolveResult == null)
return; return;
string actionMessage = ctx.TranslateString("Remove redundant arguments"); string actionMessage = ctx.TranslateString("Remove redundant arguments");
var redundantArguments = GetRedundantArguments(arguments.ToArray(), invocationResolveResult); var redundantArguments = GetRedundantArguments(arguments, invocationResolveResult);
var action = new CodeAction(actionMessage, script => { var action = new CodeAction(actionMessage, script => {
var newArgumentList = arguments var newArgumentList = arguments
.Where(arg => !redundantArguments.Contains(arg)) .Where(arg => !redundantArguments.Contains(arg))
@ -84,7 +93,6 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
}); });
var issueMessage = ctx.TranslateString("Argument is identical to the default value"); var issueMessage = ctx.TranslateString("Argument is identical to the default value");
var lastPositionalArgument = redundantArguments.FirstOrDefault(expression => !(expression is NamedArgumentExpression)); var lastPositionalArgument = redundantArguments.FirstOrDefault(expression => !(expression is NamedArgumentExpression));
bool hasNamedArguments = false;
foreach (var argument in redundantArguments) { foreach (var argument in redundantArguments) {
var localArgument = argument; var localArgument = argument;
@ -100,7 +108,6 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
var newInvocation = generateReplacement(node, newArgumentList); var newInvocation = generateReplacement(node, newArgumentList);
script.Replace(node, newInvocation); script.Replace(node, newInvocation);
})); }));
hasNamedArguments = true;
} else { } else {
var title = ctx.TranslateString("Remove this and the following positional arguments"); var title = ctx.TranslateString("Remove this and the following positional arguments");
actions.Add(new CodeAction(title, script => { actions.Add(new CodeAction(title, script => {
@ -116,11 +123,13 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
} }
} }
IEnumerable<Expression> GetRedundantArguments(Expression[] arguments, CSharpInvocationResolveResult invocationResolveResult) IList<Expression> GetRedundantArguments(Expression[] arguments, CSharpInvocationResolveResult invocationResolveResult)
{ {
var argumentToParameterMap = invocationResolveResult.GetArgumentToParameterMap(); var argumentToParameterMap = invocationResolveResult.GetArgumentToParameterMap();
var resolvedParameters = invocationResolveResult.Member.Parameters; var resolvedParameters = invocationResolveResult.Member.Parameters;
IList<Expression> redundantArguments = new List<Expression>();
for (int i = arguments.Length - 1; i >= 0; i--) { for (int i = arguments.Length - 1; i >= 0; i--) {
var parameterIndex = argumentToParameterMap[i]; var parameterIndex = argumentToParameterMap[i];
if (parameterIndex == -1) if (parameterIndex == -1)
@ -141,7 +150,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
// Stop here since any arguments before this one has to be there // Stop here since any arguments before this one has to be there
// to enable the passing of this argument // to enable the passing of this argument
break; break;
yield return argument; redundantArguments.Add(argument);
} else if (argument is NamedArgumentExpression) { } else if (argument is NamedArgumentExpression) {
var expression = ((NamedArgumentExpression)argument).Expression as PrimitiveExpression; var expression = ((NamedArgumentExpression)argument).Expression as PrimitiveExpression;
if (expression == null) if (expression == null)
@ -150,12 +159,13 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
if (expressionResolveResult == null || parameter.ConstantValue != expressionResolveResult.ConstantValue) if (expressionResolveResult == null || parameter.ConstantValue != expressionResolveResult.ConstantValue)
// continue, since there can still be more arguments that are redundant // continue, since there can still be more arguments that are redundant
continue; continue;
yield return argument; redundantArguments.Add(argument);
} else { } else {
// This is a non-constant positional argument => no more redundancies are possible // This is a non-constant positional argument => no more redundancies are possible
break; break;
} }
} }
return redundantArguments;
} }
} }
} }

Loading…
Cancel
Save