/// <summary>
/// Emit a mixin router from a class to the mixin body methods.
/// </summary>
public void emitMixinRouter(Method m)
{
string parent = FanUtil.toDotnetTypeName(m.parent());
string name = FanUtil.toDotnetMethodName(m.name());
string ret = FanUtil.toDotnetTypeName(m.inheritedReturns());
string[] parTypes = new string[] { parent };
List pars = m.@params();
int paramCount = pars.sz();
// find first param with default value
int firstDefault = paramCount;
for (int i=0; i<paramCount; i++)
if (((Param)pars.get(i)).hasDefault())
{ firstDefault = i; break; }
// generate routers
for (int i=firstDefault; i<=paramCount; i++)
{
string[] myParams = new string[i];
string[] myParamNames = new string[i];
string[] implParams = new string[i+1];
implParams[0] = parent;
for (int j=0; j<i; j++)
{
Param param = (Param)m.@params().get(j);
Type pt = param.type();
string s = FanUtil.toDotnetTypeName(pt);
myParams[j] = s;
myParamNames[j] = param.name();
implParams[j+1] = s;
}
// CLR requires public virtual
PERWAPI.MethAttr attr = PERWAPI.MethAttr.Public | PERWAPI.MethAttr.Virtual;
PERWAPI.CILInstructions code = emitter.emitMethod(name, ret, myParamNames, myParams,
attr, new string[0], new string[0]);
code.Inst(PERWAPI.Op.ldarg_0); // push this
for (int p=0; p<i; p++)
{
// push args
Param param = (Param)m.@params().get(p);
FCodeEmit.loadVar(code, FanUtil.toDotnetStackType(param.type()), p+1);
}
PERWAPI.Method meth = emitter.findMethod(parent + "_", name, implParams, ret);
code.MethInst(PERWAPI.MethodOp.call, meth);
code.Inst(PERWAPI.Op.ret);
}
}