The type.slots function in JS is not fully implmented. I checked in the java version, but it seems the JS code does not have the same structure as the working Java code. I think it would be good if both have exactly the same structure. The only two difference should be the java <-> JS syntax and the loading (from pod <-> code inline).
This would prevent us from doing double work, another option could be an partly implementation of the sys lib in Fantom.
jessevdamWed 26 Oct 2011
I added some code my self to make code work, it should give the same implementation as in the java version (just copied the code and adapted it to JS)
fan.sys.Type.prototype.buildReflection = function()
{
// these are working accumulators used to build the
// data structures of my defined and inherited slots
var slots = [];
var nameToSlot = {}; // String -> Slot
var nameToIndex = {}; // String -> Int
// merge in base class and mixin classes
var mixins = this.mixins();
for(var i=0; i< mixins.size(); ++i)
this.mergeType(mixins.get(i), slots, nameToSlot, nameToIndex);
this.mergeType(this.base(), slots, nameToSlot, nameToIndex);
for (var i in this.m_slots)
this.mergeSlot(this.m_slots[i], slots, nameToSlot, nameToIndex);
// break out into fields and methods
var fields = [];
var methods = [];
for (var i in slots)
{
if (slots[i] instanceof fan.sys.Field)
fields.push(slots[i]);
else
methods.push(slots[i]);
}
this.m_rslots = fan.sys.List.make(fan.sys.Slot.$type, slots);
this.m_rfields = fan.sys.List.make(fan.sys.Field.$type, fields);
this.m_rmethods = fan.sys.List.make(fan.sys.Method.$type, methods);
// this.slotsByName = nameToSlot;
// this.myFacets = Facets.mapFacets(pod, ftype.attrs.facets);
// this.lineNum = ftype.attrs.lineNum;
// this.sourceFile = ftype.attrs.sourceFile;
}
/**
* Merge the inherit's slots into my slot maps.
* slots: Slot[] by order
* nameToSlot: String name -> Slot
* nameToIndex: String name -> Long index of slots
*/
fan.sys.Type.prototype.mergeType = function(inheritedType, slots, nameToSlot, nameToIndex)
{
if (inheritedType == null)
return;
var inheritedSlots = inheritedType.slots();
for(var i=0; i< inheritedSlots.size(); ++i)
this.mergeSlot(inheritedSlots.get(i), slots, nameToSlot, nameToIndex);
}
/**
* 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
*/
fan.sys.Type.prototype.mergeSlot = function(slot, slots, nameToSlot, nameToIndex)
{
// skip constructors which aren't mine
if (slot.isCtor() && slot.parent() != this) return;
var name = slot.$name();
var dup = nameToIndex[name];
if (dup != null)
{
// if the slot is inherited from Obj, then we can
// safely ignore it as an override - the dup is most
// likely already the same Object 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::Object version
if (slot.parent().qname() == "sys::Obj")
return;
// if given the choice between two *inherited* slots where
// one is concrete and abstract, then choose the concrete one
var dupSlot = slots[dup];
if (slot.parent() != this && slot.isAbstract() && !dupSlot.isAbstract())
return;
// check if this is a Getter or Setter, which we should ignore
if ((slot.flags() & (fan.sys.FConst.Getter|fan.sys.FConst.Setter)) != 0)
return
nameToSlot[name] = slot;
slots[dup] = slot;
}
else
{
nameToSlot[name] = slot;
slots.push(slot);
nameToIndex[name] = slots.length - 1;
}
}
fan.sys.Type.prototype.slots = function()
{
if(this.m_rslots === undefined)
{
this.buildReflection()
}
return this.m_rslots;
}
fan.sys.Type.prototype.methods = function()
{
if(this.m_rslots === undefined)
{
this.buildReflection();
}
return this.m_rmethods;
}
fan.sys.Type.prototype.fields = function()
{
if(this.m_rslots === undefined)
{
this.buildReflection();
}
return this.m_rfields;
}
jessevdam Tue 25 Oct 2011
The type.slots function in JS is not fully implmented. I checked in the java version, but it seems the JS code does not have the same structure as the working Java code. I think it would be good if both have exactly the same structure. The only two difference should be the java <-> JS syntax and the loading (from pod <-> code inline).
This would prevent us from doing double work, another option could be an partly implementation of the sys lib in Fantom.
jessevdam Wed 26 Oct 2011
I added some code my self to make code work, it should give the same implementation as in the java version (just copied the code and adapted it to JS)