/// <summary> /// Constructor used by GenericType and we are given the generic /// method that is being parameterized. /// </summary> public Method(Type parent, string name, int flags, Facets facets, int lineNum, Type returns, Type inheritedReturns, List pars, Method generic) : base(parent, name, flags, facets, lineNum) { List fparams = pars.ro(); if ((flags & (FConst.Static|FConst.Ctor)) == 0) { object[] temp = new object[pars.sz()+1]; temp[0] = new Param("this", parent, 0); pars.copyInto(temp, 1, pars.sz()); fparams = new List(Sys.ParamType, temp); } this.m_func = new MethodFunc(this, returns, fparams); this.m_params = pars; this.m_inheritedReturns = inheritedReturns; this.m_mask = (generic != null) ? 0 : toMask(parent, returns, pars); this.m_generic = generic; }
/// <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); } }
/// <summary> /// Parameterize the specified method (reuse if generic /// parameterization isn't necessary). /// </summary> internal Method parameterize(Method m) { // if not generic, short circuit and reuse original if (!m.isGenericMethod()) return m; // new signature Func func = m.m_func; Type ret; List pars = new List(Sys.ParamType, m.m_params.sz()); // parameterize return type if (func.returns().isGenericParameter()) ret = parameterize(func.returns()); else ret = func.returns(); // narrow pars (or just reuse if not parameterized) for (int i=0; i<m.m_params.sz(); i++) { Param p = (Param)m.m_params.get(i); if (p.m_type.isGenericParameter()) { pars.add(new Param(p.m_name, parameterize(p.m_type), p.m_mask)); } else { pars.add(p); } } Method pm = new Method(this, m.m_name, m.m_flags, m.m_facets, m.m_lineNum, ret, m.m_inheritedReturns, pars, m); pm.m_reflect = m.m_reflect; return pm; }
private int runTest(Type type, Method method) { Method setup = type.method("setup", true); Method teardown = type.method("teardown", true); FanSysTest test = null; List args = null; try { test = (FanSysTest)type.make(); args = new List(Sys.ObjType, new object[] {test}); } catch (System.Exception e) { System.Console.WriteLine(); System.Console.WriteLine("ERROR: Cannot make test " + type); if (e is Err.Val) ((Err.Val)e).err().trace(); else Err.dumpStack(e); return -1; } try { test.m_curTestMethod = method; setup.callList(args); method.callList(args); return test.verifyCount; } catch (System.Exception e) { //System.Console.WriteLine(" -- " + e.GetType() + " -- "); System.Console.WriteLine(); System.Console.WriteLine("TEST FAILED"); if (e is Err.Val) ((Err.Val)e).err().trace(); else Err.dumpStack(e); return -1; } finally { try { if (args != null) teardown.callList(args); } catch (System.Exception e) { Err.dumpStack(e); } test.m_curTestMethod = null; } }
void complexAdd(Type t, object obj, Method addMethod, object val, int line) { try { addMethod.invoke(obj, new object[] { val }); } catch (System.Exception ex) { throw err("Cannot call " + t.qname() + ".add: " + ex, line, ex); } }
/// <summary> /// Constructor used by GenericType and we are given the generic /// method that is being parameterized. /// </summary> public Method(Type parent, string name, int flags, Facets facets, int lineNum, Type returns, Type inheritedReturns, List pars, Method generic) : base(parent, name, flags, facets, lineNum) { List fparams = pars.ro(); if ((flags & (FConst.Static | FConst.Ctor)) == 0) { object[] temp = new object[pars.sz() + 1]; temp[0] = new Param("this", parent, 0); pars.copyInto(temp, 1, pars.sz()); fparams = new List(Sys.ParamType, temp); } this.m_func = new MethodFunc(this, returns, fparams); this.m_params = pars; this.m_inheritedReturns = inheritedReturns; this.m_mask = (generic != null) ? 0 : toMask(parent, returns, pars); this.m_generic = generic; }
internal MethodFunc(Method method, Type returns, List pars) { this.m = method; this.m_returns = returns; this.m_params = pars; }
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; } }