Skip to content

Commit

Permalink
Extract computed keys from the class closure (#13600)
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed Jul 26, 2021
1 parent 224a35c commit 790c518
Show file tree
Hide file tree
Showing 19 changed files with 142 additions and 58 deletions.
Expand Up @@ -20,7 +20,7 @@ var Foo = /*#__PURE__*/function () {

_babelHelpers$classPr = babelHelpers.classPrivateFieldLooseBase(this, _foo2)[_foo2];

var Nested = /*#__PURE__*/function () {
var Nested = /*#__PURE__*/function (_babelHelpers$classPr2) {
function Nested() {
babelHelpers.classCallCheck(this, Nested);
Object.defineProperty(this, _foo2, {
Expand All @@ -30,11 +30,11 @@ var Foo = /*#__PURE__*/function () {
}

babelHelpers.createClass(Nested, [{
key: _babelHelpers$classPr,
key: _babelHelpers$classPr2,
value: function () {}
}]);
return Nested;
}();
}(_babelHelpers$classPr);

babelHelpers.classPrivateFieldLooseBase(this, _foo)[_foo];
}
Expand Down
Expand Up @@ -14,19 +14,17 @@ var Foo = /*#__PURE__*/function () {
babelHelpers.createClass(Foo, [{
key: "test",
value: function test() {
var _this = this;

var Nested = /*#__PURE__*/function () {
var Nested = /*#__PURE__*/function (_babelHelpers$classPr) {
function Nested() {
babelHelpers.classCallCheck(this, Nested);
}

babelHelpers.createClass(Nested, [{
key: babelHelpers.classPrivateFieldLooseBase(_this, _foo)[_foo],
key: _babelHelpers$classPr,
value: function () {}
}]);
return Nested;
}();
}(babelHelpers.classPrivateFieldLooseBase(this, _foo)[_foo]);

babelHelpers.classPrivateFieldLooseBase(this, _foo)[_foo];
}
Expand Down
Expand Up @@ -21,7 +21,7 @@ var Foo = /*#__PURE__*/function () {

_babelHelpers$classPr = babelHelpers.classPrivateFieldGet(this, _foo2);

var Nested = /*#__PURE__*/function () {
var Nested = /*#__PURE__*/function (_babelHelpers$classPr2) {
function Nested() {
babelHelpers.classCallCheck(this, Nested);

Expand All @@ -32,11 +32,11 @@ var Foo = /*#__PURE__*/function () {
}

babelHelpers.createClass(Nested, [{
key: _babelHelpers$classPr,
key: _babelHelpers$classPr2,
value: function () {}
}]);
return Nested;
}();
}(_babelHelpers$classPr);

babelHelpers.classPrivateFieldGet(this, _foo);
}
Expand Down
Expand Up @@ -15,19 +15,17 @@ var Foo = /*#__PURE__*/function () {
babelHelpers.createClass(Foo, [{
key: "test",
value: function test() {
var _this = this;

var Nested = /*#__PURE__*/function () {
var Nested = /*#__PURE__*/function (_babelHelpers$classPr) {
function Nested() {
babelHelpers.classCallCheck(this, Nested);
}

babelHelpers.createClass(Nested, [{
key: babelHelpers.classPrivateFieldGet(_this, _foo),
key: _babelHelpers$classPr,
value: function () {}
}]);
return Nested;
}();
}(babelHelpers.classPrivateFieldGet(this, _foo));

babelHelpers.classPrivateFieldGet(this, _foo);
}
Expand Down
Expand Up @@ -15,7 +15,7 @@ _ref3 = /regex/;
_baz = baz;
_ref4 = `template${expression}`;

var MyClass = /*#__PURE__*/function () {
var MyClass = /*#__PURE__*/function (_computed3, _computed4, _ref5) {
"use strict";

function MyClass() {
Expand All @@ -36,20 +36,20 @@ var MyClass = /*#__PURE__*/function () {
get: function () {},
set: function (value) {}
}, {
key: _computed,
key: _computed3,
get: function () {}
}, {
key: _computed2,
key: _computed4,
set: function (value) {}
}, {
key: _ref2,
key: _ref5,
value: function () {}
}], [{
key: "10",
value: function _() {}
}]);
return MyClass;
}();
}(_computed, _computed2, _ref2);

MyClass[_one] = "test";
MyClass[2 * 4 + 7] = "247";
Expand Down
Expand Up @@ -15,7 +15,7 @@ _ref3 = /regex/;
_baz = baz;
_ref4 = `template${expression}`;

var MyClass = /*#__PURE__*/function () {
var MyClass = /*#__PURE__*/function (_computed3, _computed4, _ref5) {
"use strict";

function MyClass() {
Expand All @@ -36,20 +36,20 @@ var MyClass = /*#__PURE__*/function () {
get: function () {},
set: function (value) {}
}, {
key: _computed,
key: _computed3,
get: function () {}
}, {
key: _computed2,
key: _computed4,
set: function (value) {}
}, {
key: _ref2,
key: _ref5,
value: function () {}
}], [{
key: "10",
value: function _() {}
}]);
return MyClass;
}();
}(_computed, _computed2, _ref2);

babelHelpers.defineProperty(MyClass, _one, "test");
babelHelpers.defineProperty(MyClass, 2 * 4 + 7, "247");
Expand Down
Expand Up @@ -4,7 +4,7 @@ var _class, _descriptor;

function dec() {}

let A = (_class = (_Symbol$search = Symbol.search, /*#__PURE__*/function () {
let A = (_class = (_Symbol$search = Symbol.search, /*#__PURE__*/function (_Symbol$search2) {
"use strict";

function A() {
Expand All @@ -13,11 +13,11 @@ let A = (_class = (_Symbol$search = Symbol.search, /*#__PURE__*/function () {
}

babelHelpers.createClass(A, [{
key: _Symbol$search,
key: _Symbol$search2,
value: function () {}
}]);
return A;
}()), (_descriptor = babelHelpers.applyDecoratedDescriptor(_class.prototype, "a", [dec], {
}(_Symbol$search)), (_descriptor = babelHelpers.applyDecoratedDescriptor(_class.prototype, "a", [dec], {
configurable: true,
enumerable: true,
writable: true,
Expand Down
29 changes: 28 additions & 1 deletion packages/babel-plugin-transform-classes/src/transformClass.ts
Expand Up @@ -62,6 +62,8 @@ export default function transformClass(
protoAlias: null,
isLoose: false,

dynamicKeys: new Map(),

methods: {
// 'list' is in the same order as the elements appear in the class body.
// if there aren't computed keys, we can safely reorder class elements
Expand Down Expand Up @@ -600,8 +602,26 @@ export default function transformClass(
);
}

function extractDynamicKeys() {
const { dynamicKeys, node, scope } = classState as {
dynamicKeys: Map<string, t.Expression>;
node: t.Class;
scope: NodePath["scope"];
};

for (const elem of node.body.body) {
if (!t.isClassMethod(elem) || !elem.computed) continue;
if (scope.isPure(elem.key, /* constatns only*/ true)) continue;

const id = scope.generateUidIdentifierBasedOnNode(elem.key);
dynamicKeys.set(id.name, elem.key);

elem.key = id;
}
}

function setupClosureParamsArgs() {
const { superName } = classState;
const { superName, dynamicKeys } = classState;
const closureParams = [];
const closureArgs = [];

Expand All @@ -623,6 +643,11 @@ export default function transformClass(
setState({ superName: t.cloneNode(param) });
}

for (const [name, value] of dynamicKeys) {
closureParams.push(t.identifier(name));
closureArgs.push(value);
}

return { closureParams, closureArgs };
}

Expand Down Expand Up @@ -668,6 +693,8 @@ export default function transformClass(
construct: buildConstructor(classRef, constructorBody, node),
});

extractDynamicKeys();

let { body } = classState;
const { closureParams, closureArgs } = setupClosureParamsArgs();

Expand Down
@@ -1,19 +1,19 @@
let A = /*#__PURE__*/function () {
let A = /*#__PURE__*/function (_x, _ref, _x2) {
"use strict";

function A() {
babelHelpers.classCallCheck(this, A);
}

babelHelpers.createClass(A, [{
key: x,
key: _x,
get: function () {}
}, {
key: (x = 2, 3),
key: _ref,
value: function () {}
}, {
key: x,
key: _x2,
set: function (_) {}
}]);
return A;
}();
}(x, (x = 2, 3), x);
@@ -0,0 +1,5 @@
expect(() => {
class A {
[A.name]() {}
}
}).toThrow(ReferenceError);
@@ -0,0 +1,4 @@
{
"plugins": ["transform-classes"],
"minNodeVersion": "10.0.0"
}
@@ -0,0 +1,11 @@
var log = [];

class A {
[log.push(1)]() {}
static [log.push(2)]() {}
[log.push(3)]() {}
static [log.push(4)]() {}
}

expect(log).toEqual([1, 2, 3, 4]);

@@ -0,0 +1,9 @@
async function* fn() {
class A {
[yield 1]() {}
}

class B extends A {
[await 1]() {}
}
}
@@ -0,0 +1,34 @@
async function* fn() {
var A = /*#__PURE__*/function (_yield$) {
"use strict";

function A() {
babelHelpers.classCallCheck(this, A);
}

babelHelpers.createClass(A, [{
key: _yield$,
value: function value() {}
}]);
return A;
}(yield 1);

var B = /*#__PURE__*/function (_A, _await$) {
"use strict";

babelHelpers.inherits(B, _A);

var _super = babelHelpers.createSuper(B);

function B() {
babelHelpers.classCallCheck(this, B);
return _super.apply(this, arguments);
}

babelHelpers.createClass(B, [{
key: _await$,
value: function value() {}
}]);
return B;
}(A, await 1);
}
@@ -1,4 +1,4 @@
var Foo = /*#__PURE__*/function () {
var Foo = /*#__PURE__*/function (_bar, _ref) {
"use strict";

function Foo() {
Expand All @@ -11,11 +11,11 @@ var Foo = /*#__PURE__*/function () {
"second";
}
}, {
key: bar,
key: _bar,
value: function value() {}
}, {
key: bar + "foo",
key: _ref,
value: function value() {}
}]);
return Foo;
}();
}(bar, bar + "foo");
Expand Up @@ -11,21 +11,21 @@ var Foo = /*#__PURE__*/function (_Bar) {
babelHelpers.classCallCheck(this, Foo);
_this = _super.call(this);

var X = /*#__PURE__*/function () {
var X = /*#__PURE__*/function (_ref) {
function X() {
babelHelpers.classCallCheck(this, X);
}

babelHelpers.createClass(X, [{
key: (() => {
var _Foo;

babelHelpers.get((_thisSuper = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(Foo.prototype)), "method", _thisSuper).call(_thisSuper);
})(),
key: _ref,
value: function value() {}
}]);
return X;
}();
}((() => {
var _Foo;

babelHelpers.get((_thisSuper = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(Foo.prototype)), "method", _thisSuper).call(_thisSuper);
})());

return _this;
}
Expand Down

0 comments on commit 790c518

Please sign in to comment.