UNPKG

@neo-one/smart-contract-compiler-esnext-esm

Version:

NEO•ONE TypeScript smart contract compiler.

187 lines (185 loc) 8.34 kB
import { Types, WellKnownSymbol } from '../../constants'; import { Helper } from '../Helper'; export class ToPrimitiveHelper extends Helper { constructor({ type, knownType, preferredType = 'default' }) { super(); this.type = type; this.knownType = knownType; this.preferredType = preferredType; } emit(sb, node, optionsIn) { if (!optionsIn.pushValue) { sb.emitOp(node, 'DROP'); return; } const throwTypeError = (options) => { sb.emitOp(node, 'DROP'); sb.emitHelper(node, options, sb.helpers.throwTypeError); }; const throwInnerTypeError = (options) => { sb.emitOp(node, 'DROP'); throwTypeError(options); }; const convertPrimitive = () => { }; const convertBuffer = (options) => { sb.emitHelper(node, options, sb.helpers.unwrapBuffer); sb.emitHelper(node, options, sb.helpers.wrapString); }; const convertObject = (options) => { const convertObjectDone = () => { sb.emitOp(node, 'NIP'); }; const tryConvert = () => { const methods = this.preferredType === 'string' ? ['toString', 'valueOf'] : ['valueOf', 'toString']; const convert = (innerOptions) => { sb.emitHelper(node, innerOptions, sb.helpers.getPropertyObjectProperty); sb.emitHelper(node, innerOptions, sb.helpers.if({ condition: () => { sb.emitOp(node, 'DUP'); sb.emitHelper(node, innerOptions, sb.helpers.isUndefined); }, whenTrue: () => { sb.emitOp(node, 'DROP'); }, whenFalse: () => { sb.emitHelper(node, innerOptions, sb.helpers.invokeCall({ bindThis: true, noArgs: true })); }, })); }; const nextConvertObject = (innerOptions) => { sb.emitOp(node, 'DROP'); sb.emitOp(node, 'DUP'); sb.emitPushString(node, methods[1]); convert(innerOptions); sb.emitHelper(node, optionsIn, sb.helpers.forBuiltinType({ type: undefined, knownType: undefined, array: throwTypeError, arrayStorage: throwTypeError, boolean: convertPrimitive, buffer: throwTypeError, null: convertPrimitive, number: convertPrimitive, object: throwTypeError, string: convertPrimitive, symbol: convertPrimitive, undefined: convertPrimitive, map: throwTypeError, mapStorage: throwTypeError, set: throwTypeError, setStorage: throwTypeError, error: throwTypeError, forwardValue: throwTypeError, iteratorResult: throwTypeError, iterable: throwTypeError, iterableIterator: throwTypeError, transaction: throwTypeError, output: throwTypeError, attribute: throwTypeError, input: throwTypeError, account: throwTypeError, asset: throwTypeError, contract: throwTypeError, header: throwTypeError, block: throwTypeError, })); }; sb.emitOp(node, 'DUP'); sb.emitOp(node, 'DUP'); sb.emitPushString(node, methods[0]); convert(optionsIn); sb.emitHelper(node, optionsIn, sb.helpers.forBuiltinType({ type: undefined, knownType: undefined, array: nextConvertObject, arrayStorage: throwInnerTypeError, boolean: convertObjectDone, buffer: nextConvertObject, null: convertObjectDone, number: convertObjectDone, object: nextConvertObject, string: convertObjectDone, symbol: convertObjectDone, undefined: convertObjectDone, map: throwInnerTypeError, mapStorage: throwInnerTypeError, set: throwInnerTypeError, setStorage: throwInnerTypeError, error: throwInnerTypeError, forwardValue: throwInnerTypeError, iteratorResult: throwInnerTypeError, iterable: throwInnerTypeError, iterableIterator: throwInnerTypeError, transaction: throwInnerTypeError, output: throwInnerTypeError, attribute: throwInnerTypeError, input: throwInnerTypeError, account: throwInnerTypeError, asset: throwInnerTypeError, contract: throwInnerTypeError, header: throwInnerTypeError, block: throwInnerTypeError, })); }; sb.emitOp(node, 'DUP'); sb.emitPushString(node, WellKnownSymbol.toPrimitive); sb.emitHelper(node, options, sb.helpers.getSymbolObjectProperty); sb.emitHelper(node, options, sb.helpers.if({ condition: () => { sb.emitOp(node, 'DUP'); sb.emitHelper(node, options, sb.helpers.isUndefined); }, whenTrue: () => { sb.emitOp(node, 'DROP'); tryConvert(); }, whenFalse: () => { sb.emitPushString(node, this.preferredType); sb.emitPushInt(node, 1); sb.emitOp(node, 'PACK'); sb.emitOp(node, 'ROT'); sb.emitOp(node, 'ROT'); sb.emitHelper(node, options, sb.helpers.invokeCall({ bindThis: true })); }, })); }; const toString = (knownType) => (options) => { sb.emitHelper(node, options, sb.helpers.toString({ type: this.type, knownType })); sb.emitHelper(node, options, sb.helpers.wrapString); }; sb.emitHelper(node, optionsIn, sb.helpers.forBuiltinType({ type: this.type, knownType: this.knownType, array: toString(Types.Array), arrayStorage: toString(Types.Array), boolean: convertPrimitive, buffer: convertBuffer, null: convertPrimitive, number: convertPrimitive, object: convertObject, string: convertPrimitive, symbol: convertPrimitive, undefined: convertPrimitive, map: toString(Types.Array), mapStorage: toString(Types.Array), set: toString(Types.Array), setStorage: toString(Types.Array), error: toString(Types.Error), forwardValue: toString(Types.ForwardValue), iteratorResult: toString(Types.IteratorResult), iterable: toString(Types.Iterable), iterableIterator: toString(Types.IterableIterator), transaction: toString(Types.Transaction), output: toString(Types.Output), attribute: toString(Types.Attribute), input: toString(Types.Input), account: toString(Types.Account), asset: toString(Types.Asset), contract: toString(Types.Contract), header: toString(Types.Header), block: toString(Types.Block), })); } } //# sourceMappingURL=ToPrimitiveHelper.js.map