in resharper/resharper-unity/src/Unity/CSharp/Feature/Services/QuickFixes/PreferNonAllocApiQuickFix.cs [41:137]
protected override Action<ITextControl> ExecutePsiTransaction(ISolution solution, IProgressIndicator progress)
{
var oldMethod = myExpression.Reference.Resolve().DeclaredElement as IMethod;
if (oldMethod == null)
return null;
var factory = CSharpElementFactory.GetInstance(myInvocationExpression);
var builder = FactoryArgumentsBuilder.Create();
if (myExpression.QualifierExpression != null)
{
builder.Argument(myExpression.QualifierExpression);
builder.Append(".");
}
builder.Append(myNewMethod.ShortName);
builder.Append("(");
var returnType = oldMethod.ReturnType;
var oldArguments = myInvocationExpression.Arguments;
var firstPositionalArgIdx = GetPositionalArgumentIndex(oldArguments);
var curArgIdx = 0;
var newParameters = myNewMethod.Parameters;
var argumentIndex = 0;
// insert new argument to correct position. If we should use positional argument, we will check it and use.
for (int i = 0; i < newParameters.Count; i++)
{
var parameter = newParameters[i];
if (parameter.Type.Equals(returnType))
{
var referenceExpression = factory.CreateReferenceExpression(GetUniqueName(myInvocationExpression, ResultParamName));
IArgument argument = curArgIdx > firstPositionalArgIdx
? factory.CreateArgument(ParameterKind.VALUE, ResultParamName, referenceExpression)
: factory.CreateArgument(ParameterKind.VALUE, referenceExpression);
builder.Argument(argument);
argumentIndex = i;
}
else
{
builder.Argument(oldArguments[curArgIdx]);
curArgIdx++;
}
if (i + 1 != newParameters.Count)
{
builder.Append(",");
}
}
builder.Append(")");
var newInvocation = factory.CreateExpression(builder.ToString(), builder.ToArguments());
var newDeclaration = (IDeclarationStatement)factory.CreateStatement("var $0 = $1;", GetUniqueName(myInvocationExpression, "size"), newInvocation);
var oldStatement = myInvocationExpression.GetContainingStatement().NotNull("oldStatement != null");
IDeclarationStatement result;
if (oldStatement is IExpressionStatement)
{
result = oldStatement.ReplaceBy(newDeclaration);
}
else
{
var declaration = (oldStatement as IDeclarationStatement).NotNull(nameof(oldStatement) + " is not IDeclarationStatement");
// if only one declaration just replace it
if (declaration.Declaration.Declarators.Count == 1)
{
result = oldStatement.ReplaceBy(newDeclaration);
}
else
{
// There are several declaration, exclude our and transform it.
var expression = myInvocationExpression.GetContainingParenthesizedExpression();
var currentInitializer = ExpressionInitializerNavigator.GetByValue(expression);
var selectedDeclarator = LocalVariableDeclarationNavigator.GetByInitial(currentInitializer).NotNull("selectedDeclarator != null");
MultipleDeclarationUtil.SplitDeclarationBefore(selectedDeclarator);
MultipleDeclarationUtil.SplitDeclarationAfter(selectedDeclarator);
result = declaration.ReplaceBy(newDeclaration);
}
}
var actualArgument = result.Descendants<IArgumentList>().First().Arguments[argumentIndex];
if (!actualArgument.IsValid())
return null;
// allow user to decide which array he will use
var hotspotsRegistry = new HotspotsRegistry(newInvocation.GetPsiServices());
hotspotsRegistry.Register(new ITreeNode[] {actualArgument});
return BulbActionUtils.ExecuteHotspotSession(hotspotsRegistry, actualArgument.GetDocumentRange());
}