Add function name to spec-transformed arrow functions (#5620)
While it may appear that this should be done by es2015-function-name, another way to think about it is that es2015-function-name implements the naming that javascript engines are supposed to do; and javascript engines cannot name function expressions that are the object of a member expression.
This commit is contained in:
@@ -8,7 +8,12 @@
|
||||
"keywords": [
|
||||
"babel-plugin"
|
||||
],
|
||||
"dependencies": {
|
||||
"babel-helper-function-name": "7.0.0-alpha.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-helper-plugin-test-runner": "7.0.0-alpha.9"
|
||||
"babel-helper-plugin-test-runner": "7.0.0-alpha.9",
|
||||
"babel-traverse": "7.0.0-alpha.9",
|
||||
"babel-types": "7.0.0-alpha.9"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
export default function ({ types: t }) {
|
||||
// @flow
|
||||
|
||||
import nameFunction from "babel-helper-function-name";
|
||||
import { type NodePath } from "babel-traverse";
|
||||
import typeof * as babelTypes from "babel-types";
|
||||
|
||||
export default function ({ types: t }: { types: babelTypes }) {
|
||||
return {
|
||||
visitor: {
|
||||
ArrowFunctionExpression(path, state) {
|
||||
ArrowFunctionExpression(path: NodePath<BabelNodeArrowFunctionExpression>, state: Object) {
|
||||
if (state.opts.spec) {
|
||||
const { node } = path;
|
||||
if (node.shadow) return;
|
||||
@@ -9,7 +15,7 @@ export default function ({ types: t }) {
|
||||
node.shadow = { this: false };
|
||||
node.type = "FunctionExpression";
|
||||
|
||||
const boundThis = t.thisExpression();
|
||||
const boundThis: any = t.thisExpression();
|
||||
boundThis._forceShadow = path;
|
||||
|
||||
// make sure that arrow function won't be instantiated
|
||||
@@ -22,8 +28,11 @@ export default function ({ types: t }) {
|
||||
]))
|
||||
);
|
||||
|
||||
const replacement = nameFunction(path);
|
||||
const named = replacement || node;
|
||||
|
||||
path.replaceWith(t.callExpression(
|
||||
t.memberExpression(node, t.identifier("bind")),
|
||||
t.memberExpression(named, t.identifier("bind")),
|
||||
[t.thisExpression()]
|
||||
));
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
[].map(x => x);
|
||||
|
||||
const f = x => x
|
||||
|
||||
const o = { k: x => x }
|
||||
@@ -0,0 +1,16 @@
|
||||
var _this = this;
|
||||
|
||||
[].map(function (x) {
|
||||
babelHelpers.newArrowCheck(this, _this);
|
||||
return x;
|
||||
}.bind(this));
|
||||
|
||||
const f = function f(x) {
|
||||
babelHelpers.newArrowCheck(this, _this);
|
||||
return x;
|
||||
}.bind(this);
|
||||
|
||||
const o = { k: function k(x) {
|
||||
babelHelpers.newArrowCheck(this, _this);
|
||||
return x;
|
||||
}.bind(this) };
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugins": ["external-helpers", ["transform-es2015-arrow-functions", { "spec": true }]]
|
||||
}
|
||||
@@ -4,4 +4,7 @@ function foo() {
|
||||
(function () {
|
||||
return () => this;
|
||||
})();
|
||||
return {
|
||||
g: () => this
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ function foo() {
|
||||
babelHelpers.newArrowCheck(this, _this);
|
||||
return x * x;
|
||||
}.bind(this));
|
||||
var f = function (x, y) {
|
||||
var f = function f(x, y) {
|
||||
babelHelpers.newArrowCheck(this, _this);
|
||||
return x * y;
|
||||
}.bind(this);
|
||||
@@ -17,4 +17,10 @@ function foo() {
|
||||
return this;
|
||||
}.bind(this);
|
||||
})();
|
||||
return {
|
||||
g: function g() {
|
||||
babelHelpers.newArrowCheck(this, _this);
|
||||
return this;
|
||||
}.bind(this)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// I don't know if this is a bug with arrow-functions spec: true
|
||||
// or with function-name, but the functions are missing their names.
|
||||
// These are actually handled by transform-es2015-arrow-function
|
||||
const x = () => x;
|
||||
const y = x => x();
|
||||
const z = { z: () => y(x) }.z;
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
var _this = this;
|
||||
|
||||
// I don't know if this is a bug with arrow-functions spec: true
|
||||
// or with function-name, but the functions are missing their names.
|
||||
const x = function () {
|
||||
// These are actually handled by transform-es2015-arrow-function
|
||||
const x = function x() {
|
||||
babelHelpers.newArrowCheck(this, _this);
|
||||
return x;
|
||||
}.bind(this);
|
||||
const y = function (x) {
|
||||
const y = function y(x) {
|
||||
babelHelpers.newArrowCheck(this, _this);
|
||||
return x();
|
||||
}.bind(this);
|
||||
const z = { z: function z() {
|
||||
babelHelpers.newArrowCheck(this, _this);
|
||||
return y(x);
|
||||
}.bind(this) }.z;
|
||||
}.bind(this) }.z;
|
||||
|
||||
Reference in New Issue
Block a user