UNPKG

@neo-one/smart-contract-compiler

Version:

NEO•ONE TypeScript smart contract compiler.

151 lines (149 loc) 8.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ObjectLiteralExpressionCompiler = 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 constants_1 = require("../constants"); const NodeCompiler_1 = require("../NodeCompiler"); class ObjectLiteralExpressionCompiler extends NodeCompiler_1.NodeCompiler { constructor() { super(...arguments); this.kind = typescript_1.default.SyntaxKind.ObjectLiteralExpression; } visitNode(sb, node, optionsIn) { const options = sb.pushValueOptions(optionsIn); sb.emitHelper(node, options, sb.helpers.createObject); ts_utils_1.tsUtils.object_.getProperties(node).forEach((prop) => { if (typescript_1.default.isGetAccessorDeclaration(prop) && ts_utils_1.tsUtils.accessor.getSetAccessor(prop) !== undefined) { return; } sb.emitOp(prop, 'DUP'); if (typescript_1.default.isPropertyAssignment(prop) || typescript_1.default.isMethodDeclaration(prop) || typescript_1.default.isGetAccessorDeclaration(prop) || typescript_1.default.isSetAccessorDeclaration(prop)) { const propertyName = ts_utils_1.tsUtils.node.getNameNode(prop); const visitProp = () => { if (typescript_1.default.isPropertyAssignment(prop)) { sb.visit(ts_utils_1.tsUtils.initializer.getInitializer(prop), options); } else { sb.emitHelper(prop, options, sb.helpers.createCallArray); sb.emitHelper(prop, options, sb.helpers.createFunctionObject({ property: constants_1.InternalObjectProperty.Call, })); } if (typescript_1.default.isSetAccessorDeclaration(prop)) { const getAccessor = ts_utils_1.tsUtils.accessor.getGetAccessor(prop); if (getAccessor !== undefined) { sb.emitHelper(getAccessor, options, sb.helpers.createCallArray); sb.emitHelper(getAccessor, options, sb.helpers.createFunctionObject({ property: constants_1.InternalObjectProperty.Call, })); } } }; const setSymbolProperty = () => { if (typescript_1.default.isSetAccessorDeclaration(prop) || typescript_1.default.isGetAccessorDeclaration(prop)) { sb.emitHelper(prop, options, sb.helpers.setAccessorSymbolObjectProperty({ hasSet: typescript_1.default.isSetAccessorDeclaration(prop), hasGet: typescript_1.default.isGetAccessorDeclaration(prop) || ts_utils_1.tsUtils.accessor.getGetAccessor(prop) !== undefined, })); } else { sb.emitHelper(prop, options, sb.helpers.setSymbolObjectProperty); } }; const setDataProperty = () => { if (typescript_1.default.isSetAccessorDeclaration(prop) || typescript_1.default.isGetAccessorDeclaration(prop)) { sb.emitHelper(prop, options, sb.helpers.setAccessorPropertyObjectProperty({ hasSet: typescript_1.default.isSetAccessorDeclaration(prop), hasGet: typescript_1.default.isGetAccessorDeclaration(prop) || ts_utils_1.tsUtils.accessor.getGetAccessor(prop) !== undefined, })); } else { sb.emitHelper(prop, options, sb.helpers.setDataPropertyObjectProperty); } }; const handlePossibleSymbol = (propertyNameType) => { const handleSymbol = () => { sb.emitHelper(prop, options, sb.helpers.unwrapSymbol); visitProp(); setSymbolProperty(); }; const handleString = () => { sb.emitHelper(prop, options, sb.helpers.toString({ type: propertyNameType })); visitProp(); setDataProperty(); }; if (propertyNameType === undefined || (!ts_utils_1.tsUtils.type_.isOnlySymbolish(propertyNameType) && ts_utils_1.tsUtils.type_.hasSymbolish(propertyNameType))) { sb.emitHelper(prop, options, sb.helpers.if({ condition: () => { sb.emitOp(prop, 'DUP'); sb.emitHelper(prop, options, sb.helpers.isSymbol); }, whenTrue: handleSymbol, whenFalse: handleString, })); } else if (ts_utils_1.tsUtils.type_.isOnlySymbolish(propertyNameType)) { handleSymbol(); } else { handleString(); } }; if (typescript_1.default.isComputedPropertyName(propertyName)) { const expr = ts_utils_1.tsUtils.expression.getExpression(propertyName); const propertyNameType = sb.context.analysis.getType(expr); sb.visit(expr, options); handlePossibleSymbol(propertyNameType); } else { if (typescript_1.default.isIdentifier(propertyName)) { sb.emitPushString(propertyName, ts_utils_1.tsUtils.node.getText(propertyName)); } else { sb.emitPushString(propertyName, typescript_1.default.isStringLiteral(propertyName) ? ts_utils_1.tsUtils.literal.getLiteralValue(propertyName) : `${ts_utils_1.tsUtils.literal.getLiteralValue(propertyName)}`); } visitProp(); setDataProperty(); } } else if (typescript_1.default.isShorthandPropertyAssignment(prop)) { const propertyName = ts_utils_1.tsUtils.node.getNameNode(prop); sb.emitPushString(propertyName, ts_utils_1.tsUtils.node.getText(propertyName)); sb.visit(propertyName, options); sb.emitHelper(prop, options, sb.helpers.setDataPropertyObjectProperty); } else { const val = sb.scope.addUnique(); const objectVal = sb.scope.addUnique(); sb.scope.set(sb, node, options, objectVal); sb.visit(ts_utils_1.tsUtils.expression.getExpression(prop), options); sb.emitOp(node, 'DUP'); sb.scope.set(sb, node, options, val); sb.emitHelper(node, options, sb.helpers.getPropertyObjectKeys); sb.emitHelper(node, options, sb.helpers.arrForEach({ each: () => { sb.scope.get(sb, node, options, objectVal); sb.emitOp(node, 'SWAP'); sb.scope.get(sb, node, options, val); sb.emitOp(node, 'OVER'); sb.emitHelper(node, options, sb.helpers.getPropertyObjectProperty); sb.emitHelper(node, options, sb.helpers.setDataPropertyObjectProperty); }, })); } }); if (!optionsIn.pushValue) { sb.emitOp(node, 'DROP'); } } } exports.ObjectLiteralExpressionCompiler = ObjectLiteralExpressionCompiler; //# sourceMappingURL=ObjectLiteralExpressionCompiler.js.map