internal static bool ReOrderArgsForNamedArguments(
MethodOrPropertySymbol methprop,
TypeArray pCurrentParameters,
AggregateType pCurrentType,
EXPRMEMGRP pGroup,
ArgInfos pArguments,
TypeManager typeManager,
ExprFactory exprFactory,
SymbolLoader symbolLoader)
{
// We use the param count from pCurrentParameters because they may have been resized
// for param arrays.
int numParameters = pCurrentParameters.size;
EXPR[] pExprArguments = new EXPR[numParameters];
// Now go through the parameters. First set all positional arguments in the new argument
// set, then for the remainder, look for a named argument with a matching name.
int index = 0;
EXPR paramArrayArgument = null;
TypeArray @params = typeManager.SubstTypeArray(
pCurrentParameters,
pCurrentType,
pGroup.typeArgs);
foreach (Name name in methprop.ParameterNames)
{
// This can happen if we had expanded our param array to size 0.
if (index >= pCurrentParameters.size)
{
break;
}
// If:
// (1) we have a param array method
// (2) we're on the last arg
// (3) the thing we have is an array init thats generated for param array
// then let us through.
if (methprop.isParamArray &&
index < pArguments.carg &&
pArguments.prgexpr[index].isARRINIT() && pArguments.prgexpr[index].asARRINIT().GeneratedForParamArray)
{
paramArrayArgument = pArguments.prgexpr[index];
}
// Positional.
if (index < pArguments.carg &&
!pArguments.prgexpr[index].isNamedArgumentSpecification() &&
!(pArguments.prgexpr[index].isARRINIT() && pArguments.prgexpr[index].asARRINIT().GeneratedForParamArray))
{
pExprArguments[index] = pArguments.prgexpr[index++];
continue;
}
// Look for names.
EXPR pNewArg = FindArgumentWithName(pArguments, name);
if (pNewArg == null)
{
if (methprop.IsParameterOptional(index))
{
pNewArg = GenerateOptionalArgument(symbolLoader, exprFactory, methprop, @params.Item(index), index);
}
else if (paramArrayArgument != null && index == methprop.Params.Count - 1)
{
// If we have a param array argument and we're on the last one, then use it.
pNewArg = paramArrayArgument;
}
else
{
// No name and no default value.
return false;
}
}
pExprArguments[index++] = pNewArg;
}
// Here we've found all the arguments, or have default values for them.
CType[] prgTypes = new CType[pCurrentParameters.size];
for (int i = 0; i < numParameters; i++)
{
if (i < pArguments.prgexpr.Count)
{
pArguments.prgexpr[i] = pExprArguments[i];
}
else
{
pArguments.prgexpr.Add(pExprArguments[i]);
}
prgTypes[i] = pArguments.prgexpr[i].type;
}
pArguments.carg = pCurrentParameters.size;
pArguments.types = symbolLoader.getBSymmgr().AllocParams(pCurrentParameters.size, prgTypes);
return true;
}