@neo-one/smart-contract-compiler
Version:
NEO•ONE TypeScript smart contract compiler.
149 lines (147 loc) • 6.72 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ParametersHelper = void 0;
const tslib_1 = require("tslib");
const ts_utils_1 = require("@neo-one/ts-utils");
const typescript_1 = tslib_1.__importDefault(require("typescript"));
const Helper_1 = require("../Helper");
class ParametersHelper extends Helper_1.Helper {
constructor(options) {
super();
this.params = options.params;
this.asArgsArr = options.asArgsArr === undefined ? false : options.asArgsArr;
this.map = options.map;
this.mapParam = options.mapParam;
}
emit(sb, node, optionsIn) {
const options = sb.pushValueOptions(optionsIn);
const params = this.params;
const restElement = params.find((param) => ts_utils_1.tsUtils.parameter.isRestParameter(param));
let parameters = restElement === undefined ? [...params] : params.slice(0, -1);
parameters =
parameters.length > 0 && ts_utils_1.tsUtils.node.getName(parameters[0]) === 'this' ? parameters.slice(1) : parameters;
if (this.asArgsArr) {
sb.emitPushInt(node, 0);
sb.emitOp(node, 'NEWARRAY');
sb.emitOp(node, 'SWAP');
}
parameters.forEach((param, idx) => {
const nameNode = ts_utils_1.tsUtils.node.getNameNode(param);
const initializer = ts_utils_1.tsUtils.initializer.getInitializer(param);
if (initializer !== undefined) {
sb.emitHelper(param, sb.noPushValueOptions(options), sb.helpers.if({
condition: () => {
sb.emitOp(param, 'DUP');
sb.emitOp(param, 'ARRAYSIZE');
sb.emitPushInt(param, idx);
sb.emitOp(param, 'LTE');
},
whenTrue: () => {
sb.visit(initializer, sb.pushValueOptions(options));
},
whenFalse: () => {
sb.emitOp(param, 'DUP');
sb.emitPushInt(param, idx);
sb.emitOp(param, 'PICKITEM');
if (this.mapParam !== undefined) {
this.mapParam(param, options);
}
sb.emitOp(param, 'DUP');
sb.emitHelper(param, sb.noPushValueOptions(options), sb.helpers.if({
condition: () => {
sb.emitHelper(param, sb.pushValueOptions(options), sb.helpers.isUndefined);
},
whenTrue: () => {
sb.emitOp(param, 'DROP');
sb.visit(initializer, sb.pushValueOptions(options));
},
}));
},
}));
}
else if (ts_utils_1.tsUtils.parameter.isOptional(param)) {
sb.emitHelper(param, sb.noPushValueOptions(options), sb.helpers.if({
condition: () => {
sb.emitOp(param, 'DUP');
sb.emitOp(param, 'ARRAYSIZE');
sb.emitPushInt(param, idx);
sb.emitOp(param, 'LTE');
},
whenTrue: () => {
sb.emitHelper(param, sb.pushValueOptions(options), sb.helpers.wrapUndefined);
},
whenFalse: () => {
sb.emitOp(param, 'DUP');
sb.emitPushInt(param, idx);
sb.emitOp(param, 'PICKITEM');
if (this.mapParam !== undefined) {
this.mapParam(param, options);
}
},
}));
}
else {
sb.emitOp(param, 'DUP');
sb.emitPushInt(param, idx);
sb.emitOp(param, 'PICKITEM');
if (this.mapParam !== undefined) {
this.mapParam(param, options);
}
}
if (this.map !== undefined) {
this.map(param, options);
}
if (this.asArgsArr) {
sb.emitOp(node, 'ROT');
sb.emitOp(node, 'TUCK');
sb.emitOp(node, 'SWAP');
sb.emitOp(node, 'APPEND');
sb.emitOp(node, 'SWAP');
}
else if (typescript_1.default.isIdentifier(nameNode)) {
sb.scope.add(ts_utils_1.tsUtils.node.getText(nameNode));
sb.scope.set(sb, node, options, ts_utils_1.tsUtils.node.getText(nameNode));
}
else if (typescript_1.default.isArrayBindingPattern(nameNode)) {
const paramType = sb.context.analysis.getType(param);
sb.emitHelper(nameNode, options, sb.helpers.arrayBinding({ type: paramType }));
}
else {
const paramType = sb.context.analysis.getType(param);
sb.emitHelper(nameNode, options, sb.helpers.objectBinding({ type: paramType }));
}
});
if (restElement === undefined) {
sb.emitOp(node, 'DROP');
}
else {
sb.emitPushInt(restElement, parameters.length);
sb.emitHelper(restElement, options, sb.helpers.arrSlice({ hasEnd: false }));
const mapParam = this.mapParam;
if (mapParam !== undefined) {
sb.emitHelper(restElement, options, sb.helpers.arrMap({
map: (innerOptions) => mapParam(restElement, innerOptions),
}));
}
if (this.asArgsArr) {
const map = this.map;
if (map !== undefined) {
sb.emitHelper(restElement, options, sb.helpers.arrMap({
map: (innerOptions) => map(restElement, innerOptions, true),
}));
}
sb.emitHelper(node, options, sb.helpers.arrConcat);
}
else {
sb.emitHelper(restElement, options, sb.helpers.wrapArray);
if (this.map !== undefined) {
this.map(restElement, options);
}
sb.scope.add(ts_utils_1.tsUtils.node.getNameOrThrow(restElement));
sb.scope.set(sb, restElement, options, ts_utils_1.tsUtils.node.getNameOrThrow(restElement));
}
}
}
}
exports.ParametersHelper = ParametersHelper;
//# sourceMappingURL=ParametersHelper.js.map