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); }
/// <summary> /// Merge the inherited slot into my slot maps. Assume this slot /// trumps any previous definition (because we process inheritance /// and my slots in the right order) /// slots: Slot[] by order /// nameToSlot: String name -> Slot /// nameToIndex: String name -> Long index of slots /// </summary> private void merge(Slot slot, List slots, Hashtable nameToSlot, Hashtable nameToIndex) { // skip constructors which aren't mine if (slot.isCtor() && slot.m_parent != this) return; string name = slot.m_name; if (nameToIndex[name] != null) { int dup = (int)nameToIndex[name]; // if the slot is inherited from Obj, then we can // safely ignore it as an override - the dup is most // likely already the same Obj method inherited from // a mixin; but the dup might actually be a more specific // override in which case we definitely don't want to // override with the sys::Obj version if (slot.parent() == Sys.ObjType) return; // if given the choice between two *inherited* slots where // one is concrete and abstract, then choose the concrete one Slot dupSlot = (Slot)slots.get(dup); if (slot.parent() != this && slot.isAbstract() && !dupSlot.isAbstract()) return; // check if this is a Getter or Setter, in which case the Field // trumps and we need to cache the method on the Field // Note: this works because we assume the compiler always generates // the field before the getter and setter in fcode if ((slot.m_flags & (FConst.Getter|FConst.Setter)) != 0) { Field field = (Field)slots.get(dup); if ((slot.m_flags & FConst.Getter) != 0) field.m_getter = (Method)slot; else field.m_setter = (Method)slot; return; } nameToSlot[name] = slot; slots.set(dup, slot); } else { nameToSlot[name] = slot; slots.add(slot); nameToIndex[name] = slots.sz()-1; } }
/// <summary> /// Merge the inherited slot into my slot maps. Assume this slot /// trumps any previous definition (because we process inheritance /// and my slots in the right order) /// slots: Slot[] by order /// nameToSlot: String name -> Slot /// nameToIndex: String name -> Long index of slots /// </summary> private void merge(Slot slot, List slots, Hashtable nameToSlot, Hashtable nameToIndex) { // skip constructors which aren't mine if (slot.isCtor() && slot.m_parent != this) { return; } string name = slot.m_name; if (nameToIndex[name] != null) { int dup = (int)nameToIndex[name]; // if the slot is inherited from Obj, then we can // safely ignore it as an override - the dup is most // likely already the same Obj method inherited from // a mixin; but the dup might actually be a more specific // override in which case we definitely don't want to // override with the sys::Obj version if (slot.parent() == Sys.ObjType) { return; } // if given the choice between two *inherited* slots where // one is concrete and abstract, then choose the concrete one Slot dupSlot = (Slot)slots.get(dup); if (slot.parent() != this && slot.isAbstract() && !dupSlot.isAbstract()) { return; } // check if this is a Getter or Setter, in which case the Field // trumps and we need to cache the method on the Field // Note: this works because we assume the compiler always generates // the field before the getter and setter in fcode if ((slot.m_flags & (FConst.Getter | FConst.Setter)) != 0) { Field field = (Field)slots.get(dup); if ((slot.m_flags & FConst.Getter) != 0) { field.m_getter = (Method)slot; } else { field.m_setter = (Method)slot; } return; } nameToSlot[name] = slot; slots.set(dup, slot); } else { nameToSlot[name] = slot; slots.add(slot); nameToIndex[name] = slots.sz() - 1; } }