UNPKG

@neo-one/smart-contract-compiler

Version:

NEO•ONE TypeScript smart contract compiler.

72 lines (70 loc) 3.11 kB
import { tsUtils } from '@neo-one/ts-utils'; import ts from 'typescript'; import { NodeCompiler } from '../NodeCompiler'; export class ForInStatementCompiler extends NodeCompiler { constructor() { super(...arguments); this.kind = ts.SyntaxKind.ForInStatement; } visitNode(sb, node, optionsIn) { const options = sb.pushValueOptions(optionsIn); const initializer = tsUtils.statement.getInitializer(node); if (!ts.isVariableDeclarationList(initializer)) { sb.context.reportUnsupported(initializer); return; } const variables = tsUtils.variable.getDeclarations(initializer); if (variables.length !== 1) { sb.context.reportUnsupported(initializer); return; } const variable = variables[0]; const expression = tsUtils.expression.getExpression(node); const statement = tsUtils.statement.getStatement(node); const expressionType = sb.context.analysis.getType(expression); const handleArray = () => { sb.emitHelper(expression, options, sb.helpers.unwrapArray); sb.emitHelper(node, options, sb.helpers.arrForEach({ withIndex: true, each: (innerOptions) => { sb.emitOp(variable, 'DROP'); sb.emitHelper(variable, options, sb.helpers.wrapNumber); sb.emitHelper(variable, options, sb.helpers.toString({ type: undefined })); sb.emitHelper(variable, options, sb.helpers.wrapString); sb.visit(variable, sb.setValueOptions(innerOptions)); sb.visit(statement, sb.noPushValueOptions(innerOptions)); }, })); }; const handleObject = () => { sb.emitHelper(node, options, sb.helpers.getPropertyObjectKeys); sb.emitHelper(node, options, sb.helpers.arrForEach({ withIndex: false, each: (innerOptions) => { sb.emitHelper(variable, sb.pushValueOptions(innerOptions), sb.helpers.wrapString); sb.visit(variable, sb.setValueOptions(sb.noPushValueOptions(innerOptions))); sb.visit(statement, sb.noPushValueOptions(innerOptions)); }, })); }; sb.visit(expression, options); if (expressionType === undefined || (tsUtils.type_.hasArrayish(expressionType) && !tsUtils.type_.isOnlyArrayish(expressionType))) { sb.emitHelper(expression, options, sb.helpers.if({ condition: () => { sb.emitOp(expression, 'DUP'); sb.emitHelper(expression, options, sb.helpers.isArray); }, whenTrue: handleArray, whenFalse: handleObject, })); } else if (tsUtils.type_.isOnlyArrayish(expressionType)) { handleArray(); } else { handleObject(); } } } //# sourceMappingURL=ForInStatementCompiler.js.map