abi.js
Version:
[![typescript-icon]][typescript-link] [![license-icon]][license-link] [![status-icon]][status-link] [![ci-icon]][ci-link] [![twitter-icon]][twitter-link]
226 lines (225 loc) • 7.43 kB
JavaScript
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _ReflectionFunction_instances, _ReflectionFunction_parseParameters, _ReflectionFunction_parseReturn;
import 'reflect-metadata';
import { parse_params } from './parser.js';
export function reflect(value, objectThis) {
return typeof value === 'object'
? new ReflectionObject(value, objectThis)
: new ReflectionFunction(value, objectThis);
}
export class ReflectionError extends Error {
}
export class Reflection {
constructor(value) {
Object.defineProperty(this, "value", {
enumerable: true,
configurable: true,
writable: true,
value: value
});
}
toString() {
return String(this.value);
}
}
export class ReflectionObject extends Reflection {
constructor(value, objectThis) {
super(value);
Object.defineProperty(this, "objectThis", {
enumerable: true,
configurable: true,
writable: true,
value: objectThis
});
}
toString() {
return String(this.value.constructor);
}
}
export class ReflectionFunction extends Reflection {
constructor(value, objectThis) {
super(value);
_ReflectionFunction_instances.add(this);
Object.defineProperty(this, "objectThis", {
enumerable: true,
configurable: true,
writable: true,
value: objectThis
});
Object.defineProperty(this, "is_arrow", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "name", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "parameters", {
enumerable: true,
configurable: true,
writable: true,
value: []
});
const str_val = value.toString();
const arrow_re = /^\(([^\(\)]*?)\)\s*\=\>\s*(.+)$/gms;
const named_re = /^(?:function\s+)?([a-zA-Z$_]+[a-zA-Z0-9$_]*)\s*\(([^\(\)]*?)\)\s*\{(.*)\}$/gms;
const arrow_res = arrow_re.exec(str_val);
const named_res = named_re.exec(str_val);
if (arrow_res) {
this.is_arrow = true;
this.name = '';
__classPrivateFieldGet(this, _ReflectionFunction_instances, "m", _ReflectionFunction_parseParameters).call(this, arrow_res[1]);
__classPrivateFieldGet(this, _ReflectionFunction_instances, "m", _ReflectionFunction_parseReturn).call(this, arrow_res[2]);
}
else if (named_res) {
this.is_arrow = false;
this.name = named_res[1] || 'anonymous';
__classPrivateFieldGet(this, _ReflectionFunction_instances, "m", _ReflectionFunction_parseParameters).call(this, named_res[2]);
__classPrivateFieldGet(this, _ReflectionFunction_instances, "m", _ReflectionFunction_parseReturn).call(this, named_res[3]);
}
else {
throw new ReflectionError(`${value} is not a function`);
}
}
getParameter(name) {
for (const param of this.parameters) {
if (param.name === name) {
return param;
}
}
return undefined;
}
hasParameter(name) {
for (const param of this.parameters) {
if (param.name === name) {
return true;
}
}
return false;
}
}
_ReflectionFunction_instances = new WeakSet(), _ReflectionFunction_parseParameters = function _ReflectionFunction_parseParameters(str_params) {
const default_params = parse_params(str_params);
const entries = Object.entries(default_params);
if (entries.length === 1 &&
entries[0][0] === '0' &&
entries[0][1] === undefined) {
return;
}
const i = 0;
for (const param of entries) {
this.parameters.push(new ReflectionParameter(this, param[0], i, param[1]));
}
}, _ReflectionFunction_parseReturn = function _ReflectionFunction_parseReturn(_str_ret) {
// TODO: throw new ReflectionError("Not implemented!");
};
export class ReflectionParameter extends Reflection {
constructor(func, name, index, value) {
super(value);
Object.defineProperty(this, "func", {
enumerable: true,
configurable: true,
writable: true,
value: func
});
Object.defineProperty(this, "name", {
enumerable: true,
configurable: true,
writable: true,
value: name
});
Object.defineProperty(this, "index", {
enumerable: true,
configurable: true,
writable: true,
value: index
});
}
getFunction() {
return this.func;
}
hasDefaultValue() {
return this.value !== undefined;
}
getDefaultValue() {
return new ReflectionParameterValue(this, this.value);
}
}
export class ReflectionValue extends Reflection {
get type() {
return typeof this.value;
}
}
export class ReflectionParameterValue extends ReflectionValue {
constructor(param, value) {
super(value);
Object.defineProperty(this, "param", {
enumerable: true,
configurable: true,
writable: true,
value: param
});
}
getParameter() {
return this.param;
}
}
export class ReflectionReturnValue extends ReflectionValue {
constructor(func, value) {
super(value);
Object.defineProperty(this, "func", {
enumerable: true,
configurable: true,
writable: true,
value: func
});
}
getFunction() {
return this.func;
}
}
export class Container {
constructor(context) {
Object.defineProperty(this, "context", {
enumerable: true,
configurable: true,
writable: true,
value: context
});
}
call(callback, context = {}) {
return callback(...this.getArgs(callback, context));
}
getArgs(callback, context = {}) {
const reflection = reflect(callback);
const args = [];
for (const param of reflection.parameters) {
args.push(this.get(param.name, param.value, context));
}
return args;
}
get(id, defaultValue, context = {}) {
context = this.mergeContext(context);
return this.make(context[id] || defaultValue, context);
}
make(value, context = {}) {
return typeof value === 'function' ? this.call(value, context) : value;
}
mergeContext(context) {
return {
...context,
...this.context,
};
}
}
export default function (context) {
return new Container(context);
}