Skip to content

Commit 87a67bf

Browse files
authored
Improve temporary variables for decorators (#16218)
1 parent dde84f0 commit 87a67bf

440 files changed

Lines changed: 1984 additions & 1998 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

packages/babel-helper-create-class-features-plugin/src/decorators.ts

Lines changed: 68 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@ function transformClass(
562562
continue;
563563
}
564564

565-
if (element.node.decorators && element.node.decorators.length > 0) {
565+
if (element.node.decorators?.length) {
566566
switch (element.node.type) {
567567
case "ClassProperty":
568568
// @ts-expect-error todo: propertyVisitor.ClassProperty should be callable. Improve typings.
@@ -646,38 +646,72 @@ function transformClass(
646646
classIdLocal: t.Identifier;
647647

648648
const decoratorsThis = new Map<t.Decorator, t.Expression>();
649-
const maybeExtractDecorator = (decorator: t.Decorator) => {
650-
const { expression } = decorator;
651-
if (version === "2023-05" && t.isMemberExpression(expression)) {
652-
let object;
653-
if (
654-
t.isSuper(expression.object) ||
655-
t.isThisExpression(expression.object)
656-
) {
657-
object = memoiseExpression(t.thisExpression(), "obj");
658-
} else if (!scopeParent.isStatic(expression.object)) {
659-
object = memoiseExpression(expression.object, "obj");
660-
expression.object = object;
661-
} else {
662-
object = expression.object;
649+
const maybeExtractDecorators = (
650+
decorators: t.Decorator[],
651+
memoiseInPlace: boolean,
652+
) => {
653+
let needMemoise = false;
654+
for (const decorator of decorators) {
655+
const { expression } = decorator;
656+
if (version === "2023-05" && t.isMemberExpression(expression)) {
657+
let object;
658+
if (
659+
t.isSuper(expression.object) ||
660+
t.isThisExpression(expression.object)
661+
) {
662+
needMemoise = true;
663+
if (memoiseInPlace) {
664+
object = memoiseExpression(t.thisExpression(), "obj");
665+
} else {
666+
object = t.thisExpression();
667+
}
668+
} else {
669+
if (!scopeParent.isStatic(expression.object)) {
670+
needMemoise = true;
671+
if (memoiseInPlace) {
672+
expression.object = memoiseExpression(expression.object, "obj");
673+
}
674+
}
675+
object = t.cloneNode(expression.object);
676+
}
677+
decoratorsThis.set(decorator, object);
678+
}
679+
if (!scopeParent.isStatic(expression)) {
680+
needMemoise = true;
681+
if (memoiseInPlace) {
682+
decorator.expression = memoiseExpression(expression, "dec");
683+
}
663684
}
664-
decoratorsThis.set(decorator, t.cloneNode(object));
665-
}
666-
if (!scopeParent.isStatic(expression)) {
667-
decorator.expression = memoiseExpression(expression, "dec");
668685
}
686+
return needMemoise && !memoiseInPlace;
669687
};
670688

671689
let needsDeclaraionForClassBinding = false;
690+
let classDecorationsFlag = 0;
691+
let classDecorations: t.Expression[] = [];
692+
let classDecorationsId: t.Identifier;
672693
if (classDecorators) {
673694
classInitLocal = scopeParent.generateDeclaredUidIdentifier("initClass");
674695
needsDeclaraionForClassBinding = path.isClassDeclaration();
675696
({ id: classIdLocal, path } = replaceClassWithVar(path, className));
676697

677698
path.node.decorators = null;
678699

679-
for (const classDecorator of classDecorators) {
680-
maybeExtractDecorator(classDecorator);
700+
const needMemoise = maybeExtractDecorators(classDecorators, false);
701+
702+
const { hasThis, decs } = generateDecorationList(
703+
classDecorators.map(el => el.expression),
704+
classDecorators.map(dec => decoratorsThis.get(dec)),
705+
version,
706+
);
707+
classDecorationsFlag = hasThis ? 1 : 0;
708+
classDecorations = decs;
709+
710+
if (needMemoise) {
711+
classDecorationsId = memoiseExpression(
712+
t.arrayExpression(classDecorations),
713+
"classDecs",
714+
);
681715
}
682716
} else {
683717
if (!path.node.id) {
@@ -696,18 +730,15 @@ function transformClass(
696730
}
697731

698732
const { node } = element;
699-
const decorators = element.get("decorators");
733+
const decorators = element.node.decorators;
700734

701-
const hasDecorators = Array.isArray(decorators) && decorators.length > 0;
735+
const hasDecorators = !!decorators?.length;
702736

703737
if (hasDecorators) {
704-
for (const decoratorPath of decorators) {
705-
maybeExtractDecorator(decoratorPath.node);
706-
}
738+
maybeExtractDecorators(decorators, true);
707739
}
708740

709-
const isComputed =
710-
"computed" in element.node && element.node.computed === true;
741+
const isComputed = "computed" in element.node && element.node.computed;
711742
if (isComputed) {
712743
if (!element.get("key").isConstantExpression()) {
713744
node.key = memoiseExpression(
@@ -722,7 +753,7 @@ function transformClass(
722753

723754
const isPrivate = key.type === "PrivateName";
724755

725-
const isStatic = !!element.node.static;
756+
const isStatic = element.node.static;
726757

727758
let name = "computedKey";
728759

@@ -881,8 +912,8 @@ function transformClass(
881912

882913
elementDecoratorInfo.push({
883914
kind,
884-
decorators: decorators.map(d => d.node.expression),
885-
decoratorsThis: decorators.map(d => decoratorsThis.get(d.node)),
915+
decorators: decorators.map(d => d.expression),
916+
decoratorsThis: decorators.map(d => decoratorsThis.get(d)),
886917
name: nameExpr,
887918
isStatic,
888919
privateMethods,
@@ -918,17 +949,6 @@ function transformClass(
918949
elementDecoratorInfo,
919950
version,
920951
);
921-
let classDecorationsFlag = 0;
922-
let classDecorations: t.Expression[] = [];
923-
if (classDecorators) {
924-
const { hasThis, decs } = generateDecorationList(
925-
classDecorators.map(el => el.expression),
926-
classDecorators.map(dec => decoratorsThis.get(dec)),
927-
version,
928-
);
929-
classDecorationsFlag = hasThis ? 1 : 0;
930-
classDecorations = decs;
931-
}
932952

933953
const elementLocals: t.Identifier[] =
934954
extractElementLocalAssignments(elementDecoratorInfo);
@@ -992,7 +1012,7 @@ function transformClass(
9921012
t.classMethod(
9931013
"constructor",
9941014
t.identifier("constructor"),
995-
[t.restElement(t.identifier("args"))],
1015+
path.node.superClass ? [t.restElement(t.identifier("args"))] : [],
9961016
t.blockStatement(body),
9971017
),
9981018
);
@@ -1143,7 +1163,6 @@ function transformClass(
11431163
superClass = id;
11441164
}
11451165
}
1146-
11471166
originalClass.body.body.unshift(
11481167
t.staticBlock(
11491168
[
@@ -1152,7 +1171,9 @@ function transformClass(
11521171
elementLocals,
11531172
classLocals,
11541173
elementDecorations,
1155-
t.arrayExpression(classDecorations),
1174+
classDecorationsId
1175+
? t.cloneNode(classDecorationsId)
1176+
: t.arrayExpression(classDecorations),
11561177
t.numericLiteral(classDecorationsFlag),
11571178
needsInstancePrivateBrandCheck ? lastInstancePrivateName : null,
11581179
typeof className === "object" ? className : undefined,
@@ -1192,8 +1213,8 @@ function transformClass(
11921213
function createLocalsAssignment(
11931214
elementLocals: t.Identifier[],
11941215
classLocals: t.Identifier[],
1195-
elementDecorations: t.ArrayExpression,
1196-
classDecorations: t.ArrayExpression,
1216+
elementDecorations: t.ArrayExpression | t.Identifier,
1217+
classDecorations: t.ArrayExpression | t.Identifier,
11971218
classDecorationsFlag: t.NumericLiteral,
11981219
maybePrivateBranName: t.PrivateName | null,
11991220
setClassName: t.Identifier | t.StringLiteral | undefined,

packages/babel-helper-create-class-features-plugin/src/fields.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1110,7 +1110,8 @@ export function buildFieldsInitNodes(
11101110
};
11111111

11121112
const classRefForInnerBinding =
1113-
ref ?? props[0].scope.generateUidIdentifier("class");
1113+
ref ??
1114+
props[0].scope.generateUidIdentifier(innerBindingRef?.name || "Class");
11141115
ref ??= t.cloneNode(innerBindingRef);
11151116

11161117
for (const prop of props) {

packages/babel-helper-create-class-features-plugin/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ export function createClassFeaturePlugin({
230230
let ref: t.Identifier | null;
231231
if (!innerBinding || !pathIsClassDeclaration) {
232232
nameFunction(path);
233-
ref = path.scope.generateUidIdentifier("class");
233+
ref = path.scope.generateUidIdentifier(innerBinding?.name || "Class");
234234
}
235235
const classRefForDefine = ref ?? t.cloneNode(innerBinding);
236236

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
var _class;
1+
var _A;
22
var _foo = /*#__PURE__*/new WeakSet();
33
class A extends B {
44
constructor(...args) {
55
super(...args);
66
babelHelpers.classPrivateMethodInitSpec(this, _foo);
77
}
88
}
9-
_class = A;
9+
_A = A;
1010
function _foo2() {
11-
let _A;
12-
babelHelpers.get(babelHelpers.getPrototypeOf(_class.prototype), "x", this);
11+
let _A2;
12+
babelHelpers.get(babelHelpers.getPrototypeOf(_A.prototype), "x", this);
1313
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
export default babelHelpers.decorate([dec()], function (_initialize) {
2-
class _class {
2+
class _Class {
33
constructor() {
44
_initialize(this);
55
}
66
}
77
return {
8-
F: _class,
8+
F: _Class,
99
d: []
1010
};
1111
});
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
babelHelpers.decorate([dec()], function (_initialize) {
22
"use strict";
33

4-
class _class {
4+
class _Class {
55
constructor() {
66
_initialize(this);
77
}
88
}
99
return {
10-
F: _class,
10+
F: _Class,
1111
d: []
1212
};
1313
});

packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-accessors--to-es2015/context-name/output.js

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
var _init_a, _init_a2, _get_a, _set_a, _init_computedKey, _init_computedKey2, _init_computedKey3, _init_computedKey4, _init_computedKey5, _init_computedKey6, _computedKey, _init_computedKey7, _initStatic, _class;
1+
var _init_a, _init_a2, _get_a, _set_a, _init_computedKey, _init_computedKey2, _init_computedKey3, _init_computedKey4, _init_computedKey5, _init_computedKey6, _computedKey, _init_computedKey7, _initStatic, _Foo;
22
const logs = [];
33
const dec = (value, context) => {
44
logs.push(context.name);
@@ -67,55 +67,55 @@ class Foo {
6767
babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _I, v);
6868
}
6969
}
70-
_class = Foo;
70+
_Foo = Foo;
7171
function _set_a2(v) {
7272
_set_a(this, v);
7373
}
7474
function _get_a2() {
7575
return _get_a(this);
7676
}
7777
(() => {
78-
[_init_a, _init_a2, _get_a, _set_a, _init_computedKey, _init_computedKey2, _init_computedKey3, _init_computedKey4, _init_computedKey5, _init_computedKey6, _init_computedKey7, _initStatic] = babelHelpers.applyDecs(_class, [[dec, 6, "a"], [dec, 6, "a", function () {
79-
return babelHelpers.classStaticPrivateFieldSpecGet(this, _class, _B);
78+
[_init_a, _init_a2, _get_a, _set_a, _init_computedKey, _init_computedKey2, _init_computedKey3, _init_computedKey4, _init_computedKey5, _init_computedKey6, _init_computedKey7, _initStatic] = babelHelpers.applyDecs(_Foo, [[dec, 6, "a"], [dec, 6, "a", function () {
79+
return babelHelpers.classStaticPrivateFieldSpecGet(this, _Foo, _B);
8080
}, function (value) {
81-
babelHelpers.classStaticPrivateFieldSpecSet(this, _class, _B, value);
81+
babelHelpers.classStaticPrivateFieldSpecSet(this, _Foo, _B, value);
8282
}], [dec, 6, "b"], [dec, 6, "c"], [dec, 6, 0], [dec, 6, 1], [dec, 6, 2n], [dec, 6, 3n], [dec, 6, _computedKey]], []);
83-
_initStatic(_class);
83+
_initStatic(_Foo);
8484
})();
8585
var _A = {
8686
writable: true,
87-
value: _init_a(_class)
87+
value: _init_a(_Foo)
8888
};
8989
var _B = {
9090
writable: true,
91-
value: _init_a2(_class)
91+
value: _init_a2(_Foo)
9292
};
9393
var _C = {
9494
writable: true,
95-
value: _init_computedKey(_class)
95+
value: _init_computedKey(_Foo)
9696
};
9797
var _D = {
9898
writable: true,
99-
value: _init_computedKey2(_class)
99+
value: _init_computedKey2(_Foo)
100100
};
101101
var _E = {
102102
writable: true,
103-
value: _init_computedKey3(_class)
103+
value: _init_computedKey3(_Foo)
104104
};
105105
var _F = {
106106
writable: true,
107-
value: _init_computedKey4(_class)
107+
value: _init_computedKey4(_Foo)
108108
};
109109
var _G = {
110110
writable: true,
111-
value: _init_computedKey5(_class)
111+
value: _init_computedKey5(_Foo)
112112
};
113113
var _H = {
114114
writable: true,
115-
value: _init_computedKey6(_class)
115+
value: _init_computedKey6(_Foo)
116116
};
117117
var _I = {
118118
writable: true,
119-
value: _init_computedKey7(_class)
119+
value: _init_computedKey7(_Foo)
120120
};
121121
expect(logs).toStrictEqual(["computing f", "calling toPrimitive", "a", "#a", "b", "c", "0", "1", "2", "3", "f()"]);

packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-accessors--to-es2015/private/output.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
var _init_a, _get_a, _set_a, _init_b, _get_b, _set_b, _initProto, _class;
1+
var _init_a, _get_a, _set_a, _init_b, _get_b, _set_b, _initProto, _Foo;
22
const dec = () => {};
33
var _A = /*#__PURE__*/new WeakMap();
44
var _a = /*#__PURE__*/new WeakMap();
@@ -24,7 +24,7 @@ class Foo {
2424
});
2525
}
2626
}
27-
_class = Foo;
27+
_Foo = Foo;
2828
function _set_a2(v) {
2929
_set_a(this, v);
3030
}
@@ -37,7 +37,7 @@ function _set_b2(v) {
3737
function _get_b2() {
3838
return _get_b(this);
3939
}
40-
[_init_a, _get_a, _set_a, _init_b, _get_b, _set_b, _initProto] = babelHelpers.applyDecs(_class, [[dec, 1, "a", function () {
40+
[_init_a, _get_a, _set_a, _init_b, _get_b, _set_b, _initProto] = babelHelpers.applyDecs(_Foo, [[dec, 1, "a", function () {
4141
return babelHelpers.classPrivateFieldGet(this, _A);
4242
}, function (value) {
4343
babelHelpers.classPrivateFieldSet(this, _A, value);

packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-accessors--to-es2015/public/output.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
var _init_a, _init_b, _init_computedKey, _initProto, _class;
1+
var _init_a, _init_b, _init_computedKey, _initProto, _Foo;
22
const dec = () => {};
33
var _A = /*#__PURE__*/new WeakMap();
44
var _B = /*#__PURE__*/new WeakMap();
@@ -37,5 +37,5 @@ class Foo {
3737
babelHelpers.classPrivateFieldSet(this, _C, v);
3838
}
3939
}
40-
_class = Foo;
41-
[_init_a, _init_b, _init_computedKey, _initProto] = babelHelpers.applyDecs(_class, [[dec, 1, "a"], [dec, 1, "b"], [dec, 1, 'c']], []);
40+
_Foo = Foo;
41+
[_init_a, _init_b, _init_computedKey, _initProto] = babelHelpers.applyDecs(_Foo, [[dec, 1, "a"], [dec, 1, "b"], [dec, 1, 'c']], []);

0 commit comments

Comments
 (0)