59 lines
2.2 KiB
JavaScript

module.exports = demangle;
/** Demangles AssemblyScript module exports to a friendly object structure. */
function demangle(exports) {
var root = {};
for (let internalName in exports) {
if (!exports.hasOwnProperty(internalName)) continue;
let elem = exports[internalName];
let parts = internalName.split(".");
let curr = root;
while (parts.length > 1) {
let part = parts.shift();
if (!curr.hasOwnProperty(part)) curr[part] = {};
curr = curr[part];
}
let name = parts[0];
let hash = name.indexOf("#");
if (hash >= 0) {
let className = name.substring(0, hash);
let classElem = curr[className];
if (typeof classElem === "undefined" || !classElem.prototype) {
let ctor = function(...args) {
return ctor.wrap(ctor.prototype.constructor(...args));
};
ctor.prototype = {};
ctor.wrap = function(thisValue) {
return Object.create(ctor.prototype, { "this": { value: thisValue, writable: false } });
};
if (classElem) Object.getOwnPropertyNames(classElem).forEach(name =>
Object.defineProperty(ctor, name, Object.getOwnPropertyDescriptor(classElem, name))
);
curr[className] = ctor;
}
name = name.substring(hash + 1);
curr = curr[className].prototype;
if (/^(get|set):/.test(name)) {
if (!curr.hasOwnProperty(name = name.substring(4))) {
let getter = exports[internalName.replace("set:", "get:")];
let setter = exports[internalName.replace("get:", "set:")];
Object.defineProperty(curr, name, {
get: function() { return getter(this.this); },
set: function(value) { setter(this.this, value); }
});
}
} else curr[name] = function(...args) { return elem(this.this, ...args); };
} else {
if (/^(get|set):/.test(name)) {
if (!curr.hasOwnProperty(name = name.substring(4))) {
Object.defineProperty(curr, name, {
get: exports[internalName.replace("set:", "get:")],
set: exports[internalName.replace("get:", "set:")]
});
}
} else curr[name] = elem;
}
}
return root;
}