var util = require("../../util"); var t = require("../../types"); exports.ForOfStatement = function (node, parent, file, scope) { var callback = spec; if (file.isFast("forOf")) callback = fast; var build = callback(node, parent, file, scope); var loop = build.loop; var block = loop.body; // inherit comments from the original loop t.inheritsComments(loop, node); // ensure that it's a block so we can take all it's statemetns t.ensureBlock(node); // push the value declaration to the new loop body if (build.declar) block.body.push(build.declar); // push the rest of the original loop body onto our new body block.body = block.body.concat(node.body.body); return loop; }; var fast = function (node, parent, file, scope) { var left = node.left; var declar, id; if (t.isIdentifier(left) || t.isPattern(left)) { // for (i of test), for ({ i } of test) id = left; } else if (t.isVariableDeclaration(left)) { // for (var i of test) id = left.declarations[0].id; declar = t.variableDeclaration(left.kind, [ t.variableDeclarator(id) ]); } else { throw file.errorWithNode(left, "Unknown node type " + left.type + " in ForOfStatement"); } var loop = util.template("for-of-fast", { LOOP_OBJECT: file.generateUidIdentifier("loopObject", scope), IS_ARRAY: file.generateUidIdentifier("isArray", scope), OBJECT: node.right, INDEX: file.generateUidIdentifier("i", scope), ID: id }); return { declar: declar, loop: loop }; }; var spec = function (node, parent, file, scope) { var left = node.left; var declar; var stepKey = file.generateUidIdentifier("step", scope); var stepValue = t.memberExpression(stepKey, t.identifier("value")); if (t.isIdentifier(left) || t.isPattern(left)) { // for (i of test), for ({ i } of test) declar = t.expressionStatement(t.assignmentExpression("=", left, stepValue)); } else if (t.isVariableDeclaration(left)) { // for (var i of test) declar = t.variableDeclaration(left.kind, [ t.variableDeclarator(left.declarations[0].id, stepValue) ]); } else { throw file.errorWithNode(left, "Unknown node type " + left.type + " in ForOfStatement"); } var loop = util.template("for-of", { ITERATOR_KEY: file.generateUidIdentifier("iterator", scope), STEP_KEY: stepKey, OBJECT: node.right }); return { declar: declar, loop: loop }; };