public void VisitFuncdef(FunctionDef f)
        {
            if (VisitDecorators(f))
            {
                return;
            }
            MethodGenerator  mgen;
            MemberAttributes attrs = 0;

            if (this.gen.CurrentMember != null)
            {
                GenerateLocalFunction(f);
                return;
            }
            if (this.classDef != null)
            {
                // Inside a class; is this a instance method?
                bool hasSelf = f.parameters.Any(p => p.Id != null && p.Id.Name == "self");
                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(this.classDef, f, adjustedPs, types, gen);
                    }
                    else
                    {
                        if (f.name.Name == "__str__")
                        {
                            attrs  = MemberAttributes.Override;
                            fnName = "ToString";
                        }
                        mgen = new MethodGenerator(this.classDef, f, fnName, adjustedPs, false, async, types, gen);
                    }
                }
                else
                {
                    mgen = new MethodGenerator(this.classDef, f, f.name.Name, f.parameters, true, async, types, gen);
                }
            }
            else
            {
                mgen = new MethodGenerator(this.classDef, f, f.name.Name, f.parameters, true, async, types, gen);
            }
            ICodeFunction fn = mgen.Generate();

            //$TODO: move into generate
            if (fn is CodeMember m)
            {
                m.Attributes |= attrs;
                if (customAttrs != null)
                {
                    m.CustomAttributes.AddRange(this.customAttrs);
                    customAttrs = null;
                }
            }
        }
Example #2
0
        public void VisitFuncdef(FunctionDef f)
        {
            if (VisitDecorators(f))
            {
                return;
            }
            MethodGenerator  mgen;
            MemberAttributes attrs = 0;

            if (this.gen.CurrentMember != null)
            {
                //$TODO: C# 7 supports local functions.
                var lgen = new LambdaBodyGenerator(f, f.parameters, true, async, types, 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.CurrentMemberStatements.Add(def);
                return;
            }
            if (this.currentClass != null)
            {
                // Inside a class; is this a instance method?
                bool hasSelf = f.parameters.Any(p => p.Id != null && p.Id.Name == "self");
                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, types, gen);
                    }
                    else
                    {
                        if (f.name.Name == "__str__")
                        {
                            attrs  = MemberAttributes.Override;
                            fnName = "ToString";
                        }
                        mgen = new MethodGenerator(f, fnName, adjustedPs, false, async, types, gen);
                    }
                }
                else
                {
                    mgen = new MethodGenerator(f, f.name.Name, f.parameters, true, async, types, gen);
                }
            }
            else
            {
                mgen = new MethodGenerator(f, f.name.Name, f.parameters, true, async, types, gen);
            }
            CodeMemberMethod m = mgen.Generate();

            m.Attributes |= attrs;
            if (customAttrs != null)
            {
                m.CustomAttributes.AddRange(this.customAttrs);
                customAttrs = null;
            }
        }