Class instance properties define their own context (#6158)
This commit is contained in:
committed by
Henry Zhu
parent
960151c876
commit
ac6eda2709
@@ -52,6 +52,10 @@ const visitor = {
|
||||
if (!path.isArrowFunctionExpression()) path.skip();
|
||||
},
|
||||
|
||||
ClassProperty(path) {
|
||||
if (!path.node.static) path.skip();
|
||||
},
|
||||
|
||||
ReturnStatement(path, state) {
|
||||
if (!path.getFunctionParent().isArrowFunctionExpression()) {
|
||||
state.returns.push(path);
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
class Foo {
|
||||
static fn = () => console.log(this);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
var _this = this;
|
||||
|
||||
class Foo {
|
||||
static fn = function () {
|
||||
return console.log(_this);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugins": ["external-helpers", "transform-es2015-arrow-functions", "syntax-class-properties"]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
class Foo {
|
||||
fn = () => console.log(this);
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"plugins": ["external-helpers", "transform-es2015-arrow-functions", "syntax-class-properties"],
|
||||
"throws": "Unable to transform arrow inside class property"
|
||||
}
|
||||
28
packages/babel-plugin-transform-class-properties/test/fixtures/regression/6153/actual.js
vendored
Normal file
28
packages/babel-plugin-transform-class-properties/test/fixtures/regression/6153/actual.js
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
() => {
|
||||
class Foo {
|
||||
fn = () => console.log(this);
|
||||
static fn = () => console.log(this);
|
||||
}
|
||||
};
|
||||
|
||||
() => class Bar {
|
||||
fn = () => console.log(this);
|
||||
static fn = () => console.log(this);
|
||||
};
|
||||
|
||||
() => {
|
||||
class Baz {
|
||||
fn = () => console.log(this);
|
||||
force = force
|
||||
static fn = () => console.log(this);
|
||||
|
||||
constructor(force) {}
|
||||
}
|
||||
};
|
||||
|
||||
var qux = function() {
|
||||
class Qux {
|
||||
fn = () => console.log(this);
|
||||
static fn = () => console.log(this);
|
||||
}
|
||||
}.bind(this)
|
||||
121
packages/babel-plugin-transform-class-properties/test/fixtures/regression/6153/expected.js
vendored
Normal file
121
packages/babel-plugin-transform-class-properties/test/fixtures/regression/6153/expected.js
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
var _this = this;
|
||||
|
||||
(function () {
|
||||
class Foo {
|
||||
constructor() {
|
||||
var _this2 = this;
|
||||
|
||||
Object.defineProperty(this, "fn", {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: function () {
|
||||
return console.log(_this2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Object.defineProperty(Foo, "fn", {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: function () {
|
||||
return console.log(_this);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
(function () {
|
||||
var _class, _temp;
|
||||
|
||||
return _temp = _class = class Bar {
|
||||
constructor() {
|
||||
var _this3 = this;
|
||||
|
||||
Object.defineProperty(this, "fn", {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: function () {
|
||||
return console.log(_this3);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}, Object.defineProperty(_class, "fn", {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: function () {
|
||||
return console.log(_this);
|
||||
}
|
||||
}), _temp;
|
||||
});
|
||||
|
||||
(function () {
|
||||
class Baz {
|
||||
constructor(force) {
|
||||
_initialiseProps.call(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Object.defineProperty(Baz, "fn", {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: function () {
|
||||
return console.log(_this);
|
||||
}
|
||||
});
|
||||
|
||||
var _initialiseProps = function () {
|
||||
var _this4 = this;
|
||||
|
||||
Object.defineProperty(this, "fn", {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: function () {
|
||||
return console.log(_this4);
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "force", {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: force
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
var qux = function () {
|
||||
var _this6 = this;
|
||||
|
||||
class Qux {
|
||||
constructor() {
|
||||
var _this5 = this;
|
||||
|
||||
Object.defineProperty(this, "fn", {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: function () {
|
||||
return console.log(_this5);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Object.defineProperty(Qux, "fn", {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: function () {
|
||||
return console.log(_this6);
|
||||
}
|
||||
});
|
||||
}.bind(this);
|
||||
3
packages/babel-plugin-transform-class-properties/test/fixtures/regression/6153/options.json
vendored
Normal file
3
packages/babel-plugin-transform-class-properties/test/fixtures/regression/6153/options.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugins": ["external-helpers", "transform-class-properties", "transform-es2015-arrow-functions"]
|
||||
}
|
||||
8
packages/babel-plugin-transform-class-properties/test/fixtures/regression/6154/actual.js
vendored
Normal file
8
packages/babel-plugin-transform-class-properties/test/fixtures/regression/6154/actual.js
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
class Test {
|
||||
constructor() {
|
||||
class Other extends Test {
|
||||
a = () => super.test;
|
||||
static a = () => super.test;
|
||||
}
|
||||
}
|
||||
}
|
||||
53
packages/babel-plugin-transform-class-properties/test/fixtures/regression/6154/expected.js
vendored
Normal file
53
packages/babel-plugin-transform-class-properties/test/fixtures/regression/6154/expected.js
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
"use strict";
|
||||
|
||||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
||||
|
||||
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
||||
|
||||
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
||||
|
||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var Test = function Test() {
|
||||
var _this2 = this;
|
||||
|
||||
_classCallCheck(this, Test);
|
||||
|
||||
var Other = function (_Test) {
|
||||
_inherits(Other, _Test);
|
||||
|
||||
function Other() {
|
||||
var _ref;
|
||||
|
||||
var _temp, _this;
|
||||
|
||||
_classCallCheck(this, Other);
|
||||
|
||||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
|
||||
args[_key] = arguments[_key];
|
||||
}
|
||||
|
||||
return _possibleConstructorReturn(_this, (_temp = _this = _possibleConstructorReturn(this, (_ref = Other.__proto__ || Object.getPrototypeOf(Other)).call.apply(_ref, [this].concat(args))), Object.defineProperty(_this, "a", {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: function value() {
|
||||
return _get(Other.prototype.__proto__ || Object.getPrototypeOf(Other.prototype), "test", _this);
|
||||
}
|
||||
}), _temp));
|
||||
}
|
||||
|
||||
return Other;
|
||||
}(Test);
|
||||
|
||||
Object.defineProperty(Other, "a", {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: function value() {
|
||||
return _get(Test.prototype.__proto__ || Object.getPrototypeOf(Test.prototype), "test", _this2);
|
||||
}
|
||||
});
|
||||
};
|
||||
3
packages/babel-plugin-transform-class-properties/test/fixtures/regression/6154/options.json
vendored
Normal file
3
packages/babel-plugin-transform-class-properties/test/fixtures/regression/6154/options.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"presets": ["es2015", "stage-2"]
|
||||
}
|
||||
3
packages/babel-plugin-transform-class-properties/test/fixtures/regression/T6719/options.json
vendored
Normal file
3
packages/babel-plugin-transform-class-properties/test/fixtures/regression/T6719/options.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugins": ["external-helpers", ["transform-class-properties", {"loose": true}], "transform-es2015-classes", "transform-es2015-block-scoping", "syntax-class-properties"]
|
||||
}
|
||||
@@ -123,7 +123,7 @@ function hoistFunctionEnvironment(
|
||||
p =>
|
||||
(p.isFunction() && !p.isArrowFunctionExpression()) ||
|
||||
p.isProgram() ||
|
||||
p.isClassProperty(),
|
||||
p.isClassProperty({ static: false }),
|
||||
);
|
||||
const inConstructor = thisEnvFn && thisEnvFn.node.kind === "constructor";
|
||||
|
||||
@@ -148,28 +148,22 @@ function hoistFunctionEnvironment(
|
||||
"Unable to handle nested super() usage in arrow",
|
||||
);
|
||||
}
|
||||
|
||||
const allSuperCalls = [];
|
||||
thisEnvFn.traverse({
|
||||
Function: child => {
|
||||
if (
|
||||
child.isArrowFunctionExpression() ||
|
||||
child.isClassProperty() ||
|
||||
child === fnPath
|
||||
) {
|
||||
return;
|
||||
}
|
||||
Function(child) {
|
||||
if (child.isArrowFunctionExpression()) return;
|
||||
child.skip();
|
||||
},
|
||||
ClassProperty(child) {
|
||||
if (child.node.static) return;
|
||||
child.skip();
|
||||
},
|
||||
CallExpression(child) {
|
||||
if (!child.get("callee").isSuper()) return;
|
||||
|
||||
allSuperCalls.push(child);
|
||||
},
|
||||
});
|
||||
|
||||
const superBinding = getSuperBinding(thisEnvFn);
|
||||
|
||||
allSuperCalls.forEach(superCall =>
|
||||
superCall.get("callee").replaceWith(t.identifier(superBinding)),
|
||||
);
|
||||
@@ -399,15 +393,12 @@ function getThisBinding(thisEnvFn, inConstructor) {
|
||||
|
||||
const supers = new WeakSet();
|
||||
thisEnvFn.traverse({
|
||||
Function: child => {
|
||||
if (
|
||||
child.isArrowFunctionExpression() ||
|
||||
child.isClassProperty() ||
|
||||
child === this
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
Function(child) {
|
||||
if (child.isArrowFunctionExpression()) return;
|
||||
child.skip();
|
||||
},
|
||||
ClassProperty(child) {
|
||||
if (child.node.static) return;
|
||||
child.skip();
|
||||
},
|
||||
CallExpression(child) {
|
||||
@@ -529,8 +520,12 @@ function getScopeInformation(fnPath) {
|
||||
const superCalls = [];
|
||||
|
||||
fnPath.traverse({
|
||||
ClassProperty(child) {
|
||||
if (child.node.static) return;
|
||||
child.skip();
|
||||
},
|
||||
Function(child) {
|
||||
if (child.isArrowFunctionExpression() || child.isClassProperty()) return;
|
||||
if (child.isArrowFunctionExpression()) return;
|
||||
child.skip();
|
||||
},
|
||||
ThisExpression(child) {
|
||||
|
||||
Reference in New Issue
Block a user