Caching class names

This commit is contained in:
vakrilov
2015-05-21 18:00:53 +03:00
parent d03e20d958
commit 2c75ba989d
2 changed files with 73 additions and 15 deletions

22
utils/types.d.ts vendored
View File

@ -61,4 +61,26 @@
* Return an array of strings with the name of all classes.
*/
export function getBaseClasses(object): Array<string>;
/**
* A function that gets the ClassInfo for an object.
* @param object The object for which the ClassInfo will be get.
* Returns a ClassInfo for the object.
*/
export function getClassInfo(object: Object): ClassInfo;
/**
* A Class holding information about a class
*/
export class ClassInfo {
/**
* Gets the name of the class.
*/
name: string;
/**
* Gets the ClassInfo for the base class of the current info.
*/
baseClassInfo: ClassInfo;
}
}

View File

@ -31,27 +31,63 @@ export function verifyCallback(value: any) {
}
}
var classInfosMap = new Map<Function, ClassInfo>();
var funcNameRegex = /function (.{1,})\(/;
export function getClass(object): string {
var results = (funcNameRegex).exec((object).constructor.toString());
return (results && results.length > 1) ? results[1] : "";
export function getClass(object: Object): string {
return getClassInfo(object).name;
}
export function getBaseClasses(object): Array<string> {
var baseProto = object.__proto__;
var result = [];
result.push(getClass(object));
export function getClassInfo(object: Object): ClassInfo {
var constructor = object.constructor;
while (baseProto !== Object.prototype) {
var baseProtoString = baseProto.toString();
// while extending some classes for platform specific versions results in duplicate class types in hierarchy
if (result.indexOf(baseProtoString) === -1) {
result.push(baseProtoString);
var result = classInfosMap.get(constructor);
if (!result) {
result = new ClassInfo(constructor);
classInfosMap.set(constructor, result);
}
baseProto = baseProto.__proto__;
}
result.push("Object");
return result;
}
export function getBaseClasses(object): Array<string> {
var result = [];
var info = getClassInfo(object);
while (info) {
result.push(info.name);
info = info.baseClassInfo;
}
return result;
}
export class ClassInfo {
private _typeCosntructor: Function;
private _name: string;
private _baseClassInfo: ClassInfo;
constructor(typeCosntructor: Function) {
this._typeCosntructor = typeCosntructor;
}
get name(): string {
if (!this._name) {
var results = (funcNameRegex).exec(this._typeCosntructor.toString());
this._name = (results && results.length > 1) ? results[1] : "";
}
return this._name;
}
get baseClassInfo(): ClassInfo {
if (isUndefined(this._baseClassInfo)) {
var constructorProto = this._typeCosntructor.prototype;
if (constructorProto.__proto__) {
this._baseClassInfo = getClassInfo(constructorProto.__proto__);
}
else {
this._baseClassInfo = null;
}
}
return this._baseClassInfo;
}
}