public virtual object make(List args) { Method make = method("make", false); if (make != null && make.isPublic()) { int numArgs = args == null ? 0 : args.sz(); List p = make.@params(); if ((numArgs == p.sz()) || (numArgs < p.sz() && ((Param)p.get(numArgs)).hasDefault())) { return(make.m_func.callList(args)); } } Slot defVal = slot("defVal", false); if (defVal is Field) { return(((Field)defVal).get(null)); } if (defVal is Method) { return(((Method)defVal).m_func.callList(null)); } throw Err.make("Type missing 'make' or 'defVal' slots: " + this).val; }
static int callMain(Type t, Method m) { // check parameter type and build main arguments List args; List pars = m.@params(); if (pars.sz() == 0) { args = null; } else if (((Param)pars.get(0)).type().@is(Sys.StrType.toListOf()) && (pars.sz() == 1 || ((Param)pars.get(1)).hasDefault())) { args = new List(Sys.ObjType, new object[] { Env.cur().args() }); } else { System.Console.WriteLine("ERROR: Invalid parameters for main: " + m.signature()); return -1; } // invoke try { if (m.isStatic()) return toResult(m.callList(args)); else return toResult(m.callOn(t.make(), args)); } catch (Err.Val ex) { ex.err().trace(); return -1; } }
/// <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); } }
private void finishMethod(MethodInfo m, bool staticOnly) { m_finishing = m.Name; string name = FanUtil.toFanMethodName(m.Name); Slot s = slot(name, false); if (s == null) { return; } if (s.parent() != this) { return; } if (staticOnly && !s.isStatic()) { return; } if (s is Method) { Method method = (Method)s; // alloc System.Reflection.MethodInfo[] array big enough // to handle all the versions with default parameters if (method.m_reflect == null) { int n = 1; for (int j = method.@params().sz() - 1; j >= 0; j--) { if (((Param)method.@params().get(j)).hasDefault()) { n++; } else { break; } } method.m_reflect = new MethodInfo[n]; } // get parameters, if sys we need to skip the // methods that use non-Fantom signatures ParameterInfo[] pars = m.GetParameters(); int numParams = pars.Length; if (m_pod == Sys.m_sysPod) { if (!checkAllFan(pars)) { return; } if (m_dotnetRepr) { bool dotnetStatic = m.IsStatic; if (!dotnetStatic) { return; } if (!method.isStatic() && !method.isCtor()) { --numParams; } } } // zero index is full signature up to using max defaults method.m_reflect[method.@params().sz() - numParams] = m; } else { Field field = (Field)s; if (m.ReturnType.ToString() == "System.Void") { field.m_setter.m_reflect = new MethodInfo[] { m } } ; else { field.m_getter.m_reflect = new MethodInfo[] { m } }; } } bool checkAllFan(ParameterInfo[] pars) { for (int i = 0; i < pars.Length; i++) { System.Type p = pars[i].ParameterType; if (!p.FullName.StartsWith("Fan.") && FanUtil.toFanType(p, false) == null) { return(false); } } return(true); }