diff --git a/.gitignore b/.gitignore
index a5fd8ecfca..9516761f30 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,5 @@ dist
/packages/babel-runtime/helpers/*.js
/packages/babel-runtime/regenerator/*.js
/packages/*/lib
-!/packages/babel-plugin-transform-regenerator/lib
_babel.github.io
/tests/.browser-build.js
diff --git a/packages/babel-browser/test/index.js b/packages/babel-browser/test/index.js
deleted file mode 100644
index 2ebb76ce39..0000000000
--- a/packages/babel-browser/test/index.js
+++ /dev/null
@@ -1,12 +0,0 @@
-var vm = require("vm");
-var fs = require("fs");
-
-var loc = __dirname + "/../dist/browser.js";
-
-suite("browser", function () {
- test("sanity check", function () {
- if (fs.existsSync(loc)) {
- require(loc);
- }
- });
-});
diff --git a/packages/babel-plugin-transform-regenerator/.gitignore b/packages/babel-plugin-transform-regenerator/.gitignore
deleted file mode 100644
index 51641efe5b..0000000000
--- a/packages/babel-plugin-transform-regenerator/.gitignore
+++ /dev/null
@@ -1,11 +0,0 @@
-npm-debug.log
-node_modules
-
-test/mocha.js
-test/mocha.css
-
-test/tests.es5.js
-test/async.es5.js
-test/tests.browser.js
-
-.idea
diff --git a/packages/babel-plugin-transform-regenerator/.test/async.es5.js b/packages/babel-plugin-transform-regenerator/.test/async.es5.js
deleted file mode 100644
index 7285217adf..0000000000
--- a/packages/babel-plugin-transform-regenerator/.test/async.es5.js
+++ /dev/null
@@ -1,805 +0,0 @@
-/**
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * https://raw.github.com/facebook/regenerator/master/LICENSE file. An
- * additional grant of patent rights can be found in the PATENTS file in
- * the same directory.
- */
-
-var assert = require("assert");
-
-describe("async functions and await expressions", function () {
- Promise = require("promise");
-
- describe("regeneratorRuntime", function () {
- it("should be defined globally", function () {
- var global = Function("return this")();
- assert.ok("regeneratorRuntime" in global);
- assert.strictEqual(global.regeneratorRuntime, regeneratorRuntime);
- });
-
- it("should have a .wrap method", function () {
- assert.strictEqual(typeof regeneratorRuntime.wrap, "function");
- });
- });
-
- describe("Promise", function () {
- it("should be defined globally", function () {
- var global = Function("return this")();
- assert.ok("Promise" in global);
- assert.strictEqual(global.Promise, Promise);
- });
-
- it("should be a function", function () {
- assert.strictEqual(typeof Promise, "function");
- });
- });
-
- describe("no-await async function", function () {
- it("should return a Promise", function (done) {
- var called = false;
-
- function noAwait(value) {
- return regeneratorRuntime.async(function noAwait$(_context) {
- while (1) switch (_context.prev = _context.next) {
- case 0:
- called = true;
- return _context.abrupt("return", value);
-
- case 2:
- case "end":
- return _context.stop();
- }
- }, null, this);
- }
-
- var promise = noAwait("asdf");
- assert.strictEqual(called, true);
-
- promise.then(function (value) {
- assert.strictEqual(called, true);
- assert.strictEqual(value, "asdf");
- done();
- }).catch(done);
- });
- });
-
- describe("one-await async function", function () {
- it("should finish asynchronously", function (done) {
- var flag1 = false;
- var flag2 = false;
-
- function oneAwait(value) {
- var result;
- return regeneratorRuntime.async(function oneAwait$(_context2) {
- while (1) switch (_context2.prev = _context2.next) {
- case 0:
- flag1 = true;
- _context2.next = 3;
- return regeneratorRuntime.awrap(value);
-
- case 3:
- result = _context2.sent;
-
- flag2 = true;
- return _context2.abrupt("return", result);
-
- case 6:
- case "end":
- return _context2.stop();
- }
- }, null, this);
- }
-
- var promise = oneAwait("asdf");
- assert.strictEqual(flag1, true);
- assert.strictEqual(flag2, false);
-
- promise.then(function (value) {
- assert.strictEqual(flag2, true);
- assert.strictEqual(value, "asdf");
- done();
- }).catch(done);
- });
- });
-
- describe("nested async function calls", function () {
- it("should evaluate in the right order", function (done) {
- var markers = [];
-
- function innerMost(marker) {
- return regeneratorRuntime.async(function innerMost$(_context3) {
- while (1) switch (_context3.prev = _context3.next) {
- case 0:
- markers.push(marker);
- _context3.next = 3;
- return regeneratorRuntime.awrap(marker);
-
- case 3:
- return _context3.abrupt("return", _context3.sent);
-
- case 4:
- case "end":
- return _context3.stop();
- }
- }, null, this);
- }
-
- function inner(marker) {
- return regeneratorRuntime.async(function inner$(_context4) {
- while (1) switch (_context4.prev = _context4.next) {
- case 0:
- markers.push(marker);
-
- _context4.t0 = assert;
- _context4.next = 4;
- return regeneratorRuntime.awrap(innerMost(marker + 1));
-
- case 4:
- _context4.t1 = _context4.sent;
- _context4.t2 = marker + 1;
-
- _context4.t0.strictEqual.call(_context4.t0, _context4.t1, _context4.t2);
-
- markers.push(marker + 2);
-
- _context4.t3 = assert;
- _context4.next = 11;
- return regeneratorRuntime.awrap(innerMost(marker + 3));
-
- case 11:
- _context4.t4 = _context4.sent;
- _context4.t5 = marker + 3;
-
- _context4.t3.strictEqual.call(_context4.t3, _context4.t4, _context4.t5);
-
- markers.push(marker + 4);
-
- case 15:
- case "end":
- return _context4.stop();
- }
- }, null, this);
- }
-
- function outer() {
- return regeneratorRuntime.async(function outer$(_context5) {
- while (1) switch (_context5.prev = _context5.next) {
- case 0:
- markers.push(0);
- _context5.next = 3;
- return regeneratorRuntime.awrap(inner(1));
-
- case 3:
- markers.push(6);
- _context5.next = 6;
- return regeneratorRuntime.awrap(inner(7));
-
- case 6:
- markers.push(12);
-
- case 7:
- case "end":
- return _context5.stop();
- }
- }, null, this);
- }
-
- outer().then(function () {
- var expected = [];
- for (var i = 0; i <= 12; ++i) expected.push(i);
- assert.deepEqual(markers, expected);
- done();
- }).catch(done);
- });
- });
-
- describe("dependent promises", function () {
- it("should be awaitable out of order", function (done) {
- function outer(value) {
- var resolved, p1, v2, v1;
- return regeneratorRuntime.async(function outer$(_context6) {
- while (1) switch (_context6.prev = _context6.next) {
- case 0:
- resolved = false;
- p1 = new Promise(function (resolve) {
- setTimeout(function () {
- resolve(value + 1);
- resolved = true;
- }, 0);
- });
-
- assert.strictEqual(resolved, false);
-
- _context6.next = 5;
- return regeneratorRuntime.awrap(p1.then(function (value) {
- return value + 1;
- }));
-
- case 5:
- v2 = _context6.sent;
-
- assert.strictEqual(resolved, true);
-
- _context6.next = 9;
- return regeneratorRuntime.awrap(p1);
-
- case 9:
- v1 = _context6.sent;
- return _context6.abrupt("return", [v1, v2]);
-
- case 11:
- case "end":
- return _context6.stop();
- }
- }, null, this);
- }
-
- outer(1).then(function (pair) {
- assert.deepEqual(pair, [2, 3]);
- done();
- }).catch(done);
- });
- });
-
- describe("rejected promises", function () {
- it("should cause await expressions to throw", function (done) {
- var error = new Error("rejected");
-
- function f(arg) {
- return regeneratorRuntime.async(function f$(_context7) {
- while (1) switch (_context7.prev = _context7.next) {
- case 0:
- _context7.prev = 0;
- _context7.next = 3;
- return regeneratorRuntime.awrap(arg);
-
- case 3:
- return _context7.abrupt("return", _context7.sent);
-
- case 6:
- _context7.prev = 6;
- _context7.t0 = _context7["catch"](0);
-
- assert.strictEqual(_context7.t0, error);
- return _context7.abrupt("return", "did throw");
-
- case 10:
- case "end":
- return _context7.stop();
- }
- }, null, this, [[0, 6]]);
- }
-
- Promise.all([f(Promise.reject(error)), f(Promise.resolve("did not throw"))]).then(function (results) {
- assert.deepEqual(results, ["did throw", "did not throw"]);
- done();
- }).catch(done);
- });
-
- it("should be returned by exceptional async functions", function (done) {
- var error = new Error("rejected");
-
- function e(arg) {
- return regeneratorRuntime.async(function e$(_context8) {
- while (1) switch (_context8.prev = _context8.next) {
- case 0:
- if (!arg) {
- _context8.next = 2;
- break;
- }
-
- throw arg;
-
- case 2:
- return _context8.abrupt("return", "did not throw");
-
- case 3:
- case "end":
- return _context8.stop();
- }
- }, null, this);
- }
-
- function f(arg) {
- return regeneratorRuntime.async(function f$(_context9) {
- while (1) switch (_context9.prev = _context9.next) {
- case 0:
- _context9.next = 2;
- return regeneratorRuntime.awrap(e(arg));
-
- case 2:
- return _context9.abrupt("return", _context9.sent);
-
- case 3:
- case "end":
- return _context9.stop();
- }
- }, null, this);
- }
-
- function g(arg) {
- return regeneratorRuntime.async(function g$(_context10) {
- while (1) switch (_context10.prev = _context10.next) {
- case 0:
- _context10.next = 2;
- return regeneratorRuntime.awrap(f(arg));
-
- case 2:
- return _context10.abrupt("return", _context10.sent);
-
- case 3:
- case "end":
- return _context10.stop();
- }
- }, null, this);
- }
-
- function h(arg) {
- return regeneratorRuntime.async(function h$(_context11) {
- while (1) switch (_context11.prev = _context11.next) {
- case 0:
- _context11.next = 2;
- return regeneratorRuntime.awrap(Promise.all([g(arg), Promise.resolve("dummy")]));
-
- case 2:
- return _context11.abrupt("return", _context11.sent);
-
- case 3:
- case "end":
- return _context11.stop();
- }
- }, null, this);
- }
-
- Promise.all([h(error).then(function () {
- done(new Error("should not have resolved"));
- }, function (e) {
- assert.strictEqual(e, error);
- return "ok1";
- }), h(null).then(function (result) {
- assert.deepEqual(result, ["did not throw", "dummy"]);
- return "ok2";
- })]).then(function (results) {
- assert.deepEqual(results, ["ok1", "ok2"]);
- done();
- }).catch(done);
- });
-
- it("should propagate failure when returned", function () {
- var rejection = new Error("rejection");
-
- function f() {
- return regeneratorRuntime.async(function f$(_context12) {
- while (1) switch (_context12.prev = _context12.next) {
- case 0:
- return _context12.abrupt("return", new Promise(function (resolve, reject) {
- reject(rejection);
- }));
-
- case 1:
- case "end":
- return _context12.stop();
- }
- }, null, this);
- }
-
- return f().then(function (result) {
- assert.ok(false, "should have been rejected");
- }, function (error) {
- assert.strictEqual(error, rejection);
- });
- });
- });
-
- describe("async function expressions", function () {
- it("should be allowed", function (done) {
- (function _callee(arg) {
- return regeneratorRuntime.async(function _callee$(_context13) {
- while (1) switch (_context13.prev = _context13.next) {
- case 0:
- _context13.next = 2;
- return regeneratorRuntime.awrap(arg);
-
- case 2:
- return _context13.abrupt("return", _context13.sent);
-
- case 3:
- case "end":
- return _context13.stop();
- }
- }, null, this);
- })(Promise.resolve(1234)).then(function (value) {
- assert.strictEqual(value, 1234);
- done();
- }).catch(done);
- });
- });
-});
-
-describe("async generator functions", function () {
- it("should return a working AsyncIterator", function () {
- var _marked = [gen].map(regeneratorRuntime.mark);
-
- var markers = [];
-
- function gen(arg) {
- var sent, result;
- return regeneratorRuntime.async(function gen$(_context14) {
- while (1) switch (_context14.prev = _context14.next) {
- case 0:
- markers.push(0);
- _context14.next = 3;
- return arg;
-
- case 3:
- sent = _context14.sent;
-
- markers.push(1);
- _context14.next = 7;
- return regeneratorRuntime.awrap(sent);
-
- case 7:
- result = _context14.sent;
-
- markers.push(2);
- _context14.t0 = assert;
- _context14.t1 = regeneratorRuntime;
- _context14.next = 13;
- return "second";
-
- case 13:
- _context14.t2 = _context14.sent;
- _context14.next = 16;
- return _context14.t1.awrap.call(_context14.t1, _context14.t2);
-
- case 16:
- _context14.t3 = _context14.sent;
-
- _context14.t0.strictEqual.call(_context14.t0, _context14.t3, "sent after second");
-
- markers.push(3);
- return _context14.abrupt("return", result);
-
- case 20:
- case "end":
- return _context14.stop();
- }
- }, _marked[0], this);
- }
-
- var iter = gen("initial argument");
- assert.deepEqual(markers, []);
-
- var firstPromise = iter.next();
- assert.deepEqual(markers, [0]);
-
- return firstPromise.then(function (firstResult) {
- assert.deepEqual(firstResult, {
- value: "initial argument",
- done: false
- });
-
- assert.deepEqual(markers, [0]);
-
- return iter.next(new Promise(function (resolve) {
- setTimeout(resolve, 100);
- }).then(function () {
- assert.deepEqual(markers, [0, 1]);
- return "will become final result";
- }));
- }).then(function (secondResult) {
- assert.deepEqual(secondResult, {
- value: "second",
- done: false
- });
-
- assert.deepEqual(markers, [0, 1, 2]);
-
- return iter.next("sent after second");
- }).then(function (finalResult) {
- assert.deepEqual(markers, [0, 1, 2, 3]);
- assert.deepEqual(finalResult, {
- value: "will become final result",
- done: true
- });
- });
- });
-
- it("should keep results in order", function () {
- var _marked2 = [range].map(regeneratorRuntime.mark);
-
- function range(limit) {
- var before, after, i;
- return regeneratorRuntime.async(function range$(_context15) {
- while (1) switch (_context15.prev = _context15.next) {
- case 0:
- before = [];
- after = [];
- i = 0;
-
- case 3:
- if (!(i < limit)) {
- _context15.next = 11;
- break;
- }
-
- before.push(i);
- _context15.next = 7;
- return i;
-
- case 7:
- after.push(i);
-
- case 8:
- ++i;
- _context15.next = 3;
- break;
-
- case 11:
- assert.deepEqual(before, after);
- return _context15.abrupt("return", before);
-
- case 13:
- case "end":
- return _context15.stop();
- }
- }, _marked2[0], this);
- }
-
- var limit = 10;
- var iter = range(limit);
- var promises = [];
- var results = [];
-
- for (var i = 0; i < limit; ++i) {
- var promise = iter.next();
- promises.push(promise);
-
- promise.then(function (result) {
- assert.strictEqual(result.done, false);
- results.push(result);
- });
- }
-
- assert.deepEqual(results, []);
-
- return Promise.all(promises).then(function (promiseResults) {
- assert.deepEqual(results, promiseResults);
-
- return iter.next();
- }).then(function (finalResult) {
- assert.deepEqual(results.map(function (result) {
- return result.value;
- }), finalResult.value);
-
- assert.strictEqual(finalResult.done, true);
- });
- });
-
- it("should be able to handle many awaits", function () {
- var _marked3 = [gen].map(regeneratorRuntime.mark);
-
- var awaitCount = 0;
-
- function countAwait(i) {
- return Promise.resolve(i).then(function () {
- ++awaitCount;
- });
- }
-
- function gen(limit) {
- var i;
- return regeneratorRuntime.async(function gen$(_context16) {
- while (1) switch (_context16.prev = _context16.next) {
- case 0:
- _context16.next = 2;
- return regeneratorRuntime.awrap(countAwait(0));
-
- case 2:
- _context16.next = 4;
- return 1;
-
- case 4:
- _context16.next = 6;
- return regeneratorRuntime.awrap(countAwait(2));
-
- case 6:
- _context16.next = 8;
- return regeneratorRuntime.awrap(countAwait(3));
-
- case 8:
- _context16.next = 10;
- return 4;
-
- case 10:
- _context16.next = 12;
- return regeneratorRuntime.awrap(countAwait(5));
-
- case 12:
- _context16.next = 14;
- return regeneratorRuntime.awrap(countAwait(6));
-
- case 14:
- _context16.next = 16;
- return regeneratorRuntime.awrap(countAwait(7));
-
- case 16:
- _context16.next = 18;
- return 8;
-
- case 18:
- i = 0;
-
- case 19:
- if (!(i < limit)) {
- _context16.next = 25;
- break;
- }
-
- _context16.next = 22;
- return regeneratorRuntime.awrap(countAwait(i));
-
- case 22:
- ++i;
- _context16.next = 19;
- break;
-
- case 25:
- return _context16.abrupt("return", "done");
-
- case 26:
- case "end":
- return _context16.stop();
- }
- }, _marked3[0], this);
- }
-
- var iter = gen(100);
-
- return iter.next().then(function (result) {
- assert.strictEqual(awaitCount, 1);
-
- assert.deepEqual(result, {
- value: 1,
- done: false
- });
-
- return iter.next();
- }).then(function (result) {
- assert.strictEqual(awaitCount, 3);
-
- assert.deepEqual(result, {
- value: 4,
- done: false
- });
-
- return iter.next();
- }).then(function (result) {
- assert.strictEqual(awaitCount, 6);
-
- assert.deepEqual(result, {
- value: 8,
- done: false
- });
-
- return iter.next();
- }).then(function (result) {
- assert.strictEqual(awaitCount, 6 + 100);
-
- assert.deepEqual(result, {
- value: "done",
- done: true
- });
-
- return iter.next();
- }).then(function (result) {
- assert.deepEqual(result, {
- value: void 0,
- done: true
- });
- });
- });
-
- it("should not propagate exceptions between iterations", function () {
- var _marked4 = [gen].map(regeneratorRuntime.mark);
-
- function gen() {
- return regeneratorRuntime.async(function gen$(_context17) {
- while (1) switch (_context17.prev = _context17.next) {
- case 0:
- _context17.next = 2;
- return 1;
-
- case 2:
- _context17.next = 4;
- return 2;
-
- case 4:
- case "end":
- return _context17.stop();
- }
- }, _marked4[0], this);
- }
-
- var iter = gen();
-
- return iter.next().then(function (result) {
- assert.deepEqual(result, {
- value: 1,
- done: false
- });
-
- return iter.throw(new Error("thrown from first yield"));
- }).then(function () {
- throw new Error("should have thrown");
- }, function (error) {
- assert.strictEqual(error.message, "thrown from first yield");
- return iter.next();
- }).then(function (result) {
- assert.deepEqual(result, {
- value: void 0,
- done: true
- });
- });
- });
-
- it("should allow yielding a rejected Promise", function () {
- var _marked5 = [gen].map(regeneratorRuntime.mark);
-
- var yielded = new Error("yielded rejection");
- var returned = new Error("returned rejection");
-
- function gen() {
- return regeneratorRuntime.async(function gen$(_context18) {
- while (1) switch (_context18.prev = _context18.next) {
- case 0:
- _context18.t0 = assert;
- _context18.next = 3;
- return Promise.reject(yielded);
-
- case 3:
- _context18.t1 = _context18.sent;
-
- _context18.t0.strictEqual.call(_context18.t0, _context18.t1, "first sent");
-
- _context18.t2 = assert;
- _context18.next = 8;
- return "middle";
-
- case 8:
- _context18.t3 = _context18.sent;
-
- _context18.t2.strictEqual.call(_context18.t2, _context18.t3, "second sent");
-
- return _context18.abrupt("return", Promise.reject(returned));
-
- case 11:
- case "end":
- return _context18.stop();
- }
- }, _marked5[0], this);
- }
-
- var iter = gen();
-
- return iter.next().then(function (result) {
- assert.ok(false, "should have yielded a rejected Promise");
- }, function (error) {
- assert.strictEqual(error, yielded);
- return iter.next("first sent");
- }).then(function (result) {
- assert.deepEqual(result, {
- value: "middle",
- done: false
- });
- return iter.next("second sent");
- }).then(function (result) {
- assert.ok(false, "should have returned a rejected Promise");
- }, function (error) {
- assert.strictEqual(error, returned);
- });
- });
-});
\ No newline at end of file
diff --git a/packages/babel-plugin-transform-regenerator/.test/index.html b/packages/babel-plugin-transform-regenerator/.test/index.html
deleted file mode 100644
index ace946a498..0000000000
--- a/packages/babel-plugin-transform-regenerator/.test/index.html
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
- Mocha
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/babel-plugin-transform-regenerator/.test/nothing-to-transform.js b/packages/babel-plugin-transform-regenerator/.test/nothing-to-transform.js
deleted file mode 100644
index 3ab38103d4..0000000000
--- a/packages/babel-plugin-transform-regenerator/.test/nothing-to-transform.js
+++ /dev/null
@@ -1,3 +0,0 @@
-function asdf() {
- return "no generators or a-s-y-n-c functions to see here";
-}
diff --git a/packages/babel-plugin-transform-regenerator/.test/run.js b/packages/babel-plugin-transform-regenerator/.test/run.js
deleted file mode 100644
index a2c3419c19..0000000000
--- a/packages/babel-plugin-transform-regenerator/.test/run.js
+++ /dev/null
@@ -1,154 +0,0 @@
-/**
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * https://raw.github.com/facebook/regenerator/master/LICENSE file. An
- * additional grant of patent rights can be found in the PATENTS file in
- * the same directory.
- */
-
-var fs = require("fs");
-var path = require("path");
-var semver = require("semver");
-var spawn = require("child_process").spawn;
-var regenerator = require("../main");
-var mochaDir = path.dirname(require.resolve("mocha"));
-
-function convert(es6File, es5File, callback) {
- fs.readFile(es6File, "utf-8", function(err, es6) {
- if (err) {
- return callback(err);
- }
-
- fs.writeFile(es5File, regenerator.compile(es6).code, callback);
- });
-}
-
-function bundle(es5Files, browserFile, callback) {
- var bundle = require("browserify")();
- es5Files.forEach(bundle.add, bundle);
- bundle.bundle(function(err, src) {
- if (err) {
- return callback(err);
- }
- fs.writeFile(browserFile, src, callback);
- });
-}
-
-var queue = [];
-function enqueue(cmd, args, quiet) {
- queue.push({
- cmd: cmd,
- args: args || [],
- quiet: !!quiet
- });
-}
-
-function flush() {
- var entry = queue.shift();
- if (entry) {
- var cmd = entry.cmd;
- if (typeof cmd === "function") {
- cmd.apply(null, entry.args.concat(asyncCallback));
- } else {
- spawn(cmd, entry.args, {
- stdio: [
- process.stdin,
- entry.quiet ? "ignore" : process.stdout,
- process.stderr
- ]
- }).on("exit", asyncCallback);
- }
- }
-}
-
-function asyncCallback(err) {
- if (err) {
- console.error("process exited abnormally:", err);
- process.exit(typeof err === "number" ? err : -1);
- } else {
- process.nextTick(flush);
- }
-}
-
-function makeMochaCopyFunction(fileName) {
- return function copy(callback) {
- var src = path.join(mochaDir, fileName);
- var dst = path.join(__dirname, fileName);
- fs.unlink(dst, function() {
- fs.symlink(src, dst, callback);
- });
- };
-}
-
-if (semver.gte(process.version, "0.11.2")) {
- enqueue("mocha", [
- "--harmony",
- "--reporter", "spec",
- "--require", "./runtime",
- "./test/tests.es6.js"
- ]);
-}
-
-enqueue(convert, [
- "./test/tests.es6.js",
- "./test/tests.es5.js"
-]);
-
-enqueue(convert, [
- "./test/async.es6.js",
- "./test/async.es5.js"
-]);
-
-enqueue(makeMochaCopyFunction("mocha.js"));
-enqueue(makeMochaCopyFunction("mocha.css"));
-
-// uglify-js does not work properly due to Node 0.11.7 bug.
-// (https://github.com/joyent/node/issues/6235)
-if (!semver.eq(process.version, "0.11.7")) {
- try {
- require.resolve("browserify"); // Throws if missing.
- enqueue(bundle, [
- ["./runtime.js",
- "./test/tests.es5.js",
- "./test/async.es5.js"],
- "./test/tests.browser.js"
- ]);
- } catch (ignored) {
- console.error("browserify not installed; skipping bundle step");
- }
-}
-
-enqueue("mocha", [
- "--reporter", "spec",
- "--require", "./runtime",
- "./test/tests.es5.js",
- "./test/async.es5.js",
- "./test/tests.transform.js"
-]);
-
-// Run command-line tool with available options to make sure it works.
-
-enqueue("./bin/regenerator", [
- "./test/async.es5.js"
-], true);
-
-enqueue("./bin/regenerator", [
- "--include-runtime",
- "./test/async.es5.js"
-], true);
-
-// Make sure we run the command-line tool on a file that does not need any
-// transformation, too.
-
-enqueue("./bin/regenerator", [
- "./test/nothing-to-transform.js"
-], true);
-
-enqueue("./bin/regenerator", [
- "--include-runtime",
- "./test/nothing-to-transform.js"
-], true);
-
-flush();
diff --git a/packages/babel-plugin-transform-regenerator/.test/tests.es5.js b/packages/babel-plugin-transform-regenerator/.test/tests.es5.js
deleted file mode 100644
index 1d24a7cfca..0000000000
--- a/packages/babel-plugin-transform-regenerator/.test/tests.es5.js
+++ /dev/null
@@ -1,5262 +0,0 @@
-var _marked4 = [range].map(regeneratorRuntime.mark);
-
-/**
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * https://raw.github.com/facebook/regenerator/master/LICENSE file. An
- * additional grant of patent rights can be found in the PATENTS file in
- * the same directory.
- */
-
-var assert = require("assert");
-var runningInTranslation = /\.wrap\(/.test(regeneratorRuntime.mark(function _callee() {
- return regeneratorRuntime.wrap(function _callee$(_context) {
- while (1) switch (_context.prev = _context.next) {
- case 0:
- case "end":
- return _context.stop();
- }
- }, _callee, this);
-}));
-var iteratorSymbol = typeof Symbol === "function" && Symbol.iterator || "@@iterator";
-
-function check(g, yields, returnValue) {
- for (var i = 0; i < yields.length; ++i) {
- var info = g.next(i);
- assert.deepEqual(info.value, yields[i]);
- assert.strictEqual(info.done, false);
- }
-
- assert.deepEqual(i > 0 ? g.next(i) : g.next(), { value: returnValue, done: true });
-}
-
-// A version of `throw` whose behavior can't be statically analyzed.
-// Useful for testing dynamic exception dispatching.
-function raise(argument) {
- throw argument;
-}
-
-function assertAlreadyFinished(generator) {
- assert.deepEqual(generator.next(), {
- value: void 0,
- done: true
- });
-}
-
-describe("regeneratorRuntime", function () {
- it("should be defined globally", function () {
- var global = Function("return this")();
- assert.ok("regeneratorRuntime" in global);
- assert.strictEqual(global.regeneratorRuntime, regeneratorRuntime);
- });
-
- it("should have a .wrap method", function () {
- assert.strictEqual(typeof regeneratorRuntime.wrap, "function");
- });
-
- it("should have a .mark method", function () {
- assert.strictEqual(typeof regeneratorRuntime.mark, "function");
- });
-
- it("should be the object name returned by util.runtimeProperty", function () {
- assert.strictEqual(require("../lib/util").runtimeProperty("foo").object.name, "regeneratorRuntime");
- });
-});
-
-(runningInTranslation ? describe : xdescribe)("@@iterator", function () {
- it("is defined on Generator.prototype and returns this", function () {
- var _marked = [gen].map(regeneratorRuntime.mark);
-
- function gen() {
- return regeneratorRuntime.wrap(function gen$(_context2) {
- while (1) switch (_context2.prev = _context2.next) {
- case 0:
- case "end":
- return _context2.stop();
- }
- }, _marked[0], this);
- }
- var iterator = gen();
- assert.ok(!iterator.hasOwnProperty(iteratorSymbol));
- assert.ok(!Object.getPrototypeOf(iterator).hasOwnProperty(iteratorSymbol));
- assert.ok(Object.getPrototypeOf(Object.getPrototypeOf(iterator)).hasOwnProperty(iteratorSymbol));
- assert.strictEqual(iterator[iteratorSymbol](), iterator);
- });
-});
-
-describe("simple argument yielder", function () {
- it("should yield only its first argument", function () {
- var _marked2 = [gen].map(regeneratorRuntime.mark);
-
- function gen(x) {
- return regeneratorRuntime.wrap(function gen$(_context3) {
- while (1) switch (_context3.prev = _context3.next) {
- case 0:
- _context3.next = 2;
- return x;
-
- case 2:
- case "end":
- return _context3.stop();
- }
- }, _marked2[0], this);
- }
-
- check(gen("oyez"), ["oyez"]);
- check(gen("foo", "bar"), ["foo"]);
- });
-
- it("should support multiple yields in expression", function () {
- var _marked3 = [gen].map(regeneratorRuntime.mark);
-
- function gen() {
- return regeneratorRuntime.wrap(function gen$(_context4) {
- while (1) switch (_context4.prev = _context4.next) {
- case 0:
- _context4.next = 2;
- return 0;
-
- case 2:
- _context4.t0 = _context4.sent;
- _context4.next = 5;
- return 0;
-
- case 5:
- _context4.t1 = _context4.sent;
- return _context4.abrupt("return", _context4.t0 + _context4.t1);
-
- case 7:
- case "end":
- return _context4.stop();
- }
- }, _marked3[0], this);
- }
- var itr = gen();
- itr.next();
- itr.next(1);
- assert.equal(itr.next(2).value, 3);
- });
-});
-
-function range(n) {
- var i;
- return regeneratorRuntime.wrap(function range$(_context5) {
- while (1) switch (_context5.prev = _context5.next) {
- case 0:
- i = 0;
-
- case 1:
- if (!(i < n)) {
- _context5.next = 7;
- break;
- }
-
- _context5.next = 4;
- return i;
-
- case 4:
- ++i;
- _context5.next = 1;
- break;
-
- case 7:
- case "end":
- return _context5.stop();
- }
- }, _marked4[0], this);
-}
-
-describe("range generator", function () {
- it("should yield the empty range", function () {
- check(range(0), []);
- });
-
- it("should yield the range 0..n-1", function () {
- check(range(5), [0, 1, 2, 3, 4]);
- });
-});
-
-describe("collatz generator", function () {
- var _marked5 = [gen].map(regeneratorRuntime.mark);
-
- function gen(n) {
- var count;
- return regeneratorRuntime.wrap(function gen$(_context6) {
- while (1) switch (_context6.prev = _context6.next) {
- case 0:
- count = 0;
- _context6.next = 3;
- return n;
-
- case 3:
- if (!(n !== 1)) {
- _context6.next = 14;
- break;
- }
-
- count += 1;
-
- if (!(n % 2)) {
- _context6.next = 10;
- break;
- }
-
- _context6.next = 8;
- return n = n * 3 + 1;
-
- case 8:
- _context6.next = 12;
- break;
-
- case 10:
- _context6.next = 12;
- return n >>= 1;
-
- case 12:
- _context6.next = 3;
- break;
-
- case 14:
- return _context6.abrupt("return", count);
-
- case 15:
- case "end":
- return _context6.stop();
- }
- }, _marked5[0], this);
- }
-
- function collatz(n) {
- var result = [n];
-
- while (n !== 1) {
- if (n % 2) {
- n *= 3;
- n += 1;
- } else {
- n >>= 1;
- }
-
- result.push(n);
- }
-
- return result;
- }
-
- var seven = collatz(7);
- var fiftyTwo = seven.slice(seven.indexOf(52));
- var eightyTwo = collatz(82);
-
- it("seven", function () {
- check(gen(7), seven, 16);
- });
-
- it("fifty two", function () {
- check(gen(52), fiftyTwo, 11);
- });
-
- it("eighty two", function () {
- check(gen(82), eightyTwo, 110);
- });
-});
-
-describe("throw", function () {
- (runningInTranslation ? it : xit)("should complete generator", function () {
- var _marked6 = [gen].map(regeneratorRuntime.mark);
-
- function gen(x) {
- return regeneratorRuntime.wrap(function gen$(_context7) {
- while (1) switch (_context7.prev = _context7.next) {
- case 0:
- throw 1;
-
- case 1:
- case "end":
- return _context7.stop();
- }
- }, _marked6[0], this);
- }
-
- var u = gen();
-
- try {
- u.next();
- } catch (err) {
- assert.strictEqual(err, 1);
- }
-
- assertAlreadyFinished(u);
- });
-});
-
-describe("try-catch generator", function () {
- var _marked7 = [usingThrow, usingRaise].map(regeneratorRuntime.mark);
-
- function usingThrow(x) {
- return regeneratorRuntime.wrap(function usingThrow$(_context8) {
- while (1) switch (_context8.prev = _context8.next) {
- case 0:
- _context8.next = 2;
- return 0;
-
- case 2:
- _context8.prev = 2;
- _context8.next = 5;
- return 1;
-
- case 5:
- if (!(x % 2 === 0)) {
- _context8.next = 7;
- break;
- }
-
- throw 2;
-
- case 7:
- _context8.next = 9;
- return x;
-
- case 9:
- _context8.next = 15;
- break;
-
- case 11:
- _context8.prev = 11;
- _context8.t0 = _context8["catch"](2);
- _context8.next = 15;
- return _context8.t0;
-
- case 15:
- _context8.next = 17;
- return 3;
-
- case 17:
- case "end":
- return _context8.stop();
- }
- }, _marked7[0], this, [[2, 11]]);
- }
-
- function usingRaise(x) {
- return regeneratorRuntime.wrap(function usingRaise$(_context9) {
- while (1) switch (_context9.prev = _context9.next) {
- case 0:
- _context9.next = 2;
- return 0;
-
- case 2:
- _context9.prev = 2;
- _context9.next = 5;
- return 1;
-
- case 5:
- if (x % 2 === 0) raise(2);
- _context9.next = 8;
- return x;
-
- case 8:
- _context9.next = 14;
- break;
-
- case 10:
- _context9.prev = 10;
- _context9.t0 = _context9["catch"](2);
- _context9.next = 14;
- return _context9.t0;
-
- case 14:
- _context9.next = 16;
- return 3;
-
- case 16:
- case "end":
- return _context9.stop();
- }
- }, _marked7[1], this, [[2, 10]]);
- }
-
- it("should catch static exceptions properly", function () {
- check(usingThrow(4), [0, 1, 2, 3]);
- check(usingThrow(5), [0, 1, 5, 3]);
- });
-
- it("should catch dynamic exceptions properly", function () {
- check(usingRaise(4), [0, 1, 2, 3]);
- check(usingRaise(5), [0, 1, 5, 3]);
- });
-});
-
-describe("nested generators in try-catch", function () {
- var _marked8 = [gen].map(regeneratorRuntime.mark);
-
- function gen() {
- return regeneratorRuntime.wrap(function gen$(_context11) {
- while (1) switch (_context11.prev = _context11.next) {
- case 0:
- _context11.prev = 0;
-
- nonExistent;
- _context11.next = 8;
- break;
-
- case 4:
- _context11.prev = 4;
- _context11.t0 = _context11["catch"](0);
- _context11.next = 8;
- return regeneratorRuntime.mark(function _callee2() {
- return regeneratorRuntime.wrap(function _callee2$(_context10) {
- while (1) switch (_context10.prev = _context10.next) {
- case 0:
- _context10.next = 2;
- return _context11.t0;
-
- case 2:
- case "end":
- return _context10.stop();
- }
- }, _callee2, this);
- });
-
- case 8:
- case "end":
- return _context11.stop();
- }
- }, _marked8[0], this, [[0, 4]]);
- }
-
- it('should get a reference to the caught error', function () {
- var genFun2 = gen().next().value;
- assert.ok(regeneratorRuntime.isGeneratorFunction(genFun2));
- var gen2 = genFun2();
- var res = gen2.next();
- assert.ok(res.value instanceof ReferenceError);
- // Note that we don't do strict equality over the message because it varies
- // across browsers (if we ever want to run tests in browsers).
- assert.ok(res.value.message.match(/nonExistent/));
- });
-});
-
-describe("try-finally generator", function () {
- var _marked9 = [usingThrow, usingRaise, usingAbrupt].map(regeneratorRuntime.mark);
-
- function usingThrow(condition) {
- return regeneratorRuntime.wrap(function usingThrow$(_context12) {
- while (1) switch (_context12.prev = _context12.next) {
- case 0:
- _context12.next = 2;
- return 0;
-
- case 2:
- _context12.prev = 2;
- _context12.next = 5;
- return 1;
-
- case 5:
- throw 2;
-
- case 8:
- _context12.prev = 8;
-
- if (!condition) {
- _context12.next = 13;
- break;
- }
-
- _context12.next = 12;
- return 4;
-
- case 12:
- return _context12.abrupt("return", 5);
-
- case 13:
- _context12.next = 15;
- return 6;
-
- case 15:
- return _context12.abrupt("return", 7);
-
- case 17:
- case "end":
- return _context12.stop();
- }
- }, _marked9[0], this, [[2,, 8, 17]]);
- }
-
- function usingRaise(condition) {
- return regeneratorRuntime.wrap(function usingRaise$(_context13) {
- while (1) switch (_context13.prev = _context13.next) {
- case 0:
- _context13.next = 2;
- return 0;
-
- case 2:
- _context13.prev = 2;
- _context13.next = 5;
- return 1;
-
- case 5:
- raise(2);
- _context13.next = 8;
- return 3;
-
- case 8:
- _context13.prev = 8;
-
- if (!condition) {
- _context13.next = 13;
- break;
- }
-
- _context13.next = 12;
- return 4;
-
- case 12:
- return _context13.abrupt("return", 5);
-
- case 13:
- _context13.next = 15;
- return 6;
-
- case 15:
- return _context13.abrupt("return", 7);
-
- case 17:
- case "end":
- return _context13.stop();
- }
- }, _marked9[1], this, [[2,, 8, 17]]);
- }
-
- function usingAbrupt(abruptType, finallyAbruptType) {
- return regeneratorRuntime.wrap(function usingAbrupt$(_context14) {
- while (1) switch (_context14.prev = _context14.next) {
- case 0:
- _context14.next = 2;
- return 0;
-
- case 2:
- _context14.prev = 2;
- _context14.next = 5;
- return 1;
-
- case 5:
- if (!(abruptType === "return")) {
- _context14.next = 9;
- break;
- }
-
- return _context14.abrupt("return", 2);
-
- case 9:
- if (!(abruptType === "break")) {
- _context14.next = 13;
- break;
- }
-
- return _context14.abrupt("break", 33);
-
- case 13:
- if (!(abruptType === "continue")) {
- _context14.next = 16;
- break;
- }
-
- abruptType = "return";
- return _context14.abrupt("continue", 31);
-
- case 16:
- _context14.prev = 16;
- _context14.next = 19;
- return 3;
-
- case 19:
- if (!(finallyAbruptType === "return")) {
- _context14.next = 23;
- break;
- }
-
- return _context14.abrupt("return", 4);
-
- case 23:
- if (!(finallyAbruptType === "break")) {
- _context14.next = 27;
- break;
- }
-
- return _context14.abrupt("break", 33);
-
- case 27:
- if (!(finallyAbruptType === "continue")) {
- _context14.next = 30;
- break;
- }
-
- finallyAbruptType = null;
- return _context14.abrupt("continue", 31);
-
- case 30:
- return _context14.finish(16);
-
- case 31:
- _context14.next = 2;
- break;
-
- case 33:
- return _context14.abrupt("return", 5);
-
- case 34:
- case "end":
- return _context14.stop();
- }
- }, _marked9[2], this, [[2,, 16, 31]]);
- }
-
- it("should honor return", function () {
- check(usingAbrupt("return", null), [0, 1, 3], 2);
- });
-
- it("should honor break", function () {
- check(usingAbrupt("break", null), [0, 1, 3], 5);
- });
-
- it("should honor continue", function () {
- check(usingAbrupt("continue", null), [0, 1, 3, 1, 3], 2);
- });
-
- it("should override abrupt with return", function () {
- check(usingAbrupt("return", "return"), [0, 1, 3], 4);
- check(usingAbrupt("break", "return"), [0, 1, 3], 4);
- check(usingAbrupt("continue", "return"), [0, 1, 3], 4);
- });
-
- it("should override abrupt with break", function () {
- check(usingAbrupt("return", "break"), [0, 1, 3], 5);
- check(usingAbrupt("break", "break"), [0, 1, 3], 5);
- check(usingAbrupt("continue", "break"), [0, 1, 3], 5);
- });
-
- it("should override abrupt with continue", function () {
- check(usingAbrupt("return", "continue"), [0, 1, 3, 1, 3], 2);
- check(usingAbrupt("break", "continue"), [0, 1, 3, 1, 3], 5);
- check(usingAbrupt("continue", "continue"), [0, 1, 3, 1, 3], 2);
- });
-
- it("should execute finally blocks statically", function () {
- check(usingThrow(true), [0, 1, 4], 5);
- check(usingThrow(false), [0, 1, 6], 7);
- });
-
- it("should execute finally blocks dynamically", function () {
- check(usingRaise(true), [0, 1, 4], 5);
- check(usingRaise(false), [0, 1, 6], 7);
- });
-
- it("should execute finally blocks before throwing", function () {
- var _marked10 = [uncaught].map(regeneratorRuntime.mark);
-
- var uncaughtError = new Error("uncaught");
-
- function uncaught(condition) {
- return regeneratorRuntime.wrap(function uncaught$(_context15) {
- while (1) switch (_context15.prev = _context15.next) {
- case 0:
- _context15.prev = 0;
- _context15.next = 3;
- return 0;
-
- case 3:
- if (!condition) {
- _context15.next = 7;
- break;
- }
-
- _context15.next = 6;
- return 1;
-
- case 6:
- raise(uncaughtError);
-
- case 7:
- _context15.next = 9;
- return 2;
-
- case 9:
- _context15.prev = 9;
- _context15.next = 12;
- return 3;
-
- case 12:
- return _context15.finish(9);
-
- case 13:
- _context15.next = 15;
- return 4;
-
- case 15:
- case "end":
- return _context15.stop();
- }
- }, _marked10[0], this, [[0,, 9, 13]]);
- }
-
- check(uncaught(false), [0, 2, 3, 4]);
-
- var u = uncaught(true);
-
- assert.deepEqual(u.next(), { value: 0, done: false });
- assert.deepEqual(u.next(), { value: 1, done: false });
- assert.deepEqual(u.next(), { value: 3, done: false });
-
- try {
- u.next();
- assert.ok(false, "should have thrown an exception");
- } catch (err) {
- assert.strictEqual(err, uncaughtError);
- }
- });
-
- it("should throw correct error when finally contains catch", function () {
- var _marked11 = [gen].map(regeneratorRuntime.mark);
-
- var right = new Error("right");
- var wrong = new Error("wrong");
-
- function gen() {
- return regeneratorRuntime.wrap(function gen$(_context16) {
- while (1) switch (_context16.prev = _context16.next) {
- case 0:
- _context16.prev = 0;
- _context16.next = 3;
- return 0;
-
- case 3:
- raise(right);
-
- case 4:
- _context16.prev = 4;
- _context16.next = 7;
- return 1;
-
- case 7:
- _context16.prev = 7;
-
- raise(wrong);
- _context16.next = 16;
- break;
-
- case 11:
- _context16.prev = 11;
- _context16.t0 = _context16["catch"](7);
-
- assert.strictEqual(_context16.t0, wrong);
- _context16.next = 16;
- return 2;
-
- case 16:
- return _context16.finish(4);
-
- case 17:
- case "end":
- return _context16.stop();
- }
- }, _marked11[0], this, [[0,, 4, 17], [7, 11]]);
- }
-
- var g = gen();
-
- assert.deepEqual(g.next(), {
- value: 0,
- done: false
- });
-
- assert.deepEqual(g.next(), {
- value: 1,
- done: false
- });
-
- assert.deepEqual(g.next(), {
- value: 2,
- done: false
- });
-
- try {
- g.next();
- assert.ok(false, "should have thrown an exception");
- } catch (err) {
- assert.strictEqual(err, right);
- }
- });
-
- it("should run finally after break within try", function () {
- var _marked12 = [gen].map(regeneratorRuntime.mark);
-
- function gen() {
- return regeneratorRuntime.wrap(function gen$(_context17) {
- while (1) switch (_context17.prev = _context17.next) {
- case 0:
- _context17.prev = 0;
- _context17.next = 3;
- return 0;
-
- case 3:
- if (!true) {
- _context17.next = 9;
- break;
- }
-
- _context17.next = 6;
- return 1;
-
- case 6:
- return _context17.abrupt("break", 9);
-
- case 9:
- _context17.prev = 9;
- _context17.next = 12;
- return 2;
-
- case 12:
- return _context17.finish(9);
-
- case 13:
- _context17.next = 15;
- return 3;
-
- case 15:
- case "end":
- return _context17.stop();
- }
- }, _marked12[0], this, [[0,, 9, 13]]);
- }
-
- check(gen(), [0, 1, 2, 3]);
- });
-});
-
-describe("try-catch-finally generator", function () {
- var _marked13 = [usingThrow, usingRaise].map(regeneratorRuntime.mark);
-
- function usingThrow() {
- return regeneratorRuntime.wrap(function usingThrow$(_context18) {
- while (1) switch (_context18.prev = _context18.next) {
- case 0:
- _context18.next = 2;
- return 0;
-
- case 2:
- _context18.prev = 2;
- _context18.prev = 3;
- _context18.next = 6;
- return 1;
-
- case 6:
- throw 2;
-
- case 9:
- _context18.next = 16;
- break;
-
- case 11:
- _context18.prev = 11;
- _context18.t0 = _context18["catch"](3);
- _context18.next = 15;
- return _context18.t0;
-
- case 15:
- throw _context18.sent;
-
- case 16:
- _context18.prev = 16;
- _context18.next = 19;
- return 5;
-
- case 19:
- return _context18.finish(16);
-
- case 20:
- _context18.next = 26;
- break;
-
- case 22:
- _context18.prev = 22;
- _context18.t1 = _context18["catch"](2);
- _context18.next = 26;
- return _context18.t1;
-
- case 26:
- _context18.next = 28;
- return 6;
-
- case 28:
- case "end":
- return _context18.stop();
- }
- }, _marked13[0], this, [[2, 22], [3, 11, 16, 20]]);
- }
-
- function usingRaise() {
- return regeneratorRuntime.wrap(function usingRaise$(_context19) {
- while (1) switch (_context19.prev = _context19.next) {
- case 0:
- _context19.next = 2;
- return 0;
-
- case 2:
- _context19.prev = 2;
- _context19.prev = 3;
- _context19.next = 6;
- return 1;
-
- case 6:
- raise(2);
- _context19.next = 9;
- return 3;
-
- case 9:
- _context19.next = 16;
- break;
-
- case 11:
- _context19.prev = 11;
- _context19.t0 = _context19["catch"](3);
- _context19.next = 15;
- return _context19.t0;
-
- case 15:
- throw _context19.sent;
-
- case 16:
- _context19.prev = 16;
- _context19.next = 19;
- return 5;
-
- case 19:
- return _context19.finish(16);
-
- case 20:
- _context19.next = 26;
- break;
-
- case 22:
- _context19.prev = 22;
- _context19.t1 = _context19["catch"](2);
- _context19.next = 26;
- return _context19.t1;
-
- case 26:
- _context19.next = 28;
- return 6;
-
- case 28:
- case "end":
- return _context19.stop();
- }
- }, _marked13[1], this, [[2, 22], [3, 11, 16, 20]]);
- }
-
- it("should statically catch and then finalize", function () {
- check(usingThrow(), [0, 1, 2, 5, 3, 6]);
- });
-
- it("should dynamically catch and then finalize", function () {
- check(usingRaise(), [0, 1, 2, 5, 3, 6]);
- });
-
- it("should execute catch and finally blocks at most once", function () {
- var _marked14 = [gen].map(regeneratorRuntime.mark);
-
- var error = new Error();
-
- function gen() {
- return regeneratorRuntime.wrap(function gen$(_context20) {
- while (1) switch (_context20.prev = _context20.next) {
- case 0:
- _context20.prev = 0;
- _context20.t0 = 1;
- _context20.next = _context20.t0 === 1 ? 4 : 7;
- break;
-
- case 4:
- _context20.next = 6;
- return "a";
-
- case 6:
- return _context20.abrupt("break", 8);
-
- case 7:
- return _context20.abrupt("break", 8);
-
- case 8:
- throw error;
-
- case 11:
- _context20.prev = 11;
- _context20.t1 = _context20["catch"](0);
-
- assert.strictEqual(_context20.t1, error);
- _context20.next = 16;
- return "b";
-
- case 16:
- _context20.next = 18;
- return "c";
-
- case 18:
- return _context20.abrupt("break", 20);
-
- case 19:
- if (false) {
- _context20.next = 16;
- break;
- }
-
- case 20:
- _context20.next = 22;
- return "d";
-
- case 22:
- return _context20.abrupt("break", 24);
-
- case 23:
- if (false) {
- _context20.next = 16;
- break;
- }
-
- case 24:
- _context20.next = 26;
- return "e";
-
- case 26:
- _context20.prev = 26;
- _context20.next = 29;
- return "f";
-
- case 29:
- return _context20.finish(26);
-
- case 30:
- case "end":
- return _context20.stop();
- }
- }, _marked14[0], this, [[0, 11, 26, 30]]);
- }
-
- check(gen(), ["a", "b", "c", "d", "e", "f"]);
- });
-
- it("should handle backwards jumps in labeled loops", function () {
- var _marked15 = [gen].map(regeneratorRuntime.mark);
-
- function gen() {
- var firstTime;
- return regeneratorRuntime.wrap(function gen$(_context21) {
- while (1) switch (_context21.prev = _context21.next) {
- case 0:
- firstTime = true;
-
- case 1:
- if (!true) {
- _context21.next = 31;
- break;
- }
-
- _context21.next = 4;
- return 0;
-
- case 4:
- _context21.prev = 4;
-
- case 5:
- if (!true) {
- _context21.next = 20;
- break;
- }
-
- _context21.next = 8;
- return 1;
-
- case 8:
- if (!firstTime) {
- _context21.next = 15;
- break;
- }
-
- firstTime = false;
- _context21.next = 12;
- return 2;
-
- case 12:
- return _context21.abrupt("continue", 1);
-
- case 15:
- _context21.next = 17;
- return 3;
-
- case 17:
- return _context21.abrupt("break", 20);
-
- case 18:
- _context21.next = 5;
- break;
-
- case 20:
- _context21.next = 22;
- return 4;
-
- case 22:
- return _context21.abrupt("break", 31);
-
- case 23:
- _context21.prev = 23;
- _context21.next = 26;
- return 5;
-
- case 26:
- return _context21.finish(23);
-
- case 27:
- _context21.next = 29;
- return 6;
-
- case 29:
- _context21.next = 1;
- break;
-
- case 31:
- _context21.next = 33;
- return 7;
-
- case 33:
- case "end":
- return _context21.stop();
- }
- }, _marked15[0], this, [[4,, 23, 27]]);
- }
-
- check(gen(), [0, 1, 2, 5, 0, 1, 3, 4, 5, 7]);
- });
-
- it("should handle loop continue statements properly", function () {
- var _marked16 = [gen].map(regeneratorRuntime.mark);
-
- var error = new Error("thrown");
- var markers = [];
-
- function gen() {
- var c;
- return regeneratorRuntime.wrap(function gen$(_context22) {
- while (1) switch (_context22.prev = _context22.next) {
- case 0:
- c = 2;
-
- case 1:
- if (!(c > 0)) {
- _context22.next = 20;
- break;
- }
-
- _context22.prev = 2;
-
- markers.push("try");
- _context22.next = 6;
- return c;
-
- case 6:
- _context22.next = 13;
- break;
-
- case 8:
- _context22.prev = 8;
- _context22.t0 = _context22["catch"](2);
-
- assert.strictEqual(_context22.t0, error);
- markers.push("catch");
- return _context22.abrupt("continue", 1);
-
- case 13:
- _context22.prev = 13;
-
- markers.push("finally");
- return _context22.finish(13);
-
- case 16:
- markers.push("decrement");
- --c;
- _context22.next = 1;
- break;
-
- case 20:
- case "end":
- return _context22.stop();
- }
- }, _marked16[0], this, [[2, 8, 13, 16]]);
- }
-
- var g = gen();
-
- assert.deepEqual(g.next(), { value: 2, done: false });
- assert.deepEqual(g.throw(error), { value: 2, done: false });
- assert.deepEqual(g.next(), { value: 1, done: false });
- assert.deepEqual(g.next(), { value: void 0, done: true });
-
- assert.deepEqual(markers, ["try", "catch", "finally", "try", "finally", "decrement", "try", "finally", "decrement"]);
- });
-});
-
-describe("dynamic exception", function () {
- var _marked17 = [gen].map(regeneratorRuntime.mark);
-
- function gen(x, fname) {
- return regeneratorRuntime.wrap(function gen$(_context23) {
- while (1) switch (_context23.prev = _context23.next) {
- case 0:
- _context23.prev = 0;
- return _context23.abrupt("return", fns[fname](x));
-
- case 4:
- _context23.prev = 4;
- _context23.t0 = _context23["catch"](0);
- _context23.next = 8;
- return _context23.t0;
-
- case 8:
- case "end":
- return _context23.stop();
- }
- }, _marked17[0], this, [[0, 4]]);
- }
-
- var fns = {
- f: function (x) {
- throw x;
- },
-
- g: function (x) {
- return x;
- }
- };
-
- it("should be dispatched correctly", function () {
- check(gen("asdf", "f"), ["asdf"]);
- check(gen("asdf", "g"), [], "asdf");
- });
-});
-
-describe("nested finally blocks", function () {
- var _marked18 = [usingThrow, usingRaise].map(regeneratorRuntime.mark);
-
- function usingThrow() {
- return regeneratorRuntime.wrap(function usingThrow$(_context24) {
- while (1) switch (_context24.prev = _context24.next) {
- case 0:
- _context24.prev = 0;
- _context24.prev = 1;
- _context24.prev = 2;
- throw "thrown";
-
- case 4:
- _context24.prev = 4;
- _context24.next = 7;
- return 1;
-
- case 7:
- return _context24.finish(4);
-
- case 8:
- _context24.next = 14;
- break;
-
- case 10:
- _context24.prev = 10;
- _context24.t0 = _context24["catch"](1);
- _context24.next = 14;
- return _context24.t0;
-
- case 14:
- _context24.prev = 14;
- _context24.next = 17;
- return 2;
-
- case 17:
- return _context24.finish(14);
-
- case 18:
- _context24.prev = 18;
- _context24.next = 21;
- return 3;
-
- case 21:
- return _context24.finish(18);
-
- case 22:
- case "end":
- return _context24.stop();
- }
- }, _marked18[0], this, [[0,, 18, 22], [1, 10, 14, 18], [2,, 4, 8]]);
- }
-
- function usingRaise() {
- return regeneratorRuntime.wrap(function usingRaise$(_context25) {
- while (1) switch (_context25.prev = _context25.next) {
- case 0:
- _context25.prev = 0;
- _context25.prev = 1;
- _context25.prev = 2;
-
- raise("thrown");
-
- case 4:
- _context25.prev = 4;
- _context25.next = 7;
- return 1;
-
- case 7:
- return _context25.finish(4);
-
- case 8:
- _context25.next = 14;
- break;
-
- case 10:
- _context25.prev = 10;
- _context25.t0 = _context25["catch"](1);
- _context25.next = 14;
- return _context25.t0;
-
- case 14:
- _context25.prev = 14;
- _context25.next = 17;
- return 2;
-
- case 17:
- return _context25.finish(14);
-
- case 18:
- _context25.prev = 18;
- _context25.next = 21;
- return 3;
-
- case 21:
- return _context25.finish(18);
-
- case 22:
- case "end":
- return _context25.stop();
- }
- }, _marked18[1], this, [[0,, 18, 22], [1, 10, 14, 18], [2,, 4, 8]]);
- }
-
- it("should statically execute in order", function () {
- check(usingThrow(), [1, "thrown", 2, 3]);
- });
-
- it("should dynamically execute in order", function () {
- check(usingRaise(), [1, "thrown", 2, 3]);
- });
-});
-
-describe("for-in loop generator", function () {
- it("should handle the simple case", function () {
- var _marked19 = [gen].map(regeneratorRuntime.mark);
-
- function gen() {
- var count, obj, key;
- return regeneratorRuntime.wrap(function gen$(_context26) {
- while (1) switch (_context26.prev = _context26.next) {
- case 0:
- count = 0;
- obj = { foo: 1, bar: 2 };
- _context26.t0 = regeneratorRuntime.keys(obj);
-
- case 3:
- if ((_context26.t1 = _context26.t0()).done) {
- _context26.next = 11;
- break;
- }
-
- key = _context26.t1.value;
-
- assert(obj.hasOwnProperty(key), key + " must be own property");
- _context26.next = 8;
- return [key, obj[key]];
-
- case 8:
- count += 1;
- _context26.next = 3;
- break;
-
- case 11:
- return _context26.abrupt("return", count);
-
- case 12:
- case "end":
- return _context26.stop();
- }
- }, _marked19[0], this);
- }
-
- check(gen(), [["foo", 1], ["bar", 2]], 2);
- });
-
- it("should handle break in loop", function () {
- var _marked20 = [gen].map(regeneratorRuntime.mark);
-
- function gen(obj) {
- var count, key;
- return regeneratorRuntime.wrap(function gen$(_context27) {
- while (1) switch (_context27.prev = _context27.next) {
- case 0:
- count = 0;
- _context27.next = 3;
- return "why not";
-
- case 3:
- _context27.t0 = regeneratorRuntime.keys(obj);
-
- case 4:
- if ((_context27.t1 = _context27.t0()).done) {
- _context27.next = 14;
- break;
- }
-
- key = _context27.t1.value;
-
- if (!obj.hasOwnProperty(key)) {
- _context27.next = 12;
- break;
- }
-
- if (!(key === "skip")) {
- _context27.next = 9;
- break;
- }
-
- return _context27.abrupt("break", 14);
-
- case 9:
- count += 1;
- _context27.next = 12;
- return [key, obj[key]];
-
- case 12:
- _context27.next = 4;
- break;
-
- case 14:
- return _context27.abrupt("return", count);
-
- case 15:
- case "end":
- return _context27.stop();
- }
- }, _marked20[0], this);
- }
-
- check(gen({ a: 1, b: 2, skip: 3, c: 4 }), ["why not", ["a", 1], ["b", 2]], 2);
- });
-
- it("should handle property deletion in loop", function () {
- var _marked21 = [gen].map(regeneratorRuntime.mark);
-
- function gen() {
- var count, obj, key;
- return regeneratorRuntime.wrap(function gen$(_context28) {
- while (1) switch (_context28.prev = _context28.next) {
- case 0:
- count = 0;
- obj = { foo: 1, bar: 2 };
- _context28.t0 = regeneratorRuntime.keys(obj);
-
- case 3:
- if ((_context28.t1 = _context28.t0()).done) {
- _context28.next = 12;
- break;
- }
-
- key = _context28.t1.value;
-
- assert(obj.hasOwnProperty(key), key + " must be own property");
- _context28.next = 8;
- return [key, obj[key]];
-
- case 8:
- delete obj.bar;
- count += 1;
- _context28.next = 3;
- break;
-
- case 12:
- return _context28.abrupt("return", count);
-
- case 13:
- case "end":
- return _context28.stop();
- }
- }, _marked21[0], this);
- }
-
- check(gen(), [["foo", 1]], 1);
- });
-
- it("should loop over inherited properties", function () {
- var _marked22 = [gen].map(regeneratorRuntime.mark);
-
- function gen() {
- var count, Foo, foo, key;
- return regeneratorRuntime.wrap(function gen$(_context29) {
- while (1) switch (_context29.prev = _context29.next) {
- case 0:
- Foo = function Foo() {
- this.baz = 1;
- };
-
- count = 0;
-
- Foo.prototype.bar = 2;
-
- foo = new Foo();
- _context29.t0 = regeneratorRuntime.keys(foo);
-
- case 5:
- if ((_context29.t1 = _context29.t0()).done) {
- _context29.next = 12;
- break;
- }
-
- key = _context29.t1.value;
- _context29.next = 9;
- return [key, foo[key]];
-
- case 9:
- count += 1;
- _context29.next = 5;
- break;
-
- case 12:
- return _context29.abrupt("return", count);
-
- case 13:
- case "end":
- return _context29.stop();
- }
- }, _marked22[0], this);
- }
-
- check(gen(), [["baz", 1], ["bar", 2]], 2);
- });
-
- it("should handle risky object expressions", function () {
- var _marked23 = [gen].map(regeneratorRuntime.mark);
-
- function a(sent) {
- assert.strictEqual(sent, 1);
- a.called = true;
- }
-
- function b(sent) {
- assert.strictEqual(sent, 2);
- b.called = true;
- return { callee: b };
- }
-
- function gen() {
- var key;
- return regeneratorRuntime.wrap(function gen$(_context30) {
- while (1) switch (_context30.prev = _context30.next) {
- case 0:
- assert.ok(!a.called);
- assert.ok(!b.called);
- _context30.next = 4;
- return 0;
-
- case 4:
- _context30.t1 = _context30.sent;
- a(_context30.t1);
- _context30.next = 8;
- return 1;
-
- case 8:
- _context30.t2 = _context30.sent;
- _context30.t0 = regeneratorRuntime.keys(b(_context30.t2));
-
- case 10:
- if ((_context30.t3 = _context30.t0()).done) {
- _context30.next = 21;
- break;
- }
-
- key = _context30.t3.value;
-
- assert.ok(a.called);
- assert.ok(b.called);
- _context30.t4 = assert;
- _context30.next = 17;
- return key;
-
- case 17:
- _context30.t5 = _context30.sent;
-
- _context30.t4.strictEqual.call(_context30.t4, _context30.t5, 3);
-
- _context30.next = 10;
- break;
-
- case 21:
- _context30.t6 = regeneratorRuntime.keys((a(1), { foo: "foo", bar: "bar" }));
-
- case 22:
- if ((_context30.t7 = _context30.t6()).done) {
- _context30.next = 28;
- break;
- }
-
- key = _context30.t7.value;
- _context30.next = 26;
- return key;
-
- case 26:
- _context30.next = 22;
- break;
-
- case 28:
- case "end":
- return _context30.stop();
- }
- }, _marked23[0], this);
- }
-
- check(gen(), [0, 1, "callee", "foo", "bar"]);
- });
-
- it("should allow non-Identifier left-hand expressions", function () {
- var _marked24 = [gen].map(regeneratorRuntime.mark);
-
- var obj = {};
- var baz = { a: 1, b: 2, c: 3 };
- var markers = [];
-
- function foo() {
- markers.push("called foo");
- return obj;
- }
-
- function gen() {
- return regeneratorRuntime.wrap(function gen$(_context31) {
- while (1) switch (_context31.prev = _context31.next) {
- case 0:
- _context31.t0 = regeneratorRuntime.keys(baz);
-
- case 1:
- if ((_context31.t1 = _context31.t0()).done) {
- _context31.next = 8;
- break;
- }
-
- foo().bar = _context31.t1.value;
-
- markers.push(obj.bar);
- _context31.next = 6;
- return obj.bar;
-
- case 6:
- _context31.next = 1;
- break;
-
- case 8:
- case "end":
- return _context31.stop();
- }
- }, _marked24[0], this);
- }
-
- check(gen(), ["a", "b", "c"]);
-
- assert.deepEqual(markers, ["called foo", "a", "called foo", "b", "called foo", "c"]);
- });
-});
-
-describe("yield chain", function () {
- var _marked25 = [gen].map(regeneratorRuntime.mark);
-
- function gen(n) {
- return regeneratorRuntime.wrap(function gen$(_context32) {
- while (1) switch (_context32.prev = _context32.next) {
- case 0:
- _context32.next = 2;
- return n;
-
- case 2:
- _context32.next = 4;
- return _context32.sent;
-
- case 4:
- _context32.next = 6;
- return _context32.sent;
-
- case 6:
- _context32.next = 8;
- return _context32.sent;
-
- case 8:
- return _context32.abrupt("return", _context32.sent);
-
- case 9:
- case "end":
- return _context32.stop();
- }
- }, _marked25[0], this);
- }
-
- it("should have correct associativity", function () {
- check(gen(5), [5, 1, 2, 3], 4);
- check(gen("asdf"), ["asdf", 1, 2, 3], 4);
- });
-});
-
-describe("object literal generator", function () {
- var _marked26 = [gen].map(regeneratorRuntime.mark);
-
- function gen(a, b) {
- return regeneratorRuntime.wrap(function gen$(_context33) {
- while (1) switch (_context33.prev = _context33.next) {
- case 0:
- _context33.t0 = a;
- _context33.next = 3;
- return a;
-
- case 3:
- _context33.t1 = _context33.sent;
- _context33.t2 = _context33.t0 - _context33.t1;
- _context33.next = 7;
- return b;
-
- case 7:
- _context33.t3 = _context33.sent;
- _context33.next = 10;
- return {
- a: _context33.t2,
- b: _context33.t3
- };
-
- case 10:
- case "end":
- return _context33.stop();
- }
- }, _marked26[0], this);
- }
-
- it("should yield the correct object", function () {
- check(gen(1, 2), [1, 2, { a: 0, b: 2 }]);
- check(gen(4, 2), [4, 2, { a: 3, b: 2 }]);
- });
-});
-
-describe("switch statement generator", function () {
- var _marked27 = [gen].map(regeneratorRuntime.mark);
-
- function gen(a) {
- return regeneratorRuntime.wrap(function gen$(_context34) {
- while (1) switch (_context34.prev = _context34.next) {
- case 0:
- _context34.next = 2;
- return a;
-
- case 2:
- _context34.t0 = _context34.sent;
- _context34.t1 = _context34.t0;
- _context34.next = 6;
- return "x";
-
- case 6:
- _context34.t2 = _context34.sent;
- _context34.t3 = a;
- _context34.t4 = _context34.t2 - _context34.t3;
-
- if (!(_context34.t1 === _context34.t4)) {
- _context34.next = 13;
- break;
- }
-
- _context34.t5 = 27;
- _context34.next = 25;
- break;
-
- case 13:
- _context34.t6 = _context34.t0;
- _context34.next = 16;
- return "y";
-
- case 16:
- _context34.t7 = _context34.sent;
- _context34.t8 = a;
- _context34.t9 = _context34.t7 - _context34.t8;
-
- if (!(_context34.t6 === _context34.t9)) {
- _context34.next = 23;
- break;
- }
-
- _context34.t10 = 28;
- _context34.next = 24;
- break;
-
- case 23:
- _context34.t10 = 29;
-
- case 24:
- _context34.t5 = _context34.t10;
-
- case 25:
- _context34.next = _context34.t5;
- break;
-
- case 27:
- return _context34.abrupt("return", "first case");
-
- case 28:
- return _context34.abrupt("return", "second case");
-
- case 29:
- case "end":
- return _context34.stop();
- }
- }, _marked27[0], this);
- }
-
- it("should jump to the correct cases", function () {
- check(gen(1), [1, "x"], "first case");
- check(gen(2), [2, "x", "y"], "second case");
- });
-});
-
-describe("infinite sequence generator", function () {
- var _marked28 = [gen, limit].map(regeneratorRuntime.mark);
-
- function gen(start, step) {
- return regeneratorRuntime.wrap(function gen$(_context35) {
- while (1) switch (_context35.prev = _context35.next) {
- case 0:
- step = step || 1;
-
- case 1:
- if (!true) {
- _context35.next = 7;
- break;
- }
-
- _context35.next = 4;
- return start;
-
- case 4:
- start += step;
- _context35.next = 1;
- break;
-
- case 7:
- case "end":
- return _context35.stop();
- }
- }, _marked28[0], this);
- }
-
- function limit(g, stop) {
- var info;
- return regeneratorRuntime.wrap(function limit$(_context36) {
- while (1) switch (_context36.prev = _context36.next) {
- case 0:
- if (!true) {
- _context36.next = 14;
- break;
- }
-
- info = g.next();
-
- if (!info.done) {
- _context36.next = 6;
- break;
- }
-
- return _context36.abrupt("return");
-
- case 6:
- if (!(info.value < stop)) {
- _context36.next = 11;
- break;
- }
-
- _context36.next = 9;
- return info.value;
-
- case 9:
- _context36.next = 12;
- break;
-
- case 11:
- return _context36.abrupt("return");
-
- case 12:
- _context36.next = 0;
- break;
-
- case 14:
- case "end":
- return _context36.stop();
- }
- }, _marked28[1], this);
- }
-
- it("should generate a lot of plausible values", function () {
- var g = gen(10, 2);
-
- assert.deepEqual(g.next(), { value: 10, done: false });
- assert.deepEqual(g.next(), { value: 12, done: false });
- assert.deepEqual(g.next(), { value: 14, done: false });
- assert.deepEqual(g.next(), { value: 16, done: false });
-
- var sum = 10 + 12 + 14 + 16;
-
- for (var n = 0; n < 1000; ++n) {
- var info = g.next();
- sum += info.value;
- assert.strictEqual(info.done, false);
- }
-
- assert.strictEqual(sum, 1017052);
- });
-
- it("should allow limiting", function () {
- check(limit(gen(10, 3), 20), [10, 13, 16, 19]);
- });
-});
-
-describe("generator function expression", function () {
- it("should behave just like a declared generator", function () {
- check(regeneratorRuntime.mark(function _callee3(x, y) {
- return regeneratorRuntime.wrap(function _callee3$(_context37) {
- while (1) switch (_context37.prev = _context37.next) {
- case 0:
- _context37.next = 2;
- return x;
-
- case 2:
- _context37.next = 4;
- return y;
-
- case 4:
- _context37.next = 6;
- return x + y;
-
- case 6:
- return _context37.abrupt("return", x * y);
-
- case 7:
- case "end":
- return _context37.stop();
- }
- }, _callee3, this);
- })(3, 7), [3, 7, 10], 21);
- });
-});
-
-describe("generator reentry attempt", function () {
- var _marked29 = [gen].map(regeneratorRuntime.mark);
-
- function gen(x) {
- return regeneratorRuntime.wrap(function gen$(_context38) {
- while (1) switch (_context38.prev = _context38.next) {
- case 0:
- _context38.prev = 0;
- _context38.next = 3;
- return x;
-
- case 3:
- _context38.t0 = x;
-
- _context38.sent.next(_context38.t0);
-
- _context38.next = 11;
- break;
-
- case 7:
- _context38.prev = 7;
- _context38.t1 = _context38["catch"](0);
- _context38.next = 11;
- return _context38.t1;
-
- case 11:
- return _context38.abrupt("return", x + 1);
-
- case 12:
- case "end":
- return _context38.stop();
- }
- }, _marked29[0], this, [[0, 7]]);
- }
-
- it("should complain with a TypeError", function () {
- var g = gen(3);
- assert.deepEqual(g.next(), { value: 3, done: false });
- var complaint = g.next(g); // Sending the generator to itself.
- assert.ok(complaint.value instanceof Error);
- assert.strictEqual(complaint.value.message, "Generator is already running");
- assert.deepEqual(g.next(), { value: 4, done: true });
- });
-});
-
-describe("completed generator", function () {
- var _marked30 = [gen].map(regeneratorRuntime.mark);
-
- function gen() {
- return regeneratorRuntime.wrap(function gen$(_context39) {
- while (1) switch (_context39.prev = _context39.next) {
- case 0:
- return _context39.abrupt("return", "ALL DONE");
-
- case 1:
- case "end":
- return _context39.stop();
- }
- }, _marked30[0], this);
- }
-
- (runningInTranslation ? it : xit)("should refuse to resume", function () {
- var g = gen();
-
- assert.deepEqual(g.next(), {
- value: "ALL DONE", done: true
- });
-
- assertAlreadyFinished(g);
- });
-});
-
-describe("delegated yield", function () {
- it("should delegate correctly", function () {
- var _marked31 = [gen].map(regeneratorRuntime.mark);
-
- function gen(condition) {
- return regeneratorRuntime.wrap(function gen$(_context40) {
- while (1) switch (_context40.prev = _context40.next) {
- case 0:
- _context40.next = 2;
- return 0;
-
- case 2:
- if (!condition) {
- _context40.next = 8;
- break;
- }
-
- _context40.next = 5;
- return 1;
-
- case 5:
- return _context40.delegateYield(gen(false), "t0", 6);
-
- case 6:
- _context40.next = 8;
- return 2;
-
- case 8:
- _context40.next = 10;
- return 3;
-
- case 10:
- case "end":
- return _context40.stop();
- }
- }, _marked31[0], this);
- }
-
- check(gen(true), [0, 1, 0, 3, 2, 3]);
- check(gen(false), [0, 3]);
- });
-
- it("should cope with empty delegatees", function () {
- var _marked32 = [gen].map(regeneratorRuntime.mark);
-
- function gen(condition) {
- return regeneratorRuntime.wrap(function gen$(_context41) {
- while (1) switch (_context41.prev = _context41.next) {
- case 0:
- if (!condition) {
- _context41.next = 6;
- break;
- }
-
- _context41.next = 3;
- return 0;
-
- case 3:
- return _context41.delegateYield(gen(false), "t0", 4);
-
- case 4:
- _context41.next = 6;
- return 1;
-
- case 6:
- case "end":
- return _context41.stop();
- }
- }, _marked32[0], this);
- }
-
- check(gen(true), [0, 1]);
- check(gen(false), []);
- });
-
- it("should support deeper nesting", function () {
- var _marked33 = [outer, middle, inner].map(regeneratorRuntime.mark);
-
- function outer(n) {
- return regeneratorRuntime.wrap(function outer$(_context42) {
- while (1) switch (_context42.prev = _context42.next) {
- case 0:
- _context42.next = 2;
- return n;
-
- case 2:
- return _context42.delegateYield(middle(n - 1, inner(n + 10)), "t0", 3);
-
- case 3:
- _context42.next = 5;
- return n + 1;
-
- case 5:
- case "end":
- return _context42.stop();
- }
- }, _marked33[0], this);
- }
-
- function middle(n, plusTen) {
- return regeneratorRuntime.wrap(function middle$(_context43) {
- while (1) switch (_context43.prev = _context43.next) {
- case 0:
- _context43.next = 2;
- return n;
-
- case 2:
- return _context43.delegateYield(inner(n - 1), "t0", 3);
-
- case 3:
- _context43.next = 5;
- return n + 1;
-
- case 5:
- return _context43.delegateYield(plusTen, "t1", 6);
-
- case 6:
- case "end":
- return _context43.stop();
- }
- }, _marked33[1], this);
- }
-
- function inner(n) {
- return regeneratorRuntime.wrap(function inner$(_context44) {
- while (1) switch (_context44.prev = _context44.next) {
- case 0:
- _context44.next = 2;
- return n;
-
- case 2:
- case "end":
- return _context44.stop();
- }
- }, _marked33[2], this);
- }
-
- check(outer(5), [5, 4, 3, 5, 15, 6]);
- });
-
- it("should pass sent values through", function () {
- var _marked34 = [outer, inner].map(regeneratorRuntime.mark);
-
- function outer(n) {
- return regeneratorRuntime.wrap(function outer$(_context45) {
- while (1) switch (_context45.prev = _context45.next) {
- case 0:
- return _context45.delegateYield(inner(n << 1), "t0", 1);
-
- case 1:
- _context45.next = 3;
- return "zxcv";
-
- case 3:
- case "end":
- return _context45.stop();
- }
- }, _marked34[0], this);
- }
-
- function inner(n) {
- return regeneratorRuntime.wrap(function inner$(_context46) {
- while (1) switch (_context46.prev = _context46.next) {
- case 0:
- _context46.next = 2;
- return n;
-
- case 2:
- _context46.next = 4;
- return _context46.sent;
-
- case 4:
- _context46.next = 6;
- return _context46.sent;
-
- case 6:
- return _context46.abrupt("return", _context46.sent);
-
- case 7:
- case "end":
- return _context46.stop();
- }
- }, _marked34[1], this);
- }
-
- var g = outer(3);
- assert.deepEqual(g.next(), { value: 6, done: false });
- assert.deepEqual(g.next(1), { value: 1, done: false });
- assert.deepEqual(g.next(2), { value: 2, done: false });
- assert.deepEqual(g.next(4), { value: "zxcv", done: false });
- assert.deepEqual(g.next(5), { value: void 0, done: true });
- });
-
- it("should be governed by enclosing try statements", function () {
- var _marked35 = [outer, inner].map(regeneratorRuntime.mark);
-
- var error = new Error("thrown");
-
- function outer(n) {
- return regeneratorRuntime.wrap(function outer$(_context47) {
- while (1) switch (_context47.prev = _context47.next) {
- case 0:
- _context47.prev = 0;
- _context47.next = 3;
- return 0;
-
- case 3:
- return _context47.delegateYield(inner(n), "t0", 4);
-
- case 4:
- _context47.next = 6;
- return 1;
-
- case 6:
- _context47.next = 12;
- break;
-
- case 8:
- _context47.prev = 8;
- _context47.t1 = _context47["catch"](0);
- _context47.next = 12;
- return _context47.t1.message;
-
- case 12:
- _context47.next = 14;
- return 4;
-
- case 14:
- case "end":
- return _context47.stop();
- }
- }, _marked35[0], this, [[0, 8]]);
- }
-
- function inner(n) {
- return regeneratorRuntime.wrap(function inner$(_context48) {
- while (1) switch (_context48.prev = _context48.next) {
- case 0:
- if (!(n-- > 0)) {
- _context48.next = 9;
- break;
- }
-
- _context48.prev = 1;
-
- if (n === 3) {
- raise(error);
- }
-
- case 3:
- _context48.prev = 3;
- _context48.next = 6;
- return n;
-
- case 6:
- return _context48.finish(3);
-
- case 7:
- _context48.next = 0;
- break;
-
- case 9:
- case "end":
- return _context48.stop();
- }
- }, _marked35[1], this, [[1,, 3, 7]]);
- }
-
- check(outer(3), [0, 2, 1, 0, 1, 4]);
- check(outer(5), [0, 4, 3, "thrown", 4]);
- });
-
- it("should dispatch .thrown exceptions correctly", function () {
- var _marked36 = [gen, inner].map(regeneratorRuntime.mark);
-
- var count = 0;
-
- function gen() {
- return regeneratorRuntime.wrap(function gen$(_context49) {
- while (1) switch (_context49.prev = _context49.next) {
- case 0:
- return _context49.delegateYield(inner(), "t0", 1);
-
- case 1:
- _context49.prev = 1;
- return _context49.delegateYield(inner(), "t1", 3);
-
- case 3:
- _context49.next = 7;
- break;
-
- case 5:
- _context49.prev = 5;
- _context49.t2 = _context49["catch"](1);
-
- case 7:
- return _context49.delegateYield(inner(), "t3", 8);
-
- case 8:
- return _context49.abrupt("return", _context49.t3);
-
- case 9:
- case "end":
- return _context49.stop();
- }
- }, _marked36[0], this, [[1, 5]]);
- }
-
- function inner() {
- return regeneratorRuntime.wrap(function inner$(_context50) {
- while (1) switch (_context50.prev = _context50.next) {
- case 0:
- _context50.next = 2;
- return count++;
-
- case 2:
- return _context50.abrupt("return", _context50.sent);
-
- case 3:
- case "end":
- return _context50.stop();
- }
- }, _marked36[1], this);
- }
-
- var g = gen();
-
- assert.deepEqual(g.next(), {
- value: 0,
- done: false
- });
-
- assert.deepEqual(g.next(), {
- value: 1,
- done: false
- });
-
- assert.deepEqual(g.throw(new Error("lol")), {
- value: 2,
- done: false
- });
-
- assert.deepEqual(g.next("sent"), {
- value: "sent",
- done: true
- });
- });
-
- it("should call .return methods of delegate iterators", function () {
- var _marked37 = [gen].map(regeneratorRuntime.mark);
-
- var throwee = new Error("argument to gen.throw");
- var thrownFromThrow = new Error("thrown from throw method");
- var thrownFromReturn = new Error("thrown from return method");
-
- function gen(delegate) {
- return regeneratorRuntime.wrap(function gen$(_context51) {
- while (1) switch (_context51.prev = _context51.next) {
- case 0:
- _context51.prev = 0;
- return _context51.delegateYield(delegate, "t0", 2);
-
- case 2:
- return _context51.abrupt("return", _context51.t0);
-
- case 5:
- _context51.prev = 5;
- _context51.t1 = _context51["catch"](0);
- return _context51.abrupt("return", _context51.t1);
-
- case 8:
- case "end":
- return _context51.stop();
- }
- }, _marked37[0], this, [[0, 5]]);
- }
-
- function check(throwMethod, returnMethod) {
- var throwCalled = false;
- var returnCalled = false;
- var count = 0;
- var iterator = {
- next: function () {
- return { value: count++, done: false };
- }
- };
-
- iterator[iteratorSymbol] = function () {
- return this;
- };
-
- if (throwMethod) {
- iterator["throw"] = function () {
- throwCalled = true;
- return throwMethod.apply(this, arguments);
- };
- }
-
- if (returnMethod) {
- iterator["return"] = function () {
- returnCalled = true;
- return returnMethod.apply(this, arguments);
- };
- }
-
- var g = gen(iterator);
-
- assert.deepEqual(g.next(), { value: 0, done: false });
- assert.deepEqual(g.next(), { value: 1, done: false });
- assert.deepEqual(g.next(), { value: 2, done: false });
- assert.deepEqual(g.next(), { value: 3, done: false });
-
- assert.strictEqual(throwCalled, false);
- assert.strictEqual(returnCalled, false);
-
- var result = {};
-
- result.throwResult = g.throw(throwee);
- result.throwCalled = throwCalled;
- result.returnCalled = returnCalled;
-
- return result;
- }
-
- var checkResult = check(undefined, function () {
- throw thrownFromReturn;
- });
- if (runningInTranslation) {
- // BUG: Node v0.11 and v0.12 neglect to call .return here.
- assert.strictEqual(checkResult.throwResult.value, thrownFromReturn);
- } else {
- // This is the TypeError that results from trying to call the
- // undefined .throw method of the iterator.
- assert.ok(checkResult.throwResult.value instanceof TypeError);
- }
- assert.strictEqual(checkResult.throwResult.done, true);
- assert.strictEqual(checkResult.throwCalled, false);
- // BUG: Node v0.11 and v0.12 neglect to call .return here.
- assert.strictEqual(checkResult.returnCalled, runningInTranslation);
-
- checkResult = check(undefined, function () {
- return { value: "from return", done: true };
- });
- assert.notStrictEqual(checkResult.throwResult.value, throwee);
- // This is the TypeError that results from trying to call the
- // undefined .throw method of the iterator.
- assert.ok(checkResult.throwResult.value instanceof TypeError);
- assert.strictEqual(checkResult.throwResult.done, true);
- assert.strictEqual(checkResult.throwCalled, false);
- // BUG: Node v0.11 and v0.12 neglect to call .return here.
- assert.strictEqual(checkResult.returnCalled, runningInTranslation);
-
- var checkResult = check(function (thrown) {
- return { value: "from throw", done: true };
- }, function () {
- throw thrownFromReturn;
- });
- assert.strictEqual(checkResult.throwResult.value, "from throw");
- assert.strictEqual(checkResult.throwResult.done, true);
- assert.strictEqual(checkResult.throwCalled, true);
- assert.strictEqual(checkResult.returnCalled, false);
-
- var checkResult = check(function (thrown) {
- throw thrownFromThrow;
- }, function () {
- throw thrownFromReturn;
- });
- assert.strictEqual(checkResult.throwResult.value, thrownFromThrow);
- assert.strictEqual(checkResult.throwResult.done, true);
- assert.strictEqual(checkResult.throwCalled, true);
- assert.strictEqual(checkResult.returnCalled, false);
-
- var checkResult = check(undefined, undefined);
- assert.notStrictEqual(checkResult.throwResult.value, throwee);
- // This is the TypeError that results from trying to call the
- // undefined .throw method of the iterator.
- assert.ok(checkResult.throwResult.value instanceof TypeError);
- assert.strictEqual(checkResult.throwResult.done, true);
- assert.strictEqual(checkResult.throwCalled, false);
- assert.strictEqual(checkResult.returnCalled, false);
- });
-
- it("should not be required to have a .return method", function () {
- var _marked38 = [gen].map(regeneratorRuntime.mark);
-
- function gen(delegate) {
- return regeneratorRuntime.wrap(function gen$(_context52) {
- while (1) switch (_context52.prev = _context52.next) {
- case 0:
- return _context52.delegateYield(delegate, "t0", 1);
-
- case 1:
- return _context52.abrupt("return", _context52.t0);
-
- case 2:
- case "end":
- return _context52.stop();
- }
- }, _marked38[0], this);
- }
-
- var inner = range(5);
- var iterator = { next: inner.next.bind(inner) };
- iterator[iteratorSymbol] = function () {
- return this;
- };
-
- var g = gen(iterator);
- assert.deepEqual(g.next(), { value: 0, done: false });
- assert.deepEqual(g.next(), { value: 1, done: false });
- assert.deepEqual(g.next(), { value: 2, done: false });
-
- if (typeof g.return === "function") {
- assert.deepEqual(g.return(-1), { value: -1, done: true });
- assert.deepEqual(g.next(), { value: void 0, done: true });
- }
- });
-
- (runningInTranslation ? it : xit)("should support any iterable argument", function () {
- var _marked39 = [gen, string].map(regeneratorRuntime.mark);
-
- function gen() {
- return regeneratorRuntime.wrap(function gen$(_context53) {
- while (1) switch (_context53.prev = _context53.next) {
- case 0:
- _context53.next = 2;
- return 0;
-
- case 2:
- _context53.next = 4;
- return "one";
-
- case 4:
- _context53.t0 = _context53.sent;
- _context53.next = 7;
- return "two";
-
- case 7:
- _context53.t1 = _context53.sent;
- _context53.next = 10;
- return "three";
-
- case 10:
- _context53.t2 = _context53.sent;
- return _context53.delegateYield([_context53.t0, _context53.t1, _context53.t2], "t3", 12);
-
- case 12:
- _context53.next = 14;
- return 5;
-
- case 14:
- case "end":
- return _context53.stop();
- }
- }, _marked39[0], this);
- }
-
- check(gen(), [0, "one", "two", "three", 2, 3, 4, 5]);
-
- function string() {
- return regeneratorRuntime.wrap(function string$(_context54) {
- while (1) switch (_context54.prev = _context54.next) {
- case 0:
- return _context54.delegateYield("asdf", "t0", 1);
-
- case 1:
- return _context54.abrupt("return", _context54.t0);
-
- case 2:
- case "end":
- return _context54.stop();
- }
- }, _marked39[1], this);
- }
-
- check(string(), ["a", "s", "d", "f"]);
- });
-
- it("should evaluate to the return value of the delegate", function () {
- var _marked40 = [inner, outer].map(regeneratorRuntime.mark);
-
- function inner() {
- return regeneratorRuntime.wrap(function inner$(_context55) {
- while (1) switch (_context55.prev = _context55.next) {
- case 0:
- _context55.next = 2;
- return 1;
-
- case 2:
- return _context55.abrupt("return", 2);
-
- case 3:
- case "end":
- return _context55.stop();
- }
- }, _marked40[0], this);
- }
-
- function outer(delegate) {
- return regeneratorRuntime.wrap(function outer$(_context56) {
- while (1) switch (_context56.prev = _context56.next) {
- case 0:
- return _context56.delegateYield(delegate, "t0", 1);
-
- case 1:
- return _context56.abrupt("return", _context56.t0);
-
- case 2:
- case "end":
- return _context56.stop();
- }
- }, _marked40[1], this);
- }
-
- check(outer(inner()), [1], 2);
-
- var arrayDelegate = [3, 4];
- if (!runningInTranslation) {
- // Node v0.11 doesn't know how to turn arrays into iterators over
- // their elements without a little help.
- arrayDelegate = regeneratorRuntime.values(arrayDelegate);
- }
- check(outer(arrayDelegate), [3, 4], void 0); // See issue #143.
-
- if (!runningInTranslation) {
- return;
- }
-
- check(outer({
- next: function () {
- return { value: "oyez", done: true };
- }
- }), [], "oyez");
- });
-
- it("should work as a subexpression", function () {
- var _marked41 = [inner, gen].map(regeneratorRuntime.mark);
-
- function inner(arg) {
- return regeneratorRuntime.wrap(function inner$(_context57) {
- while (1) switch (_context57.prev = _context57.next) {
- case 0:
- return _context57.abrupt("return", arg);
-
- case 1:
- case "end":
- return _context57.stop();
- }
- }, _marked41[0], this);
- }
-
- function gen(delegate) {
- return regeneratorRuntime.wrap(function gen$(_context58) {
- while (1) switch (_context58.prev = _context58.next) {
- case 0:
- return _context58.delegateYield(delegate, "t0", 1);
-
- case 1:
- _context58.t1 = _context58.t0;
- return _context58.abrupt("return", 1 + _context58.t1);
-
- case 3:
- case "end":
- return _context58.stop();
- }
- }, _marked41[1], this);
- }
-
- check(gen(inner(2)), [], 3);
- check(gen(inner(3)), [], 4);
-
- if (!runningInTranslation) {
- return;
- }
-
- check(gen({
- next: function () {
- return { value: "foo", done: true };
- }
- }), [], "1foo");
- });
-});
-
-describe("function declaration hoisting", function () {
- it("should work even if the declarations are out of order", function () {
- var _marked42 = [gen].map(regeneratorRuntime.mark);
-
- function gen(n) {
- var increment, halve, decrement;
- return regeneratorRuntime.wrap(function gen$(_context59) {
- while (1) switch (_context59.prev = _context59.next) {
- case 0:
- increment = function increment(x) {
- return x + 1;
- };
-
- _context59.next = 3;
- return increment(n);
-
- case 3:
- if (!(n % 2)) {
- _context59.next = 10;
- break;
- }
-
- decrement = function decrement(x) {
- return x - 1;
- };
-
- halve = function halve(x) {
- return x >> 1;
- };
-
- _context59.next = 8;
- return halve(decrement(n));
-
- case 8:
- _context59.next = 11;
- break;
-
- case 10:
- // The behavior of function declarations nested inside conditional
- // blocks is notoriously underspecified, and in V8 it appears the
- // halve function is still defined when we take this branch, so
- // "undefine" it for consistency with regenerator semantics.
- halve = void 0;
-
- case 11:
- _context59.next = 13;
- return typeof halve;
-
- case 13:
- _context59.next = 15;
- return increment(increment(n));
-
- case 15:
- case "end":
- return _context59.stop();
- }
- }, _marked42[0], this);
- }
-
- check(gen(3), [4, 1, "function", 5]);
- check(gen(4), [5, "undefined", 6]);
- });
-
- it("should work for nested generator function declarations", function () {
- var _marked44 = [outer].map(regeneratorRuntime.mark);
-
- function outer(n) {
- var _marked43, inner;
-
- return regeneratorRuntime.wrap(function outer$(_context61) {
- while (1) switch (_context61.prev = _context61.next) {
- case 0:
- inner = function inner(n) {
- return regeneratorRuntime.wrap(function inner$(_context60) {
- while (1) switch (_context60.prev = _context60.next) {
- case 0:
- _context60.next = 2;
- return n - 1;
-
- case 2:
- _context60.next = 4;
- return n;
-
- case 4:
- _context60.next = 6;
- return n + 1;
-
- case 6:
- return _context60.abrupt("return", _context60.sent);
-
- case 7:
- case "end":
- return _context60.stop();
- }
- }, _marked43[0], this);
- };
-
- _marked43 = [inner].map(regeneratorRuntime.mark);
- _context61.next = 4;
- return 0;
-
- case 4:
- assert.ok(regeneratorRuntime.isGeneratorFunction(inner));
- return _context61.delegateYield(inner(n), "t0", 6);
-
- case 6:
- return _context61.abrupt("return", _context61.t0);
-
- case 7:
- case "end":
- return _context61.stop();
- }
- }, _marked44[0], this);
- }
-
- check(outer(2), [0, 1, 2, 3], 4);
- });
-
- it("should not interfere with function rebinding", function () {
- var _marked45 = [toBeRebound].map(regeneratorRuntime.mark);
-
- function rebindTo(value) {
- var oldValue = toBeRebound;
- toBeRebound = value;
- return oldValue;
- }
-
- function toBeRebound() {
- var originalValue;
- return regeneratorRuntime.wrap(function toBeRebound$(_context62) {
- while (1) switch (_context62.prev = _context62.next) {
- case 0:
- originalValue = toBeRebound;
- _context62.next = 3;
- return toBeRebound;
-
- case 3:
- assert.strictEqual(rebindTo(42), originalValue);
- _context62.next = 6;
- return toBeRebound;
-
- case 6:
- assert.strictEqual(rebindTo("asdf"), 42);
- _context62.next = 9;
- return toBeRebound;
-
- case 9:
- case "end":
- return _context62.stop();
- }
- }, _marked45[0], this);
- }
-
- var original = toBeRebound;
- check(toBeRebound(), [original, 42, "asdf"]);
-
- function attemptToRebind(value) {
- var oldValue = safe;
- safe = value;
- return oldValue;
- }
-
- var safe = regeneratorRuntime.mark(function safe() {
- var originalValue;
- return regeneratorRuntime.wrap(function safe$(_context63) {
- while (1) switch (_context63.prev = _context63.next) {
- case 0:
- originalValue = safe;
- _context63.next = 3;
- return safe;
-
- case 3:
- assert.strictEqual(attemptToRebind(42), originalValue);
- _context63.next = 6;
- return safe;
-
- case 6:
- assert.strictEqual(attemptToRebind("asdf"), 42);
- _context63.next = 9;
- return safe;
-
- case 9:
- case "end":
- return _context63.stop();
- }
- }, safe, this);
- });
-
- original = safe;
- check(safe(), [safe, safe, safe]);
- });
-});
-
-describe("the arguments object", function () {
- it("should work in simple variadic functions", function () {
- var _marked46 = [sum].map(regeneratorRuntime.mark);
-
- function sum() {
- var result,
- i,
- _args64 = arguments;
- return regeneratorRuntime.wrap(function sum$(_context64) {
- while (1) switch (_context64.prev = _context64.next) {
- case 0:
- result = 0;
- i = 0;
-
- case 2:
- if (!(i < _args64.length)) {
- _context64.next = 8;
- break;
- }
-
- _context64.next = 5;
- return result += _args64[i];
-
- case 5:
- ++i;
- _context64.next = 2;
- break;
-
- case 8:
- return _context64.abrupt("return", result);
-
- case 9:
- case "end":
- return _context64.stop();
- }
- }, _marked46[0], this);
- }
-
- check(sum(1, 2, 3), [1, 3, 6], 6);
- check(sum(9, -5, 3, 0, 2), [9, 4, 7, 7, 9], 9);
- });
-
- it("should alias function parameters", function () {
- var _marked47 = [gen].map(regeneratorRuntime.mark);
-
- function gen(x, y) {
- var temp,
- _args65 = arguments;
- return regeneratorRuntime.wrap(function gen$(_context65) {
- while (1) switch (_context65.prev = _context65.next) {
- case 0:
- _context65.next = 2;
- return x;
-
- case 2:
- ++_args65[0];
- _context65.next = 5;
- return x;
-
- case 5:
- _context65.next = 7;
- return y;
-
- case 7:
- --_args65[1];
- _context65.next = 10;
- return y;
-
- case 10:
- temp = y;
-
- y = x;
- x = temp;
-
- _context65.next = 15;
- return x;
-
- case 15:
- _context65.next = 17;
- return y;
-
- case 17:
- case "end":
- return _context65.stop();
- }
- }, _marked47[0], this);
- }
-
- check(gen(3, 7), [3, 4, 7, 6, 6, 4]);
- check(gen(10, -5), [10, 11, -5, -6, -6, 11]);
- });
-
- it("should be shadowable by explicit declarations", function () {
- var _marked48 = [asParameter, asVariable].map(regeneratorRuntime.mark);
-
- function asParameter(x, arguments) {
- var _args66 = arguments;
- return regeneratorRuntime.wrap(function asParameter$(_context66) {
- while (1) switch (_context66.prev = _context66.next) {
- case 0:
- _args66 = _args66 + 1;
- _context66.next = 3;
- return x + _args66;
-
- case 3:
- case "end":
- return _context66.stop();
- }
- }, _marked48[0], this);
- }
-
- check(asParameter(4, 5), [10]);
- check(asParameter("asdf", "zxcv"), ["asdfzxcv1"]);
-
- function asVariable(x) {
- var arguments,
- _args67 = arguments;
- return regeneratorRuntime.wrap(function asVariable$(_context67) {
- while (1) switch (_context67.prev = _context67.next) {
- case 0:
- // TODO References to arguments before the variable declaration
- // seem to see the object instead of the undefined value.
- _args67 = x + 1;
- _context67.next = 3;
- return _args67;
-
- case 3:
- case "end":
- return _context67.stop();
- }
- }, _marked48[1], this);
- }
-
- check(asVariable(4), [5]);
- check(asVariable("asdf"), ["asdf1"]);
- });
-
- it("should not get confused by properties", function () {
- var _marked49 = [gen].map(regeneratorRuntime.mark);
-
- function gen(args) {
- var obj;
- return regeneratorRuntime.wrap(function gen$(_context68) {
- while (1) switch (_context68.prev = _context68.next) {
- case 0:
- obj = { arguments: args };
- _context68.next = 3;
- return obj.arguments;
-
- case 3:
- obj.arguments = "oyez";
- _context68.next = 6;
- return obj;
-
- case 6:
- case "end":
- return _context68.stop();
- }
- }, _marked49[0], this);
- }
-
- check(gen(42), [42, { arguments: "oyez" }]);
- });
-
- it("supports .callee", function () {
- var _marked50 = [gen].map(regeneratorRuntime.mark);
-
- function gen(doYield) {
- var _args69 = arguments;
- return regeneratorRuntime.wrap(function gen$(_context69) {
- while (1) switch (_context69.prev = _context69.next) {
- case 0:
- _context69.next = 2;
- return 1;
-
- case 2:
- if (!doYield) {
- _context69.next = 7;
- break;
- }
-
- _context69.next = 5;
- return 2;
-
- case 5:
- _context69.next = 12;
- break;
-
- case 7:
- _context69.next = 9;
- return 3;
-
- case 9:
- return _context69.delegateYield(_args69.callee(true), "t0", 10);
-
- case 10:
- _context69.next = 12;
- return 4;
-
- case 12:
- _context69.next = 14;
- return 5;
-
- case 14:
- case "end":
- return _context69.stop();
- }
- }, _marked50[0], this);
- }
-
- check(gen(false), [1, 3, 1, 2, 5, 4, 5]);
- });
-});
-
-describe("catch parameter shadowing", function () {
- it("should leave outer variables unmodified", function () {
- var _marked51 = [gen].map(regeneratorRuntime.mark);
-
- function gen(x) {
- var y;
- return regeneratorRuntime.wrap(function gen$(_context70) {
- while (1) switch (_context70.prev = _context70.next) {
- case 0:
- y = x + 1;
- _context70.prev = 1;
- throw x + 2;
-
- case 5:
- _context70.prev = 5;
- _context70.t0 = _context70["catch"](1);
- _context70.next = 9;
- return _context70.t0;
-
- case 9:
- _context70.t0 += 1;
- _context70.next = 12;
- return _context70.t0;
-
- case 12:
- _context70.next = 14;
- return x;
-
- case 14:
- _context70.prev = 14;
- throw x + 3;
-
- case 18:
- _context70.prev = 18;
- _context70.t1 = _context70["catch"](14);
- _context70.next = 22;
- return _context70.t1;
-
- case 22:
- _context70.t1 *= 2;
- _context70.next = 25;
- return _context70.t1;
-
- case 25:
- _context70.next = 27;
- return y;
-
- case 27:
- case "end":
- return _context70.stop();
- }
- }, _marked51[0], this, [[1, 5], [14, 18]]);
- }
-
- check(gen(1), [3, 4, 1, 4, 8, 2]);
- check(gen(2), [4, 5, 2, 5, 10, 3]);
- });
-
- it("should not replace variables defined in inner scopes", function () {
- var _marked52 = [gen].map(regeneratorRuntime.mark);
-
- function gen(x) {
- return regeneratorRuntime.wrap(function gen$(_context71) {
- while (1) switch (_context71.prev = _context71.next) {
- case 0:
- _context71.prev = 0;
- throw x;
-
- case 4:
- _context71.prev = 4;
- _context71.t0 = _context71["catch"](0);
- _context71.next = 8;
- return _context71.t0;
-
- case 8:
- _context71.next = 10;
- return (function (x) {
- return x += 1;
- })(_context71.t0 + 1);
-
- case 10:
- _context71.next = 12;
- return (function () {
- var x = arguments[0];
- return x * 2;
- })(_context71.t0 + 2);
-
- case 12:
- _context71.next = 14;
- return (function () {
- function notCalled(x) {
- throw x;
- }
-
- _context71.t0 >>= 1;
- return _context71.t0;
- })();
-
- case 14:
- _context71.next = 16;
- return _context71.t0 -= 1;
-
- case 16:
- _context71.next = 18;
- return x;
-
- case 18:
- case "end":
- return _context71.stop();
- }
- }, _marked52[0], this, [[0, 4]]);
- }
-
- check(gen(10), [10, 12, 24, 5, 4, 10]);
- check(gen(11), [11, 13, 26, 5, 4, 11]);
- });
-
- it("should allow nested catch parameters of the same name", function () {
- var _marked53 = [gen].map(regeneratorRuntime.mark);
-
- function gen() {
- return regeneratorRuntime.wrap(function gen$(_context72) {
- while (1) switch (_context72.prev = _context72.next) {
- case 0:
- _context72.prev = 0;
-
- raise("e1");
- _context72.next = 18;
- break;
-
- case 4:
- _context72.prev = 4;
- _context72.t0 = _context72["catch"](0);
- _context72.next = 8;
- return _context72.t0;
-
- case 8:
- _context72.prev = 8;
-
- raise("e2");
- _context72.next = 16;
- break;
-
- case 12:
- _context72.prev = 12;
- _context72.t1 = _context72["catch"](8);
- _context72.next = 16;
- return _context72.t1;
-
- case 16:
- _context72.next = 18;
- return _context72.t0;
-
- case 18:
- case "end":
- return _context72.stop();
- }
- }, _marked53[0], this, [[0, 4], [8, 12]]);
- }
-
- check(gen(), ["e1", "e2", "e1"]);
- });
-
- it("should not interfere with non-referential identifiers", function () {
- var _marked54 = [gen].map(regeneratorRuntime.mark);
-
- function gen() {
- return regeneratorRuntime.wrap(function gen$(_context73) {
- while (1) switch (_context73.prev = _context73.next) {
- case 0:
- _context73.prev = 0;
- _context73.next = 3;
- return 1;
-
- case 3:
- raise(new Error("oyez"));
- _context73.next = 6;
- return 2;
-
- case 6:
- _context73.next = 15;
- break;
-
- case 8:
- _context73.prev = 8;
- _context73.t0 = _context73["catch"](0);
- _context73.next = 12;
- return 3;
-
- case 12:
- _context73.t0.e = "e.e";
- _context73.t0[_context73.t0.message] = "e.oyez";
- return _context73.abrupt("return", {
- e: _context73.t0,
- identity: function (x) {
- var e = x;
- return e;
- }
- });
-
- case 15:
- _context73.next = 17;
- return 4;
-
- case 17:
- case "end":
- return _context73.stop();
- }
- }, _marked54[0], this, [[0, 8]]);
- }
-
- var g = gen();
- assert.deepEqual(g.next(), { value: 1, done: false });
- assert.deepEqual(g.next(), { value: 3, done: false });
-
- var info = g.next();
- assert.strictEqual(info.done, true);
- assert.strictEqual(info.value.e.message, "oyez");
- assert.strictEqual(info.value.e.e, "e.e");
- assert.strictEqual(info.value.e.oyez, "e.oyez");
- assert.strictEqual(info.value.identity("same"), "same");
- });
-});
-
-describe("empty while loops", function () {
- it("should be preserved in generated code", function () {
- var _marked55 = [gen].map(regeneratorRuntime.mark);
-
- function gen(x) {
- return regeneratorRuntime.wrap(function gen$(_context74) {
- while (1) switch (_context74.prev = _context74.next) {
- case 0:
- while (x) {
- // empty while loop
- }
-
- do {
- // empty do-while loop
- } while (x);
-
- return _context74.abrupt("return", gen.toString());
-
- case 3:
- case "end":
- return _context74.stop();
- }
- }, _marked55[0], this);
- }
-
- var info = gen(false).next();
- assert.strictEqual(info.done, true);
- assert.ok(/empty while loop/.test(info.value));
- assert.ok(/empty do-while loop/.test(info.value));
- });
-});
-
-describe("object literals with multiple yields", function () {
- it("should receive different sent values", function () {
- var _marked56 = [gen].map(regeneratorRuntime.mark);
-
- function gen(fn) {
- return regeneratorRuntime.wrap(function gen$(_context75) {
- while (1) switch (_context75.prev = _context75.next) {
- case 0:
- _context75.next = 2;
- return "a";
-
- case 2:
- _context75.t0 = _context75.sent;
- _context75.next = 5;
- return "b";
-
- case 5:
- _context75.t1 = _context75.sent;
- _context75.next = 8;
- return "c";
-
- case 8:
- _context75.t2 = _context75.sent;
- _context75.next = 11;
- return "d";
-
- case 11:
- _context75.t3 = _context75.sent;
- _context75.t4 = fn(_context75.t2, _context75.t3);
- _context75.next = 15;
- return "e";
-
- case 15:
- _context75.t5 = _context75.sent;
- _context75.next = 18;
- return "f";
-
- case 18:
- _context75.t6 = _context75.sent;
- _context75.t7 = [_context75.t5, _context75.t6];
- return _context75.abrupt("return", {
- a: _context75.t0,
- b: _context75.t1,
- c: _context75.t4,
- d: _context75.t7
- });
-
- case 21:
- case "end":
- return _context75.stop();
- }
- }, _marked56[0], this);
- }
-
- check(gen(function sum(x, y) {
- return x + y;
- }), ["a", "b", "c", "d", "e", "f"], {
- a: 1,
- b: 2,
- c: 3 + 4,
- d: [5, 6]
- });
- });
-});
-
-describe("generator .throw method", function () {
- (runningInTranslation ? it : xit)("should complete generator", function () {
- var _marked57 = [gen].map(regeneratorRuntime.mark);
-
- function gen(x) {
- return regeneratorRuntime.wrap(function gen$(_context76) {
- while (1) switch (_context76.prev = _context76.next) {
- case 0:
- _context76.next = 2;
- return 2;
-
- case 2:
- throw 1;
-
- case 3:
- case "end":
- return _context76.stop();
- }
- }, _marked57[0], this);
- }
-
- var u = gen();
-
- u.next();
-
- try {
- u.throw(2);
- } catch (err) {
- assert.strictEqual(err, 2);
- }
-
- assertAlreadyFinished(u);
- });
-
- it("should work after the final call to .next", function () {
- var _marked58 = [gen].map(regeneratorRuntime.mark);
-
- function gen() {
- return regeneratorRuntime.wrap(function gen$(_context77) {
- while (1) switch (_context77.prev = _context77.next) {
- case 0:
- _context77.next = 2;
- return 1;
-
- case 2:
- case "end":
- return _context77.stop();
- }
- }, _marked58[0], this);
- }
-
- var g = gen();
- assert.deepEqual(g.next(), { value: 1, done: false });
-
- var exception = new Error("unhandled exception");
- try {
- g.throw(exception);
- assert.ok(false, "should have thrown an exception");
- } catch (err) {
- assert.strictEqual(err, exception);
- }
- });
-
- it("should immediately complete a new-born generator", function () {
- var _marked59 = [gen].map(regeneratorRuntime.mark);
-
- var began = false;
-
- function gen() {
- return regeneratorRuntime.wrap(function gen$(_context78) {
- while (1) switch (_context78.prev = _context78.next) {
- case 0:
- began = true;
- _context78.next = 3;
- return 1;
-
- case 3:
- case "end":
- return _context78.stop();
- }
- }, _marked59[0], this);
- }
-
- var g = gen();
- var exception = new Error("unhandled exception");
- try {
- g.throw(exception);
- assert.ok(false, "should have thrown an exception");
- } catch (err) {
- assert.strictEqual(err, exception);
- assert.strictEqual(began, false);
- }
- });
-
- it("should not propagate errors handled inside a delegate", function () {
- var _marked60 = [outer, inner].map(regeneratorRuntime.mark);
-
- function outer() {
- return regeneratorRuntime.wrap(function outer$(_context79) {
- while (1) switch (_context79.prev = _context79.next) {
- case 0:
- _context79.prev = 0;
- return _context79.delegateYield(inner(), "t0", 2);
-
- case 2:
- _context79.next = 7;
- break;
-
- case 4:
- _context79.prev = 4;
- _context79.t1 = _context79["catch"](0);
- return _context79.abrupt("return", -1);
-
- case 7:
- return _context79.abrupt("return", 1);
-
- case 8:
- case "end":
- return _context79.stop();
- }
- }, _marked60[0], this, [[0, 4]]);
- }
-
- function inner() {
- return regeneratorRuntime.wrap(function inner$(_context80) {
- while (1) switch (_context80.prev = _context80.next) {
- case 0:
- _context80.prev = 0;
- _context80.next = 3;
- return void 0;
-
- case 3:
- _context80.next = 8;
- break;
-
- case 5:
- _context80.prev = 5;
- _context80.t0 = _context80["catch"](0);
- return _context80.abrupt("return");
-
- case 8:
- case "end":
- return _context80.stop();
- }
- }, _marked60[1], this, [[0, 5]]);
- }
-
- var g = outer();
- g.next();
- assert.equal(g.throw(new Error('foo')).value, 1);
- });
-
- it("should propagate errors unhandled inside a delegate", function () {
- var _marked61 = [outer, inner].map(regeneratorRuntime.mark);
-
- function outer() {
- return regeneratorRuntime.wrap(function outer$(_context81) {
- while (1) switch (_context81.prev = _context81.next) {
- case 0:
- _context81.prev = 0;
- return _context81.delegateYield(inner(), "t0", 2);
-
- case 2:
- _context81.next = 7;
- break;
-
- case 4:
- _context81.prev = 4;
- _context81.t1 = _context81["catch"](0);
- return _context81.abrupt("return", -1);
-
- case 7:
- return _context81.abrupt("return", 1);
-
- case 8:
- case "end":
- return _context81.stop();
- }
- }, _marked61[0], this, [[0, 4]]);
- }
-
- function inner() {
- return regeneratorRuntime.wrap(function inner$(_context82) {
- while (1) switch (_context82.prev = _context82.next) {
- case 0:
- _context82.next = 2;
- return void 0;
-
- case 2:
- case "end":
- return _context82.stop();
- }
- }, _marked61[1], this);
- }
-
- var g = outer();
- g.next();
- assert.equal(g.throw(new Error('foo')).value, -1);
- });
-});
-
-describe("unqualified function calls", function () {
- it("should have a global `this` object", function () {
- var _marked62 = [invoke].map(regeneratorRuntime.mark);
-
- function getThis() {
- return this;
- }
-
- // This is almost certainly the global object, but there's a chance it
- // might be null or undefined (in strict mode).
- var unqualifiedThis = getThis();
-
- function invoke() {
- return regeneratorRuntime.wrap(function invoke$(_context83) {
- while (1) switch (_context83.prev = _context83.next) {
- case 0:
- _context83.next = 2;
- return "dummy";
-
- case 2:
- return _context83.abrupt("return", (0, _context83.sent)());
-
- case 3:
- case "end":
- return _context83.stop();
- }
- }, _marked62[0], this);
- }
-
- var g = invoke();
- var info = g.next();
-
- assert.deepEqual(info, { value: "dummy", done: false });
-
- info = g.next(getThis);
-
- // Avoid using assert.strictEqual when the arguments might equal the
- // global object, since JSON.stringify chokes on circular structures.
- assert.ok(info.value === unqualifiedThis);
-
- assert.strictEqual(info.done, true);
- });
-});
-
-describe("yield* expression results", function () {
- it("have correct values", function () {
- var _marked63 = [foo, bar].map(regeneratorRuntime.mark);
-
- function foo() {
- return regeneratorRuntime.wrap(function foo$(_context84) {
- while (1) switch (_context84.prev = _context84.next) {
- case 0:
- _context84.next = 2;
- return 0;
-
- case 2:
- return _context84.delegateYield(bar(), "t0", 3);
-
- case 3:
- return _context84.abrupt("return", _context84.t0);
-
- case 4:
- case "end":
- return _context84.stop();
- }
- }, _marked63[0], this);
- }
-
- function bar() {
- return regeneratorRuntime.wrap(function bar$(_context85) {
- while (1) switch (_context85.prev = _context85.next) {
- case 0:
- _context85.next = 2;
- return 1;
-
- case 2:
- return _context85.abrupt("return", 2);
-
- case 3:
- case "end":
- return _context85.stop();
- }
- }, _marked63[1], this);
- }
-
- check(foo(), [0, 1], 2);
- });
-
- it("can be used in complex expressions", function () {
- var _marked64 = [foo, bar].map(regeneratorRuntime.mark);
-
- function pumpNumber(gen) {
- var n = 0;
-
- while (true) {
- var res = n > 0 ? gen.next(n) : gen.next();
- n = res.value;
- if (res.done) {
- return n;
- }
- }
- }
-
- function foo() {
- return regeneratorRuntime.wrap(function foo$(_context86) {
- while (1) switch (_context86.prev = _context86.next) {
- case 0:
- return _context86.delegateYield(bar(), "t0", 1);
-
- case 1:
- _context86.t1 = _context86.t0;
- return _context86.delegateYield(bar(), "t2", 3);
-
- case 3:
- _context86.t3 = _context86.t2;
- return _context86.abrupt("return", _context86.t1 + _context86.t3);
-
- case 5:
- case "end":
- return _context86.stop();
- }
- }, _marked64[0], this);
- }
-
- function bar() {
- return regeneratorRuntime.wrap(function bar$(_context87) {
- while (1) switch (_context87.prev = _context87.next) {
- case 0:
- _context87.next = 2;
- return 2;
-
- case 2:
- _context87.t0 = _context87.sent;
- _context87.next = 5;
- return 3;
-
- case 5:
- _context87.t1 = _context87.sent;
- return _context87.abrupt("return", _context87.t0 + _context87.t1);
-
- case 7:
- case "end":
- return _context87.stop();
- }
- }, _marked64[1], this);
- }
-
- assert.strictEqual(pumpNumber(bar()), 5);
- assert.strictEqual(pumpNumber(foo()), 10);
- });
-});
-
-describe("isGeneratorFunction", function () {
- it("should work for function declarations", function () {
- var _marked65 = [genFun].map(regeneratorRuntime.mark);
-
- // Do the assertions up here to make sure the generator function is
- // marked at the beginning of the block the function is declared in.
- assert.strictEqual(regeneratorRuntime.isGeneratorFunction(genFun), true);
-
- assert.strictEqual(regeneratorRuntime.isGeneratorFunction(normalFun), false);
-
- function normalFun() {
- return 0;
- }
-
- function genFun() {
- return regeneratorRuntime.wrap(function genFun$(_context88) {
- while (1) switch (_context88.prev = _context88.next) {
- case 0:
- _context88.next = 2;
- return 0;
-
- case 2:
- case "end":
- return _context88.stop();
- }
- }, _marked65[0], this);
- }
- });
-
- it("should work for function expressions", function () {
- assert.strictEqual(regeneratorRuntime.isGeneratorFunction(regeneratorRuntime.mark(function genFun() {
- return regeneratorRuntime.wrap(function genFun$(_context89) {
- while (1) switch (_context89.prev = _context89.next) {
- case 0:
- _context89.next = 2;
- return 0;
-
- case 2:
- case "end":
- return _context89.stop();
- }
- }, genFun, this);
- })), true);
-
- assert.strictEqual(regeneratorRuntime.isGeneratorFunction(function normalFun() {
- return 0;
- }), false);
- });
-});
-
-describe("new expressions", function () {
- it("should be able to contain yield sub-expressions", function () {
- var _marked66 = [gen].map(regeneratorRuntime.mark);
-
- function A(first, second) {
- this.first = first;
- this.second = second;
- }
-
- function gen() {
- return regeneratorRuntime.wrap(function gen$(_context90) {
- while (1) switch (_context90.prev = _context90.next) {
- case 0:
- _context90.next = 2;
- return 0;
-
- case 2:
- _context90.t0 = _context90.sent;
- _context90.next = 5;
- return 1;
-
- case 5:
- _context90.t1 = _context90.sent;
- _context90.next = 8;
- return 2;
-
- case 8:
- _context90.t2 = _context90.sent;
- _context90.next = 11;
- return new _context90.t0(_context90.t1, _context90.t2);
-
- case 11:
- return _context90.abrupt("return", _context90.sent);
-
- case 12:
- case "end":
- return _context90.stop();
- }
- }, _marked66[0], this);
- }
-
- var g = gen();
-
- assert.deepEqual(g.next(), { value: 0, done: false });
- assert.deepEqual(g.next(A), { value: 1, done: false });
- assert.deepEqual(g.next("asdf"), { value: 2, done: false });
-
- var info = g.next("zxcv");
- assert.strictEqual(info.done, false);
- assert.ok(info.value instanceof A);
- assert.strictEqual(info.value.first, "asdf");
- assert.strictEqual(info.value.second, "zxcv");
-
- assert.deepEqual(g.next("qwer"), { value: "qwer", done: true });
- });
-});
-
-describe("block binding", function () {
- it("should translate block binding correctly", function () {
- "use strict";
-
- var _marked67 = [gen].map(regeneratorRuntime.mark);
-
- function gen() {
- var a$0, a$1, a, _a, _a2;
-
- return regeneratorRuntime.wrap(function gen$(_context91) {
- while (1) switch (_context91.prev = _context91.next) {
- case 0:
- a$0 = 0, a$1 = 1;
- a = 3;
- _a = 1;
- _context91.next = 5;
- return _a + a$0;
-
- case 5:
- _a2 = 2;
- _context91.next = 8;
- return _a2 - 1 + a$1;
-
- case 8:
- _context91.next = 10;
- return a;
-
- case 10:
- case "end":
- return _context91.stop();
- }
- }, _marked67[0], this);
- }
-
- var g = gen();
-
- assert.deepEqual(g.next(), { value: 1, done: false });
- assert.deepEqual(g.next(), { value: 2, done: false });
- assert.deepEqual(g.next(), { value: 3, done: false });
- assert.deepEqual(g.next(), { value: void 0, done: true });
- });
-
- it("should translate block binding with iife correctly", function () {
- "use strict";
-
- var _marked68 = [gen].map(regeneratorRuntime.mark);
-
- function gen() {
- var arr, _loop, x;
-
- return regeneratorRuntime.wrap(function gen$(_context92) {
- while (1) switch (_context92.prev = _context92.next) {
- case 0:
- arr = [];
-
- _loop = function (x) {
- var y = x;
- arr.push(function () {
- return y;
- });
- };
-
- for (x = 0; x < 3; x++) {
- _loop(x);
- }
-
- x = undefined;
-
- case 4:
- if (!(x = arr.pop())) {
- _context92.next = 9;
- break;
- }
-
- _context92.next = 7;
- return x;
-
- case 7:
- _context92.next = 4;
- break;
-
- case 9:
- case "end":
- return _context92.stop();
- }
- }, _marked68[0], this);
- }
-
- var g = gen();
-
- assert.equal(g.next().value(), 2);
- assert.equal(g.next().value(), 1);
- assert.equal(g.next().value(), 0);
- assert.deepEqual(g.next(), { value: void 0, done: true });
- });
-});
-
-describe("newborn generators", function () {
- it("should be able to yield* non-newborn generators", function () {
- var _marked69 = [inner, outer].map(regeneratorRuntime.mark);
-
- function inner() {
- return regeneratorRuntime.wrap(function inner$(_context93) {
- while (1) switch (_context93.prev = _context93.next) {
- case 0:
- _context93.next = 2;
- return 1;
-
- case 2:
- _context93.t0 = _context93.sent;
- _context93.next = 5;
- return 2;
-
- case 5:
- _context93.t1 = _context93.sent;
- return _context93.abrupt("return", [_context93.t0, _context93.t1]);
-
- case 7:
- case "end":
- return _context93.stop();
- }
- }, _marked69[0], this);
- }
-
- function outer(delegate) {
- return regeneratorRuntime.wrap(function outer$(_context94) {
- while (1) switch (_context94.prev = _context94.next) {
- case 0:
- return _context94.delegateYield(delegate, "t0", 1);
-
- case 1:
- return _context94.abrupt("return", _context94.t0);
-
- case 2:
- case "end":
- return _context94.stop();
- }
- }, _marked69[1], this);
- }
-
- var n = inner();
-
- assert.deepEqual(n.next(), {
- value: 1,
- done: false
- });
-
- var g = outer(n);
-
- // I would really like to be able to pass 3 to g.next here, but V8
- // ignores values sent to newborn generators, and SpiderMonkey throws
- // a TypeError.
- assert.deepEqual(g.next(), {
- value: 2,
- done: false
- });
-
- assert.deepEqual(g.next(4), {
- value: [void 0, 4],
- done: true
- });
- });
-
- it("should support the ignore-initial-yield wrapper idiom", function () {
- var _marked70 = [inner].map(regeneratorRuntime.mark);
-
- var markers = [];
-
- function inner() {
- var sent1, sent2;
- return regeneratorRuntime.wrap(function inner$(_context95) {
- while (1) switch (_context95.prev = _context95.next) {
- case 0:
- markers.push(0);
- _context95.next = 3;
- return 1;
-
- case 3:
- sent1 = _context95.sent;
-
- markers.push(2);
- _context95.next = 7;
- return 2;
-
- case 7:
- sent2 = _context95.sent;
-
- markers.push(3);
- return _context95.abrupt("return", [sent1, sent2]);
-
- case 10:
- case "end":
- return _context95.stop();
- }
- }, _marked70[0], this);
- }
-
- function wrapper(delegate) {
- var gen = regeneratorRuntime.mark(function _callee4() {
- var sent, info;
- return regeneratorRuntime.wrap(function _callee4$(_context96) {
- while (1) switch (_context96.prev = _context96.next) {
- case 0:
- _context96.next = 2;
- return "ignored";
-
- case 2:
- sent = _context96.sent;
-
- markers.push(1);
-
- case 4:
- if ((info = delegate.next(sent)).done) {
- _context96.next = 10;
- break;
- }
-
- _context96.next = 7;
- return info.value;
-
- case 7:
- sent = _context96.sent;
- _context96.next = 4;
- break;
-
- case 10:
-
- markers.push(4);
-
- return _context96.abrupt("return", info.value);
-
- case 12:
- case "end":
- return _context96.stop();
- }
- }, _callee4, this);
- })();
-
- // Ensure that gen is not newborn and that the next invocation of
- // gen.next(value) can send value to the initial yield expression.
- gen.next();
-
- return gen;
- }
-
- var n = inner();
-
- assert.deepEqual(n.next(), {
- value: 1,
- done: false
- });
-
- var g = wrapper(n);
-
- // Unlike in the previous spec, it's fine to pass 3 to g.next here,
- // because g is not newborn, because g.next was already called once
- // before g was returned from the wrapper function.
- assert.deepEqual(g.next(3), {
- value: 2,
- done: false
- });
-
- assert.deepEqual(g.next(4), {
- value: [3, 4],
- done: true
- });
-
- // Ensure we encountered the marker points in the expected order.
- assert.deepEqual(markers, [0, 1, 2, 3, 4]);
- });
-
- it("should allow chaining newborn and non-newborn generators", function () {
- var _marked71 = [range, chain, y3, y5].map(regeneratorRuntime.mark);
-
- function range(n) {
- var i;
- return regeneratorRuntime.wrap(function range$(_context97) {
- while (1) switch (_context97.prev = _context97.next) {
- case 0:
- i = 0;
-
- case 1:
- if (!(i < n)) {
- _context97.next = 7;
- break;
- }
-
- _context97.next = 4;
- return i;
-
- case 4:
- ++i;
- _context97.next = 1;
- break;
-
- case 7:
- case "end":
- return _context97.stop();
- }
- }, _marked71[0], this);
- }
-
- function chain(a, b) {
- return regeneratorRuntime.wrap(function chain$(_context98) {
- while (1) switch (_context98.prev = _context98.next) {
- case 0:
- return _context98.delegateYield(a, "t0", 1);
-
- case 1:
- return _context98.delegateYield(b, "t1", 2);
-
- case 2:
- case "end":
- return _context98.stop();
- }
- }, _marked71[1], this);
- }
-
- check(chain(range(3), range(5)), [0, 1, 2, 0, 1, 2, 3, 4]);
-
- function y3(x) {
- return regeneratorRuntime.wrap(function y3$(_context99) {
- while (1) switch (_context99.prev = _context99.next) {
- case 0:
- _context99.next = 2;
- return x;
-
- case 2:
- _context99.next = 4;
- return _context99.sent;
-
- case 4:
- _context99.next = 6;
- return _context99.sent;
-
- case 6:
- return _context99.abrupt("return", _context99.sent);
-
- case 7:
- case "end":
- return _context99.stop();
- }
- }, _marked71[2], this);
- }
-
- function y5(x) {
- return regeneratorRuntime.wrap(function y5$(_context100) {
- while (1) switch (_context100.prev = _context100.next) {
- case 0:
- _context100.next = 2;
- return x;
-
- case 2:
- _context100.next = 4;
- return _context100.sent;
-
- case 4:
- _context100.next = 6;
- return _context100.sent;
-
- case 6:
- _context100.next = 8;
- return _context100.sent;
-
- case 8:
- _context100.next = 10;
- return _context100.sent;
-
- case 10:
- return _context100.abrupt("return", _context100.sent);
-
- case 11:
- case "end":
- return _context100.stop();
- }
- }, _marked71[3], this);
- }
-
- check(chain(y3("foo"), y5("bar")), ["foo", 1, 2, "bar", 4, 5, 6, 7]);
-
- var g3 = y3("three");
- assert.deepEqual(g3.next(), {
- value: "three",
- done: false
- });
-
- var g5 = y5("five");
- assert.deepEqual(g5.next(), {
- value: "five",
- done: false
- });
-
- var undef; // A little easier to read than void 0.
- check(chain(g3, g5), [undef, 1, undef, 3, 4, 5]);
- });
-});
-
-describe("labeled break and continue statements", function () {
- it("should be able to exit multiple try statements", function () {
- var _marked72 = [gen].map(regeneratorRuntime.mark);
-
- var e1 = "first";
- var e2 = "second";
- var e3 = "third";
- var e4 = "fourth";
-
- function gen(n, which) {
- var i;
- return regeneratorRuntime.wrap(function gen$(_context101) {
- while (1) switch (_context101.prev = _context101.next) {
- case 0:
- _context101.prev = 0;
- _context101.next = 3;
- return 0;
-
- case 3:
- raise(e1);
-
- case 4:
- _context101.prev = 4;
- _context101.next = 7;
- return 1;
-
- case 7:
- i = 0;
-
- case 8:
- if (!(i < n)) {
- _context101.next = 42;
- break;
- }
-
- _context101.next = 11;
- return i;
-
- case 11:
- _context101.prev = 11;
-
- raise(e2);
-
- case 13:
- _context101.prev = 13;
- _context101.next = 16;
- return 2;
-
- case 16:
- _context101.prev = 16;
-
- raise(e3);
-
- case 18:
- _context101.prev = 18;
- _context101.next = 21;
- return 3;
-
- case 21:
- _context101.prev = 21;
-
- raise(e4);
-
- case 23:
- _context101.prev = 23;
- _context101.next = 26;
- return 4;
-
- case 26:
- if (!(which === "break")) {
- _context101.next = 30;
- break;
- }
-
- _context101.next = 29;
- return "breaking";
-
- case 29:
- return _context101.abrupt("break", 42);
-
- case 30:
- if (!(which === "continue")) {
- _context101.next = 34;
- break;
- }
-
- _context101.next = 33;
- return "continuing";
-
- case 33:
- return _context101.abrupt("continue", 39);
-
- case 34:
- _context101.next = 36;
- return 5;
-
- case 36:
- return _context101.finish(23);
-
- case 37:
- return _context101.finish(18);
-
- case 38:
- return _context101.finish(13);
-
- case 39:
- ++i;
- _context101.next = 8;
- break;
-
- case 42:
- _context101.next = 44;
- return 6;
-
- case 44:
- return _context101.finish(4);
-
- case 45:
- case "end":
- return _context101.stop();
- }
- }, _marked72[0], this, [[0,, 4, 45], [11,, 13, 39], [16,, 18, 38], [21,, 23, 37]]);
- }
-
- try {
- check(gen(1, "break"), [0, 1, 0, 2, 3, 4, "breaking", 6]);
- assert.ok(false, "should have thrown an exception");
- } catch (err) {
- assert.strictEqual(err, e1);
- }
-
- try {
- check(gen(3, "continue"), [0, 1, 0, 2, 3, 4, "continuing", 1, 2, 3, 4, "continuing", 2, 2, 3, 4, "continuing", 6 // Loop finished naturally.
- ]);
- assert.ok(false, "should have thrown an exception");
- } catch (err) {
- assert.strictEqual(err, e1);
- }
-
- try {
- check(gen(3, "neither"), [0, 1, 0, 2, 3, 4, 5]);
- assert.ok(false, "should have thrown an exception");
- } catch (err) {
- assert.strictEqual(err, e4);
- }
- });
-
- it("should allow breaking from any labeled statement", function () {
- var _marked73 = [gen].map(regeneratorRuntime.mark);
-
- function gen(limit) {
- var i;
- return regeneratorRuntime.wrap(function gen$(_context102) {
- while (1) switch (_context102.prev = _context102.next) {
- case 0:
- _context102.next = 2;
- return 0;
-
- case 2:
- i = 0;
-
- case 3:
- if (!(i < limit)) {
- _context102.next = 32;
- break;
- }
-
- _context102.next = 6;
- return 1;
-
- case 6:
- _context102.next = 8;
- return 2;
-
- case 8:
- return _context102.abrupt("break", 11);
-
- case 11:
- if (!(limit === 3)) {
- _context102.next = 26;
- break;
- }
-
- _context102.next = 14;
- return 4;
-
- case 14:
- if (!(i === 0)) {
- _context102.next = 16;
- break;
- }
-
- return _context102.abrupt("break", 26);
-
- case 16:
- _context102.next = 18;
- return 5;
-
- case 18:
- if (!(i === 1)) {
- _context102.next = 20;
- break;
- }
-
- return _context102.abrupt("break", 26);
-
- case 20:
- _context102.next = 22;
- return 6;
-
- case 22:
- if (!(i === 2)) {
- _context102.next = 24;
- break;
- }
-
- return _context102.abrupt("break", 32);
-
- case 24:
- _context102.next = 26;
- return 7;
-
- case 26:
- return _context102.abrupt("break", 27);
-
- case 27:
- _context102.next = 29;
- return 8;
-
- case 29:
- ++i;
- _context102.next = 3;
- break;
-
- case 32:
- _context102.next = 34;
- return 9;
-
- case 34:
- case "end":
- return _context102.stop();
- }
- }, _marked73[0], this);
- }
-
- check(gen(0), [0, 9]);
- check(gen(1), [0, 1, 2, 8, 9]);
- check(gen(2), [0, 1, 2, 8, 1, 2, 8, 9]);
- check(gen(3), [0, 1, 2, 4, 8, 1, 2, 4, 5, 8, 1, 2, 4, 5, 6, 9]);
- });
-});
-
-describe("for loop with var decl and no update expression", function () {
- var _marked74 = [range].map(regeneratorRuntime.mark);
-
- // https://github.com/facebook/regenerator/issues/103
- function range() {
- var i;
- return regeneratorRuntime.wrap(function range$(_context103) {
- while (1) switch (_context103.prev = _context103.next) {
- case 0:
- for (i = 0; false;) {}
-
- case 1:
- case "end":
- return _context103.stop();
- }
- }, _marked74[0], this);
- }
-
- it("should compile and run", function () {
- check(range(), []);
- });
-});
-
-describe("generator function prototype", function () {
- function getProto(obj) {
- return Object.getPrototypeOf ? Object.getPrototypeOf(obj) : obj.__proto__;
- }
-
- it("should follow the expected object model", function () {
- var _marked75 = [f2, f, f].map(regeneratorRuntime.mark);
-
- var GeneratorFunctionPrototype = getProto(f);
- var GeneratorFunction = GeneratorFunctionPrototype.constructor;
-
- assert.strictEqual(GeneratorFunction.name, 'GeneratorFunction');
- assert.strictEqual(GeneratorFunction.prototype, GeneratorFunctionPrototype);
- assert.strictEqual(GeneratorFunctionPrototype.prototype.constructor, GeneratorFunctionPrototype);
- assert.strictEqual(GeneratorFunctionPrototype.prototype, getProto(f.prototype));
- assert.strictEqual(getProto(GeneratorFunctionPrototype), Function.prototype);
-
- if (typeof process === "undefined" || process.version.slice(1, 3) === "0.") {
- // Node version strings start with 0.
- assert.strictEqual(GeneratorFunctionPrototype.name, "GeneratorFunctionPrototype");
- } else if (process.version.slice(1, 3) === "1.") {
- // iojs version strings start with 1., and iojs gets this .name
- // property wrong. TODO report this?
- assert.strictEqual(GeneratorFunctionPrototype.name, "");
- }
-
- assert.strictEqual(typeof f2, "function");
- assert.strictEqual(f2.constructor, GeneratorFunction);
- assert.ok(f2 instanceof GeneratorFunction);
- assert.strictEqual(f2.name, "f2");
-
- var g = f();
- assert.ok(g instanceof f);
- assert.strictEqual(getProto(g), f.prototype);
-
- assert.deepEqual([], Object.getOwnPropertyNames(f.prototype));
- // assert.deepEqual([], Object.getOwnPropertyNames(g));
-
- f.prototype.x = 42;
-
- var g2 = f();
- assert.strictEqual(g2.x, 42);
-
- var g3 = new f();
- assert.strictEqual(g3.x, 42);
-
- function f2() {
- return regeneratorRuntime.wrap(function f2$(_context104) {
- while (1) switch (_context104.prev = _context104.next) {
- case 0:
- _context104.next = 2;
- return 1;
-
- case 2:
- case "end":
- return _context104.stop();
- }
- }, _marked75[0], this);
- }
-
- assert.strictEqual(getProto(f), getProto(f2));
- assert.strictEqual(f.hasOwnProperty('constructor'), false);
- assert.strictEqual(getProto(f).constructor.name, 'GeneratorFunction');
-
- // Intentionally at the end to test hoisting.
- function f() {
- return regeneratorRuntime.wrap(function f$(_context105) {
- while (1) switch (_context105.prev = _context105.next) {
- case 0:
- _context105.next = 2;
- return this;
-
- case 2:
- case "end":
- return _context105.stop();
- }
- }, _marked75[1], this);
- }
-
- function f() {
- return regeneratorRuntime.wrap(function f$(_context106) {
- while (1) switch (_context106.prev = _context106.next) {
- case 0:
- _context106.next = 2;
- return 1;
-
- case 2:
- case "end":
- return _context106.stop();
- }
- }, _marked75[2], this);
- }
-
- var f2 = f;
- f = 42;
- var g = f2();
-
- assert.deepEqual(g.next(), { value: 1, done: false });
- assert.deepEqual(g.next(), { value: void 0, done: true });
- assert.ok(g instanceof f2);
- });
-});
-
-describe("for-of loops", function () {
- (runningInTranslation ? it : xit)("should work for Arrays", function () {
- var sum = 0;
- var _iteratorNormalCompletion = true;
- var _didIteratorError = false;
- var _iteratorError = undefined;
-
- try {
- for (var _iterator = [1, 2].concat(3)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
- var x = _step.value;
-
- sum += x;
- }
- } catch (err) {
- _didIteratorError = true;
- _iteratorError = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion && _iterator.return) {
- _iterator.return();
- }
- } finally {
- if (_didIteratorError) {
- throw _iteratorError;
- }
- }
- }
-
- assert.strictEqual(sum, 6);
- });
-
- it("should work for generators", function () {
- var value,
- values = [];
- var _iteratorNormalCompletion2 = true;
- var _didIteratorError2 = false;
- var _iteratorError2 = undefined;
-
- try {
- for (var _iterator2 = range(3)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
- value = _step2.value;
-
- values.push(value);
- }
- } catch (err) {
- _didIteratorError2 = true;
- _iteratorError2 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion2 && _iterator2.return) {
- _iterator2.return();
- }
- } finally {
- if (_didIteratorError2) {
- throw _iteratorError2;
- }
- }
- }
-
- assert.deepEqual(values, [0, 1, 2]);
- });
-
- it("should work inside of generators", function () {
- var _marked76 = [yieldPermutations].map(regeneratorRuntime.mark);
-
- function yieldPermutations(list) {
- var count, first, genRest, _iteratorNormalCompletion3, _didIteratorError3, _iteratorError3, _iterator3, _step3, perm, i, prefix, suffix;
-
- return regeneratorRuntime.wrap(function yieldPermutations$(_context107) {
- while (1) switch (_context107.prev = _context107.next) {
- case 0:
- if (!(list.length < 2)) {
- _context107.next = 4;
- break;
- }
-
- _context107.next = 3;
- return list;
-
- case 3:
- return _context107.abrupt("return", 1);
-
- case 4:
- count = 0;
- first = list.slice(0, 1);
- genRest = yieldPermutations(list.slice(1));
- _iteratorNormalCompletion3 = true;
- _didIteratorError3 = false;
- _iteratorError3 = undefined;
- _context107.prev = 10;
- _iterator3 = genRest[Symbol.iterator]();
-
- case 12:
- if (_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done) {
- _context107.next = 27;
- break;
- }
-
- perm = _step3.value;
- i = 0;
-
- case 15:
- if (!(i < list.length)) {
- _context107.next = 23;
- break;
- }
-
- prefix = perm.slice(0, i);
- suffix = perm.slice(i);
- _context107.next = 20;
- return prefix.concat(first, suffix);
-
- case 20:
- ++i;
- _context107.next = 15;
- break;
-
- case 23:
-
- count += i;
-
- case 24:
- _iteratorNormalCompletion3 = true;
- _context107.next = 12;
- break;
-
- case 27:
- _context107.next = 33;
- break;
-
- case 29:
- _context107.prev = 29;
- _context107.t0 = _context107["catch"](10);
- _didIteratorError3 = true;
- _iteratorError3 = _context107.t0;
-
- case 33:
- _context107.prev = 33;
- _context107.prev = 34;
-
- if (!_iteratorNormalCompletion3 && _iterator3.return) {
- _iterator3.return();
- }
-
- case 36:
- _context107.prev = 36;
-
- if (!_didIteratorError3) {
- _context107.next = 39;
- break;
- }
-
- throw _iteratorError3;
-
- case 39:
- return _context107.finish(36);
-
- case 40:
- return _context107.finish(33);
-
- case 41:
- return _context107.abrupt("return", count);
-
- case 42:
- case "end":
- return _context107.stop();
- }
- }, _marked76[0], this, [[10, 29, 33, 41], [34,, 36, 40]]);
- }
-
- var count = 0;
- var _iteratorNormalCompletion4 = true;
- var _didIteratorError4 = false;
- var _iteratorError4 = undefined;
-
- try {
- for (var _iterator4 = yieldPermutations([])[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
- var perm = _step4.value;
-
- assert.deepEqual(perm, []);
- ++count;
- }
- } catch (err) {
- _didIteratorError4 = true;
- _iteratorError4 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion4 && _iterator4.return) {
- _iterator4.return();
- }
- } finally {
- if (_didIteratorError4) {
- throw _iteratorError4;
- }
- }
- }
-
- assert.strictEqual(count, 1);
-
- check(yieldPermutations([1]), [[1]], 1);
-
- check(yieldPermutations([2, 1]), [[2, 1], [1, 2]], 2);
-
- check(yieldPermutations([1, 3, 2]), [[1, 3, 2], [3, 1, 2], [3, 2, 1], [1, 2, 3], [2, 1, 3], [2, 3, 1]], 6);
- });
-});
-
-describe("generator return method", function () {
- if (!runningInTranslation) {
- // The return method has not been specified or implemented natively,
- // yet, so these tests need only pass in translation.
- return;
- }
-
- it("should work with newborn generators", function () {
- var _marked77 = [gen].map(regeneratorRuntime.mark);
-
- function gen() {
- return regeneratorRuntime.wrap(function gen$(_context108) {
- while (1) switch (_context108.prev = _context108.next) {
- case 0:
- _context108.next = 2;
- return 0;
-
- case 2:
- case "end":
- return _context108.stop();
- }
- }, _marked77[0], this);
- }
-
- var g = gen();
-
- assert.deepEqual(g.return("argument"), {
- value: "argument",
- done: true
- });
-
- assertAlreadyFinished(g);
- });
-
- it("should behave as if generator actually returned", function () {
- var _marked78 = [gen].map(regeneratorRuntime.mark);
-
- var executedFinally = false;
-
- function gen() {
- return regeneratorRuntime.wrap(function gen$(_context109) {
- while (1) switch (_context109.prev = _context109.next) {
- case 0:
- _context109.prev = 0;
- _context109.next = 3;
- return 0;
-
- case 3:
- _context109.next = 8;
- break;
-
- case 5:
- _context109.prev = 5;
- _context109.t0 = _context109["catch"](0);
-
- assert.ok(false, "should not have executed the catch handler");
-
- case 8:
- _context109.prev = 8;
-
- executedFinally = true;
- return _context109.finish(8);
-
- case 11:
- case "end":
- return _context109.stop();
- }
- }, _marked78[0], this, [[0, 5, 8, 11]]);
- }
-
- var g = gen();
- assert.deepEqual(g.next(), { value: 0, done: false });
-
- assert.deepEqual(g.return("argument"), {
- value: "argument",
- done: true
- });
-
- assert.strictEqual(executedFinally, true);
- assertAlreadyFinished(g);
- });
-
- it("should return both delegate and delegator", function () {
- var _marked79 = [callee, caller].map(regeneratorRuntime.mark);
-
- var checkpoints = [];
-
- function callee(errorToThrow) {
- return regeneratorRuntime.wrap(function callee$(_context110) {
- while (1) switch (_context110.prev = _context110.next) {
- case 0:
- _context110.prev = 0;
- _context110.next = 3;
- return 1;
-
- case 3:
- _context110.next = 5;
- return 2;
-
- case 5:
- _context110.prev = 5;
-
- checkpoints.push("callee finally");
-
- if (!errorToThrow) {
- _context110.next = 9;
- break;
- }
-
- throw errorToThrow;
-
- case 9:
- return _context110.finish(5);
-
- case 10:
- case "end":
- return _context110.stop();
- }
- }, _marked79[0], this, [[0,, 5, 10]]);
- }
-
- function caller(errorToThrow) {
- return regeneratorRuntime.wrap(function caller$(_context111) {
- while (1) switch (_context111.prev = _context111.next) {
- case 0:
- _context111.prev = 0;
- _context111.next = 3;
- return 0;
-
- case 3:
- return _context111.delegateYield(callee(errorToThrow), "t0", 4);
-
- case 4:
- _context111.next = 6;
- return 3;
-
- case 6:
- _context111.prev = 6;
-
- checkpoints.push("caller finally");
- return _context111.finish(6);
-
- case 9:
- case "end":
- return _context111.stop();
- }
- }, _marked79[1], this, [[0,, 6, 9]]);
- }
-
- var g1 = caller();
-
- assert.deepEqual(g1.next(), { value: 0, done: false });
- assert.deepEqual(g1.next(), { value: 1, done: false });
- assert.deepEqual(g1.return(-1), { value: -1, done: true });
- assert.deepEqual(checkpoints, ["callee finally", "caller finally"]);
-
- var error = new Error("thrown from callee");
- var g2 = caller(error);
-
- assert.deepEqual(g2.next(), { value: 0, done: false });
- assert.deepEqual(g2.next(), { value: 1, done: false });
-
- try {
- g2.return(-1);
- assert.ok(false, "should have thrown an exception");
- } catch (thrown) {
- assert.strictEqual(thrown, error);
- }
-
- assert.deepEqual(checkpoints, ["callee finally", "caller finally", "callee finally", "caller finally"]);
- });
-});
-
-describe("expressions containing yield subexpressions", function () {
- it("should evaluate all subexpressions before yielding", function () {
- var _marked80 = [gen].map(regeneratorRuntime.mark);
-
- function gen(x) {
- return regeneratorRuntime.wrap(function gen$(_context112) {
- while (1) switch (_context112.prev = _context112.next) {
- case 0:
- _context112.t0 = x;
- _context112.next = 3;
- return function (y) {
- x = y;
- };
-
- case 3:
- _context112.t1 = _context112.sent;
- return _context112.abrupt("return", _context112.t0 * _context112.t1);
-
- case 5:
- case "end":
- return _context112.stop();
- }
- }, _marked80[0], this);
- }
-
- var g = gen(2);
- var result = g.next();
- assert.strictEqual(result.done, false);
-
- result.value(5);
-
- assert.deepEqual(g.next(5), {
- value: 10,
- done: true
- });
- });
-
- it("should work even with getter member expressions", function () {
- var _marked81 = [gen].map(regeneratorRuntime.mark);
-
- function gen() {
- return regeneratorRuntime.wrap(function gen$(_context113) {
- while (1) switch (_context113.prev = _context113.next) {
- case 0:
- _context113.t0 = a.b;
- _context113.next = 3;
- return "asdf";
-
- case 3:
- _context113.t1 = _context113.sent;
- return _context113.abrupt("return", _context113.t0 + _context113.t1);
-
- case 5:
- case "end":
- return _context113.stop();
- }
- }, _marked81[0], this);
- }
-
- var a = {};
- var b = 0;
-
- Object.defineProperty(a, "b", {
- get: function () {
- return ++b;
- }
- });
-
- var g = gen();
-
- assert.strictEqual(a.b, 1);
-
- assert.deepEqual(g.next(), {
- value: "asdf",
- done: false
- });
-
- assert.strictEqual(a.b, 3);
-
- assert.deepEqual(g.next(2), {
- value: 4,
- done: true
- });
- });
-
- it("should evaluate all array elements before yielding", function () {
- var _marked82 = [gen].map(regeneratorRuntime.mark);
-
- function gen() {
- return regeneratorRuntime.wrap(function gen$(_context114) {
- while (1) switch (_context114.prev = _context114.next) {
- case 0:
- _context114.t0 = a;
- _context114.next = 3;
- return "asdf";
-
- case 3:
- _context114.t1 = _context114.sent;
- _context114.t2 = a;
- return _context114.abrupt("return", [_context114.t0, _context114.t1, _context114.t2]);
-
- case 6:
- case "end":
- return _context114.stop();
- }
- }, _marked82[0], this);
- }
-
- var a = 1;
- var g = gen();
-
- assert.deepEqual(g.next(), {
- value: "asdf",
- done: false
- });
-
- a = 3;
-
- assert.deepEqual(g.next(2), {
- value: [1, 2, 3],
- done: true
- });
- });
-
- it("should handle callee member expressions correctly", function () {
- var _marked83 = [gen].map(regeneratorRuntime.mark);
-
- function gen() {
- return regeneratorRuntime.wrap(function gen$(_context115) {
- while (1) switch (_context115.prev = _context115.next) {
- case 0:
- _context115.t0 = a.slice(0);
- _context115.next = 3;
- return "asdf";
-
- case 3:
- _context115.t1 = _context115.sent;
- a = _context115.t0.concat.call(_context115.t0, _context115.t1);
- return _context115.abrupt("return", a);
-
- case 6:
- case "end":
- return _context115.stop();
- }
- }, _marked83[0], this);
- }
-
- var a = [];
- var g = gen();
-
- assert.deepEqual(g.next(), {
- value: "asdf",
- done: false
- });
-
- a.push(1);
-
- assert.deepEqual(g.next(2), {
- value: [2],
- done: true
- });
- });
-
- it("should handle implicit stringification correctly", function () {
- var _marked84 = [gen].map(regeneratorRuntime.mark);
-
- function gen() {
- return regeneratorRuntime.wrap(function gen$(_context116) {
- while (1) switch (_context116.prev = _context116.next) {
- case 0:
- _context116.t0 = a;
- _context116.next = 3;
- return "asdf";
-
- case 3:
- _context116.t1 = _context116.sent;
- return _context116.abrupt("return", _context116.t0 + _context116.t1);
-
- case 5:
- case "end":
- return _context116.stop();
- }
- }, _marked84[0], this);
- }
-
- var a = [1, 2];
- var g = gen();
-
- assert.deepEqual(g.next(), {
- value: "asdf",
- done: false
- });
-
- a = [4, 5];
-
- assert.deepEqual(g.next(",3"), {
- value: "1,2,3",
- done: true
- });
- });
-});
\ No newline at end of file
diff --git a/packages/babel-plugin-transform-regenerator/.test/tests.transform.js b/packages/babel-plugin-transform-regenerator/.test/tests.transform.js
deleted file mode 100644
index e67e1d9569..0000000000
--- a/packages/babel-plugin-transform-regenerator/.test/tests.transform.js
+++ /dev/null
@@ -1,47 +0,0 @@
-var regenerator = require("..");
-var babylon = require("babylon");
-var assert = require("assert");
-var babel = require("babel-core");
-var t = require("babel-types");
-
-describe("_blockHoist nodes", function() {
- it("should be hoisted to the outer body", function() {
- var foo;
- var names = [];
- var ast = babylon.parse([
- "function *foo(doNotHoistMe, hoistMe) {",
- " var sent = yield doNotHoistMe();",
- " hoistMe();",
- " names.push(sent);",
- " return 123;",
- "}"
- ].join("\n"));
-
- var hoistMeStmt = ast.program.body[0].body.body[1];
- t.assertExpressionStatement(hoistMeStmt);
- t.assertCallExpression(hoistMeStmt.expression);
- t.assertIdentifier(hoistMeStmt.expression.callee);
- assert.strictEqual(hoistMeStmt.expression.callee.name, "hoistMe");
-
- hoistMeStmt._blockHoist = 1;
-
- eval(babel.transformFromAst(ast, null, { plugins: [regenerator] }).code);
-
- assert.strictEqual(typeof foo, "function");
- assert.ok(regeneratorRuntime.isGeneratorFunction(foo));
- assert.strictEqual(names.length, 0);
-
- var g = foo(function doNotHoistMe() {
- names.push("doNotHoistMe");
- return "yielded";
- }, function hoistMe() {
- names.push("hoistMe");
- });
-
- assert.deepEqual(names, ["hoistMe"]);
- assert.deepEqual(g.next(), { value: "yielded", done: false });
- assert.deepEqual(names, ["hoistMe", "doNotHoistMe"]);
- assert.deepEqual(g.next("oyez"), { value: 123, done: true });
- assert.deepEqual(names, ["hoistMe", "doNotHoistMe", "oyez"]);
- });
-});
diff --git a/packages/babel-plugin-transform-regenerator/.travis.yml b/packages/babel-plugin-transform-regenerator/.travis.yml
deleted file mode 100644
index 928d48bb5c..0000000000
--- a/packages/babel-plugin-transform-regenerator/.travis.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-language: node_js
-node_js:
- - "4.0"
- - "iojs"
- - "0.12"
- - "0.11"
- - "0.10"
- - "0.8"
-before_install:
- - npm install -g npm@1.4.28
-sudo: false
diff --git a/packages/babel-plugin-transform-regenerator/CONTRIBUTING.md b/packages/babel-plugin-transform-regenerator/CONTRIBUTING.md
deleted file mode 100644
index a4ad349e65..0000000000
--- a/packages/babel-plugin-transform-regenerator/CONTRIBUTING.md
+++ /dev/null
@@ -1,80 +0,0 @@
-# Contributing to Regenerator
-
-Regenerator uses GitHub as its sole source of truth. Everything happens
-here. Facebook employees who contribute to Regenerator are expected to do
-so in the same way as everyone else. In other words, this document applies
-equally to all contributors.
-
-### `master` is unsafe
-
-We will do our best to keep `master` in good shape, with tests passing at
-all times. But in order to move fast, we will make API changes that your
-application might not be compatible with. We will do our best to
-communicate these changes and always version appropriately so you can lock
-into a specific version if need be.
-
-### Pull Requests
-
-In case you've never submitted a pull request (PR) via GitHub before,
-please read [this short
-tutorial](https://help.github.com/articles/creating-a-pull-request). If
-you've submitted a PR before, there should be nothing surprising about our
-procedures for Regenerator.
-
-*Before* submitting a pull request, please make sure the following is done…
-
-1. Fork the repo and create your branch from `master`.
-2. If you've added code that should be tested, add tests!
-3. Ensure the test suite passes (`npm test`).
-4. If you haven't already, complete the CLA.
-5. Submit a pull request via GitHub.
-6. Check that Travis CI tests pass (pull request turns green).
-
-### Contributor License Agreement ("CLA")
-
-In order to accept your pull request, we need you to submit a CLA. You
-only need to do this once, so if you've done this for another Facebook
-open source project, you're good to go. If you are submitting a pull
-request for the first time, just let us know that you have completed the
-CLA and we can cross-check with your GitHub username.
-
-Complete your CLA here:
-
-## Bugs
-
-### Where to Find Known Issues
-
-We will be using GitHub Issues for all bugs. Before filing a new issue,
-please try to make sure your problem doesn't already exist. If you think
-your issue is more general than one that already exists, our preference is
-still to modify the original issue to reflect the underlying problem more
-faithfully.
-
-### Reporting New Issues
-
-The best way to get a bug fixed is to provide a reduced test case, and the
-easiest way to reduce a testcase is to edit it in [the
-sandbox](http://facebook.github.io/regenerator/) until you're satisfied
-and then click the "report a bug" link (the new issue will be populated
-automatically with your code).
-
-### Security Bugs
-
-Facebook has a [bounty program](https://www.facebook.com/whitehat/) for
-the safe disclosure of security bugs. With that in mind, please do not
-file public issues and go through the process outlined on that page.
-
-## Coding Style
-
-* Use semicolons;
-* Commas last,
-* 2 spaces for indentation (no tabs).
-* Prefer `"` over `'`
-* 80 character line length
-* Match surrounding coding style.
-* Less code is better code.
-
-## License
-
-By contributing to Regenerator, you agree that your contributions will be
-licensed under the [BSD License](LICENSE).
diff --git a/packages/babel-plugin-transform-regenerator/README.md b/packages/babel-plugin-transform-regenerator/README.md
index c220dba788..d22e2292e9 100644
--- a/packages/babel-plugin-transform-regenerator/README.md
+++ b/packages/babel-plugin-transform-regenerator/README.md
@@ -1,74 +1 @@
-regenerator [](https://travis-ci.org/facebook/regenerator)
-===
-
-This package implements a fully-functional source transformation that
-takes the proposed syntax for generators/`yield` from future versions of
-JS ([ECMAScript6 or ES6](http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts), experimentally implemented in Node.js v0.11) and
-spits out efficient JS-of-today (ES5) that behaves the same way.
-
-A small runtime library (less than 1KB compressed) is required to provide the
-`wrapGenerator` function. You can install it either as a CommonJS module
-or as a standalone .js file, whichever you prefer.
-
-Installation
----
-
-From NPM:
-```sh
-npm install -g regenerator
-```
-
-From GitHub:
-```sh
-cd path/to/node_modules
-git clone git://github.com/facebook/regenerator.git
-cd regenerator
-npm install .
-npm test
-```
-
-Usage
----
-
-You have several options for using this module.
-
-Simplest usage:
-```sh
-regenerator es6.js > es5.js # Just the transform.
-regenerator --include-runtime es6.js > es5.js # Add the runtime too.
-regenerator src lib # Transform every .js file in src and output to lib.
-```
-
-Programmatic usage:
-```js
-var es5Source = require("regenerator").compile(es6Source).code;
-var es5SourceWithRuntime = require("regenerator").compile(es6Source, {
- includeRuntime: true
-}).code;
-```
-
-Babel plugin:
-```js
-var babel = require("babel-core");
-var code = babel.transform(es6Source, {
- plugins: [require("generator")]
-}).code;
-```
-
-How can you get involved?
----
-
-The easiest way to get involved is to look for buggy examples using [the
-sandbox](http://facebook.github.io/regenerator/), and when you find
-something strange just click the "report a bug" link (the new issue form
-will be populated automatically with the problematic code).
-
-Alternatively, you can
-[fork](https://github.com/facebook/regenerator/fork) the repository,
-create some failing tests cases in [test/tests.es6.js](test/tests.es6.js),
-and send pull requests for me to fix.
-
-If you're feeling especially brave, you are more than welcome to dive into
-the transformer code and fix the bug(s) yourself, but I must warn you that
-the code could really benefit from [better implementation
-comments](https://github.com/facebook/regenerator/issues/7).
+# babel-plugin-transform-regenerator
diff --git a/packages/babel-plugin-transform-regenerator/bin/regenerator b/packages/babel-plugin-transform-regenerator/bin/regenerator
deleted file mode 100755
index 88a4e27c12..0000000000
--- a/packages/babel-plugin-transform-regenerator/bin/regenerator
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/env node
-// -*- mode: js -*-
-
-var compile = require("../main").compile;
-
-require("commoner").version(
- require("../package.json").version
-).resolve(function(id) {
- return this.readModuleP(id);
-}).option(
- "-r, --include-runtime",
- "Prepend the runtime to the output."
-).process(function(id, source) {
- return compile(source, {
- includeRuntime: this.options.includeRuntime
- }).code;
-});
diff --git a/packages/babel-plugin-transform-regenerator/lib/emit.js b/packages/babel-plugin-transform-regenerator/lib/emit.js
index 078a8c0dfd..d435cd2e0a 100644
--- a/packages/babel-plugin-transform-regenerator/lib/emit.js
+++ b/packages/babel-plugin-transform-regenerator/lib/emit.js
@@ -8,54 +8,66 @@
* the same directory.
*/
-var traverse = require("babel-traverse");
-var assert = require("assert");
-var t = require("babel-types");
-var leap = require("./leap");
-var meta = require("./meta");
-var util = require("./util");
-var runtimeProperty = util.runtimeProperty;
+"use strict";
+
+var _interopRequireDefault = require("babel-runtime/helpers/interop-require-default")["default"];
+
+var _interopRequireWildcard = require("babel-runtime/helpers/interop-require-wildcard")["default"];
+
+var _assert = require("assert");
+
+var _assert2 = _interopRequireDefault(_assert);
+
+var _babelTypes = require("babel-types");
+
+var t = _interopRequireWildcard(_babelTypes);
+
+var _leap = require("./leap");
+
+var leap = _interopRequireWildcard(_leap);
+
+var _meta = require("./meta");
+
+var meta = _interopRequireWildcard(_meta);
+
+var _util = require("./util");
+
+var util = _interopRequireWildcard(_util);
+
var hasOwn = Object.prototype.hasOwnProperty;
function Emitter(contextId) {
- assert.ok(this instanceof Emitter);
+ _assert2["default"].ok(this instanceof Emitter);
t.assertIdentifier(contextId);
// Used to generate unique temporary names.
this.nextTempId = 0;
- Object.defineProperties(this, {
- // In order to make sure the context object does not collide with
- // anything in the local scope, we might have to rename it, so we
- // refer to it symbolically instead of just assuming that it will be
- // called "context".
- contextId: { value: contextId },
+ // In order to make sure the context object does not collide with
+ // anything in the local scope, we might have to rename it, so we
+ // refer to it symbolically instead of just assuming that it will be
+ // called "context".
+ this.contextId = contextId;
- // An append-only list of Statements that grows each time this.emit is
- // called.
- listing: { value: [] },
+ // An append-only list of Statements that grows each time this.emit is
+ // called.
+ this.listing = [];
- // A sparse array whose keys correspond to locations in this.listing
- // that have been marked as branch/jump targets.
- marked: { value: [true] },
+ // A sparse array whose keys correspond to locations in this.listing
+ // that have been marked as branch/jump targets.
+ this.marked = [true];
- // The last location will be marked when this.getDispatchLoop is
- // called.
- finalLoc: { value: loc() },
+ // The last location will be marked when this.getDispatchLoop is
+ // called.
+ this.finalLoc = loc();
- // A list of all leap.TryEntry statements emitted.
- tryEntries: { value: [] }
- });
+ // A list of all leap.TryEntry statements emitted.
+ this.tryEntries = [];
- // The .leapManager property needs to be defined by a separate
- // defineProperties call so that .finalLoc will be visible to the
- // leap.LeapManager constructor.
- Object.defineProperties(this, {
- // Each time we evaluate the body of a loop, we tell this.leapManager
- // to enter a nested loop context that determines the meaning of break
- // and continue statements therein.
- leapManager: { value: new leap.LeapManager(this) }
- });
+ // Each time we evaluate the body of a loop, we tell this.leapManager
+ // to enter a nested loop context that determines the meaning of break
+ // and continue statements therein.
+ this.leapManager = new leap.LeapManager(this);
}
var Ep = Emitter.prototype;
@@ -72,7 +84,7 @@ function loc() {
// Sets the exact value of the given location to the offset of the next
// Statement emitted.
-Ep.mark = function(loc) {
+Ep.mark = function (loc) {
t.assertLiteral(loc);
var index = this.listing.length;
if (loc.value === -1) {
@@ -80,44 +92,38 @@ Ep.mark = function(loc) {
} else {
// Locations can be marked redundantly, but their values cannot change
// once set the first time.
- assert.strictEqual(loc.value, index);
+ _assert2["default"].strictEqual(loc.value, index);
}
this.marked[index] = true;
return loc;
};
-Ep.emit = function(node) {
- if (t.isExpression(node))
- node = t.expressionStatement(node);
+Ep.emit = function (node) {
+ if (t.isExpression(node)) node = t.expressionStatement(node);
t.assertStatement(node);
this.listing.push(node);
};
// Shorthand for emitting assignment statements. This will come in handy
// for assignments to temporary variables.
-Ep.emitAssign = function(lhs, rhs) {
+Ep.emitAssign = function (lhs, rhs) {
this.emit(this.assign(lhs, rhs));
return lhs;
};
// Shorthand for an assignment statement.
-Ep.assign = function(lhs, rhs) {
- return t.expressionStatement(
- t.assignmentExpression("=", lhs, rhs));
+Ep.assign = function (lhs, rhs) {
+ return t.expressionStatement(t.assignmentExpression("=", lhs, rhs));
};
// Convenience function for generating expressions like context.next,
// context.sent, and context.rval.
-Ep.contextProperty = function(name, computed) {
- return t.memberExpression(
- this.contextId,
- computed ? t.stringLiteral(name) : t.identifier(name),
- !!computed
- );
+Ep.contextProperty = function (name, computed) {
+ return t.memberExpression(this.contextId, computed ? t.stringLiteral(name) : t.identifier(name), !!computed);
};
// Shorthand for setting context.rval and jumping to `context.stop()`.
-Ep.stop = function(rval) {
+Ep.stop = function (rval) {
if (rval) {
this.setReturnValue(rval);
}
@@ -125,22 +131,16 @@ Ep.stop = function(rval) {
this.jump(this.finalLoc);
};
-Ep.setReturnValue = function(valuePath) {
+Ep.setReturnValue = function (valuePath) {
t.assertExpression(valuePath.value);
- this.emitAssign(
- this.contextProperty("rval"),
- this.explodeExpression(valuePath)
- );
+ this.emitAssign(this.contextProperty("rval"), this.explodeExpression(valuePath));
};
-Ep.clearPendingException = function(tryLoc, assignee) {
+Ep.clearPendingException = function (tryLoc, assignee) {
t.assertLiteral(tryLoc);
- var catchCall = t.callExpression(
- this.contextProperty("catch", true),
- [tryLoc]
- );
+ var catchCall = t.callExpression(this.contextProperty("catch", true), [tryLoc]);
if (assignee) {
this.emitAssign(assignee, catchCall);
@@ -151,46 +151,33 @@ Ep.clearPendingException = function(tryLoc, assignee) {
// Emits code for an unconditional jump to the given location, even if the
// exact value of the location is not yet known.
-Ep.jump = function(toLoc) {
+Ep.jump = function (toLoc) {
this.emitAssign(this.contextProperty("next"), toLoc);
this.emit(t.breakStatement());
};
// Conditional jump.
-Ep.jumpIf = function(test, toLoc) {
+Ep.jumpIf = function (test, toLoc) {
t.assertExpression(test);
t.assertLiteral(toLoc);
- this.emit(t.ifStatement(
- test,
- t.blockStatement([
- this.assign(this.contextProperty("next"), toLoc),
- t.breakStatement()
- ])
- ));
+ this.emit(t.ifStatement(test, t.blockStatement([this.assign(this.contextProperty("next"), toLoc), t.breakStatement()])));
};
// Conditional jump, with the condition negated.
-Ep.jumpIfNot = function(test, toLoc) {
+Ep.jumpIfNot = function (test, toLoc) {
t.assertExpression(test);
t.assertLiteral(toLoc);
- var negatedTest;
- if (t.isUnaryExpression(test) &&
- test.operator === "!") {
+ var negatedTest = undefined;
+ if (t.isUnaryExpression(test) && test.operator === "!") {
// Avoid double negation.
negatedTest = test.argument;
} else {
negatedTest = t.unaryExpression("!", test);
}
- this.emit(t.ifStatement(
- negatedTest,
- t.blockStatement([
- this.assign(this.contextProperty("next"), toLoc),
- t.breakStatement()
- ])
- ));
+ this.emit(t.ifStatement(negatedTest, t.blockStatement([this.assign(this.contextProperty("next"), toLoc), t.breakStatement()])));
};
// Returns a unique MemberExpression that can be used to store and
@@ -198,17 +185,14 @@ Ep.jumpIfNot = function(test, toLoc) {
// the context object, which is presumed to coexist peacefully with all
// other local variables, and since we just increment `nextTempId`
// monotonically, uniqueness is assured.
-Ep.makeTempVar = function() {
+Ep.makeTempVar = function () {
return this.contextProperty("t" + this.nextTempId++);
};
-Ep.getContextFunction = function(id) {
- return t.functionExpression(
- id || null/*Anonymous*/,
- [this.contextId],
- t.blockStatement([this.getDispatchLoop()]),
- false, // Not a generator anymore!
- false // Nor an expression.
+Ep.getContextFunction = function (id) {
+ return t.functionExpression(id || null, /*Anonymous*/
+ [this.contextId], t.blockStatement([this.getDispatchLoop()]), false, // Not a generator anymore!
+ false // Nor an expression.
);
};
@@ -223,27 +207,24 @@ Ep.getContextFunction = function(id) {
//
// Each marked location in this.listing will correspond to one generated
// case statement.
-Ep.getDispatchLoop = function() {
+Ep.getDispatchLoop = function () {
var self = this;
var cases = [];
- var current;
+ var current = undefined;
// If we encounter a break, continue, or return statement in a switch
// case, we can skip the rest of the statements until the next case.
var alreadyEnded = false;
- self.listing.forEach(function(stmt, i) {
+ self.listing.forEach(function (stmt, i) {
if (self.marked.hasOwnProperty(i)) {
- cases.push(t.switchCase(
- t.numericLiteral(i),
- current = []));
+ cases.push(t.switchCase(t.numericLiteral(i), current = []));
alreadyEnded = false;
}
if (!alreadyEnded) {
current.push(stmt);
- if (t.isCompletionStatement(stmt))
- alreadyEnded = true;
+ if (t.isCompletionStatement(stmt)) alreadyEnded = true;
}
});
@@ -251,35 +232,20 @@ Ep.getDispatchLoop = function() {
// we can finally resolve this.finalLoc.value.
this.finalLoc.value = this.listing.length;
- cases.push(
- t.switchCase(this.finalLoc, [
- // Intentionally fall through to the "end" case...
- ]),
+ cases.push(t.switchCase(this.finalLoc, [
+ // Intentionally fall through to the "end" case...
+ ]),
- // So that the runtime can jump to the final location without having
- // to know its offset, we provide the "end" case as a synonym.
- t.switchCase(t.stringLiteral("end"), [
- // This will check/clear both context.thrown and context.rval.
- t.returnStatement(
- t.callExpression(this.contextProperty("stop"), [])
- )
- ])
- );
+ // So that the runtime can jump to the final location without having
+ // to know its offset, we provide the "end" case as a synonym.
+ t.switchCase(t.stringLiteral("end"), [
+ // This will check/clear both context.thrown and context.rval.
+ t.returnStatement(t.callExpression(this.contextProperty("stop"), []))]));
- return t.whileStatement(
- t.numericLiteral(1),
- t.switchStatement(
- t.assignmentExpression(
- "=",
- this.contextProperty("prev"),
- this.contextProperty("next")
- ),
- cases
- )
- );
+ return t.whileStatement(t.numericLiteral(1), t.switchStatement(t.assignmentExpression("=", this.contextProperty("prev"), this.contextProperty("next")), cases));
};
-Ep.getTryLocsList = function() {
+Ep.getTryLocsList = function () {
if (this.tryEntries.length === 0) {
// To avoid adding a needless [] to the majority of runtime.wrap
// argument lists, force the caller to handle this case specially.
@@ -288,29 +254,25 @@ Ep.getTryLocsList = function() {
var lastLocValue = 0;
- return t.arrayExpression(
- this.tryEntries.map(function(tryEntry) {
- var thisLocValue = tryEntry.firstLoc.value;
- assert.ok(thisLocValue >= lastLocValue, "try entries out of order");
- lastLocValue = thisLocValue;
+ return t.arrayExpression(this.tryEntries.map(function (tryEntry) {
+ var thisLocValue = tryEntry.firstLoc.value;
+ _assert2["default"].ok(thisLocValue >= lastLocValue, "try entries out of order");
+ lastLocValue = thisLocValue;
- var ce = tryEntry.catchEntry;
- var fe = tryEntry.finallyEntry;
+ var ce = tryEntry.catchEntry;
+ var fe = tryEntry.finallyEntry;
- var locs = [
- tryEntry.firstLoc,
- // The null here makes a hole in the array.
- ce ? ce.firstLoc : null
- ];
+ var locs = [tryEntry.firstLoc,
+ // The null here makes a hole in the array.
+ ce ? ce.firstLoc : null];
- if (fe) {
- locs[2] = fe.firstLoc;
- locs[3] = fe.afterLoc;
- }
+ if (fe) {
+ locs[2] = fe.firstLoc;
+ locs[3] = fe.afterLoc;
+ }
- return t.arrayExpression(locs);
- })
- );
+ return t.arrayExpression(locs);
+ }));
};
// All side effects must be realized in order.
@@ -320,56 +282,47 @@ Ep.getTryLocsList = function() {
// No destructive modification of AST nodes.
-Ep.explode = function(path, ignoreResult) {
+Ep.explode = function (path, ignoreResult) {
var node = path.node;
var self = this;
t.assertNode(node);
- if (t.isDeclaration(node))
- throw getDeclError(node);
+ if (t.isDeclaration(node)) throw getDeclError(node);
- if (t.isStatement(node))
- return self.explodeStatement(path);
+ if (t.isStatement(node)) return self.explodeStatement(path);
- if (t.isExpression(node))
- return self.explodeExpression(path, ignoreResult);
+ if (t.isExpression(node)) return self.explodeExpression(path, ignoreResult);
switch (node.type) {
- case "Program":
- return path.get("body").map(
- self.explodeStatement,
- self
- );
+ case "Program":
+ return path.get("body").map(self.explodeStatement, self);
- case "VariableDeclarator":
- throw getDeclError(node);
+ case "VariableDeclarator":
+ throw getDeclError(node);
- // These node types should be handled by their parent nodes
- // (ObjectExpression, SwitchStatement, and TryStatement, respectively).
- case "Property":
- case "SwitchCase":
- case "CatchClause":
- throw new Error(
- node.type + " nodes should be handled by their parents");
+ // These node types should be handled by their parent nodes
+ // (ObjectExpression, SwitchStatement, and TryStatement, respectively).
+ case "Property":
+ case "SwitchCase":
+ case "CatchClause":
+ throw new Error(node.type + " nodes should be handled by their parents");
- default:
- throw new Error(
- "unknown Node of type " +
- JSON.stringify(node.type));
+ default:
+ throw new Error("unknown Node of type " + JSON.stringify(node.type));
}
};
function getDeclError(node) {
- return new Error(
- "all declarations should have been transformed into " +
- "assignments before the Exploder began its work: " +
- JSON.stringify(node));
+ return new Error("all declarations should have been transformed into " + "assignments before the Exploder began its work: " + JSON.stringify(node));
}
-Ep.explodeStatement = function(path, labelId) {
+Ep.explodeStatement = function (path, labelId) {
var stmt = path.node;
var self = this;
+ var before = undefined,
+ after = undefined,
+ head = undefined;
t.assertStatement(stmt);
@@ -399,373 +352,308 @@ Ep.explodeStatement = function(path, labelId) {
}
switch (stmt.type) {
- case "ExpressionStatement":
- self.explodeExpression(path.get("expression"), true);
- break;
+ case "ExpressionStatement":
+ self.explodeExpression(path.get("expression"), true);
+ break;
- case "LabeledStatement":
- var after = loc();
+ case "LabeledStatement":
+ after = loc();
- // Did you know you can break from any labeled block statement or
- // control structure? Well, you can! Note: when a labeled loop is
- // encountered, the leap.LabeledEntry created here will immediately
- // enclose a leap.LoopEntry on the leap manager's stack, and both
- // entries will have the same label. Though this works just fine, it
- // may seem a bit redundant. In theory, we could check here to
- // determine if stmt knows how to handle its own label; for example,
- // stmt happens to be a WhileStatement and so we know it's going to
- // establish its own LoopEntry when we explode it (below). Then this
- // LabeledEntry would be unnecessary. Alternatively, we might be
- // tempted not to pass stmt.label down into self.explodeStatement,
- // because we've handled the label here, but that's a mistake because
- // labeled loops may contain labeled continue statements, which is not
- // something we can handle in this generic case. All in all, I think a
- // little redundancy greatly simplifies the logic of this case, since
- // it's clear that we handle all possible LabeledStatements correctly
- // here, regardless of whether they interact with the leap manager
- // themselves. Also remember that labels and break/continue-to-label
- // statements are rare, and all of this logic happens at transform
- // time, so it has no additional runtime cost.
- self.leapManager.withEntry(
- new leap.LabeledEntry(after, stmt.label),
- function() {
+ // Did you know you can break from any labeled block statement or
+ // control structure? Well, you can! Note: when a labeled loop is
+ // encountered, the leap.LabeledEntry created here will immediately
+ // enclose a leap.LoopEntry on the leap manager's stack, and both
+ // entries will have the same label. Though this works just fine, it
+ // may seem a bit redundant. In theory, we could check here to
+ // determine if stmt knows how to handle its own label; for example,
+ // stmt happens to be a WhileStatement and so we know it's going to
+ // establish its own LoopEntry when we explode it (below). Then this
+ // LabeledEntry would be unnecessary. Alternatively, we might be
+ // tempted not to pass stmt.label down into self.explodeStatement,
+ // because we've handled the label here, but that's a mistake because
+ // labeled loops may contain labeled continue statements, which is not
+ // something we can handle in this generic case. All in all, I think a
+ // little redundancy greatly simplifies the logic of this case, since
+ // it's clear that we handle all possible LabeledStatements correctly
+ // here, regardless of whether they interact with the leap manager
+ // themselves. Also remember that labels and break/continue-to-label
+ // statements are rare, and all of this logic happens at transform
+ // time, so it has no additional runtime cost.
+ self.leapManager.withEntry(new leap.LabeledEntry(after, stmt.label), function () {
self.explodeStatement(path.get("body"), stmt.label);
- }
- );
+ });
- self.mark(after);
+ self.mark(after);
- break;
+ break;
- case "WhileStatement":
- var before = loc();
- var after = loc();
+ case "WhileStatement":
+ before = loc();
+ after = loc();
- self.mark(before);
- self.jumpIfNot(self.explodeExpression(path.get("test")), after);
- self.leapManager.withEntry(
- new leap.LoopEntry(after, before, labelId),
- function() { self.explodeStatement(path.get("body")); }
- );
- self.jump(before);
- self.mark(after);
-
- break;
-
- case "DoWhileStatement":
- var first = loc();
- var test = loc();
- var after = loc();
-
- self.mark(first);
- self.leapManager.withEntry(
- new leap.LoopEntry(after, test, labelId),
- function() { self.explode(path.get("body")); }
- );
- self.mark(test);
- self.jumpIf(self.explodeExpression(path.get("test")), first);
- self.mark(after);
-
- break;
-
- case "ForStatement":
- var head = loc();
- var update = loc();
- var after = loc();
-
- if (stmt.init) {
- // We pass true here to indicate that if stmt.init is an expression
- // then we do not care about its result.
- self.explode(path.get("init"), true);
- }
-
- self.mark(head);
-
- if (stmt.test) {
+ self.mark(before);
self.jumpIfNot(self.explodeExpression(path.get("test")), after);
- } else {
- // No test means continue unconditionally.
- }
+ self.leapManager.withEntry(new leap.LoopEntry(after, before, labelId), function () {
+ self.explodeStatement(path.get("body"));
+ });
+ self.jump(before);
+ self.mark(after);
- self.leapManager.withEntry(
- new leap.LoopEntry(after, update, labelId),
- function() { self.explodeStatement(path.get("body")); }
- );
+ break;
- self.mark(update);
+ case "DoWhileStatement":
+ var first = loc();
+ var test = loc();
+ after = loc();
- if (stmt.update) {
- // We pass true here to indicate that if stmt.update is an
- // expression then we do not care about its result.
- self.explode(path.get("update"), true);
- }
+ self.mark(first);
+ self.leapManager.withEntry(new leap.LoopEntry(after, test, labelId), function () {
+ self.explode(path.get("body"));
+ });
+ self.mark(test);
+ self.jumpIf(self.explodeExpression(path.get("test")), first);
+ self.mark(after);
- self.jump(head);
+ break;
- self.mark(after);
+ case "ForStatement":
+ head = loc();
+ var update = loc();
+ after = loc();
- break;
-
- case "TypeCastExpression":
- return self.explodeExpression(path.get("expression"));
-
- case "ForInStatement":
- var head = loc();
- var after = loc();
-
- var keyIterNextFn = self.makeTempVar();
- self.emitAssign(
- keyIterNextFn,
- t.callExpression(
- runtimeProperty("keys"),
- [self.explodeExpression(path.get("right"))]
- )
- );
-
- self.mark(head);
-
- var keyInfoTmpVar = self.makeTempVar();
- self.jumpIf(
- t.memberExpression(
- t.assignmentExpression(
- "=",
- keyInfoTmpVar,
- t.callExpression(keyIterNextFn, [])
- ),
- t.identifier("done"),
- false
- ),
- after
- );
-
- self.emitAssign(
- stmt.left,
- t.memberExpression(
- keyInfoTmpVar,
- t.identifier("value"),
- false
- )
- );
-
- self.leapManager.withEntry(
- new leap.LoopEntry(after, head, labelId),
- function() { self.explodeStatement(path.get("body")); }
- );
-
- self.jump(head);
-
- self.mark(after);
-
- break;
-
- case "BreakStatement":
- self.emitAbruptCompletion({
- type: "break",
- target: self.leapManager.getBreakLoc(stmt.label)
- });
-
- break;
-
- case "ContinueStatement":
- self.emitAbruptCompletion({
- type: "continue",
- target: self.leapManager.getContinueLoc(stmt.label)
- });
-
- break;
-
- case "SwitchStatement":
- // Always save the discriminant into a temporary variable in case the
- // test expressions overwrite values like context.sent.
- var disc = self.emitAssign(
- self.makeTempVar(),
- self.explodeExpression(path.get("discriminant"))
- );
-
- var after = loc();
- var defaultLoc = loc();
- var condition = defaultLoc;
- var caseLocs = [];
-
- // If there are no cases, .cases might be undefined.
- var cases = stmt.cases || [];
-
- for (var i = cases.length - 1; i >= 0; --i) {
- var c = cases[i];
- t.assertSwitchCase(c);
-
- if (c.test) {
- condition = t.conditionalExpression(
- t.binaryExpression("===", disc, c.test),
- caseLocs[i] = loc(),
- condition
- );
- } else {
- caseLocs[i] = defaultLoc;
+ if (stmt.init) {
+ // We pass true here to indicate that if stmt.init is an expression
+ // then we do not care about its result.
+ self.explode(path.get("init"), true);
}
- }
- var discriminant = path.get("discriminant");
- discriminant.replaceWith(condition);
- self.jump(self.explodeExpression(discriminant));
+ self.mark(head);
- self.leapManager.withEntry(
- new leap.SwitchEntry(after),
- function() {
- path.get("cases").forEach(function(casePath) {
- var c = casePath.node;
+ if (stmt.test) {
+ self.jumpIfNot(self.explodeExpression(path.get("test")), after);
+ } else {
+ // No test means continue unconditionally.
+ }
+
+ self.leapManager.withEntry(new leap.LoopEntry(after, update, labelId), function () {
+ self.explodeStatement(path.get("body"));
+ });
+
+ self.mark(update);
+
+ if (stmt.update) {
+ // We pass true here to indicate that if stmt.update is an
+ // expression then we do not care about its result.
+ self.explode(path.get("update"), true);
+ }
+
+ self.jump(head);
+
+ self.mark(after);
+
+ break;
+
+ case "TypeCastExpression":
+ return self.explodeExpression(path.get("expression"));
+
+ case "ForInStatement":
+ head = loc();
+ after = loc();
+
+ var keyIterNextFn = self.makeTempVar();
+ self.emitAssign(keyIterNextFn, t.callExpression(util.runtimeProperty("keys"), [self.explodeExpression(path.get("right"))]));
+
+ self.mark(head);
+
+ var keyInfoTmpVar = self.makeTempVar();
+ self.jumpIf(t.memberExpression(t.assignmentExpression("=", keyInfoTmpVar, t.callExpression(keyIterNextFn, [])), t.identifier("done"), false), after);
+
+ self.emitAssign(stmt.left, t.memberExpression(keyInfoTmpVar, t.identifier("value"), false));
+
+ self.leapManager.withEntry(new leap.LoopEntry(after, head, labelId), function () {
+ self.explodeStatement(path.get("body"));
+ });
+
+ self.jump(head);
+
+ self.mark(after);
+
+ break;
+
+ case "BreakStatement":
+ self.emitAbruptCompletion({
+ type: "break",
+ target: self.leapManager.getBreakLoc(stmt.label)
+ });
+
+ break;
+
+ case "ContinueStatement":
+ self.emitAbruptCompletion({
+ type: "continue",
+ target: self.leapManager.getContinueLoc(stmt.label)
+ });
+
+ break;
+
+ case "SwitchStatement":
+ // Always save the discriminant into a temporary variable in case the
+ // test expressions overwrite values like context.sent.
+ var disc = self.emitAssign(self.makeTempVar(), self.explodeExpression(path.get("discriminant")));
+
+ after = loc();
+ var defaultLoc = loc();
+ var condition = defaultLoc;
+ var caseLocs = [];
+
+ // If there are no cases, .cases might be undefined.
+ var cases = stmt.cases || [];
+
+ for (var i = cases.length - 1; i >= 0; --i) {
+ var c = cases[i];
+ t.assertSwitchCase(c);
+
+ if (c.test) {
+ condition = t.conditionalExpression(t.binaryExpression("===", disc, c.test), caseLocs[i] = loc(), condition);
+ } else {
+ caseLocs[i] = defaultLoc;
+ }
+ }
+
+ var discriminant = path.get("discriminant");
+ discriminant.replaceWith(condition);
+ self.jump(self.explodeExpression(discriminant));
+
+ self.leapManager.withEntry(new leap.SwitchEntry(after), function () {
+ path.get("cases").forEach(function (casePath) {
var i = casePath.key;
-
self.mark(caseLocs[i]);
casePath.get("consequent").forEach(function (path) {
self.explodeStatement(path);
});
});
+ });
+
+ self.mark(after);
+ if (defaultLoc.value === -1) {
+ self.mark(defaultLoc);
+ _assert2["default"].strictEqual(after.value, defaultLoc.value);
}
- );
- self.mark(after);
- if (defaultLoc.value === -1) {
- self.mark(defaultLoc);
- assert.strictEqual(after.value, defaultLoc.value);
- }
+ break;
- break;
+ case "IfStatement":
+ var elseLoc = stmt.alternate && loc();
+ after = loc();
- case "IfStatement":
- var elseLoc = stmt.alternate && loc();
- var after = loc();
+ self.jumpIfNot(self.explodeExpression(path.get("test")), elseLoc || after);
- self.jumpIfNot(
- self.explodeExpression(path.get("test")),
- elseLoc || after
- );
+ self.explodeStatement(path.get("consequent"));
- self.explodeStatement(path.get("consequent"));
+ if (elseLoc) {
+ self.jump(after);
+ self.mark(elseLoc);
+ self.explodeStatement(path.get("alternate"));
+ }
- if (elseLoc) {
- self.jump(after);
- self.mark(elseLoc);
- self.explodeStatement(path.get("alternate"));
- }
+ self.mark(after);
- self.mark(after);
+ break;
- break;
+ case "ReturnStatement":
+ self.emitAbruptCompletion({
+ type: "return",
+ value: self.explodeExpression(path.get("argument"))
+ });
- case "ReturnStatement":
- self.emitAbruptCompletion({
- type: "return",
- value: self.explodeExpression(path.get("argument"))
- });
+ break;
- break;
+ case "WithStatement":
+ throw new Error("WithStatement not supported in generator functions.");
- case "WithStatement":
- throw new Error(
- node.type + " not supported in generator functions.");
+ case "TryStatement":
+ after = loc();
- case "TryStatement":
- var after = loc();
+ var handler = stmt.handler;
- var handler = stmt.handler;
+ var catchLoc = handler && loc();
+ var catchEntry = catchLoc && new leap.CatchEntry(catchLoc, handler.param);
- var catchLoc = handler && loc();
- var catchEntry = catchLoc && new leap.CatchEntry(
- catchLoc,
- handler.param
- );
+ var finallyLoc = stmt.finalizer && loc();
+ var finallyEntry = finallyLoc && new leap.FinallyEntry(finallyLoc, after);
- var finallyLoc = stmt.finalizer && loc();
- var finallyEntry = finallyLoc &&
- new leap.FinallyEntry(finallyLoc, after);
+ var tryEntry = new leap.TryEntry(self.getUnmarkedCurrentLoc(), catchEntry, finallyEntry);
- var tryEntry = new leap.TryEntry(
- self.getUnmarkedCurrentLoc(),
- catchEntry,
- finallyEntry
- );
+ self.tryEntries.push(tryEntry);
+ self.updateContextPrevLoc(tryEntry.firstLoc);
- self.tryEntries.push(tryEntry);
- self.updateContextPrevLoc(tryEntry.firstLoc);
+ self.leapManager.withEntry(tryEntry, function () {
+ self.explodeStatement(path.get("block"));
- self.leapManager.withEntry(tryEntry, function() {
- self.explodeStatement(path.get("block"));
+ if (catchLoc) {
+ (function () {
+ if (finallyLoc) {
+ // If we have both a catch block and a finally block, then
+ // because we emit the catch block first, we need to jump over
+ // it to the finally block.
+ self.jump(finallyLoc);
+ } else {
+ // If there is no finally block, then we need to jump over the
+ // catch block to the fall-through location.
+ self.jump(after);
+ }
- if (catchLoc) {
- if (finallyLoc) {
- // If we have both a catch block and a finally block, then
- // because we emit the catch block first, we need to jump over
- // it to the finally block.
- self.jump(finallyLoc);
+ self.updateContextPrevLoc(self.mark(catchLoc));
- } else {
- // If there is no finally block, then we need to jump over the
- // catch block to the fall-through location.
- self.jump(after);
+ var bodyPath = path.get("handler.body");
+ var safeParam = self.makeTempVar();
+ self.clearPendingException(tryEntry.firstLoc, safeParam);
+
+ bodyPath.traverse(catchParamVisitor, {
+ safeParam: safeParam,
+ catchParamName: handler.param.name
+ });
+
+ self.leapManager.withEntry(catchEntry, function () {
+ self.explodeStatement(bodyPath);
+ });
+ })();
}
- self.updateContextPrevLoc(self.mark(catchLoc));
+ if (finallyLoc) {
+ self.updateContextPrevLoc(self.mark(finallyLoc));
- var bodyPath = path.get("handler.body");
- var safeParam = self.makeTempVar();
- self.clearPendingException(tryEntry.firstLoc, safeParam);
+ self.leapManager.withEntry(finallyEntry, function () {
+ self.explodeStatement(path.get("finalizer"));
+ });
- var catchScope = bodyPath.scope;
- // TODO: t.assertCatchClause(catchScope.block);
- // TODO: assert.strictEqual(catchScope.lookup(catchParamName), catchScope);
+ self.emit(t.returnStatement(t.callExpression(self.contextProperty("finish"), [finallyEntry.firstLoc])));
+ }
+ });
- bodyPath.traverse(catchParamVisitor, {
- safeParam: safeParam,
- catchParamName: handler.param.name
- });
+ self.mark(after);
- self.leapManager.withEntry(catchEntry, function() {
- self.explodeStatement(bodyPath);
- });
- }
+ break;
- if (finallyLoc) {
- self.updateContextPrevLoc(self.mark(finallyLoc));
+ case "ThrowStatement":
+ self.emit(t.throwStatement(self.explodeExpression(path.get("argument"))));
- self.leapManager.withEntry(finallyEntry, function() {
- self.explodeStatement(path.get("finalizer"));
- });
+ break;
- self.emit(t.returnStatement(t.callExpression(
- self.contextProperty("finish"),
- [finallyEntry.firstLoc]
- )));
- }
- });
-
- self.mark(after);
-
- break;
-
- case "ThrowStatement":
- self.emit(t.throwStatement(
- self.explodeExpression(path.get("argument"))
- ));
-
- break;
-
- default:
- throw new Error(
- "unknown Statement of type " +
- JSON.stringify(stmt.type));
+ default:
+ throw new Error("unknown Statement of type " + JSON.stringify(stmt.type));
}
};
var catchParamVisitor = {
- Identifier: function(path, state) {
+ Identifier: function Identifier(path, state) {
if (path.node.name === state.catchParamName && util.isReference(path)) {
path.replaceWith(state.safeParam);
}
},
- Scope: function(path, state) {
+ Scope: function Scope(path, state) {
if (path.scope.hasOwnBinding(state.catchParamName)) {
// Don't descend into nested scopes that shadow the catch
// parameter with their own declarations.
@@ -774,42 +662,26 @@ var catchParamVisitor = {
}
};
-Ep.emitAbruptCompletion = function(record) {
+Ep.emitAbruptCompletion = function (record) {
if (!isValidCompletion(record)) {
- assert.ok(
- false,
- "invalid completion record: " +
- JSON.stringify(record)
- );
+ _assert2["default"].ok(false, "invalid completion record: " + JSON.stringify(record));
}
- assert.notStrictEqual(
- record.type, "normal",
- "normal completions are not abrupt"
- );
+ _assert2["default"].notStrictEqual(record.type, "normal", "normal completions are not abrupt");
var abruptArgs = [t.stringLiteral(record.type)];
- if (record.type === "break" ||
- record.type === "continue") {
+ if (record.type === "break" || record.type === "continue") {
t.assertLiteral(record.target);
abruptArgs[1] = record.target;
- } else if (record.type === "return" ||
- record.type === "throw") {
+ } else if (record.type === "return" || record.type === "throw") {
if (record.value) {
t.assertExpression(record.value);
abruptArgs[1] = record.value;
}
}
- this.emit(
- t.returnStatement(
- t.callExpression(
- this.contextProperty("abrupt"),
- abruptArgs
- )
- )
- );
+ this.emit(t.returnStatement(t.callExpression(this.contextProperty("abrupt"), abruptArgs)));
};
function isValidCompletion(record) {
@@ -819,22 +691,17 @@ function isValidCompletion(record) {
return !hasOwn.call(record, "target");
}
- if (type === "break" ||
- type === "continue") {
- return !hasOwn.call(record, "value")
- && t.isLiteral(record.target);
+ if (type === "break" || type === "continue") {
+ return !hasOwn.call(record, "value") && t.isLiteral(record.target);
}
- if (type === "return" ||
- type === "throw") {
- return hasOwn.call(record, "value")
- && !hasOwn.call(record, "target");
+ if (type === "return" || type === "throw") {
+ return hasOwn.call(record, "value") && !hasOwn.call(record, "target");
}
return false;
}
-
// Not all offsets into emitter.listing are potential jump targets. For
// example, execution typically falls into the beginning of a try block
// without jumping directly there. This method returns the current offset
@@ -844,7 +711,7 @@ function isValidCompletion(record) {
// statements). There's no logical harm in marking such locations as jump
// targets, but minimizing the number of switch cases keeps the generated
// code shorter.
-Ep.getUnmarkedCurrentLoc = function() {
+Ep.getUnmarkedCurrentLoc = function () {
return t.numericLiteral(this.listing.length);
};
@@ -858,7 +725,7 @@ Ep.getUnmarkedCurrentLoc = function() {
// would know the location of the current instruction with complete
// precision at all times, but we don't have that luxury here, as it would
// be costly and verbose to set context.prev before every statement.
-Ep.updateContextPrevLoc = function(loc) {
+Ep.updateContextPrevLoc = function (loc) {
if (loc) {
t.assertLiteral(loc);
@@ -868,9 +735,8 @@ Ep.updateContextPrevLoc = function(loc) {
loc.value = this.listing.length;
} else {
// Otherwise assert that the location matches the current offset.
- assert.strictEqual(loc.value, this.listing.length);
+ _assert2["default"].strictEqual(loc.value, this.listing.length);
}
-
} else {
loc = this.getUnmarkedCurrentLoc();
}
@@ -881,7 +747,7 @@ Ep.updateContextPrevLoc = function(loc) {
this.emitAssign(this.contextProperty("prev"), loc);
};
-Ep.explodeExpression = function(path, ignoreResult) {
+Ep.explodeExpression = function (path, ignoreResult) {
var expr = path.node;
if (expr) {
t.assertExpression(expr);
@@ -890,7 +756,7 @@ Ep.explodeExpression = function(path, ignoreResult) {
}
var self = this;
- var result; // Used optionally by several cases below.
+ var result = undefined; // Used optionally by several cases below.
function finish(expr) {
t.assertExpression(expr);
@@ -923,35 +789,27 @@ Ep.explodeExpression = function(path, ignoreResult) {
// control the precise order in which the generated code realizes the
// side effects of those subexpressions.
function explodeViaTempVar(tempVar, childPath, ignoreChildResult) {
- assert.ok(
- !ignoreChildResult || !tempVar,
- "Ignoring the result of a child expression but forcing it to " +
- "be assigned to a temporary variable?"
- );
+ _assert2["default"].ok(!ignoreChildResult || !tempVar, "Ignoring the result of a child expression but forcing it to " + "be assigned to a temporary variable?");
var result = self.explodeExpression(childPath, ignoreChildResult);
if (ignoreChildResult) {
// Side effects already emitted above.
- } else if (tempVar || (hasLeapingChildren &&
- !t.isLiteral(result))) {
- // If tempVar was provided, then the result will always be assigned
- // to it, even if the result does not otherwise need to be assigned
- // to a temporary variable. When no tempVar is provided, we have
- // the flexibility to decide whether a temporary variable is really
- // necessary. Unfortunately, in general, a temporary variable is
- // required whenever any child contains a yield expression, since it
- // is difficult to prove (at all, let alone efficiently) whether
- // this result would evaluate to the same value before and after the
- // yield (see #206). One narrow case where we can prove it doesn't
- // matter (and thus we do not need a temporary variable) is when the
- // result in question is a Literal value.
- result = self.emitAssign(
- tempVar || self.makeTempVar(),
- result
- );
- }
+ } else if (tempVar || hasLeapingChildren && !t.isLiteral(result)) {
+ // If tempVar was provided, then the result will always be assigned
+ // to it, even if the result does not otherwise need to be assigned
+ // to a temporary variable. When no tempVar is provided, we have
+ // the flexibility to decide whether a temporary variable is really
+ // necessary. Unfortunately, in general, a temporary variable is
+ // required whenever any child contains a yield expression, since it
+ // is difficult to prove (at all, let alone efficiently) whether
+ // this result would evaluate to the same value before and after the
+ // yield (see #206). One narrow case where we can prove it doesn't
+ // matter (and thus we do not need a temporary variable) is when the
+ // result in question is a Literal value.
+ result = self.emitAssign(tempVar || self.makeTempVar(), result);
+ }
return result;
}
@@ -960,236 +818,175 @@ Ep.explodeExpression = function(path, ignoreResult) {
// return a result.
switch (expr.type) {
- case "MemberExpression":
- return finish(t.memberExpression(
- self.explodeExpression(path.get("object")),
- expr.computed
- ? explodeViaTempVar(null, path.get("property"))
- : expr.property,
- expr.computed
- ));
+ case "MemberExpression":
+ return finish(t.memberExpression(self.explodeExpression(path.get("object")), expr.computed ? explodeViaTempVar(null, path.get("property")) : expr.property, expr.computed));
- case "CallExpression":
- var calleePath = path.get("callee");
- var argsPath = path.get("arguments");
+ case "CallExpression":
+ var calleePath = path.get("callee");
+ var argsPath = path.get("arguments");
- var newCallee;
- var newArgs = [];
+ var newCallee = undefined;
+ var newArgs = [];
- var hasLeapingArgs = false;
- argsPath.forEach(function(argPath) {
- hasLeapingArgs = hasLeapingArgs ||
- meta.containsLeap(argPath.node);
- });
+ var hasLeapingArgs = false;
+ argsPath.forEach(function (argPath) {
+ hasLeapingArgs = hasLeapingArgs || meta.containsLeap(argPath.node);
+ });
- if (t.isMemberExpression(calleePath.node)) {
- if (hasLeapingArgs) {
- // If the arguments of the CallExpression contained any yield
- // expressions, then we need to be sure to evaluate the callee
- // before evaluating the arguments, but if the callee was a member
- // expression, then we must be careful that the object of the
- // member expression still gets bound to `this` for the call.
+ if (t.isMemberExpression(calleePath.node)) {
+ if (hasLeapingArgs) {
+ // If the arguments of the CallExpression contained any yield
+ // expressions, then we need to be sure to evaluate the callee
+ // before evaluating the arguments, but if the callee was a member
+ // expression, then we must be careful that the object of the
+ // member expression still gets bound to `this` for the call.
- var newObject = explodeViaTempVar(
+ var newObject = explodeViaTempVar(
// Assign the exploded callee.object expression to a temporary
// variable so that we can use it twice without reevaluating it.
- self.makeTempVar(),
- calleePath.get("object")
- );
+ self.makeTempVar(), calleePath.get("object"));
- var newProperty = calleePath.node.computed
- ? explodeViaTempVar(null, calleePath.get("property"))
- : calleePath.node.property;
+ var newProperty = calleePath.node.computed ? explodeViaTempVar(null, calleePath.get("property")) : calleePath.node.property;
- newArgs.unshift(newObject);
-
- newCallee = t.memberExpression(
- t.memberExpression(
- newObject,
- newProperty,
- calleePath.node.computed
- ),
- t.identifier("call"),
- false
- );
+ newArgs.unshift(newObject);
+ newCallee = t.memberExpression(t.memberExpression(newObject, newProperty, calleePath.node.computed), t.identifier("call"), false);
+ } else {
+ newCallee = self.explodeExpression(calleePath);
+ }
} else {
newCallee = self.explodeExpression(calleePath);
+
+ if (t.isMemberExpression(newCallee)) {
+ // If the callee was not previously a MemberExpression, then the
+ // CallExpression was "unqualified," meaning its `this` object
+ // should be the global object. If the exploded expression has
+ // become a MemberExpression (e.g. a context property, probably a
+ // temporary variable), then we need to force it to be unqualified
+ // by using the (0, object.property)(...) trick; otherwise, it
+ // will receive the object of the MemberExpression as its `this`
+ // object.
+ newCallee = t.sequenceExpression([t.numericLiteral(0), newCallee]);
+ }
}
- } else {
- newCallee = self.explodeExpression(calleePath);
+ argsPath.forEach(function (argPath) {
+ newArgs.push(explodeViaTempVar(null, argPath));
+ });
- if (t.isMemberExpression(newCallee)) {
- // If the callee was not previously a MemberExpression, then the
- // CallExpression was "unqualified," meaning its `this` object
- // should be the global object. If the exploded expression has
- // become a MemberExpression (e.g. a context property, probably a
- // temporary variable), then we need to force it to be unqualified
- // by using the (0, object.property)(...) trick; otherwise, it
- // will receive the object of the MemberExpression as its `this`
- // object.
- newCallee = t.sequenceExpression([
- t.numericLiteral(0),
- newCallee
- ]);
- }
- }
+ return finish(t.callExpression(newCallee, newArgs));
- argsPath.forEach(function(argPath) {
- newArgs.push(explodeViaTempVar(null, argPath));
- });
-
- return finish(t.callExpression(
- newCallee,
- newArgs
- ));
-
- case "NewExpression":
- return finish(t.newExpression(
- explodeViaTempVar(null, path.get("callee")),
- path.get("arguments").map(function(argPath) {
+ case "NewExpression":
+ return finish(t.newExpression(explodeViaTempVar(null, path.get("callee")), path.get("arguments").map(function (argPath) {
return explodeViaTempVar(null, argPath);
- })
- ));
+ })));
- case "ObjectExpression":
- return finish(t.objectExpression(
- path.get("properties").map(function(propPath) {
+ case "ObjectExpression":
+ return finish(t.objectExpression(path.get("properties").map(function (propPath) {
if (propPath.isObjectProperty()) {
- return t.objectProperty(
- propPath.node.key,
- explodeViaTempVar(null, propPath.get("value")),
- propPath.node.computed
- );
+ return t.objectProperty(propPath.node.key, explodeViaTempVar(null, propPath.get("value")), propPath.node.computed);
} else {
return propPath.node;
}
- })
- ));
+ })));
- case "ArrayExpression":
- return finish(t.arrayExpression(
- path.get("elements").map(function(elemPath) {
+ case "ArrayExpression":
+ return finish(t.arrayExpression(path.get("elements").map(function (elemPath) {
return explodeViaTempVar(null, elemPath);
- })
- ));
+ })));
- case "SequenceExpression":
- var lastIndex = expr.expressions.length - 1;
+ case "SequenceExpression":
+ var lastIndex = expr.expressions.length - 1;
- path.get("expressions").forEach(function(exprPath) {
- if (exprPath.key === lastIndex) {
- result = self.explodeExpression(exprPath, ignoreResult);
- } else {
- self.explodeExpression(exprPath, true);
+ path.get("expressions").forEach(function (exprPath) {
+ if (exprPath.key === lastIndex) {
+ result = self.explodeExpression(exprPath, ignoreResult);
+ } else {
+ self.explodeExpression(exprPath, true);
+ }
+ });
+
+ return result;
+
+ case "LogicalExpression":
+ after = loc();
+
+ if (!ignoreResult) {
+ result = self.makeTempVar();
}
- });
- return result;
+ var left = explodeViaTempVar(result, path.get("left"));
- case "LogicalExpression":
- var after = loc();
+ if (expr.operator === "&&") {
+ self.jumpIfNot(left, after);
+ } else {
+ _assert2["default"].strictEqual(expr.operator, "||");
+ self.jumpIf(left, after);
+ }
- if (!ignoreResult) {
- result = self.makeTempVar();
- }
-
- var left = explodeViaTempVar(result, path.get("left"));
-
- if (expr.operator === "&&") {
- self.jumpIfNot(left, after);
- } else {
- assert.strictEqual(expr.operator, "||");
- self.jumpIf(left, after);
- }
-
- explodeViaTempVar(result, path.get("right"), ignoreResult);
-
- self.mark(after);
-
- return result;
-
- case "ConditionalExpression":
- var elseLoc = loc();
- var after = loc();
- var test = self.explodeExpression(path.get("test"));
-
- self.jumpIfNot(test, elseLoc);
-
- if (!ignoreResult) {
- result = self.makeTempVar();
- }
-
- explodeViaTempVar(result, path.get("consequent"), ignoreResult);
- self.jump(after);
-
- self.mark(elseLoc);
- explodeViaTempVar(result, path.get("alternate"), ignoreResult);
-
- self.mark(after);
-
- return result;
-
- case "UnaryExpression":
- return finish(t.unaryExpression(
- expr.operator,
- // Can't (and don't need to) break up the syntax of the argument.
- // Think about delete a[b].
- self.explodeExpression(path.get("argument")),
- !!expr.prefix
- ));
-
- case "BinaryExpression":
- return finish(t.binaryExpression(
- expr.operator,
- explodeViaTempVar(null, path.get("left")),
- explodeViaTempVar(null, path.get("right"))
- ));
-
- case "AssignmentExpression":
- return finish(t.assignmentExpression(
- expr.operator,
- self.explodeExpression(path.get("left")),
- self.explodeExpression(path.get("right"))
- ));
-
- case "UpdateExpression":
- return finish(t.updateExpression(
- expr.operator,
- self.explodeExpression(path.get("argument")),
- expr.prefix
- ));
-
- case "YieldExpression":
- var after = loc();
- var arg = expr.argument && self.explodeExpression(path.get("argument"));
-
- if (arg && expr.delegate) {
- var result = self.makeTempVar();
-
- self.emit(t.returnStatement(t.callExpression(
- self.contextProperty("delegateYield"), [
- arg,
- t.stringLiteral(result.property.name),
- after
- ]
- )));
+ explodeViaTempVar(result, path.get("right"), ignoreResult);
self.mark(after);
return result;
- }
- self.emitAssign(self.contextProperty("next"), after);
- self.emit(t.returnStatement(arg || null));
- self.mark(after);
+ case "ConditionalExpression":
+ var elseLoc = loc();
+ after = loc();
+ var test = self.explodeExpression(path.get("test"));
- return self.contextProperty("sent");
+ self.jumpIfNot(test, elseLoc);
- default:
- throw new Error(
- "unknown Expression of type " +
- JSON.stringify(expr.type));
+ if (!ignoreResult) {
+ result = self.makeTempVar();
+ }
+
+ explodeViaTempVar(result, path.get("consequent"), ignoreResult);
+ self.jump(after);
+
+ self.mark(elseLoc);
+ explodeViaTempVar(result, path.get("alternate"), ignoreResult);
+
+ self.mark(after);
+
+ return result;
+
+ case "UnaryExpression":
+ return finish(t.unaryExpression(expr.operator,
+ // Can't (and don't need to) break up the syntax of the argument.
+ // Think about delete a[b].
+ self.explodeExpression(path.get("argument")), !!expr.prefix));
+
+ case "BinaryExpression":
+ return finish(t.binaryExpression(expr.operator, explodeViaTempVar(null, path.get("left")), explodeViaTempVar(null, path.get("right"))));
+
+ case "AssignmentExpression":
+ return finish(t.assignmentExpression(expr.operator, self.explodeExpression(path.get("left")), self.explodeExpression(path.get("right"))));
+
+ case "UpdateExpression":
+ return finish(t.updateExpression(expr.operator, self.explodeExpression(path.get("argument")), expr.prefix));
+
+ case "YieldExpression":
+ after = loc();
+ var arg = expr.argument && self.explodeExpression(path.get("argument"));
+
+ if (arg && expr.delegate) {
+ var _result = self.makeTempVar();
+
+ self.emit(t.returnStatement(t.callExpression(self.contextProperty("delegateYield"), [arg, t.stringLiteral(_result.property.name), after])));
+
+ self.mark(after);
+
+ return _result;
+ }
+
+ self.emitAssign(self.contextProperty("next"), after);
+ self.emit(t.returnStatement(arg || null));
+ self.mark(after);
+
+ return self.contextProperty("sent");
+
+ default:
+ throw new Error("unknown Expression of type " + JSON.stringify(expr.type));
}
-};
+};
\ No newline at end of file
diff --git a/packages/babel-plugin-transform-regenerator/lib/hoist.js b/packages/babel-plugin-transform-regenerator/lib/hoist.js
index 9ca822485b..d05db03455 100644
--- a/packages/babel-plugin-transform-regenerator/lib/hoist.js
+++ b/packages/babel-plugin-transform-regenerator/lib/hoist.js
@@ -8,16 +8,23 @@
* the same directory.
*/
-var traverse = require("babel-traverse");
-var assert = require("assert");
-var t = require("babel-types");
+"use strict";
+
+var _Object$keys = require("babel-runtime/core-js/object/keys")["default"];
+
+var _interopRequireWildcard = require("babel-runtime/helpers/interop-require-wildcard")["default"];
+
+var _babelTypes = require("babel-types");
+
+var t = _interopRequireWildcard(_babelTypes);
+
var hasOwn = Object.prototype.hasOwnProperty;
// The hoist function takes a FunctionExpression or FunctionDeclaration
// and replaces any Declaration nodes in its body with assignments, then
// returns a VariableDeclaration containing just the names of the removed
// declarations.
-exports.hoist = function(funPath) {
+exports.hoist = function (funPath) {
t.assertFunction(funPath.node);
var vars = {};
@@ -27,30 +34,26 @@ exports.hoist = function(funPath) {
// TODO assert.equal(vdec.kind, "var");
var exprs = [];
- vdec.declarations.forEach(function(dec) {
+ vdec.declarations.forEach(function (dec) {
vars[dec.id.name] = dec.id;
if (dec.init) {
- exprs.push(t.assignmentExpression(
- "=", dec.id, dec.init
- ));
+ exprs.push(t.assignmentExpression("=", dec.id, dec.init));
} else if (includeIdentifiers) {
exprs.push(dec.id);
}
});
- if (exprs.length === 0)
- return null;
+ if (exprs.length === 0) return null;
- if (exprs.length === 1)
- return exprs[0];
+ if (exprs.length === 1) return exprs[0];
return t.sequenceExpression(exprs);
}
funPath.get("body").traverse({
VariableDeclaration: {
- exit: function(path) {
+ exit: function exit(path) {
var expr = varDeclToExpr(path.node, false);
if (expr === null) {
path.remove();
@@ -66,38 +69,25 @@ exports.hoist = function(funPath) {
}
},
- ForStatement: function(path) {
+ ForStatement: function ForStatement(path) {
var init = path.node.init;
if (t.isVariableDeclaration(init)) {
path.get("init").replaceWith(varDeclToExpr(init, false));
}
},
- ForXStatement: function(path) {
+ ForXStatement: function ForXStatement(path) {
var left = path.get("left");
if (left.isVariableDeclaration()) {
left.replaceWith(varDeclToExpr(left.node, true));
}
},
- FunctionDeclaration: function(path) {
+ FunctionDeclaration: function FunctionDeclaration(path) {
var node = path.node;
vars[node.id.name] = node.id;
- var parentNode = path.parent.node;
- var assignment = t.expressionStatement(
- t.assignmentExpression(
- "=",
- node.id,
- t.functionExpression(
- node.id,
- node.params,
- node.body,
- node.generator,
- node.expression
- )
- )
- );
+ var assignment = t.expressionStatement(t.assignmentExpression("=", node.id, t.functionExpression(node.id, node.params, node.body, node.generator, node.expression)));
if (path.parentPath.isBlockStatement()) {
// Insert the assignment form before the first statement in the
@@ -118,14 +108,14 @@ exports.hoist = function(funPath) {
path.skip();
},
- FunctionExpression: function(path) {
+ FunctionExpression: function FunctionExpression(path) {
// Don't descend into nested function expressions.
path.skip();
}
});
var paramNames = {};
- funPath.get("params").forEach(function(paramPath) {
+ funPath.get("params").forEach(function (paramPath) {
var param = paramPath.node;
if (t.isIdentifier(param)) {
paramNames[param.name] = param;
@@ -137,7 +127,7 @@ exports.hoist = function(funPath) {
var declarations = [];
- Object.keys(vars).forEach(function(name) {
+ _Object$keys(vars).forEach(function (name) {
if (!hasOwn.call(paramNames, name)) {
declarations.push(t.variableDeclarator(vars[name], null));
}
@@ -148,4 +138,4 @@ exports.hoist = function(funPath) {
}
return t.variableDeclaration("var", declarations);
-};
+};
\ No newline at end of file
diff --git a/packages/babel-plugin-transform-regenerator/lib/leap.js b/packages/babel-plugin-transform-regenerator/lib/leap.js
index 7f06103d5b..011e9a9ec9 100644
--- a/packages/babel-plugin-transform-regenerator/lib/leap.js
+++ b/packages/babel-plugin-transform-regenerator/lib/leap.js
@@ -8,13 +8,24 @@
* the same directory.
*/
-var assert = require("assert");
-var t = require("babel-types");
-var inherits = require("util").inherits;
-var hasOwn = Object.prototype.hasOwnProperty;
+"use strict";
+
+var _interopRequireDefault = require("babel-runtime/helpers/interop-require-default")["default"];
+
+var _interopRequireWildcard = require("babel-runtime/helpers/interop-require-wildcard")["default"];
+
+var _assert = require("assert");
+
+var _assert2 = _interopRequireDefault(_assert);
+
+var _babelTypes = require("babel-types");
+
+var t = _interopRequireWildcard(_babelTypes);
+
+var _util = require("util");
function Entry() {
- assert.ok(this instanceof Entry);
+ _assert2["default"].ok(this instanceof Entry);
}
function FunctionEntry(returnLoc) {
@@ -23,7 +34,7 @@ function FunctionEntry(returnLoc) {
this.returnLoc = returnLoc;
}
-inherits(FunctionEntry, Entry);
+_util.inherits(FunctionEntry, Entry);
exports.FunctionEntry = FunctionEntry;
function LoopEntry(breakLoc, continueLoc, label) {
@@ -43,7 +54,7 @@ function LoopEntry(breakLoc, continueLoc, label) {
this.label = label;
}
-inherits(LoopEntry, Entry);
+_util.inherits(LoopEntry, Entry);
exports.LoopEntry = LoopEntry;
function SwitchEntry(breakLoc) {
@@ -52,7 +63,7 @@ function SwitchEntry(breakLoc) {
this.breakLoc = breakLoc;
}
-inherits(SwitchEntry, Entry);
+_util.inherits(SwitchEntry, Entry);
exports.SwitchEntry = SwitchEntry;
function TryEntry(firstLoc, catchEntry, finallyEntry) {
@@ -61,26 +72,26 @@ function TryEntry(firstLoc, catchEntry, finallyEntry) {
t.assertLiteral(firstLoc);
if (catchEntry) {
- assert.ok(catchEntry instanceof CatchEntry);
+ _assert2["default"].ok(catchEntry instanceof CatchEntry);
} else {
catchEntry = null;
}
if (finallyEntry) {
- assert.ok(finallyEntry instanceof FinallyEntry);
+ _assert2["default"].ok(finallyEntry instanceof FinallyEntry);
} else {
finallyEntry = null;
}
// Have to have one or the other (or both).
- assert.ok(catchEntry || finallyEntry);
+ _assert2["default"].ok(catchEntry || finallyEntry);
this.firstLoc = firstLoc;
this.catchEntry = catchEntry;
this.finallyEntry = finallyEntry;
}
-inherits(TryEntry, Entry);
+_util.inherits(TryEntry, Entry);
exports.TryEntry = TryEntry;
function CatchEntry(firstLoc, paramId) {
@@ -93,7 +104,7 @@ function CatchEntry(firstLoc, paramId) {
this.paramId = paramId;
}
-inherits(CatchEntry, Entry);
+_util.inherits(CatchEntry, Entry);
exports.CatchEntry = CatchEntry;
function FinallyEntry(firstLoc, afterLoc) {
@@ -104,7 +115,7 @@ function FinallyEntry(firstLoc, afterLoc) {
this.afterLoc = afterLoc;
}
-inherits(FinallyEntry, Entry);
+_util.inherits(FinallyEntry, Entry);
exports.FinallyEntry = FinallyEntry;
function LabeledEntry(breakLoc, label) {
@@ -117,14 +128,14 @@ function LabeledEntry(breakLoc, label) {
this.label = label;
}
-inherits(LabeledEntry, Entry);
+_util.inherits(LabeledEntry, Entry);
exports.LabeledEntry = LabeledEntry;
function LeapManager(emitter) {
- assert.ok(this instanceof LeapManager);
+ _assert2["default"].ok(this instanceof LeapManager);
var Emitter = require("./emit").Emitter;
- assert.ok(emitter instanceof Emitter);
+ _assert2["default"].ok(emitter instanceof Emitter);
this.emitter = emitter;
this.entryStack = [new FunctionEntry(emitter.finalLoc)];
@@ -133,43 +144,42 @@ function LeapManager(emitter) {
var LMp = LeapManager.prototype;
exports.LeapManager = LeapManager;
-LMp.withEntry = function(entry, callback) {
- assert.ok(entry instanceof Entry);
+LMp.withEntry = function (entry, callback) {
+ _assert2["default"].ok(entry instanceof Entry);
this.entryStack.push(entry);
try {
callback.call(this.emitter);
} finally {
var popped = this.entryStack.pop();
- assert.strictEqual(popped, entry);
+ _assert2["default"].strictEqual(popped, entry);
}
};
-LMp._findLeapLocation = function(property, label) {
+LMp._findLeapLocation = function (property, label) {
for (var i = this.entryStack.length - 1; i >= 0; --i) {
var entry = this.entryStack[i];
var loc = entry[property];
if (loc) {
if (label) {
- if (entry.label &&
- entry.label.name === label.name) {
+ if (entry.label && entry.label.name === label.name) {
return loc;
}
} else if (entry instanceof LabeledEntry) {
// Ignore LabeledEntry entries unless we are actually breaking to
// a label.
} else {
- return loc;
- }
+ return loc;
+ }
}
}
return null;
};
-LMp.getBreakLoc = function(label) {
+LMp.getBreakLoc = function (label) {
return this._findLeapLocation("breakLoc", label);
};
-LMp.getContinueLoc = function(label) {
+LMp.getContinueLoc = function (label) {
return this._findLeapLocation("continueLoc", label);
-};
+};
\ No newline at end of file
diff --git a/packages/babel-plugin-transform-regenerator/lib/meta.js b/packages/babel-plugin-transform-regenerator/lib/meta.js
index 0d354b8607..3412dd58b4 100644
--- a/packages/babel-plugin-transform-regenerator/lib/meta.js
+++ b/packages/babel-plugin-transform-regenerator/lib/meta.js
@@ -8,9 +8,22 @@
* the same directory.
*/
-var assert = require("assert");
+"use strict";
+
+var _interopRequireDefault = require("babel-runtime/helpers/interop-require-default")["default"];
+
+var _interopRequireWildcard = require("babel-runtime/helpers/interop-require-wildcard")["default"];
+
+var _assert = require("assert");
+
+var _assert2 = _interopRequireDefault(_assert);
+
+var _babelTypes = require("babel-types");
+
+var t = _interopRequireWildcard(_babelTypes);
+
var m = require("private").makeAccessor();
-var t = require("babel-types");
+
var hasOwn = Object.prototype.hasOwnProperty;
function makePredicate(propertyName, knownTypes) {
@@ -24,11 +37,11 @@ function makePredicate(propertyName, knownTypes) {
if (result) {
// Do nothing.
} else if (Array.isArray(child)) {
- child.some(check);
- } else if (t.isNode(child)) {
- assert.strictEqual(result, false);
- result = predicate(child);
- }
+ child.some(check);
+ } else if (t.isNode(child)) {
+ _assert2["default"].strictEqual(result, false);
+ result = predicate(child);
+ }
return result;
}
@@ -48,16 +61,13 @@ function makePredicate(propertyName, knownTypes) {
t.assertNode(node);
var meta = m(node);
- if (hasOwn.call(meta, propertyName))
- return meta[propertyName];
+ if (hasOwn.call(meta, propertyName)) return meta[propertyName];
// Certain types are "opaque," which means they have no side
// effects or leaps and we don't care about their subexpressions.
- if (hasOwn.call(opaqueTypes, node.type))
- return meta[propertyName] = false;
+ if (hasOwn.call(opaqueTypes, node.type)) return meta[propertyName] = false;
- if (hasOwn.call(knownTypes, node.type))
- return meta[propertyName] = true;
+ if (hasOwn.call(knownTypes, node.type)) return meta[propertyName] = true;
return meta[propertyName] = onlyChildren(node);
}
@@ -100,4 +110,4 @@ for (var type in leapTypes) {
}
exports.hasSideEffects = makePredicate("hasSideEffects", sideEffectTypes);
-exports.containsLeap = makePredicate("containsLeap", leapTypes);
+exports.containsLeap = makePredicate("containsLeap", leapTypes);
\ No newline at end of file
diff --git a/packages/babel-plugin-transform-regenerator/lib/util.js b/packages/babel-plugin-transform-regenerator/lib/util.js
index ba3adccbfc..e5f709ab64 100644
--- a/packages/babel-plugin-transform-regenerator/lib/util.js
+++ b/packages/babel-plugin-transform-regenerator/lib/util.js
@@ -8,16 +8,22 @@
* the same directory.
*/
-var t = require("babel-types");
+"use strict";
-exports.runtimeProperty = function(name) {
- return t.memberExpression(
- t.identifier("regeneratorRuntime"),
- t.identifier(name),
- false
- );
-};
+var _interopRequireWildcard = require("babel-runtime/helpers/interop-require-wildcard")["default"];
-exports.isReference = function(path) {
+exports.__esModule = true;
+exports.runtimeProperty = runtimeProperty;
+exports.isReference = isReference;
+
+var _babelTypes = require("babel-types");
+
+var t = _interopRequireWildcard(_babelTypes);
+
+function runtimeProperty(name) {
+ return t.memberExpression(t.identifier("regeneratorRuntime"), t.identifier(name), false);
+}
+
+function isReference(path) {
return path.isReferenced() || path.parentPath.isAssignmentExpression({ left: path.node });
-};
+}
\ No newline at end of file
diff --git a/packages/babel-plugin-transform-regenerator/lib/visit.js b/packages/babel-plugin-transform-regenerator/lib/visit.js
index 0f68ffc686..73118bcdef 100644
--- a/packages/babel-plugin-transform-regenerator/lib/visit.js
+++ b/packages/babel-plugin-transform-regenerator/lib/visit.js
@@ -8,20 +8,33 @@
* the same directory.
*/
-var traverse = require("babel-traverse");
-var babylon = require("babylon");
-var assert = require("assert");
-var fs = require("fs");
-var t = require("babel-types");
-var hoist = require("./hoist").hoist;
-var Emitter = require("./emit").Emitter;
-var util = require("./util");
-var runtimeProperty = util.runtimeProperty;
+"use strict";
+
+var _interopRequireDefault = require("babel-runtime/helpers/interop-require-default")["default"];
+
+var _interopRequireWildcard = require("babel-runtime/helpers/interop-require-wildcard")["default"];
+
+var _assert = require("assert");
+
+var _assert2 = _interopRequireDefault(_assert);
+
+var _babelTypes = require("babel-types");
+
+var t = _interopRequireWildcard(_babelTypes);
+
+var _hoist = require("./hoist");
+
+var _emit = require("./emit");
+
+var _util = require("./util");
+
+var util = _interopRequireWildcard(_util);
+
var getMarkInfo = require("private").makeAccessor();
exports.visitor = {
Function: {
- exit: function(path, state) {
+ exit: function exit(path, state) {
var node = path.node;
if (node.generator) {
@@ -43,9 +56,7 @@ exports.visitor = {
if (node.expression) {
// Transform expression lambdas into normal functions.
node.expression = false;
- node.body = t.blockStatement([
- t.returnStatement(node.body)
- ]);
+ node.body = t.blockStatement([t.returnStatement(node.body)]);
}
if (node.async) {
@@ -56,7 +67,7 @@ exports.visitor = {
var outerBody = [];
var innerBody = [];
- bodyBlockPath.get("body").forEach(function(childPath) {
+ bodyBlockPath.get("body").forEach(function (childPath) {
var node = childPath.node;
if (node && node._blockHoist != null) {
outerBody.push(node);
@@ -82,41 +93,33 @@ exports.visitor = {
// Turn all declarations into vars, and replace the original
// declarations with equivalent assignment expressions.
- var vars = hoist(path);
+ var vars = _hoist.hoist(path);
var didRenameArguments = renameArguments(path, argsId);
if (didRenameArguments) {
vars = vars || t.variableDeclaration("var", []);
- vars.declarations.push(t.variableDeclarator(
- argsId, t.identifier("arguments")
- ));
+ vars.declarations.push(t.variableDeclarator(argsId, t.identifier("arguments")));
}
- var emitter = new Emitter(contextId);
+ var emitter = new _emit.Emitter(contextId);
emitter.explode(path.get("body"));
if (vars && vars.declarations.length > 0) {
outerBody.push(vars);
}
- var wrapArgs = [
- emitter.getContextFunction(innerFnId),
- // Async functions that are not generators don't care about the
- // outer function because they don't need it to be marked and don't
- // inherit from its .prototype.
- node.generator ? outerFnExpr : t.nullLiteral(),
- t.thisExpression()
- ];
+ var wrapArgs = [emitter.getContextFunction(innerFnId),
+ // Async functions that are not generators don't care about the
+ // outer function because they don't need it to be marked and don't
+ // inherit from its .prototype.
+ node.generator ? outerFnExpr : t.nullLiteral(), t.thisExpression()];
var tryLocsList = emitter.getTryLocsList();
if (tryLocsList) {
wrapArgs.push(tryLocsList);
}
- var wrapCall = t.callExpression(
- runtimeProperty(node.async ? "async" : "wrap"),
- wrapArgs
- );
+ var wrapCall = t.callExpression(util.runtimeProperty(node.async ? "async" : "wrap"), wrapArgs);
outerBody.push(t.returnStatement(wrapCall));
node.body = t.blockStatement(outerBody);
@@ -130,9 +133,8 @@ exports.visitor = {
node.async = false;
}
- if (wasGeneratorFunction &&
- t.isExpression(node)) {
- path.replaceWith(t.callExpression(runtimeProperty("mark"), [node]));
+ if (wasGeneratorFunction && t.isExpression(node)) {
+ path.replaceWith(t.callExpression(util.runtimeProperty("mark"), [node]));
}
}
}
@@ -147,7 +149,7 @@ function getOuterFnExpr(funPath) {
t.assertFunction(node);
if (node.generator && // Non-generator functions don't need to be marked.
- t.isFunctionDeclaration(node)) {
+ t.isFunctionDeclaration(node)) {
var pp = funPath.findParent(function (path) {
return path.isProgram() || path.isBlockStatement();
});
@@ -164,40 +166,22 @@ function getOuterFnExpr(funPath) {
var index = funDeclIdArray.elements.length;
funDeclIdArray.elements.push(node.id);
- return t.memberExpression(
- markedArray,
- t.numericLiteral(index),
- true
- );
+ return t.memberExpression(markedArray, t.numericLiteral(index), true);
}
- return node.id || (
- node.id = funPath.scope.parent.generateUidIdentifier("callee")
- );
+ return node.id || (node.id = funPath.scope.parent.generateUidIdentifier("callee"));
}
function getRuntimeMarkDecl(blockPath) {
var block = blockPath.node;
- assert.ok(Array.isArray(block.body));
+ _assert2["default"].ok(Array.isArray(block.body));
var info = getMarkInfo(block);
if (info.decl) {
return info.decl;
}
- info.decl = t.variableDeclaration("var", [
- t.variableDeclarator(
- blockPath.scope.generateUidIdentifier("marked"),
- t.callExpression(
- t.memberExpression(
- t.arrayExpression([]),
- t.identifier("map"),
- false
- ),
- [runtimeProperty("mark")]
- )
- )
- ]);
+ info.decl = t.variableDeclaration("var", [t.variableDeclarator(blockPath.scope.generateUidIdentifier("marked"), t.callExpression(t.memberExpression(t.arrayExpression([]), t.identifier("map"), false), [util.runtimeProperty("mark")]))]);
blockPath.unshiftContainer("body", info.decl);
@@ -220,11 +204,11 @@ function renameArguments(funcPath, argsId) {
}
var argumentsVisitor = {
- "FunctionExpression|FunctionDeclaration": function(path) {
+ "FunctionExpression|FunctionDeclaration": function FunctionExpressionFunctionDeclaration(path) {
path.skip();
},
- Identifier: function(path, state) {
+ Identifier: function Identifier(path, state) {
if (path.node.name === "arguments" && util.isReference(path)) {
path.replaceWith(state.argsId);
state.didRenameArguments = true;
@@ -233,23 +217,17 @@ var argumentsVisitor = {
};
var awaitVisitor = {
- Function: function(path) {
+ Function: function Function(path) {
path.skip(); // Don't descend into nested function scopes.
},
- AwaitExpression: function(path) {
+ AwaitExpression: function AwaitExpression(path) {
// Convert await and await* expressions to yield expressions.
var argument = path.node.argument;
// Transforming `await x` to `yield regeneratorRuntime.awrap(x)`
// causes the argument to be wrapped in such a way that the runtime
// can distinguish between awaited and merely yielded values.
- path.replaceWith(t.yieldExpression(
- t.callExpression(
- runtimeProperty("awrap"),
- [argument]
- ),
- false
- ));
+ path.replaceWith(t.yieldExpression(t.callExpression(util.runtimeProperty("awrap"), [argument]), false));
}
-};
+};
\ No newline at end of file
diff --git a/packages/babel-plugin-transform-regenerator/main.js b/packages/babel-plugin-transform-regenerator/main.js
deleted file mode 100644
index 2272f35859..0000000000
--- a/packages/babel-plugin-transform-regenerator/main.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * https://raw.github.com/facebook/regenerator/master/LICENSE file. An
- * additional grant of patent rights can be found in the PATENTS file in
- * the same directory.
- */
-
-var asyncFunctionSyntax = require("babel-plugin-syntax-async-functions");
-var blockScopingPlugin = require("babel-plugin-transform-es2015-block-scoping");
-var forOfPlugin = require("babel-plugin-transform-es2015-for-of");
-var babel = require("babel-core");
-
-var regenerator = module.exports = function() {
- return require("./lib/visit");
-};
-
-regenerator.compile = function(code, opts) {
- // todo: includeRuntime
- return babel.transform(code, buildBabelOptions(opts));
-};
-
-regenerator.transform = function (ast, opts) {
- return babel.transformFromAst(ast, null, buildBabelOptions(opts));
-};
-
-function buildBabelOptions(opts) {
- return {
- plugins: [regenerator, blockScopingPlugin, asyncFunctionSyntax, forOfPlugin],
- sourceType: "script"
- };
-}
diff --git a/packages/babel-plugin-transform-regenerator/package.json b/packages/babel-plugin-transform-regenerator/package.json
index a534c0c641..a9bacb0fb3 100644
--- a/packages/babel-plugin-transform-regenerator/package.json
+++ b/packages/babel-plugin-transform-regenerator/package.json
@@ -1,32 +1,10 @@
{
- "author": "Ben Newman ",
"name": "babel-plugin-transform-regenerator",
- "description": "Source transformer enabling ECMAScript 6 generator functions (yield) in JavaScript-of-today (ES5)",
- "keywords": [
- "generator",
- "yield",
- "coroutine",
- "rewriting",
- "transformation",
- "syntax",
- "codegen",
- "rewriting",
- "refactoring",
- "transpiler",
- "desugaring",
- "ES6"
- ],
+ "author": "Ben Newman ",
+ "description": "",
"version": "6.0.18",
"homepage": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-regenerator",
- "repository": {
- "type": "git",
- "url": "git://github.com/facebook/regenerator.git"
- },
- "main": "main.js",
- "bin": "bin/regenerator",
- "scripts": {
- "test": "node test/run.js"
- },
+ "main": "lib/index.js",
"dependencies": {
"commoner": "~0.10.3",
"babel-plugin-transform-es2015-block-scoping": "^6.0.18",
@@ -39,13 +17,5 @@
"private": "~0.1.5",
"through": "~2.3.8"
},
- "devDependencies": {
- "mocha": "~2.3.3",
- "promise": "~7.0.4",
- "semver": "~5.0.3"
- },
- "license": "BSD",
- "engines": {
- "node": ">= 0.6"
- }
+ "license": "BSD"
}
diff --git a/packages/babel-plugin-transform-regenerator/src/emit.js b/packages/babel-plugin-transform-regenerator/src/emit.js
new file mode 100644
index 0000000000..bf24a6349c
--- /dev/null
+++ b/packages/babel-plugin-transform-regenerator/src/emit.js
@@ -0,0 +1,1181 @@
+/**
+ * Copyright (c) 2014, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * https://raw.github.com/facebook/regenerator/master/LICENSE file. An
+ * additional grant of patent rights can be found in the PATENTS file in
+ * the same directory.
+ */
+
+import assert from "assert";
+import * as t from "babel-types";
+import * as leap from "./leap";
+import * as meta from "./meta";
+import * as util from "./util";
+
+let hasOwn = Object.prototype.hasOwnProperty;
+
+function Emitter(contextId) {
+ assert.ok(this instanceof Emitter);
+ t.assertIdentifier(contextId);
+
+ // Used to generate unique temporary names.
+ this.nextTempId = 0;
+
+ // In order to make sure the context object does not collide with
+ // anything in the local scope, we might have to rename it, so we
+ // refer to it symbolically instead of just assuming that it will be
+ // called "context".
+ this.contextId = contextId;
+
+ // An append-only list of Statements that grows each time this.emit is
+ // called.
+ this.listing = [];
+
+ // A sparse array whose keys correspond to locations in this.listing
+ // that have been marked as branch/jump targets.
+ this.marked = [true];
+
+ // The last location will be marked when this.getDispatchLoop is
+ // called.
+ this.finalLoc = loc();
+
+ // A list of all leap.TryEntry statements emitted.
+ this.tryEntries = [];
+
+ // Each time we evaluate the body of a loop, we tell this.leapManager
+ // to enter a nested loop context that determines the meaning of break
+ // and continue statements therein.
+ this.leapManager = new leap.LeapManager(this);
+}
+
+let Ep = Emitter.prototype;
+exports.Emitter = Emitter;
+
+// Offsets into this.listing that could be used as targets for branches or
+// jumps are represented as numeric Literal nodes. This representation has
+// the amazingly convenient benefit of allowing the exact value of the
+// location to be determined at any time, even after generating code that
+// refers to the location.
+function loc() {
+ return t.numericLiteral(-1);
+}
+
+// Sets the exact value of the given location to the offset of the next
+// Statement emitted.
+Ep.mark = function(loc) {
+ t.assertLiteral(loc);
+ let index = this.listing.length;
+ if (loc.value === -1) {
+ loc.value = index;
+ } else {
+ // Locations can be marked redundantly, but their values cannot change
+ // once set the first time.
+ assert.strictEqual(loc.value, index);
+ }
+ this.marked[index] = true;
+ return loc;
+};
+
+Ep.emit = function(node) {
+ if (t.isExpression(node))
+ node = t.expressionStatement(node);
+ t.assertStatement(node);
+ this.listing.push(node);
+};
+
+// Shorthand for emitting assignment statements. This will come in handy
+// for assignments to temporary variables.
+Ep.emitAssign = function(lhs, rhs) {
+ this.emit(this.assign(lhs, rhs));
+ return lhs;
+};
+
+// Shorthand for an assignment statement.
+Ep.assign = function(lhs, rhs) {
+ return t.expressionStatement(
+ t.assignmentExpression("=", lhs, rhs));
+};
+
+// Convenience function for generating expressions like context.next,
+// context.sent, and context.rval.
+Ep.contextProperty = function(name, computed) {
+ return t.memberExpression(
+ this.contextId,
+ computed ? t.stringLiteral(name) : t.identifier(name),
+ !!computed
+ );
+};
+
+// Shorthand for setting context.rval and jumping to `context.stop()`.
+Ep.stop = function(rval) {
+ if (rval) {
+ this.setReturnValue(rval);
+ }
+
+ this.jump(this.finalLoc);
+};
+
+Ep.setReturnValue = function(valuePath) {
+ t.assertExpression(valuePath.value);
+
+ this.emitAssign(
+ this.contextProperty("rval"),
+ this.explodeExpression(valuePath)
+ );
+};
+
+Ep.clearPendingException = function(tryLoc, assignee) {
+ t.assertLiteral(tryLoc);
+
+ let catchCall = t.callExpression(
+ this.contextProperty("catch", true),
+ [tryLoc]
+ );
+
+ if (assignee) {
+ this.emitAssign(assignee, catchCall);
+ } else {
+ this.emit(catchCall);
+ }
+};
+
+// Emits code for an unconditional jump to the given location, even if the
+// exact value of the location is not yet known.
+Ep.jump = function(toLoc) {
+ this.emitAssign(this.contextProperty("next"), toLoc);
+ this.emit(t.breakStatement());
+};
+
+// Conditional jump.
+Ep.jumpIf = function(test, toLoc) {
+ t.assertExpression(test);
+ t.assertLiteral(toLoc);
+
+ this.emit(t.ifStatement(
+ test,
+ t.blockStatement([
+ this.assign(this.contextProperty("next"), toLoc),
+ t.breakStatement()
+ ])
+ ));
+};
+
+// Conditional jump, with the condition negated.
+Ep.jumpIfNot = function(test, toLoc) {
+ t.assertExpression(test);
+ t.assertLiteral(toLoc);
+
+ let negatedTest;
+ if (t.isUnaryExpression(test) &&
+ test.operator === "!") {
+ // Avoid double negation.
+ negatedTest = test.argument;
+ } else {
+ negatedTest = t.unaryExpression("!", test);
+ }
+
+ this.emit(t.ifStatement(
+ negatedTest,
+ t.blockStatement([
+ this.assign(this.contextProperty("next"), toLoc),
+ t.breakStatement()
+ ])
+ ));
+};
+
+// Returns a unique MemberExpression that can be used to store and
+// retrieve temporary values. Since the object of the member expression is
+// the context object, which is presumed to coexist peacefully with all
+// other local variables, and since we just increment `nextTempId`
+// monotonically, uniqueness is assured.
+Ep.makeTempVar = function() {
+ return this.contextProperty("t" + this.nextTempId++);
+};
+
+Ep.getContextFunction = function(id) {
+ return t.functionExpression(
+ id || null/*Anonymous*/,
+ [this.contextId],
+ t.blockStatement([this.getDispatchLoop()]),
+ false, // Not a generator anymore!
+ false // Nor an expression.
+ );
+};
+
+// Turns this.listing into a loop of the form
+//
+// while (1) switch (context.next) {
+// case 0:
+// ...
+// case n:
+// return context.stop();
+// }
+//
+// Each marked location in this.listing will correspond to one generated
+// case statement.
+Ep.getDispatchLoop = function() {
+ let self = this;
+ let cases = [];
+ let current;
+
+ // If we encounter a break, continue, or return statement in a switch
+ // case, we can skip the rest of the statements until the next case.
+ let alreadyEnded = false;
+
+ self.listing.forEach(function(stmt, i) {
+ if (self.marked.hasOwnProperty(i)) {
+ cases.push(t.switchCase(
+ t.numericLiteral(i),
+ current = []));
+ alreadyEnded = false;
+ }
+
+ if (!alreadyEnded) {
+ current.push(stmt);
+ if (t.isCompletionStatement(stmt))
+ alreadyEnded = true;
+ }
+ });
+
+ // Now that we know how many statements there will be in this.listing,
+ // we can finally resolve this.finalLoc.value.
+ this.finalLoc.value = this.listing.length;
+
+ cases.push(
+ t.switchCase(this.finalLoc, [
+ // Intentionally fall through to the "end" case...
+ ]),
+
+ // So that the runtime can jump to the final location without having
+ // to know its offset, we provide the "end" case as a synonym.
+ t.switchCase(t.stringLiteral("end"), [
+ // This will check/clear both context.thrown and context.rval.
+ t.returnStatement(
+ t.callExpression(this.contextProperty("stop"), [])
+ )
+ ])
+ );
+
+ return t.whileStatement(
+ t.numericLiteral(1),
+ t.switchStatement(
+ t.assignmentExpression(
+ "=",
+ this.contextProperty("prev"),
+ this.contextProperty("next")
+ ),
+ cases
+ )
+ );
+};
+
+Ep.getTryLocsList = function() {
+ if (this.tryEntries.length === 0) {
+ // To avoid adding a needless [] to the majority of runtime.wrap
+ // argument lists, force the caller to handle this case specially.
+ return null;
+ }
+
+ let lastLocValue = 0;
+
+ return t.arrayExpression(
+ this.tryEntries.map(function(tryEntry) {
+ let thisLocValue = tryEntry.firstLoc.value;
+ assert.ok(thisLocValue >= lastLocValue, "try entries out of order");
+ lastLocValue = thisLocValue;
+
+ let ce = tryEntry.catchEntry;
+ let fe = tryEntry.finallyEntry;
+
+ let locs = [
+ tryEntry.firstLoc,
+ // The null here makes a hole in the array.
+ ce ? ce.firstLoc : null
+ ];
+
+ if (fe) {
+ locs[2] = fe.firstLoc;
+ locs[3] = fe.afterLoc;
+ }
+
+ return t.arrayExpression(locs);
+ })
+ );
+};
+
+// All side effects must be realized in order.
+
+// If any subexpression harbors a leap, all subexpressions must be
+// neutered of side effects.
+
+// No destructive modification of AST nodes.
+
+Ep.explode = function(path, ignoreResult) {
+ let node = path.node;
+ let self = this;
+
+ t.assertNode(node);
+
+ if (t.isDeclaration(node))
+ throw getDeclError(node);
+
+ if (t.isStatement(node))
+ return self.explodeStatement(path);
+
+ if (t.isExpression(node))
+ return self.explodeExpression(path, ignoreResult);
+
+ switch (node.type) {
+ case "Program":
+ return path.get("body").map(
+ self.explodeStatement,
+ self
+ );
+
+ case "VariableDeclarator":
+ throw getDeclError(node);
+
+ // These node types should be handled by their parent nodes
+ // (ObjectExpression, SwitchStatement, and TryStatement, respectively).
+ case "Property":
+ case "SwitchCase":
+ case "CatchClause":
+ throw new Error(
+ node.type + " nodes should be handled by their parents");
+
+ default:
+ throw new Error(
+ "unknown Node of type " +
+ JSON.stringify(node.type));
+ }
+};
+
+function getDeclError(node) {
+ return new Error(
+ "all declarations should have been transformed into " +
+ "assignments before the Exploder began its work: " +
+ JSON.stringify(node));
+}
+
+Ep.explodeStatement = function(path, labelId) {
+ let stmt = path.node;
+ let self = this;
+ let before, after, head;
+
+ t.assertStatement(stmt);
+
+ if (labelId) {
+ t.assertIdentifier(labelId);
+ } else {
+ labelId = null;
+ }
+
+ // Explode BlockStatement nodes even if they do not contain a yield,
+ // because we don't want or need the curly braces.
+ if (t.isBlockStatement(stmt)) {
+ path.get("body").forEach(function (path) {
+ self.explodeStatement(path);
+ });
+ return;
+ }
+
+ if (!meta.containsLeap(stmt)) {
+ // Technically we should be able to avoid emitting the statement
+ // altogether if !meta.hasSideEffects(stmt), but that leads to
+ // confusing generated code (for instance, `while (true) {}` just
+ // disappears) and is probably a more appropriate job for a dedicated
+ // dead code elimination pass.
+ self.emit(stmt);
+ return;
+ }
+
+ switch (stmt.type) {
+ case "ExpressionStatement":
+ self.explodeExpression(path.get("expression"), true);
+ break;
+
+ case "LabeledStatement":
+ after = loc();
+
+ // Did you know you can break from any labeled block statement or
+ // control structure? Well, you can! Note: when a labeled loop is
+ // encountered, the leap.LabeledEntry created here will immediately
+ // enclose a leap.LoopEntry on the leap manager's stack, and both
+ // entries will have the same label. Though this works just fine, it
+ // may seem a bit redundant. In theory, we could check here to
+ // determine if stmt knows how to handle its own label; for example,
+ // stmt happens to be a WhileStatement and so we know it's going to
+ // establish its own LoopEntry when we explode it (below). Then this
+ // LabeledEntry would be unnecessary. Alternatively, we might be
+ // tempted not to pass stmt.label down into self.explodeStatement,
+ // because we've handled the label here, but that's a mistake because
+ // labeled loops may contain labeled continue statements, which is not
+ // something we can handle in this generic case. All in all, I think a
+ // little redundancy greatly simplifies the logic of this case, since
+ // it's clear that we handle all possible LabeledStatements correctly
+ // here, regardless of whether they interact with the leap manager
+ // themselves. Also remember that labels and break/continue-to-label
+ // statements are rare, and all of this logic happens at transform
+ // time, so it has no additional runtime cost.
+ self.leapManager.withEntry(
+ new leap.LabeledEntry(after, stmt.label),
+ function() {
+ self.explodeStatement(path.get("body"), stmt.label);
+ }
+ );
+
+ self.mark(after);
+
+ break;
+
+ case "WhileStatement":
+ before = loc();
+ after = loc();
+
+ self.mark(before);
+ self.jumpIfNot(self.explodeExpression(path.get("test")), after);
+ self.leapManager.withEntry(
+ new leap.LoopEntry(after, before, labelId),
+ function() { self.explodeStatement(path.get("body")); }
+ );
+ self.jump(before);
+ self.mark(after);
+
+ break;
+
+ case "DoWhileStatement":
+ let first = loc();
+ let test = loc();
+ after = loc();
+
+ self.mark(first);
+ self.leapManager.withEntry(
+ new leap.LoopEntry(after, test, labelId),
+ function() { self.explode(path.get("body")); }
+ );
+ self.mark(test);
+ self.jumpIf(self.explodeExpression(path.get("test")), first);
+ self.mark(after);
+
+ break;
+
+ case "ForStatement":
+ head = loc();
+ let update = loc();
+ after = loc();
+
+ if (stmt.init) {
+ // We pass true here to indicate that if stmt.init is an expression
+ // then we do not care about its result.
+ self.explode(path.get("init"), true);
+ }
+
+ self.mark(head);
+
+ if (stmt.test) {
+ self.jumpIfNot(self.explodeExpression(path.get("test")), after);
+ } else {
+ // No test means continue unconditionally.
+ }
+
+ self.leapManager.withEntry(
+ new leap.LoopEntry(after, update, labelId),
+ function() { self.explodeStatement(path.get("body")); }
+ );
+
+ self.mark(update);
+
+ if (stmt.update) {
+ // We pass true here to indicate that if stmt.update is an
+ // expression then we do not care about its result.
+ self.explode(path.get("update"), true);
+ }
+
+ self.jump(head);
+
+ self.mark(after);
+
+ break;
+
+ case "TypeCastExpression":
+ return self.explodeExpression(path.get("expression"));
+
+ case "ForInStatement":
+ head = loc();
+ after = loc();
+
+ let keyIterNextFn = self.makeTempVar();
+ self.emitAssign(
+ keyIterNextFn,
+ t.callExpression(
+ util.runtimeProperty("keys"),
+ [self.explodeExpression(path.get("right"))]
+ )
+ );
+
+ self.mark(head);
+
+ let keyInfoTmpVar = self.makeTempVar();
+ self.jumpIf(
+ t.memberExpression(
+ t.assignmentExpression(
+ "=",
+ keyInfoTmpVar,
+ t.callExpression(keyIterNextFn, [])
+ ),
+ t.identifier("done"),
+ false
+ ),
+ after
+ );
+
+ self.emitAssign(
+ stmt.left,
+ t.memberExpression(
+ keyInfoTmpVar,
+ t.identifier("value"),
+ false
+ )
+ );
+
+ self.leapManager.withEntry(
+ new leap.LoopEntry(after, head, labelId),
+ function() { self.explodeStatement(path.get("body")); }
+ );
+
+ self.jump(head);
+
+ self.mark(after);
+
+ break;
+
+ case "BreakStatement":
+ self.emitAbruptCompletion({
+ type: "break",
+ target: self.leapManager.getBreakLoc(stmt.label)
+ });
+
+ break;
+
+ case "ContinueStatement":
+ self.emitAbruptCompletion({
+ type: "continue",
+ target: self.leapManager.getContinueLoc(stmt.label)
+ });
+
+ break;
+
+ case "SwitchStatement":
+ // Always save the discriminant into a temporary variable in case the
+ // test expressions overwrite values like context.sent.
+ let disc = self.emitAssign(
+ self.makeTempVar(),
+ self.explodeExpression(path.get("discriminant"))
+ );
+
+ after = loc();
+ let defaultLoc = loc();
+ let condition = defaultLoc;
+ let caseLocs = [];
+
+ // If there are no cases, .cases might be undefined.
+ let cases = stmt.cases || [];
+
+ for (let i = cases.length - 1; i >= 0; --i) {
+ let c = cases[i];
+ t.assertSwitchCase(c);
+
+ if (c.test) {
+ condition = t.conditionalExpression(
+ t.binaryExpression("===", disc, c.test),
+ caseLocs[i] = loc(),
+ condition
+ );
+ } else {
+ caseLocs[i] = defaultLoc;
+ }
+ }
+
+ let discriminant = path.get("discriminant");
+ discriminant.replaceWith(condition);
+ self.jump(self.explodeExpression(discriminant));
+
+ self.leapManager.withEntry(
+ new leap.SwitchEntry(after),
+ function() {
+ path.get("cases").forEach(function(casePath) {
+ let i = casePath.key;
+ self.mark(caseLocs[i]);
+
+ casePath.get("consequent").forEach(function (path) {
+ self.explodeStatement(path);
+ });
+ });
+ }
+ );
+
+ self.mark(after);
+ if (defaultLoc.value === -1) {
+ self.mark(defaultLoc);
+ assert.strictEqual(after.value, defaultLoc.value);
+ }
+
+ break;
+
+ case "IfStatement":
+ let elseLoc = stmt.alternate && loc();
+ after = loc();
+
+ self.jumpIfNot(
+ self.explodeExpression(path.get("test")),
+ elseLoc || after
+ );
+
+ self.explodeStatement(path.get("consequent"));
+
+ if (elseLoc) {
+ self.jump(after);
+ self.mark(elseLoc);
+ self.explodeStatement(path.get("alternate"));
+ }
+
+ self.mark(after);
+
+ break;
+
+ case "ReturnStatement":
+ self.emitAbruptCompletion({
+ type: "return",
+ value: self.explodeExpression(path.get("argument"))
+ });
+
+ break;
+
+ case "WithStatement":
+ throw new Error("WithStatement not supported in generator functions.");
+
+ case "TryStatement":
+ after = loc();
+
+ let handler = stmt.handler;
+
+ let catchLoc = handler && loc();
+ let catchEntry = catchLoc && new leap.CatchEntry(
+ catchLoc,
+ handler.param
+ );
+
+ let finallyLoc = stmt.finalizer && loc();
+ let finallyEntry = finallyLoc &&
+ new leap.FinallyEntry(finallyLoc, after);
+
+ let tryEntry = new leap.TryEntry(
+ self.getUnmarkedCurrentLoc(),
+ catchEntry,
+ finallyEntry
+ );
+
+ self.tryEntries.push(tryEntry);
+ self.updateContextPrevLoc(tryEntry.firstLoc);
+
+ self.leapManager.withEntry(tryEntry, function() {
+ self.explodeStatement(path.get("block"));
+
+ if (catchLoc) {
+ if (finallyLoc) {
+ // If we have both a catch block and a finally block, then
+ // because we emit the catch block first, we need to jump over
+ // it to the finally block.
+ self.jump(finallyLoc);
+
+ } else {
+ // If there is no finally block, then we need to jump over the
+ // catch block to the fall-through location.
+ self.jump(after);
+ }
+
+ self.updateContextPrevLoc(self.mark(catchLoc));
+
+ let bodyPath = path.get("handler.body");
+ let safeParam = self.makeTempVar();
+ self.clearPendingException(tryEntry.firstLoc, safeParam);
+
+ bodyPath.traverse(catchParamVisitor, {
+ safeParam: safeParam,
+ catchParamName: handler.param.name
+ });
+
+ self.leapManager.withEntry(catchEntry, function() {
+ self.explodeStatement(bodyPath);
+ });
+ }
+
+ if (finallyLoc) {
+ self.updateContextPrevLoc(self.mark(finallyLoc));
+
+ self.leapManager.withEntry(finallyEntry, function() {
+ self.explodeStatement(path.get("finalizer"));
+ });
+
+ self.emit(t.returnStatement(t.callExpression(
+ self.contextProperty("finish"),
+ [finallyEntry.firstLoc]
+ )));
+ }
+ });
+
+ self.mark(after);
+
+ break;
+
+ case "ThrowStatement":
+ self.emit(t.throwStatement(
+ self.explodeExpression(path.get("argument"))
+ ));
+
+ break;
+
+ default:
+ throw new Error(
+ "unknown Statement of type " +
+ JSON.stringify(stmt.type));
+ }
+};
+
+let catchParamVisitor = {
+ Identifier: function(path, state) {
+ if (path.node.name === state.catchParamName && util.isReference(path)) {
+ path.replaceWith(state.safeParam);
+ }
+ },
+
+ Scope: function(path, state) {
+ if (path.scope.hasOwnBinding(state.catchParamName)) {
+ // Don't descend into nested scopes that shadow the catch
+ // parameter with their own declarations.
+ path.skip();
+ }
+ }
+};
+
+Ep.emitAbruptCompletion = function(record) {
+ if (!isValidCompletion(record)) {
+ assert.ok(
+ false,
+ "invalid completion record: " +
+ JSON.stringify(record)
+ );
+ }
+
+ assert.notStrictEqual(
+ record.type, "normal",
+ "normal completions are not abrupt"
+ );
+
+ let abruptArgs = [t.stringLiteral(record.type)];
+
+ if (record.type === "break" ||
+ record.type === "continue") {
+ t.assertLiteral(record.target);
+ abruptArgs[1] = record.target;
+ } else if (record.type === "return" ||
+ record.type === "throw") {
+ if (record.value) {
+ t.assertExpression(record.value);
+ abruptArgs[1] = record.value;
+ }
+ }
+
+ this.emit(
+ t.returnStatement(
+ t.callExpression(
+ this.contextProperty("abrupt"),
+ abruptArgs
+ )
+ )
+ );
+};
+
+function isValidCompletion(record) {
+ let type = record.type;
+
+ if (type === "normal") {
+ return !hasOwn.call(record, "target");
+ }
+
+ if (type === "break" ||
+ type === "continue") {
+ return !hasOwn.call(record, "value")
+ && t.isLiteral(record.target);
+ }
+
+ if (type === "return" ||
+ type === "throw") {
+ return hasOwn.call(record, "value")
+ && !hasOwn.call(record, "target");
+ }
+
+ return false;
+}
+
+
+// Not all offsets into emitter.listing are potential jump targets. For
+// example, execution typically falls into the beginning of a try block
+// without jumping directly there. This method returns the current offset
+// without marking it, so that a switch case will not necessarily be
+// generated for this offset (I say "not necessarily" because the same
+// location might end up being marked in the process of emitting other
+// statements). There's no logical harm in marking such locations as jump
+// targets, but minimizing the number of switch cases keeps the generated
+// code shorter.
+Ep.getUnmarkedCurrentLoc = function() {
+ return t.numericLiteral(this.listing.length);
+};
+
+// The context.prev property takes the value of context.next whenever we
+// evaluate the switch statement discriminant, which is generally good
+// enough for tracking the last location we jumped to, but sometimes
+// context.prev needs to be more precise, such as when we fall
+// successfully out of a try block and into a finally block without
+// jumping. This method exists to update context.prev to the freshest
+// available location. If we were implementing a full interpreter, we
+// would know the location of the current instruction with complete
+// precision at all times, but we don't have that luxury here, as it would
+// be costly and verbose to set context.prev before every statement.
+Ep.updateContextPrevLoc = function(loc) {
+ if (loc) {
+ t.assertLiteral(loc);
+
+ if (loc.value === -1) {
+ // If an uninitialized location literal was passed in, set its value
+ // to the current this.listing.length.
+ loc.value = this.listing.length;
+ } else {
+ // Otherwise assert that the location matches the current offset.
+ assert.strictEqual(loc.value, this.listing.length);
+ }
+
+ } else {
+ loc = this.getUnmarkedCurrentLoc();
+ }
+
+ // Make sure context.prev is up to date in case we fell into this try
+ // statement without jumping to it. TODO Consider avoiding this
+ // assignment when we know control must have jumped here.
+ this.emitAssign(this.contextProperty("prev"), loc);
+};
+
+Ep.explodeExpression = function(path, ignoreResult) {
+ let expr = path.node;
+ if (expr) {
+ t.assertExpression(expr);
+ } else {
+ return expr;
+ }
+
+ let self = this;
+ let result; // Used optionally by several cases below.
+
+ function finish(expr) {
+ t.assertExpression(expr);
+ if (ignoreResult) {
+ self.emit(expr);
+ } else {
+ return expr;
+ }
+ }
+
+ // If the expression does not contain a leap, then we either emit the
+ // expression as a standalone statement or return it whole.
+ if (!meta.containsLeap(expr)) {
+ return finish(expr);
+ }
+
+ // If any child contains a leap (such as a yield or labeled continue or
+ // break statement), then any sibling subexpressions will almost
+ // certainly have to be exploded in order to maintain the order of their
+ // side effects relative to the leaping child(ren).
+ let hasLeapingChildren = meta.containsLeap.onlyChildren(expr);
+
+ // In order to save the rest of explodeExpression from a combinatorial
+ // trainwreck of special cases, explodeViaTempVar is responsible for
+ // deciding when a subexpression needs to be "exploded," which is my
+ // very technical term for emitting the subexpression as an assignment
+ // to a temporary variable and the substituting the temporary variable
+ // for the original subexpression. Think of exploded view diagrams, not
+ // Michael Bay movies. The point of exploding subexpressions is to
+ // control the precise order in which the generated code realizes the
+ // side effects of those subexpressions.
+ function explodeViaTempVar(tempVar, childPath, ignoreChildResult) {
+ assert.ok(
+ !ignoreChildResult || !tempVar,
+ "Ignoring the result of a child expression but forcing it to " +
+ "be assigned to a temporary variable?"
+ );
+
+ let result = self.explodeExpression(childPath, ignoreChildResult);
+
+ if (ignoreChildResult) {
+ // Side effects already emitted above.
+
+ } else if (tempVar || (hasLeapingChildren &&
+ !t.isLiteral(result))) {
+ // If tempVar was provided, then the result will always be assigned
+ // to it, even if the result does not otherwise need to be assigned
+ // to a temporary variable. When no tempVar is provided, we have
+ // the flexibility to decide whether a temporary variable is really
+ // necessary. Unfortunately, in general, a temporary variable is
+ // required whenever any child contains a yield expression, since it
+ // is difficult to prove (at all, let alone efficiently) whether
+ // this result would evaluate to the same value before and after the
+ // yield (see #206). One narrow case where we can prove it doesn't
+ // matter (and thus we do not need a temporary variable) is when the
+ // result in question is a Literal value.
+ result = self.emitAssign(
+ tempVar || self.makeTempVar(),
+ result
+ );
+ }
+ return result;
+ }
+
+ // If ignoreResult is true, then we must take full responsibility for
+ // emitting the expression with all its side effects, and we should not
+ // return a result.
+
+ switch (expr.type) {
+ case "MemberExpression":
+ return finish(t.memberExpression(
+ self.explodeExpression(path.get("object")),
+ expr.computed
+ ? explodeViaTempVar(null, path.get("property"))
+ : expr.property,
+ expr.computed
+ ));
+
+ case "CallExpression":
+ let calleePath = path.get("callee");
+ let argsPath = path.get("arguments");
+
+ let newCallee;
+ let newArgs = [];
+
+ let hasLeapingArgs = false;
+ argsPath.forEach(function(argPath) {
+ hasLeapingArgs = hasLeapingArgs ||
+ meta.containsLeap(argPath.node);
+ });
+
+ if (t.isMemberExpression(calleePath.node)) {
+ if (hasLeapingArgs) {
+ // If the arguments of the CallExpression contained any yield
+ // expressions, then we need to be sure to evaluate the callee
+ // before evaluating the arguments, but if the callee was a member
+ // expression, then we must be careful that the object of the
+ // member expression still gets bound to `this` for the call.
+
+ let newObject = explodeViaTempVar(
+ // Assign the exploded callee.object expression to a temporary
+ // variable so that we can use it twice without reevaluating it.
+ self.makeTempVar(),
+ calleePath.get("object")
+ );
+
+ let newProperty = calleePath.node.computed
+ ? explodeViaTempVar(null, calleePath.get("property"))
+ : calleePath.node.property;
+
+ newArgs.unshift(newObject);
+
+ newCallee = t.memberExpression(
+ t.memberExpression(
+ newObject,
+ newProperty,
+ calleePath.node.computed
+ ),
+ t.identifier("call"),
+ false
+ );
+
+ } else {
+ newCallee = self.explodeExpression(calleePath);
+ }
+
+ } else {
+ newCallee = self.explodeExpression(calleePath);
+
+ if (t.isMemberExpression(newCallee)) {
+ // If the callee was not previously a MemberExpression, then the
+ // CallExpression was "unqualified," meaning its `this` object
+ // should be the global object. If the exploded expression has
+ // become a MemberExpression (e.g. a context property, probably a
+ // temporary variable), then we need to force it to be unqualified
+ // by using the (0, object.property)(...) trick; otherwise, it
+ // will receive the object of the MemberExpression as its `this`
+ // object.
+ newCallee = t.sequenceExpression([
+ t.numericLiteral(0),
+ newCallee
+ ]);
+ }
+ }
+
+ argsPath.forEach(function(argPath) {
+ newArgs.push(explodeViaTempVar(null, argPath));
+ });
+
+ return finish(t.callExpression(
+ newCallee,
+ newArgs
+ ));
+
+ case "NewExpression":
+ return finish(t.newExpression(
+ explodeViaTempVar(null, path.get("callee")),
+ path.get("arguments").map(function(argPath) {
+ return explodeViaTempVar(null, argPath);
+ })
+ ));
+
+ case "ObjectExpression":
+ return finish(t.objectExpression(
+ path.get("properties").map(function(propPath) {
+ if (propPath.isObjectProperty()) {
+ return t.objectProperty(
+ propPath.node.key,
+ explodeViaTempVar(null, propPath.get("value")),
+ propPath.node.computed
+ );
+ } else {
+ return propPath.node;
+ }
+ })
+ ));
+
+ case "ArrayExpression":
+ return finish(t.arrayExpression(
+ path.get("elements").map(function(elemPath) {
+ return explodeViaTempVar(null, elemPath);
+ })
+ ));
+
+ case "SequenceExpression":
+ let lastIndex = expr.expressions.length - 1;
+
+ path.get("expressions").forEach(function(exprPath) {
+ if (exprPath.key === lastIndex) {
+ result = self.explodeExpression(exprPath, ignoreResult);
+ } else {
+ self.explodeExpression(exprPath, true);
+ }
+ });
+
+ return result;
+
+ case "LogicalExpression":
+ after = loc();
+
+ if (!ignoreResult) {
+ result = self.makeTempVar();
+ }
+
+ let left = explodeViaTempVar(result, path.get("left"));
+
+ if (expr.operator === "&&") {
+ self.jumpIfNot(left, after);
+ } else {
+ assert.strictEqual(expr.operator, "||");
+ self.jumpIf(left, after);
+ }
+
+ explodeViaTempVar(result, path.get("right"), ignoreResult);
+
+ self.mark(after);
+
+ return result;
+
+ case "ConditionalExpression":
+ let elseLoc = loc();
+ after = loc();
+ let test = self.explodeExpression(path.get("test"));
+
+ self.jumpIfNot(test, elseLoc);
+
+ if (!ignoreResult) {
+ result = self.makeTempVar();
+ }
+
+ explodeViaTempVar(result, path.get("consequent"), ignoreResult);
+ self.jump(after);
+
+ self.mark(elseLoc);
+ explodeViaTempVar(result, path.get("alternate"), ignoreResult);
+
+ self.mark(after);
+
+ return result;
+
+ case "UnaryExpression":
+ return finish(t.unaryExpression(
+ expr.operator,
+ // Can't (and don't need to) break up the syntax of the argument.
+ // Think about delete a[b].
+ self.explodeExpression(path.get("argument")),
+ !!expr.prefix
+ ));
+
+ case "BinaryExpression":
+ return finish(t.binaryExpression(
+ expr.operator,
+ explodeViaTempVar(null, path.get("left")),
+ explodeViaTempVar(null, path.get("right"))
+ ));
+
+ case "AssignmentExpression":
+ return finish(t.assignmentExpression(
+ expr.operator,
+ self.explodeExpression(path.get("left")),
+ self.explodeExpression(path.get("right"))
+ ));
+
+ case "UpdateExpression":
+ return finish(t.updateExpression(
+ expr.operator,
+ self.explodeExpression(path.get("argument")),
+ expr.prefix
+ ));
+
+ case "YieldExpression":
+ after = loc();
+ let arg = expr.argument && self.explodeExpression(path.get("argument"));
+
+ if (arg && expr.delegate) {
+ let result = self.makeTempVar();
+
+ self.emit(t.returnStatement(t.callExpression(
+ self.contextProperty("delegateYield"), [
+ arg,
+ t.stringLiteral(result.property.name),
+ after
+ ]
+ )));
+
+ self.mark(after);
+
+ return result;
+ }
+
+ self.emitAssign(self.contextProperty("next"), after);
+ self.emit(t.returnStatement(arg || null));
+ self.mark(after);
+
+ return self.contextProperty("sent");
+
+ default:
+ throw new Error(
+ "unknown Expression of type " +
+ JSON.stringify(expr.type));
+ }
+};
diff --git a/packages/babel-plugin-transform-regenerator/src/hoist.js b/packages/babel-plugin-transform-regenerator/src/hoist.js
new file mode 100644
index 0000000000..222b0c651d
--- /dev/null
+++ b/packages/babel-plugin-transform-regenerator/src/hoist.js
@@ -0,0 +1,148 @@
+/**
+ * Copyright (c) 2014, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * https://raw.github.com/facebook/regenerator/master/LICENSE file. An
+ * additional grant of patent rights can be found in the PATENTS file in
+ * the same directory.
+ */
+
+import * as t from "babel-types";
+let hasOwn = Object.prototype.hasOwnProperty;
+
+// The hoist function takes a FunctionExpression or FunctionDeclaration
+// and replaces any Declaration nodes in its body with assignments, then
+// returns a VariableDeclaration containing just the names of the removed
+// declarations.
+exports.hoist = function(funPath) {
+ t.assertFunction(funPath.node);
+
+ let vars = {};
+
+ function varDeclToExpr(vdec, includeIdentifiers) {
+ t.assertVariableDeclaration(vdec);
+ // TODO assert.equal(vdec.kind, "var");
+ let exprs = [];
+
+ vdec.declarations.forEach(function(dec) {
+ vars[dec.id.name] = dec.id;
+
+ if (dec.init) {
+ exprs.push(t.assignmentExpression(
+ "=", dec.id, dec.init
+ ));
+ } else if (includeIdentifiers) {
+ exprs.push(dec.id);
+ }
+ });
+
+ if (exprs.length === 0)
+ return null;
+
+ if (exprs.length === 1)
+ return exprs[0];
+
+ return t.sequenceExpression(exprs);
+ }
+
+ funPath.get("body").traverse({
+ VariableDeclaration: {
+ exit: function(path) {
+ let expr = varDeclToExpr(path.node, false);
+ if (expr === null) {
+ path.remove();
+ } else {
+ // We don't need to traverse this expression any further because
+ // there can't be any new declarations inside an expression.
+ path.replaceWith(t.expressionStatement(expr));
+ }
+
+ // Since the original node has been either removed or replaced,
+ // avoid traversing it any further.
+ path.skip();
+ }
+ },
+
+ ForStatement: function(path) {
+ let init = path.node.init;
+ if (t.isVariableDeclaration(init)) {
+ path.get("init").replaceWith(varDeclToExpr(init, false));
+ }
+ },
+
+ ForXStatement: function(path) {
+ let left = path.get("left");
+ if (left.isVariableDeclaration()) {
+ left.replaceWith(varDeclToExpr(left.node, true));
+ }
+ },
+
+ FunctionDeclaration: function(path) {
+ let node = path.node;
+ vars[node.id.name] = node.id;
+
+ let assignment = t.expressionStatement(
+ t.assignmentExpression(
+ "=",
+ node.id,
+ t.functionExpression(
+ node.id,
+ node.params,
+ node.body,
+ node.generator,
+ node.expression
+ )
+ )
+ );
+
+ if (path.parentPath.isBlockStatement()) {
+ // Insert the assignment form before the first statement in the
+ // enclosing block.
+ path.parentPath.unshiftContainer("body", assignment);
+
+ // Remove the function declaration now that we've inserted the
+ // equivalent assignment form at the beginning of the block.
+ path.remove();
+ } else {
+ // If the parent node is not a block statement, then we can just
+ // replace the declaration with the equivalent assignment form
+ // without worrying about hoisting it.
+ path.replaceWith(assignment);
+ }
+
+ // Don't hoist variables out of inner functions.
+ path.skip();
+ },
+
+ FunctionExpression: function(path) {
+ // Don't descend into nested function expressions.
+ path.skip();
+ }
+ });
+
+ let paramNames = {};
+ funPath.get("params").forEach(function(paramPath) {
+ let param = paramPath.node;
+ if (t.isIdentifier(param)) {
+ paramNames[param.name] = param;
+ } else {
+ // Variables declared by destructuring parameter patterns will be
+ // harmlessly re-declared.
+ }
+ });
+
+ let declarations = [];
+
+ Object.keys(vars).forEach(function(name) {
+ if (!hasOwn.call(paramNames, name)) {
+ declarations.push(t.variableDeclarator(vars[name], null));
+ }
+ });
+
+ if (declarations.length === 0) {
+ return null; // Be sure to handle this case!
+ }
+
+ return t.variableDeclaration("var", declarations);
+};
diff --git a/packages/babel-plugin-transform-regenerator/src/index.js b/packages/babel-plugin-transform-regenerator/src/index.js
new file mode 100644
index 0000000000..34fea7a15a
--- /dev/null
+++ b/packages/babel-plugin-transform-regenerator/src/index.js
@@ -0,0 +1,13 @@
+/**
+ * Copyright (c) 2014, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * https://raw.github.com/facebook/regenerator/master/LICENSE file. An
+ * additional grant of patent rights can be found in the PATENTS file in
+ * the same directory.
+ */
+
+export default function () {
+ return require("./visit");
+}
diff --git a/packages/babel-plugin-transform-regenerator/src/leap.js b/packages/babel-plugin-transform-regenerator/src/leap.js
new file mode 100644
index 0000000000..047a2bf263
--- /dev/null
+++ b/packages/babel-plugin-transform-regenerator/src/leap.js
@@ -0,0 +1,174 @@
+/**
+ * Copyright (c) 2014, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * https://raw.github.com/facebook/regenerator/master/LICENSE file. An
+ * additional grant of patent rights can be found in the PATENTS file in
+ * the same directory.
+ */
+
+import assert from "assert";
+import * as t from "babel-types";
+import { inherits } from "util";
+
+function Entry() {
+ assert.ok(this instanceof Entry);
+}
+
+function FunctionEntry(returnLoc) {
+ Entry.call(this);
+ t.assertLiteral(returnLoc);
+ this.returnLoc = returnLoc;
+}
+
+inherits(FunctionEntry, Entry);
+exports.FunctionEntry = FunctionEntry;
+
+function LoopEntry(breakLoc, continueLoc, label) {
+ Entry.call(this);
+
+ t.assertLiteral(breakLoc);
+ t.assertLiteral(continueLoc);
+
+ if (label) {
+ t.assertIdentifier(label);
+ } else {
+ label = null;
+ }
+
+ this.breakLoc = breakLoc;
+ this.continueLoc = continueLoc;
+ this.label = label;
+}
+
+inherits(LoopEntry, Entry);
+exports.LoopEntry = LoopEntry;
+
+function SwitchEntry(breakLoc) {
+ Entry.call(this);
+ t.assertLiteral(breakLoc);
+ this.breakLoc = breakLoc;
+}
+
+inherits(SwitchEntry, Entry);
+exports.SwitchEntry = SwitchEntry;
+
+function TryEntry(firstLoc, catchEntry, finallyEntry) {
+ Entry.call(this);
+
+ t.assertLiteral(firstLoc);
+
+ if (catchEntry) {
+ assert.ok(catchEntry instanceof CatchEntry);
+ } else {
+ catchEntry = null;
+ }
+
+ if (finallyEntry) {
+ assert.ok(finallyEntry instanceof FinallyEntry);
+ } else {
+ finallyEntry = null;
+ }
+
+ // Have to have one or the other (or both).
+ assert.ok(catchEntry || finallyEntry);
+
+ this.firstLoc = firstLoc;
+ this.catchEntry = catchEntry;
+ this.finallyEntry = finallyEntry;
+}
+
+inherits(TryEntry, Entry);
+exports.TryEntry = TryEntry;
+
+function CatchEntry(firstLoc, paramId) {
+ Entry.call(this);
+
+ t.assertLiteral(firstLoc);
+ t.assertIdentifier(paramId);
+
+ this.firstLoc = firstLoc;
+ this.paramId = paramId;
+}
+
+inherits(CatchEntry, Entry);
+exports.CatchEntry = CatchEntry;
+
+function FinallyEntry(firstLoc, afterLoc) {
+ Entry.call(this);
+ t.assertLiteral(firstLoc);
+ t.assertLiteral(afterLoc);
+ this.firstLoc = firstLoc;
+ this.afterLoc = afterLoc;
+}
+
+inherits(FinallyEntry, Entry);
+exports.FinallyEntry = FinallyEntry;
+
+function LabeledEntry(breakLoc, label) {
+ Entry.call(this);
+
+ t.assertLiteral(breakLoc);
+ t.assertIdentifier(label);
+
+ this.breakLoc = breakLoc;
+ this.label = label;
+}
+
+inherits(LabeledEntry, Entry);
+exports.LabeledEntry = LabeledEntry;
+
+function LeapManager(emitter) {
+ assert.ok(this instanceof LeapManager);
+
+ let Emitter = require("./emit").Emitter;
+ assert.ok(emitter instanceof Emitter);
+
+ this.emitter = emitter;
+ this.entryStack = [new FunctionEntry(emitter.finalLoc)];
+}
+
+let LMp = LeapManager.prototype;
+exports.LeapManager = LeapManager;
+
+LMp.withEntry = function(entry, callback) {
+ assert.ok(entry instanceof Entry);
+ this.entryStack.push(entry);
+ try {
+ callback.call(this.emitter);
+ } finally {
+ let popped = this.entryStack.pop();
+ assert.strictEqual(popped, entry);
+ }
+};
+
+LMp._findLeapLocation = function(property, label) {
+ for (let i = this.entryStack.length - 1; i >= 0; --i) {
+ let entry = this.entryStack[i];
+ let loc = entry[property];
+ if (loc) {
+ if (label) {
+ if (entry.label &&
+ entry.label.name === label.name) {
+ return loc;
+ }
+ } else if (entry instanceof LabeledEntry) {
+ // Ignore LabeledEntry entries unless we are actually breaking to
+ // a label.
+ } else {
+ return loc;
+ }
+ }
+ }
+
+ return null;
+};
+
+LMp.getBreakLoc = function(label) {
+ return this._findLeapLocation("breakLoc", label);
+};
+
+LMp.getContinueLoc = function(label) {
+ return this._findLeapLocation("continueLoc", label);
+};
diff --git a/packages/babel-plugin-transform-regenerator/src/meta.js b/packages/babel-plugin-transform-regenerator/src/meta.js
new file mode 100644
index 0000000000..dc7ffcdd45
--- /dev/null
+++ b/packages/babel-plugin-transform-regenerator/src/meta.js
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2014, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * https://raw.github.com/facebook/regenerator/master/LICENSE file. An
+ * additional grant of patent rights can be found in the PATENTS file in
+ * the same directory.
+ */
+
+import assert from "assert";
+let m = require("private").makeAccessor();
+import * as t from "babel-types";
+let hasOwn = Object.prototype.hasOwnProperty;
+
+function makePredicate(propertyName, knownTypes) {
+ function onlyChildren(node) {
+ t.assertNode(node);
+
+ // Assume no side effects until we find out otherwise.
+ let result = false;
+
+ function check(child) {
+ if (result) {
+ // Do nothing.
+ } else if (Array.isArray(child)) {
+ child.some(check);
+ } else if (t.isNode(child)) {
+ assert.strictEqual(result, false);
+ result = predicate(child);
+ }
+ return result;
+ }
+
+ let keys = t.VISITOR_KEYS[node.type];
+ if (keys) {
+ for (let i = 0; i < keys.length; i++) {
+ let key = keys[i];
+ let child = node[key];
+ check(child);
+ }
+ }
+
+ return result;
+ }
+
+ function predicate(node) {
+ t.assertNode(node);
+
+ let meta = m(node);
+ if (hasOwn.call(meta, propertyName))
+ return meta[propertyName];
+
+ // Certain types are "opaque," which means they have no side
+ // effects or leaps and we don't care about their subexpressions.
+ if (hasOwn.call(opaqueTypes, node.type))
+ return meta[propertyName] = false;
+
+ if (hasOwn.call(knownTypes, node.type))
+ return meta[propertyName] = true;
+
+ return meta[propertyName] = onlyChildren(node);
+ }
+
+ predicate.onlyChildren = onlyChildren;
+
+ return predicate;
+}
+
+let opaqueTypes = {
+ FunctionExpression: true
+};
+
+// These types potentially have side effects regardless of what side
+// effects their subexpressions have.
+let sideEffectTypes = {
+ CallExpression: true, // Anything could happen!
+ ForInStatement: true, // Modifies the key variable.
+ UnaryExpression: true, // Think delete.
+ BinaryExpression: true, // Might invoke .toString() or .valueOf().
+ AssignmentExpression: true, // Side-effecting by definition.
+ UpdateExpression: true, // Updates are essentially assignments.
+ NewExpression: true // Similar to CallExpression.
+};
+
+// These types are the direct cause of all leaps in control flow.
+let leapTypes = {
+ YieldExpression: true,
+ BreakStatement: true,
+ ContinueStatement: true,
+ ReturnStatement: true,
+ ThrowStatement: true
+};
+
+// All leap types are also side effect types.
+for (let type in leapTypes) {
+ if (hasOwn.call(leapTypes, type)) {
+ sideEffectTypes[type] = leapTypes[type];
+ }
+}
+
+exports.hasSideEffects = makePredicate("hasSideEffects", sideEffectTypes);
+exports.containsLeap = makePredicate("containsLeap", leapTypes);
diff --git a/packages/babel-plugin-transform-regenerator/src/util.js b/packages/babel-plugin-transform-regenerator/src/util.js
new file mode 100644
index 0000000000..78bfa0f28b
--- /dev/null
+++ b/packages/babel-plugin-transform-regenerator/src/util.js
@@ -0,0 +1,23 @@
+/**
+ * Copyright (c) 2014, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * https://raw.github.com/facebook/regenerator/master/LICENSE file. An
+ * additional grant of patent rights can be found in the PATENTS file in
+ * the same directory.
+ */
+
+import * as t from "babel-types";
+
+export function runtimeProperty(name) {
+ return t.memberExpression(
+ t.identifier("regeneratorRuntime"),
+ t.identifier(name),
+ false
+ );
+}
+
+export function isReference(path) {
+ return path.isReferenced() || path.parentPath.isAssignmentExpression({ left: path.node });
+}
diff --git a/packages/babel-plugin-transform-regenerator/src/visit.js b/packages/babel-plugin-transform-regenerator/src/visit.js
new file mode 100644
index 0000000000..ad22fe3c76
--- /dev/null
+++ b/packages/babel-plugin-transform-regenerator/src/visit.js
@@ -0,0 +1,252 @@
+/**
+ * Copyright (c) 2014, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * https://raw.github.com/facebook/regenerator/master/LICENSE file. An
+ * additional grant of patent rights can be found in the PATENTS file in
+ * the same directory.
+ */
+
+import assert from "assert";
+import * as t from "babel-types";
+import { hoist } from "./hoist";
+import { Emitter } from "./emit";
+import * as util from "./util";
+
+let getMarkInfo = require("private").makeAccessor();
+
+exports.visitor = {
+ Function: {
+ exit: function(path, state) {
+ let node = path.node;
+
+ if (node.generator) {
+ if (node.async) {
+ // Async generator
+ if (state.opts.asyncGenerators === false) return;
+ } else {
+ // Plain generator
+ if (state.opts.generators === false) return;
+ }
+ } else if (node.async) {
+ // Async function
+ if (state.opts.async === false) return;
+ } else {
+ // Not a generator or async function.
+ return;
+ }
+
+ if (node.expression) {
+ // Transform expression lambdas into normal functions.
+ node.expression = false;
+ node.body = t.blockStatement([
+ t.returnStatement(node.body)
+ ]);
+ }
+
+ if (node.async) {
+ path.get("body").traverse(awaitVisitor);
+ }
+
+ let bodyBlockPath = path.get("body");
+ let outerBody = [];
+ let innerBody = [];
+
+ bodyBlockPath.get("body").forEach(function(childPath) {
+ let node = childPath.node;
+ if (node && node._blockHoist != null) {
+ outerBody.push(node);
+ } else {
+ innerBody.push(node);
+ }
+ });
+
+ if (outerBody.length > 0) {
+ // Only replace the inner body if we actually hoisted any statements
+ // to the outer body.
+ bodyBlockPath.node.body = innerBody;
+ }
+
+ let outerFnExpr = getOuterFnExpr(path);
+ // Note that getOuterFnExpr has the side-effect of ensuring that the
+ // function has a name (so node.id will always be an Identifier), even
+ // if a temporary name has to be synthesized.
+ t.assertIdentifier(node.id);
+ let innerFnId = t.identifier(node.id.name + "$");
+ let contextId = path.scope.generateUidIdentifier("context");
+ let argsId = path.scope.generateUidIdentifier("args");
+
+ // Turn all declarations into vars, and replace the original
+ // declarations with equivalent assignment expressions.
+ let vars = hoist(path);
+
+ let didRenameArguments = renameArguments(path, argsId);
+ if (didRenameArguments) {
+ vars = vars || t.variableDeclaration("var", []);
+ vars.declarations.push(t.variableDeclarator(
+ argsId, t.identifier("arguments")
+ ));
+ }
+
+ let emitter = new Emitter(contextId);
+ emitter.explode(path.get("body"));
+
+ if (vars && vars.declarations.length > 0) {
+ outerBody.push(vars);
+ }
+
+ let wrapArgs = [
+ emitter.getContextFunction(innerFnId),
+ // Async functions that are not generators don't care about the
+ // outer function because they don't need it to be marked and don't
+ // inherit from its .prototype.
+ node.generator ? outerFnExpr : t.nullLiteral(),
+ t.thisExpression()
+ ];
+
+ let tryLocsList = emitter.getTryLocsList();
+ if (tryLocsList) {
+ wrapArgs.push(tryLocsList);
+ }
+
+ let wrapCall = t.callExpression(
+ util.runtimeProperty(node.async ? "async" : "wrap"),
+ wrapArgs
+ );
+
+ outerBody.push(t.returnStatement(wrapCall));
+ node.body = t.blockStatement(outerBody);
+
+ let wasGeneratorFunction = node.generator;
+ if (wasGeneratorFunction) {
+ node.generator = false;
+ }
+
+ if (node.async) {
+ node.async = false;
+ }
+
+ if (wasGeneratorFunction &&
+ t.isExpression(node)) {
+ path.replaceWith(t.callExpression(util.runtimeProperty("mark"), [node]));
+ }
+ }
+ }
+};
+
+// Given a NodePath for a Function, return an Expression node that can be
+// used to refer reliably to the function object from inside the function.
+// This expression is essentially a replacement for arguments.callee, with
+// the key advantage that it works in strict mode.
+function getOuterFnExpr(funPath) {
+ let node = funPath.node;
+ t.assertFunction(node);
+
+ if (node.generator && // Non-generator functions don't need to be marked.
+ t.isFunctionDeclaration(node)) {
+ let pp = funPath.findParent(function (path) {
+ return path.isProgram() || path.isBlockStatement();
+ });
+
+ if (!pp) {
+ return node.id;
+ }
+
+ let markDecl = getRuntimeMarkDecl(pp);
+ let markedArray = markDecl.declarations[0].id;
+ let funDeclIdArray = markDecl.declarations[0].init.callee.object;
+ t.assertArrayExpression(funDeclIdArray);
+
+ let index = funDeclIdArray.elements.length;
+ funDeclIdArray.elements.push(node.id);
+
+ return t.memberExpression(
+ markedArray,
+ t.numericLiteral(index),
+ true
+ );
+ }
+
+ return node.id || (
+ node.id = funPath.scope.parent.generateUidIdentifier("callee")
+ );
+}
+
+function getRuntimeMarkDecl(blockPath) {
+ let block = blockPath.node;
+ assert.ok(Array.isArray(block.body));
+
+ let info = getMarkInfo(block);
+ if (info.decl) {
+ return info.decl;
+ }
+
+ info.decl = t.variableDeclaration("var", [
+ t.variableDeclarator(
+ blockPath.scope.generateUidIdentifier("marked"),
+ t.callExpression(
+ t.memberExpression(
+ t.arrayExpression([]),
+ t.identifier("map"),
+ false
+ ),
+ [util.runtimeProperty("mark")]
+ )
+ )
+ ]);
+
+ blockPath.unshiftContainer("body", info.decl);
+
+ return info.decl;
+}
+
+function renameArguments(funcPath, argsId) {
+ let state = {
+ didRenameArguments: false,
+ argsId: argsId
+ };
+
+ funcPath.traverse(argumentsVisitor, state);
+
+ // If the traversal replaced any arguments references, then we need to
+ // alias the outer function's arguments binding (be it the implicit
+ // arguments object or some other parameter or variable) to the variable
+ // named by argsId.
+ return state.didRenameArguments;
+}
+
+let argumentsVisitor = {
+ "FunctionExpression|FunctionDeclaration": function(path) {
+ path.skip();
+ },
+
+ Identifier: function(path, state) {
+ if (path.node.name === "arguments" && util.isReference(path)) {
+ path.replaceWith(state.argsId);
+ state.didRenameArguments = true;
+ }
+ }
+};
+
+let awaitVisitor = {
+ Function: function(path) {
+ path.skip(); // Don't descend into nested function scopes.
+ },
+
+ AwaitExpression: function(path) {
+ // Convert await and await* expressions to yield expressions.
+ let argument = path.node.argument;
+
+ // Transforming `await x` to `yield regeneratorRuntime.awrap(x)`
+ // causes the argument to be wrapped in such a way that the runtime
+ // can distinguish between awaited and merely yielded values.
+ path.replaceWith(t.yieldExpression(
+ t.callExpression(
+ util.runtimeProperty("awrap"),
+ [argument]
+ ),
+ false
+ ));
+ }
+};