UNPKG

@neo-one/smart-contract-compiler

Version:

NEO•ONE TypeScript smart contract compiler.

122 lines (120 loc) 5.76 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PropertyAccessExpressionCompiler = 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 DiagnosticCode_1 = require("../../DiagnosticCode"); const DiagnosticMessage_1 = require("../../DiagnosticMessage"); const builtins_1 = require("../builtins"); const NodeCompiler_1 = require("../NodeCompiler"); class PropertyAccessExpressionCompiler extends NodeCompiler_1.NodeCompiler { constructor() { super(...arguments); this.kind = typescript_1.default.SyntaxKind.PropertyAccessExpression; } visitNode(sb, expr, optionsIn) { const isOptionalChain = typescript_1.default.isOptionalChain(expr); const value = ts_utils_1.tsUtils.expression.getExpression(expr); const valueType = sb.context.analysis.getType(value); const name = ts_utils_1.tsUtils.node.getNameNode(expr); const nameValue = ts_utils_1.tsUtils.node.getName(expr); const handleBuiltin = (member, visited) => { if (builtins_1.isBuiltinInstanceMemberValue(member)) { member.emitValue(sb, expr, optionsIn, visited); return; } if (builtins_1.isBuiltinMemberValue(member)) { member.emitValue(sb, expr, optionsIn); return; } if (optionsIn.setValue) { sb.context.reportError(name, DiagnosticCode_1.DiagnosticCode.InvalidBuiltinModify, DiagnosticMessage_1.DiagnosticMessage.CannotModifyBuiltin); } else { sb.context.reportError(name, DiagnosticCode_1.DiagnosticCode.InvalidBuiltinReference, DiagnosticMessage_1.DiagnosticMessage.CannotReferenceBuiltinProperty); } }; const builtin = sb.context.builtins.getMember(value, name); if (builtin !== undefined) { handleBuiltin(builtin, false); return; } const throwTypeError = (innerOptions) => { sb.emitOp(expr, 'DROP'); sb.emitHelper(expr, innerOptions, sb.helpers.throwTypeError); }; const processUndefined = (innerOptions) => { sb.emitOp(expr, 'DROP'); sb.emitHelper(expr, innerOptions, sb.helpers.wrapUndefined); }; const throwTypeErrorUnlessOptionalChain = (innerOptions) => { isOptionalChain ? processUndefined(innerOptions) : throwTypeError(innerOptions); }; const createProcessBuiltin = (valueName) => { const member = sb.context.builtins.getOnlyMember(valueName, nameValue); if (member === undefined) { return throwTypeError; } return () => { handleBuiltin(member, true); }; }; const processObject = (innerOptions) => { sb.emitPushString(name, nameValue); if (optionsIn.pushValue && optionsIn.setValue) { sb.emitOp(expr, 'OVER'); sb.emitOp(expr, 'OVER'); sb.emitPushInt(expr, 4); sb.emitOp(expr, 'ROLL'); sb.emitHelper(expr, innerOptions, sb.helpers.setPropertyObjectProperty); sb.emitHelper(expr, innerOptions, sb.helpers.getPropertyObjectProperty); } else if (optionsIn.setValue) { sb.emitOp(expr, 'ROT'); sb.emitHelper(expr, innerOptions, sb.helpers.setPropertyObjectProperty); } else { sb.emitHelper(expr, innerOptions, sb.helpers.getPropertyObjectProperty); if (!optionsIn.pushValue) { sb.emitOp(expr, 'DROP'); } } }; const options = sb.pushValueOptions(sb.noSetValueOptions(optionsIn)); sb.visit(value, options); sb.emitHelper(value, options, sb.helpers.forBuiltinType({ type: valueType, array: createProcessBuiltin('Array'), arrayStorage: createProcessBuiltin('ArrayStorage'), boolean: createProcessBuiltin('Boolean'), buffer: createProcessBuiltin('Buffer'), null: throwTypeErrorUnlessOptionalChain, number: createProcessBuiltin('Number'), object: processObject, string: createProcessBuiltin('String'), symbol: createProcessBuiltin('Symbol'), undefined: throwTypeErrorUnlessOptionalChain, map: createProcessBuiltin('Map'), mapStorage: createProcessBuiltin('MapStorage'), set: createProcessBuiltin('Set'), setStorage: createProcessBuiltin('SetStorage'), error: createProcessBuiltin('Error'), forwardValue: createProcessBuiltin('ForwardValue'), iteratorResult: createProcessBuiltin('IteratorResult'), iterable: createProcessBuiltin('Iterable'), iterableIterator: createProcessBuiltin('IterableIterator'), transaction: createProcessBuiltin('TransactionBase'), output: createProcessBuiltin('Output'), attribute: createProcessBuiltin('AttributeBase'), input: createProcessBuiltin('Input'), account: createProcessBuiltin('Account'), asset: createProcessBuiltin('Asset'), contract: createProcessBuiltin('Contract'), header: createProcessBuiltin('Header'), block: createProcessBuiltin('Block'), })); } } exports.PropertyAccessExpressionCompiler = PropertyAccessExpressionCompiler; //# sourceMappingURL=PropertyAccessExpressionCompiler.js.map