/// <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; } }