Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix class private properties when privateFieldsAsSymbols #16312

Merged
merged 3 commits into from Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
64 changes: 45 additions & 19 deletions packages/babel-helper-create-class-features-plugin/src/fields.ts
Expand Up @@ -47,7 +47,7 @@ if (!process.env.BABEL_8_BREAKING) {

export function buildPrivateNamesMap(
className: string,
privateFieldsAsProperties: boolean,
privateFieldsAsSymbolsOrProperties: boolean,
props: PropPath[],
file: File,
) {
Expand All @@ -63,7 +63,7 @@ export function buildPrivateNamesMap(
let initAdded = false;
let id: t.Identifier;
if (
!privateFieldsAsProperties &&
!privateFieldsAsSymbolsOrProperties &&
(process.env.BABEL_8_BREAKING || newHelpers(file)) &&
isMethod &&
!isStatic
Expand Down Expand Up @@ -183,7 +183,9 @@ export function buildPrivateNamesNodes(
}

if (init) {
annotateAsPure(init);
if (!privateFieldsAsSymbols) {
annotateAsPure(init);
}
initNodes.push(template.statement.ast`var ${id} = ${init}`);
}
}
Expand Down Expand Up @@ -1283,7 +1285,7 @@ function buildPrivateMethodDeclaration(
file: File,
prop: NodePath<t.ClassPrivateMethod>,
privateNamesMap: PrivateNamesMap,
privateFieldsAsProperties = false,
privateFieldsAsSymbolsOrProperties = false,
) {
const privateName = privateNamesMap.get(prop.node.key.id.name);
const {
Expand All @@ -1310,7 +1312,7 @@ function buildPrivateMethodDeclaration(
if (
(process.env.BABEL_8_BREAKING || newHelpers(file)) &&
(isGetter || isSetter) &&
!privateFieldsAsProperties
!privateFieldsAsSymbolsOrProperties
) {
const scope = prop.get("body").scope;
const thisArg = scope.generateUidIdentifier("this");
Expand Down Expand Up @@ -1350,7 +1352,7 @@ function buildPrivateMethodDeclaration(
initAdded: true,
});
declId = setId;
} else if (isStatic && !privateFieldsAsProperties) {
} else if (isStatic && !privateFieldsAsSymbolsOrProperties) {
declId = id;
}

Expand Down Expand Up @@ -1511,7 +1513,7 @@ export function buildFieldsInitNodes(
privateNamesMap: PrivateNamesMap,
file: File,
setPublicClassFields: boolean,
privateFieldsAsProperties: boolean,
privateFieldsAsSymbolsOrProperties: boolean,
noUninitializedPrivateFieldAccess: boolean,
constantSuper: boolean,
innerBindingRef: t.Identifier | null,
Expand Down Expand Up @@ -1606,12 +1608,18 @@ export function buildFieldsInitNodes(
}
break;
}
case isStatic && isPrivate && isField && privateFieldsAsProperties:
case isStatic &&
isPrivate &&
isField &&
privateFieldsAsSymbolsOrProperties:
staticNodes.push(
buildPrivateFieldInitLoose(t.cloneNode(ref), prop, privateNamesMap),
);
break;
case isStatic && isPrivate && isField && !privateFieldsAsProperties:
case isStatic &&
isPrivate &&
isField &&
!privateFieldsAsSymbolsOrProperties:
if (!process.env.BABEL_8_BREAKING && !newHelpers(file)) {
staticNodes.push(
buildPrivateStaticFieldInitSpecOld(prop, privateNamesMap),
Expand Down Expand Up @@ -1645,12 +1653,18 @@ export function buildFieldsInitNodes(
buildPublicFieldInitSpec(t.cloneNode(ref), prop, file),
);
break;
case isInstance && isPrivate && isField && privateFieldsAsProperties:
case isInstance &&
isPrivate &&
isField &&
privateFieldsAsSymbolsOrProperties:
instanceNodes.push(
buildPrivateFieldInitLoose(t.thisExpression(), prop, privateNamesMap),
);
break;
case isInstance && isPrivate && isField && !privateFieldsAsProperties:
case isInstance &&
isPrivate &&
isField &&
!privateFieldsAsSymbolsOrProperties:
instanceNodes.push(
buildPrivateInstanceFieldInitSpec(
t.thisExpression(),
Expand All @@ -1660,7 +1674,10 @@ export function buildFieldsInitNodes(
),
);
break;
case isInstance && isPrivate && isMethod && privateFieldsAsProperties:
case isInstance &&
isPrivate &&
isMethod &&
privateFieldsAsSymbolsOrProperties:
instanceNodes.unshift(
buildPrivateMethodInitLoose(
t.thisExpression(),
Expand All @@ -1675,11 +1692,14 @@ export function buildFieldsInitNodes(
// @ts-expect-error checked in switch
prop,
privateNamesMap,
privateFieldsAsProperties,
privateFieldsAsSymbolsOrProperties,
),
);
break;
case isInstance && isPrivate && isMethod && !privateFieldsAsProperties:
case isInstance &&
isPrivate &&
isMethod &&
!privateFieldsAsSymbolsOrProperties:
instanceNodes.unshift(
buildPrivateInstanceMethodInitSpec(
t.thisExpression(),
Expand All @@ -1695,11 +1715,14 @@ export function buildFieldsInitNodes(
// @ts-expect-error checked in switch
prop,
privateNamesMap,
privateFieldsAsProperties,
privateFieldsAsSymbolsOrProperties,
),
);
break;
case isStatic && isPrivate && isMethod && !privateFieldsAsProperties:
case isStatic &&
isPrivate &&
isMethod &&
!privateFieldsAsSymbolsOrProperties:
if (!process.env.BABEL_8_BREAKING && !newHelpers(file)) {
staticNodes.unshift(
// @ts-expect-error checked in switch
Expand All @@ -1712,11 +1735,14 @@ export function buildFieldsInitNodes(
// @ts-expect-error checked in switch
prop,
privateNamesMap,
privateFieldsAsProperties,
privateFieldsAsSymbolsOrProperties,
),
);
break;
case isStatic && isPrivate && isMethod && privateFieldsAsProperties:
case isStatic &&
isPrivate &&
isMethod &&
privateFieldsAsSymbolsOrProperties:
staticNodes.unshift(
buildPrivateStaticMethodInitLoose(
t.cloneNode(ref),
Expand All @@ -1732,7 +1758,7 @@ export function buildFieldsInitNodes(
// @ts-expect-error checked in switch
prop,
privateNamesMap,
privateFieldsAsProperties,
privateFieldsAsSymbolsOrProperties,
),
);
break;
Expand Down
Expand Up @@ -240,7 +240,7 @@ export function createClassFeaturePlugin({

const privateNamesMap = buildPrivateNamesMap(
classRefForDefine.name,
privateFieldsAsProperties ?? loose,
privateFieldsAsSymbolsOrProperties ?? loose,
props,
file,
);
Expand Down
@@ -1,8 +1,8 @@
var _privateField = /*#__PURE__*/Symbol("privateField");
var _Cl_brand = /*#__PURE__*/Symbol("privateFieldValue");
var _privateField = Symbol("privateField");
var _privateFieldValue = Symbol("privateFieldValue");
class Cl {
constructor() {
Object.defineProperty(this, _Cl_brand, {
Object.defineProperty(this, _privateFieldValue, {
get: _get_privateFieldValue,
set: _set_privateFieldValue
});
Expand All @@ -13,10 +13,10 @@ class Cl {
this.publicField = "not secret string";
}
publicGetPrivateField() {
return babelHelpers.classPrivateFieldLooseBase(this, _Cl_brand)[_Cl_brand];
return babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue];
}
publicSetPrivateField(newValue) {
babelHelpers.classPrivateFieldLooseBase(this, _Cl_brand)[_Cl_brand] = newValue;
babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue] = newValue;
}
}
function _get_privateFieldValue() {
Expand Down
@@ -1,8 +1,8 @@
var _A;
var _A_brand = /*#__PURE__*/Symbol("getA");
var _getA = Symbol("getA");
class A {
constructor() {
Object.defineProperty(this, _A_brand, {
Object.defineProperty(this, _getA, {
get: _get_getA,
set: void 0
});
Expand Down
@@ -1,16 +1,16 @@
var _privateField = /*#__PURE__*/Symbol("privateField");
var _Cl_brand = /*#__PURE__*/Symbol("privateFieldValue");
var _privateField = Symbol("privateField");
var _privateFieldValue = Symbol("privateFieldValue");
class Cl {
constructor() {
Object.defineProperty(this, _Cl_brand, {
Object.defineProperty(this, _privateFieldValue, {
get: void 0,
set: _set_privateFieldValue
});
Object.defineProperty(this, _privateField, {
writable: true,
value: 0
});
this.publicField = babelHelpers.classPrivateFieldLooseBase(this, _Cl_brand)[_Cl_brand];
this.publicField = babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue];
}
}
function _set_privateFieldValue(newValue) {
Expand Down
@@ -1,8 +1,8 @@
var _C_brand = /*#__PURE__*/Symbol("a");
var _a = Symbol("a");
class C {
constructor() {
/* before get a */
Object.defineProperty(this, _C_brand, {
Object.defineProperty(this, _a, {
get: _get_a,
set: _set_a
});
Expand Down
@@ -1,17 +1,17 @@
var _privateField = /*#__PURE__*/Symbol("privateField");
var _Cl_brand = /*#__PURE__*/Symbol("privateFieldValue");
var _privateField = Symbol("privateField");
var _privateFieldValue = Symbol("privateFieldValue");
class Cl {
constructor() {
Object.defineProperty(this, _Cl_brand, {
Object.defineProperty(this, _privateFieldValue, {
get: _get_privateFieldValue,
set: void 0
});
Object.defineProperty(this, _privateField, {
writable: true,
value: 0
});
babelHelpers.classPrivateFieldLooseBase(this, _Cl_brand)[_Cl_brand] = 1;
[babelHelpers.classPrivateFieldLooseBase(this, _Cl_brand)[_Cl_brand]] = [1];
babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue] = 1;
[babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue]] = [1];
}
}
function _get_privateFieldValue() {
Expand Down
@@ -1,8 +1,8 @@
var _privateField = /*#__PURE__*/Symbol("privateField");
var _Cl_brand = /*#__PURE__*/Symbol("privateFieldValue");
var _privateField = Symbol("privateField");
var _privateFieldValue = Symbol("privateFieldValue");
class Cl {
constructor() {
Object.defineProperty(this, _Cl_brand, {
Object.defineProperty(this, _privateFieldValue, {
get: _get_privateFieldValue,
set: _set_privateFieldValue
});
Expand All @@ -13,10 +13,10 @@ class Cl {
this.publicField = "not secret string";
}
publicGetPrivateField() {
return babelHelpers.classPrivateFieldLooseBase(this, _Cl_brand)[_Cl_brand];
return babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue];
}
publicSetPrivateField(newValue) {
babelHelpers.classPrivateFieldLooseBase(this, _Cl_brand)[_Cl_brand] = newValue;
babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue] = newValue;
}
get publicFieldValue() {
return this.publicField;
Expand All @@ -27,13 +27,13 @@ class Cl {
testUpdates() {
babelHelpers.classPrivateFieldLooseBase(this, _privateField)[_privateField] = 0;
this.publicField = 0;
babelHelpers.classPrivateFieldLooseBase(this, _Cl_brand)[_Cl_brand] = babelHelpers.classPrivateFieldLooseBase(this, _Cl_brand)[_Cl_brand]++;
babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue] = babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue]++;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems we should optimize this helper.

this.publicFieldValue = this.publicFieldValue++;
++babelHelpers.classPrivateFieldLooseBase(this, _Cl_brand)[_Cl_brand];
++babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue];
++this.publicFieldValue;
babelHelpers.classPrivateFieldLooseBase(this, _Cl_brand)[_Cl_brand] += 1;
babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue] += 1;
this.publicFieldValue += 1;
babelHelpers.classPrivateFieldLooseBase(this, _Cl_brand)[_Cl_brand] = -(babelHelpers.classPrivateFieldLooseBase(this, _Cl_brand)[_Cl_brand] ** babelHelpers.classPrivateFieldLooseBase(this, _Cl_brand)[_Cl_brand]);
babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue] = -(babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue] ** babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue]);
this.publicFieldValue = -(this.publicFieldValue ** this.publicFieldValue);
}
}
Expand Down
@@ -1,12 +1,12 @@
var _Foo_brand = /*#__PURE__*/Symbol("privateMethod");
var _privateMethod = Symbol("privateMethod");
class Foo {
constructor() {
Object.defineProperty(this, _Foo_brand, {
value: _privateMethod
Object.defineProperty(this, _privateMethod, {
value: _privateMethod2
});
this.publicField = babelHelpers.classPrivateFieldLooseBase(this, _Foo_brand)[_Foo_brand]();
this.publicField = babelHelpers.classPrivateFieldLooseBase(this, _privateMethod)[_privateMethod]();
}
}
function _privateMethod() {
function _privateMethod2() {
return 42;
}
@@ -1,20 +1,20 @@
var _priv = /*#__PURE__*/Symbol("priv");
var _Cl_brand = /*#__PURE__*/Symbol("method");
var _priv = Symbol("priv");
var _method = Symbol("method");
class Cl {
constructor() {
Object.defineProperty(this, _Cl_brand, {
value: _method
Object.defineProperty(this, _method, {
value: _method2
});
babelHelpers.defineProperty(this, "prop", babelHelpers.classPrivateFieldLooseBase(this, _Cl_brand)[_Cl_brand](1));
babelHelpers.defineProperty(this, "prop", babelHelpers.classPrivateFieldLooseBase(this, _method)[_method](1));
Object.defineProperty(this, _priv, {
writable: true,
value: babelHelpers.classPrivateFieldLooseBase(this, _Cl_brand)[_Cl_brand](2)
value: babelHelpers.classPrivateFieldLooseBase(this, _method)[_method](2)
});
}
getPriv() {
return babelHelpers.classPrivateFieldLooseBase(this, _priv)[_priv];
}
}
function _method(x) {
function _method2(x) {
return x;
}
@@ -1,13 +1,13 @@
var _A;
var _A_brand = /*#__PURE__*/Symbol("getA");
var _getA = Symbol("getA");
class A {
constructor() {
Object.defineProperty(this, _A_brand, {
value: _getA
Object.defineProperty(this, _getA, {
value: _getA2
});
}
}
_A = A;
function _getA() {
function _getA2() {
return _A;
}