fix async function remap helper from outputing incorrect calls causing wrong scoping - fixes #2708 - fixes #2715
This commit is contained in:
@@ -13,6 +13,11 @@ _Note: Gaps between patch versions are faulty, broken or test releases._
|
||||
|
||||
See [CHANGELOG - 6to5](CHANGELOG-6to5.md) for the pre-4.0.0 version changelog.
|
||||
|
||||
## 6.0.15
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix async function remap helper from outputing incorrect calls causing wrong scoping.
|
||||
|
||||
## 6.0.14
|
||||
|
||||
* **Spec Compliancy**
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
var foo = function () {
|
||||
return babelHelpers.asyncToGenerator(function* () {
|
||||
var foo = (function () {
|
||||
var ref = babelHelpers.asyncToGenerator(function* () {
|
||||
var wat = yield bar();
|
||||
})();
|
||||
};
|
||||
});
|
||||
return function foo() {
|
||||
return ref.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
var foo = async function bar() {
|
||||
console.log(bar);
|
||||
};
|
||||
|
||||
foo();
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
var foo = function () {
|
||||
return babelHelpers.asyncToGenerator(function* bar() {
|
||||
var foo = (function () {
|
||||
var ref = babelHelpers.asyncToGenerator(function* bar() {
|
||||
console.log(bar);
|
||||
})();
|
||||
};
|
||||
|
||||
foo();
|
||||
});
|
||||
return function foo() {
|
||||
return ref.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
foo(async function () {
|
||||
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
foo(babelHelpers.asyncToGenerator(function* () {}));
|
||||
3
packages/babel-core/test/fixtures/transformation/async-to-generator/parameters/actual.js
vendored
Normal file
3
packages/babel-core/test/fixtures/transformation/async-to-generator/parameters/actual.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
async function foo(bar) {
|
||||
|
||||
}
|
||||
6
packages/babel-core/test/fixtures/transformation/async-to-generator/parameters/expected.js
vendored
Normal file
6
packages/babel-core/test/fixtures/transformation/async-to-generator/parameters/expected.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
let foo = (function () {
|
||||
var ref = babelHelpers.asyncToGenerator(function* foo(bar) {});
|
||||
return function foo(_x) {
|
||||
return ref.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
@@ -1,5 +1,8 @@
|
||||
let foo = function foo() {
|
||||
return babelHelpers.asyncToGenerator(function* foo() {
|
||||
let foo = (function () {
|
||||
var ref = babelHelpers.asyncToGenerator(function* foo() {
|
||||
var wat = yield bar();
|
||||
})();
|
||||
};
|
||||
});
|
||||
return function foo() {
|
||||
return ref.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { coroutine as _coroutine } from "bluebird";
|
||||
var foo = function () {
|
||||
return _coroutine(function* () {
|
||||
var foo = (function () {
|
||||
var ref = _coroutine(function* () {
|
||||
var wat = yield bar();
|
||||
})();
|
||||
};
|
||||
});
|
||||
|
||||
return function foo() {
|
||||
return ref.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
var foo = async function bar() {
|
||||
console.log(bar);
|
||||
};
|
||||
|
||||
foo();
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { coroutine as _coroutine } from "bluebird";
|
||||
var foo = function () {
|
||||
return _coroutine(function* bar() {
|
||||
var foo = (function () {
|
||||
var ref = _coroutine(function* bar() {
|
||||
console.log(bar);
|
||||
})();
|
||||
};
|
||||
});
|
||||
|
||||
foo();
|
||||
return function foo() {
|
||||
return ref.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import { coroutine as _coroutine } from "bluebird";
|
||||
|
||||
let foo = function foo() {
|
||||
return _coroutine(function* foo() {
|
||||
let foo = (function () {
|
||||
var ref = _coroutine(function* foo() {
|
||||
var wat = yield bar();
|
||||
})();
|
||||
};
|
||||
});
|
||||
|
||||
return function foo() {
|
||||
return ref.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
"main": "lib/index.js",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^5.0.0",
|
||||
"babel-template": "^6.0.14",
|
||||
"babel-types": "^6.0.14",
|
||||
"babel-traverse": "^6.0.14",
|
||||
"babel-helper-function-name": "^6.0.14"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,18 @@
|
||||
|
||||
import type { NodePath } from "babel-traverse";
|
||||
import nameFunction from "babel-helper-function-name";
|
||||
import template from "babel-template";
|
||||
import * as t from "babel-types";
|
||||
|
||||
let buildWrapper = template(`
|
||||
(function () {
|
||||
var ref = FUNCTION;
|
||||
return function (PARAMS) {
|
||||
return ref.apply(this, arguments);
|
||||
};
|
||||
})
|
||||
`);
|
||||
|
||||
let awaitVisitor = {
|
||||
Function(path) {
|
||||
path.skip();
|
||||
@@ -14,45 +24,78 @@ let awaitVisitor = {
|
||||
}
|
||||
};
|
||||
|
||||
export default function (path: NodePath, callId: Object) {
|
||||
function classMethod(path: NodePath, callId: Object) {
|
||||
let node = path.node;
|
||||
if (node.generator) return;
|
||||
let body = node.body;
|
||||
|
||||
if (path.isClassMethod()) {
|
||||
node.async = false;
|
||||
node.async = false;
|
||||
|
||||
let body = node.body;
|
||||
let container = t.functionExpression(null, [], t.blockStatement(body.body), true);
|
||||
container.shadow = true;
|
||||
body.body = [
|
||||
t.returnStatement(t.callExpression(
|
||||
t.callExpression(callId, [container]),
|
||||
[]
|
||||
))
|
||||
];
|
||||
}
|
||||
|
||||
let container = t.functionExpression(null, [], t.blockStatement(body.body), true);
|
||||
container.shadow = true;
|
||||
body.body = [t.returnStatement(t.callExpression(t.callExpression(callId, [container]), []))];
|
||||
return;
|
||||
}
|
||||
function plainFunction(path: NodePath, callId: Object) {
|
||||
let node = path.node;
|
||||
|
||||
node.async = false;
|
||||
node.generator = true;
|
||||
|
||||
path.traverse(awaitVisitor);
|
||||
|
||||
let container = t.functionExpression(null, [], t.blockStatement([
|
||||
t.returnStatement(t.callExpression(t.callExpression(callId, [node]), []))
|
||||
]));
|
||||
node.shadow = container;
|
||||
let built = t.callExpression(callId, [node]);
|
||||
let container = buildWrapper({
|
||||
FUNCTION: built,
|
||||
PARAMS: node.params.map(() => path.scope.generateUidIdentifier("x"))
|
||||
}).expression;
|
||||
|
||||
let retFunction = container.body.body[1].argument;
|
||||
|
||||
if (path.isFunctionDeclaration()) {
|
||||
let declar = t.variableDeclaration("let", [
|
||||
t.variableDeclarator(t.identifier(node.id.name), container)
|
||||
t.variableDeclarator(
|
||||
t.identifier(node.id.name),
|
||||
t.callExpression(container, [])
|
||||
)
|
||||
]);
|
||||
declar._blockHoist = true;
|
||||
|
||||
nameFunction({
|
||||
node: container,
|
||||
node: retFunction,
|
||||
parent: declar.declarations[0],
|
||||
scope: path.scope
|
||||
});
|
||||
|
||||
path.replaceWith(declar);
|
||||
} else {
|
||||
path.replaceWith(container);
|
||||
nameFunction({
|
||||
node: retFunction,
|
||||
parent: path.parent,
|
||||
scope: path.scope
|
||||
});
|
||||
|
||||
if (retFunction.id || node.params.length) {
|
||||
// we have an inferred function id or params so we need this wrapper
|
||||
path.replaceWith(t.callExpression(container, []));
|
||||
} else {
|
||||
// we can omit this wrapper as the conditions it protects for do not apply
|
||||
path.replaceWith(built);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default function (path: NodePath, callId: Object) {
|
||||
let node = path.node;
|
||||
if (node.generator) return;
|
||||
|
||||
if (path.isClassMethod()) {
|
||||
return classMethod(path, callId);
|
||||
} else {
|
||||
return plainFunction(path, callId);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user