@neo-one/smart-contract-compiler-esnext-esm
Version:
NEO•ONE TypeScript smart contract compiler.
187 lines (185 loc) • 8.34 kB
JavaScript
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