Skip to content

Commit f4a9616

Browse files
[static blocks] Do not inject new static fields after static code (#17443)
* [static blocks] Do not inject new static fields after static code * Update fixtures * Less parentheses * Avoid temp variable * Preserve class name * Fix Babel 8 * Fix ts * fix ts again * harden new-target test * Fix old Babel 7 compat --------- Co-authored-by: Huáng Jùnliàng <[email protected]>
1 parent 764084a commit f4a9616

File tree

26 files changed

+412
-97
lines changed

26 files changed

+412
-97
lines changed

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

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2238,9 +2238,8 @@ function shouldTransformClass(node: t.Class) {
22382238
return isDecorated(node) || node.body.body.some(shouldTransformElement);
22392239
}
22402240

2241-
// Todo: unify name references logic with helper-function-name
2242-
function NamedEvaluationVisitoryFactory(
2243-
isAnonymous: (path: NodePath) => boolean,
2241+
export function buildNamedEvaluationVisitor(
2242+
needsName: (path: NodePath) => boolean,
22442243
visitor: (
22452244
path: NodePath,
22462245
state: PluginPass,
@@ -2288,7 +2287,7 @@ function NamedEvaluationVisitoryFactory(
22882287
const id = path.node.id;
22892288
if (id.type === "Identifier") {
22902289
const initializer = skipTransparentExprWrappers(path.get("init"));
2291-
if (isAnonymous(initializer)) {
2290+
if (needsName(initializer)) {
22922291
const name = id.name;
22932292
visitor(initializer, state, name);
22942293
}
@@ -2298,7 +2297,7 @@ function NamedEvaluationVisitoryFactory(
22982297
const id = path.node.left;
22992298
if (id.type === "Identifier") {
23002299
const initializer = skipTransparentExprWrappers(path.get("right"));
2301-
if (isAnonymous(initializer)) {
2300+
if (needsName(initializer)) {
23022301
switch (path.node.operator) {
23032302
case "=":
23042303
case "&&=":
@@ -2313,7 +2312,7 @@ function NamedEvaluationVisitoryFactory(
23132312
const id = path.node.left;
23142313
if (id.type === "Identifier") {
23152314
const initializer = skipTransparentExprWrappers(path.get("right"));
2316-
if (isAnonymous(initializer)) {
2315+
if (needsName(initializer)) {
23172316
const name = id.name;
23182317
visitor(initializer, state, name);
23192318
}
@@ -2329,7 +2328,7 @@ function NamedEvaluationVisitoryFactory(
23292328
const initializer = skipTransparentExprWrappers(
23302329
propertyPath.get("value") as NodePath<t.Expression>,
23312330
);
2332-
if (isAnonymous(initializer)) {
2331+
if (needsName(initializer)) {
23332332
if (!node.computed) {
23342333
// 13.2.5.5 RS: PropertyDefinitionEvaluation
23352334
if (!isProtoKey(id as t.StringLiteral | t.Identifier)) {
@@ -2358,7 +2357,7 @@ function NamedEvaluationVisitoryFactory(
23582357
ClassPrivateProperty(path, state) {
23592358
const { node } = path;
23602359
const initializer = skipTransparentExprWrappers(path.get("value"));
2361-
if (isAnonymous(initializer)) {
2360+
if (needsName(initializer)) {
23622361
const className = t.stringLiteral("#" + node.key.id.name);
23632362
visitor(initializer, state, className);
23642363
}
@@ -2367,7 +2366,7 @@ function NamedEvaluationVisitoryFactory(
23672366
const { node } = path;
23682367
const id = node.key;
23692368
const initializer = skipTransparentExprWrappers(path.get("value"));
2370-
if (isAnonymous(initializer)) {
2369+
if (needsName(initializer)) {
23712370
if (!node.computed) {
23722371
if (id.type === "Identifier") {
23732372
visitor(initializer, state, id.name);
@@ -2396,7 +2395,7 @@ function NamedEvaluationVisitoryFactory(
23962395
const { node } = path;
23972396
const id = node.key;
23982397
const initializer = skipTransparentExprWrappers(path.get("value"));
2399-
if (isAnonymous(initializer)) {
2398+
if (needsName(initializer)) {
24002399
if (!node.computed) {
24012400
if (id.type === "Identifier") {
24022401
visitor(initializer, state, id.name);
@@ -2455,7 +2454,7 @@ export default function (
24552454
const ignoreFunctionLength = assumption("ignoreFunctionLength") ?? loose;
24562455

24572456
const namedEvaluationVisitor: Visitor<PluginPass> =
2458-
NamedEvaluationVisitoryFactory(
2457+
buildNamedEvaluationVisitor(
24592458
isDecoratedAnonymousClassExpression,
24602459
visitClass,
24612460
);

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ import {
1111
buildCheckInRHS,
1212
} from "./fields.ts";
1313
import type { PropPath } from "./fields.ts";
14-
import createDecoratorTransform, { hasDecorators } from "./decorators.ts";
14+
import createDecoratorTransform, {
15+
hasDecorators,
16+
buildNamedEvaluationVisitor,
17+
} from "./decorators.ts";
1518
import type { DecoratorVersionKind } from "./decorators.ts";
1619
import { buildDecoratedClass } from "./decorators-2018-09.ts" with { if: "!process.env.BABEL_8_BREAKING" };
1720
import { injectInitialization, extractComputedKeys } from "./misc.ts";
@@ -23,7 +26,13 @@ import {
2326
} from "./features.ts";
2427
import { assertFieldTransformed } from "./typescript.ts";
2528

26-
export { FEATURES, enableFeature, injectInitialization, buildCheckInRHS };
29+
export {
30+
FEATURES,
31+
enableFeature,
32+
injectInitialization,
33+
buildCheckInRHS,
34+
buildNamedEvaluationVisitor,
35+
};
2736

2837
const versionKey = "@babel/plugin-class-features/version";
2938

packages/babel-plugin-proposal-decorators/test/fixtures/2023-11-misc/outer-class-binding-mutated/output.js

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
var _staticBlock;
23
let _computedKeyDecs, _computedKey, _init_computedKey, _init_extra_computedKey;
34
"class binding in plain class, decorated field, and computed keys";
45
const errs = [];
@@ -19,12 +20,13 @@
1920
capture(() => K);
2021
assertUninitialized(() => K);
2122
class K {
22-
static #_ = [_init_computedKey, _init_extra_computedKey] = babelHelpers.applyDecs2311(this, [], [[_computedKeyDecs, 0, _computedKey]]).e;
2323
constructor() {
2424
_init_extra_computedKey(this);
2525
}
2626
[(_computedKeyDecs = [capture(() => K), assertUninitialized(() => K)], _computedKey = babelHelpers.toPropertyKey((capture(() => K), assertUninitialized(() => K))))] = _init_computedKey(this);
27+
static #_ = _staticBlock = () => [_init_computedKey, _init_extra_computedKey] = babelHelpers.applyDecs2311(this, [], [[_computedKeyDecs, 0, _computedKey]]).e;
2728
}
29+
_staticBlock();
2830
const E = ReferenceError;
2931
expect(errs.map(e => e.constructor)).toEqual([E, E, E]);
3032
const C = K;
@@ -53,19 +55,20 @@
5355
_classDecs = [capture(() => _K), assertUninitialized(() => _K)];
5456
let _K, _t_K;
5557
{
58+
var _staticBlock2;
5659
let _K;
5760
class K {
58-
static #_ = {
59-
e: [_init_computedKey2, _init_extra_computedKey2],
60-
c: [_K, _initClass]
61-
} = babelHelpers.applyDecs2311(this, _classDecs, [[_computedKeyDecs2, 0, _computedKey2]]);
6261
constructor() {
6362
_init_extra_computedKey2(this);
6463
}
6564
//todo: add the assertUninitialized decorator when we properly implement class tdz
6665
[(_computedKeyDecs2 = capture(() => _K), _computedKey2 = babelHelpers.toPropertyKey(capture(() => _K)))] = _init_computedKey2(this);
67-
static #_2 = _initClass();
66+
static #_ = _staticBlock2 = () => ({
67+
e: [_init_computedKey2, _init_extra_computedKey2],
68+
c: [_K, _initClass]
69+
} = babelHelpers.applyDecs2311(this, _classDecs, [[_computedKeyDecs2, 0, _computedKey2]]), _initClass());
6870
}
71+
_staticBlock2();
6972
_t_K = _K;
7073
}
7174
_K = _t_K;
@@ -97,18 +100,19 @@
97100
_classDecs2 = [capture(() => _K2), assertUninitialized(() => _K2)];
98101
let _K2, _t_K2;
99102
{
103+
var _staticBlock3;
100104
let _K2;
101105
new class extends babelHelpers.identity {
102-
static [class K {
103-
static [(_computedKeyDecs3 = capture(() => _K2), _computedKey3 = babelHelpers.toPropertyKey(capture(() => _K2)), "_")];
104-
static #_ = (() => {
106+
static [(class K {
107+
static [(_computedKeyDecs3 = capture(() => _K2), _computedKey3 = babelHelpers.toPropertyKey(capture(() => _K2)), "_")] = void (_staticBlock3 = () => {
105108
delete this._;
106109
({
107110
e: [_init_computedKey3, _init_extra_computedKey3],
108111
c: [_K2, _initClass2]
109112
} = babelHelpers.applyDecs2311(this, _classDecs2, [[_computedKeyDecs3, 8, _computedKey3]]));
110-
})();
111-
}];
113+
return this;
114+
});
115+
}, _staticBlock3())];
112116
//todo: add the assertUninitialized decorator when we properly implement class tdz
113117
[_computedKey3] = _init_computedKey3();
114118
constructor() {
@@ -150,19 +154,20 @@
150154
_classDecs3 = [capture(await (() => _K3)), assertUninitialized(await (() => _K3))];
151155
let _K3, _t_K3;
152156
{
157+
var _staticBlock4;
153158
let _K3;
154159
class K {
155-
static #_ = (() => {
160+
//todo: add the assertUninitialized decorator when we properly implement class tdz
161+
static [(_computedKeyDecs4 = capture(await (() => _K3)), _computedKey4 = babelHelpers.toPropertyKey(capture(await (() => _K3))))]() {}
162+
static #_ = _staticBlock4 = () => ((() => {
156163
({
157164
e: [_initStatic],
158165
c: [_K3, _initClass3]
159166
} = babelHelpers.applyDecs2311(this, _classDecs3, [[_computedKeyDecs4, 10, _computedKey4]]));
160167
_initStatic(this);
161-
})();
162-
//todo: add the assertUninitialized decorator when we properly implement class tdz
163-
static [(_computedKeyDecs4 = capture(await (() => _K3)), _computedKey4 = babelHelpers.toPropertyKey(capture(await (() => _K3))))]() {}
164-
static #_2 = _initClass3();
168+
})(), _initClass3());
165169
}
170+
_staticBlock4();
166171
_t_K3 = _K3;
167172
}
168173
_K3 = _t_K3;

0 commit comments

Comments
 (0)