public void VisitFuncdef(FunctionDef f)
{
MethodGenerator mgen;
MemberAttributes attrs = 0;
if (this.gen.CurrentMethod != null)
{
var lgen = new LambdaBodyGenerator(f, f.parameters, true, gen);
var def = lgen.GenerateLambdaVariable(f);
var meth = lgen.Generate();
def.InitExpression = gen.Lambda(
meth.Parameters.Select(p => new CodeVariableReferenceExpression(p.ParameterName)).ToArray(),
meth.Statements);
gen.CurrentMethod.Statements.Add(def);
return;
}
if (this.currentClass != null)
{
// Inside a class; is this a instance method?
bool hasSelf = f.parameters.Where(p => p.Id != null && p.Id.Name == "self").Count() > 0;
if (hasSelf)
{
// Presence of 'self' says it _is_ an instance method.
var adjustedPs = f.parameters.Where(p => p.Id == null || p.Id.Name != "self").ToList();
var fnName = f.name.Name;
if (fnName == "__init__")
{
// Magic function __init__ is a ctor.
mgen = new ConstructorGenerator(f, adjustedPs, gen);
}
else
{
if (f.name.Name == "__str__")
{
attrs = MemberAttributes.Override;
fnName = "ToString";
}
mgen = new MethodGenerator(f, fnName, adjustedPs, false, gen);
}
}
else
{
mgen = new MethodGenerator(f, f.name.Name, f.parameters, true, gen);
}
}
else
{
mgen = new MethodGenerator(f, f.name.Name, f.parameters, true, gen);
}
CodeMemberMethod m = mgen.Generate();
m.Attributes |= attrs;
if (customAttrs != null)
{
m.CustomAttributes.AddRange(this.customAttrs);
customAttrs = null;
}
}