Implement support for async generator functions and for-await statements

This commit is contained in:
zenparsing
2016-04-14 09:35:25 -04:00
committed by Henry Zhu
parent bf0e256c3a
commit 26e79c5433
44 changed files with 779 additions and 25 deletions

View File

@@ -0,0 +1,4 @@
node_modules
*.log
src
test

View File

@@ -0,0 +1,35 @@
# babel-plugin-transform-async-functions
Turn async generator functions and for-await statements to ES2015 generators
## Installation
```sh
$ npm install babel-plugin-transform-async-generator-functions
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["transform-async-generator-functions"]
}
```
### Via CLI
```sh
$ babel --plugins transform-async-generator-functions script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["transform-async-generator-functions"]
});
```

View File

@@ -0,0 +1,19 @@
{
"name": "babel-plugin-transform-async-generator-functions",
"version": "6.7.4",
"description": "Turn async generator functions into ES2015 generators",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-async-generator-functions",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
],
"dependencies": {
"babel-helper-remap-async-to-generator": "^6.7.0",
"babel-plugin-syntax-async-generators": "^6.5.0",
"babel-runtime": "^5.0.0"
},
"devDependencies": {
"babel-helper-plugin-test-runner": "^6.3.13"
}
}

View File

@@ -0,0 +1,36 @@
import remapAsyncToGenerator from "babel-helper-remap-async-to-generator";
export default function ({ types: t }) {
let yieldStarVisitor = {
Function(path) {
path.skip();
},
YieldExpression({ node }, state) {
if (!node.delegate) return;
let callee = state.addHelper("asyncGeneratorDelegate");
node.argument = t.callExpression(callee, [
t.callExpression(state.addHelper("asyncIterator"), [node.argument]),
t.memberExpression(state.addHelper("asyncGenerator"), t.identifier("await"))
]);
}
};
return {
inherits: require("babel-plugin-syntax-async-generators"),
visitor: {
Function(path, state) {
if (!path.node.async || !path.node.generator) return;
path.get("body").traverse(yieldStarVisitor, state);
remapAsyncToGenerator(path, state.file, {
wrapAsync: t.memberExpression(
state.addHelper("asyncGenerator"), t.identifier("wrap")),
wrapAwait: t.memberExpression(
state.addHelper("asyncGenerator"), t.identifier("await"))
});
}
}
};
}

View File

@@ -0,0 +1,8 @@
class C {
async *g() {
this;
await 1;
yield 2;
return 3;
}
}

View File

@@ -0,0 +1,12 @@
class C {
*g() {
var _this = this;
return babelHelpers.asyncGenerator.wrap(function* () {
_this;
yield babelHelpers.asyncGenerator.await(1);
yield 2;
return 3;
})();
}
}

View File

@@ -0,0 +1,6 @@
async function* agf() {
this;
await 1;
yield 2;
return 3;
}

View File

@@ -0,0 +1,11 @@
let agf = (() => {
var ref = babelHelpers.asyncGenerator.wrap(function* () {
this;
yield babelHelpers.asyncGenerator.await(1);
yield 2;
return 3;
});
return function agf() {
return ref.apply(this, arguments);
};
})();

View File

@@ -0,0 +1,6 @@
(async function* agf() {
this;
await 1;
yield 2;
return 3;
});

View File

@@ -0,0 +1,14 @@
(() => {
var ref = babelHelpers.asyncGenerator.wrap(function* () {
this;
yield babelHelpers.asyncGenerator.await(1);
yield 2;
return 3;
});
function agf() {
return ref.apply(this, arguments);
}
return agf;
})();

View File

@@ -0,0 +1,8 @@
({
async *g() {
this;
await 1;
yield 2;
return 3;
}
});

View File

@@ -0,0 +1,12 @@
({
*g() {
var _this = this;
return babelHelpers.asyncGenerator.wrap(function* () {
_this;
yield babelHelpers.asyncGenerator.await(1);
yield 2;
return 3;
})();
}
});

View File

@@ -0,0 +1,3 @@
{
"plugins": ["external-helpers", "transform-async-generator-functions"]
}

View File

@@ -0,0 +1,8 @@
class C {
static async *g() {
this;
await 1;
yield 2;
return 3;
}
}

View File

@@ -0,0 +1,12 @@
class C {
static *g() {
var _this = this;
return babelHelpers.asyncGenerator.wrap(function* () {
_this;
yield babelHelpers.asyncGenerator.await(1);
yield 2;
return 3;
})();
}
}

View File

@@ -0,0 +1,4 @@
async function* g() {
yield* [1, 2, 3];
yield* iterable;
}

View File

@@ -0,0 +1,9 @@
let g = (() => {
var ref = babelHelpers.asyncGenerator.wrap(function* () {
yield* babelHelpers.asyncGeneratorDelegate(babelHelpers.asyncIterator([1, 2, 3]), babelHelpers.asyncGenerator.await);
yield* babelHelpers.asyncGeneratorDelegate(babelHelpers.asyncIterator(iterable), babelHelpers.asyncGenerator.await);
});
return function g() {
return ref.apply(this, arguments);
};
})();

View File

@@ -0,0 +1,5 @@
async () => {
for await (let x of y) {
f(x);
}
};

View File

@@ -0,0 +1,26 @@
babelHelpers.asyncToGenerator(function* () {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = babelHelpers.asyncIterator(y), _step, _value; _step = yield _iterator.next(), _iteratorNormalCompletion = _step.done, _value = yield _step.value, !_iteratorNormalCompletion; _iteratorNormalCompletion = true) {
let x = _value;
f(x);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
yield _iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
});

View File

@@ -0,0 +1,5 @@
async function f() {
for await (let x of y) {
g(x);
}
}

View File

@@ -0,0 +1,31 @@
let f = (() => {
var ref = babelHelpers.asyncToGenerator(function* () {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = babelHelpers.asyncIterator(y), _step, _value; _step = yield _iterator.next(), _iteratorNormalCompletion = _step.done, _value = yield _step.value, !_iteratorNormalCompletion; _iteratorNormalCompletion = true) {
let x = _value;
g(x);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
yield _iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
});
return function f() {
return ref.apply(this, arguments);
};
})();

View File

@@ -0,0 +1,5 @@
async function* g() {
for await (let x of y) {
f(x);
}
}

View File

@@ -0,0 +1,31 @@
let g = (() => {
var ref = babelHelpers.asyncGenerator.wrap(function* () {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = babelHelpers.asyncIterator(y), _step, _value; _step = yield babelHelpers.asyncGenerator.await(_iterator.next()), _iteratorNormalCompletion = _step.done, _value = yield babelHelpers.asyncGenerator.await(_step.value), !_iteratorNormalCompletion; _iteratorNormalCompletion = true) {
let x = _value;
f(x);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
yield babelHelpers.asyncGenerator.await(_iterator.return());
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
});
return function g() {
return ref.apply(this, arguments);
};
})();

View File

@@ -0,0 +1,5 @@
async function f() {
for await (let { x, y: [z] } of a) {
g(x, z);
}
}

View File

@@ -0,0 +1,31 @@
let f = (() => {
var ref = babelHelpers.asyncToGenerator(function* () {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = babelHelpers.asyncIterator(a), _step, _value; _step = yield _iterator.next(), _iteratorNormalCompletion = _step.done, _value = yield _step.value, !_iteratorNormalCompletion; _iteratorNormalCompletion = true) {
let { x, y: [z] } = _value;
g(x, z);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
yield _iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
});
return function f() {
return ref.apply(this, arguments);
};
})();

View File

@@ -0,0 +1,7 @@
{
"plugins": [
"external-helpers",
"transform-async-to-generator",
"transform-async-generator-functions"
]
}

View File

@@ -0,0 +1,11 @@
async function* g() {
() => this;
function f() {
() => this;
}
async () => {
this;
await 1;
}
await 1;
}

View File

@@ -0,0 +1,20 @@
let g = (() => {
var ref = babelHelpers.asyncGenerator.wrap(function* () {
var _this = this;
(function () {
return _this;
});
function f() {
() => this;
}
babelHelpers.asyncToGenerator(function* () {
_this;
yield 1;
});
yield babelHelpers.asyncGenerator.await(1);
});
return function g() {
return ref.apply(this, arguments);
};
})();

View File

@@ -0,0 +1,4 @@
async function* g(x = async function() { await 1 }) {
await 2;
yield 3;
}

View File

@@ -0,0 +1,11 @@
let g = (() => {
var ref = babelHelpers.asyncGenerator.wrap(function* (x = babelHelpers.asyncToGenerator(function* () {
yield 1;
})) {
yield babelHelpers.asyncGenerator.await(2);
yield 3;
});
return function g(_x) {
return ref.apply(this, arguments);
};
})();

View File

@@ -0,0 +1,7 @@
async function f() {
await 1;
async function* g() {
await 2;
yield 3;
}
}

View File

@@ -0,0 +1,18 @@
let f = (() => {
var ref = babelHelpers.asyncToGenerator(function* () {
let g = (() => {
var ref = babelHelpers.asyncGenerator.wrap(function* () {
yield babelHelpers.asyncGenerator.await(2);
yield 3;
});
return function g() {
return ref.apply(this, arguments);
};
})();
yield 1;
});
return function f() {
return ref.apply(this, arguments);
};
})();

View File

@@ -0,0 +1,7 @@
{
"plugins": [
"external-helpers",
"transform-async-to-generator",
"transform-async-generator-functions"
]
}

View File

@@ -0,0 +1 @@
require("babel-helper-plugin-test-runner")(__dirname);