addClass method
Define a bound class in the JS context.
Implementation
@override
void addClass(ClassInfo classInfo) {
List<String> arr = ["(function(privateKey, call, classInfo) { \nfunction ${classInfo.name}() {"];
arr.add("if (arguments[0] != privateKey) this[privateKey] = call.apply(this, [classInfo, 0, Array.prototype.slice.call(arguments)])");
arr.add("};");
Map<String, _WebField> fields = {};
for (int i = 1, t = classInfo.members.length; i < t; ++i) {
var member = classInfo.members[i];
if (member.type & MEMBER_FUNCTION != 0) {
arr.add("""
${classInfo.name}${member.type & MEMBER_STATIC == 0 ? '.prototype' : ''}.${member.name} = function() {
return call.apply(this, [classInfo, $i, Array.prototype.slice.call(arguments)]);
};
""");
} else {
_WebField field = fields.containsKey(member.name)
? fields[member.name]!
: (fields[member.name] = new _WebField());
if (member.type & MEMBER_GETTER != 0) {
field.getter = i;
} else if (member.type & MEMBER_SETTER != 0) {
field.setter = i;
}
field.isStatic = member.type & MEMBER_STATIC != 0;
}
}
for (var iter in fields.entries) {
String name = iter.key;
var field = iter.value;
arr.add('Object.defineProperty(${classInfo.name}${field.isStatic ? '' : '.prototype'}, "$name", {');
if (field.getter != 0) {
arr.add("""
get: function() {
return call.apply(this, [classInfo, ${field.getter}, Array.prototype.slice.call(arguments)])
},
""");
}
if (field.setter != 0) {
arr.add("""
set: function() {
return call.apply(this, [classInfo, ${field.setter}, Array.prototype.slice.call(arguments)])
}
""");
}
arr.add('});');
}
arr.add("return ${classInfo.name}});");
js.JsFunction func = _eval.apply([arr.join('\n')]);
js.JsFunction clazz = func.apply([privateKey, callFunction, classInfo]);
clazz[classPrivateKey] = classInfo;
global[classInfo.name] = clazz;
classes[classInfo] = clazz;
}