public static BuiltinFunction MakeOrAdd(BuiltinFunction existing, string name, MethodBase mi, FunctionType funcType) { if (existing != null) { existing.AddMethod(mi); return existing; } else { return MakeMethod(name, mi, funcType); } }
private void FindMatchingTargets(Type[] sig, MethodBase[] targets, BuiltinFunction rm) { int args = sig.Length; foreach (MethodBase mb in targets) { ParameterInfo[] pis = mb.GetParameters(); if (pis.Length != args) continue; // Check each parameter type for an exact match. bool match = true; for (int i = 0; i < args; i++) if (pis[i].ParameterType != sig[i]) { match = false; break; } if (!match) continue; // Okay, we have a match, add it to the list. rm.AddMethod(mb); } }
// Use indexing on generic methods to provide a new reflected method with targets bound with // the supplied type arguments. public object this[object key] { get { // Retrieve the list of type arguments from the index. Type[] types; Tuple typesTuple = key as Tuple; if (typesTuple != null) { types = new Type[typesTuple.Count]; for (int i = 0; i < types.Length; i++) { types[i] = Converter.ConvertToType(typesTuple[i]); } } else { types = new Type[] { Converter.ConvertToType(key) }; } // Start building a new ReflectedMethod that will contain targets with bound type // arguments. BuiltinFunction rm = new BuiltinFunction(); // Search for generic targets with the correct arity (number of type parameters). // Compatible targets must be MethodInfos by definition (constructors never take // type arguments). int arity = types.Length; foreach (MethodBase mb in targets) { MethodInfo mi = mb as MethodInfo; if (mi == null) continue; if (mi.ContainsGenericParameters && mi.GetGenericArguments().Length == arity) rm.AddMethod(mi.MakeGenericMethod(types)); } if (rm.Targets == null) throw Ops.TypeError(string.Format("bad type args to this generic method {0}", this)); rm.Name = Name; rm.FunctionType = FunctionType | FunctionType.OptimizeChecked; // don't want to optimize & whack our dictionary. return rm; } }