@neo-one/smart-contract-compiler
Version:
NEO•ONE TypeScript smart contract compiler.
151 lines (149 loc) • 8.2 kB
JavaScript
;
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