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