'use strict'; var ok = require('assert').ok; var Node = require('./Node'); class ForEach extends Node { constructor(def) { super('ForEach'); this.varName = def.varName; this.in = def.in; this.body = this.makeContainer(def.body); this.separator = def.separator; this.statusVarName = def.statusVarName; this.iterator = def.iterator; this.isArray = def.isArray; ok(this.varName, '"varName" is required'); ok(this.in != null, '"in" is required'); } generateCode(codegen) { var varName = this.varName; var inExpression = this.in; var separator = this.separator; var statusVarName = this.statusVarName; var iterator = this.iterator; var context = codegen.context; var builder = codegen.builder; var isArray = this.isArray; if (separator && !statusVarName) { statusVarName = '__loop'; } if (iterator) { let params = [varName]; if (statusVarName) { params.push(statusVarName); } return builder.functionCall(iterator, [ inExpression, builder.functionDeclaration(null, params, this.body) ]); } else if (statusVarName) { let body = this.body; if (separator) { let isNotLastTest = builder.functionCall( builder.memberExpression(statusVarName, builder.identifier('isLast')), []); isNotLastTest = builder.negate(isNotLastTest); body = body.items.concat([ builder.ifStatement(isNotLastTest, [ builder.text(separator, false) ]) ]); } return builder.functionCall(context.helper('forEachWithStatusVar'), [ inExpression, builder.functionDeclaration(null, [varName, statusVarName], body) ]); } else { if (isArray) { context.addVar(varName.name); var indexVarId = context.addVar(varName.name + '__i'); var arrayVarId = context.addVar(varName.name + '__array'); var lengthVarId = context.addVar(varName.name + '__len'); var init = builder.sequenceExpression([ builder.assignment(indexVarId, builder.literal(0)), builder.assignment(arrayVarId, inExpression), builder.assignment(lengthVarId, builder.binaryExpression(arrayVarId, '&&', builder.memberExpression(arrayVarId, builder.identifier('length')))) ]); var test = builder.binaryExpression(indexVarId, '<', lengthVarId); var update = builder.unaryExpression(indexVarId, '++'); var loopBody = [ builder.assignment(varName, builder.memberExpression(arrayVarId, indexVarId, true)) ].concat(this.body); return builder.forStatement(init, test, update, loopBody); } else { return builder.functionCall(context.helper('forEach'), [ inExpression, builder.functionDeclaration(null, [varName], this.body) ]); } } } walk(walker) { this.varName = walker.walk(this.varName); this.in = walker.walk(this.in); this.body = walker.walk(this.body); this.separator = walker.walk(this.separator); this.statusVarName = walker.walk(this.statusVarName); this.iterator = walker.walk(this.iterator); } } module.exports = ForEach;