Skip to content

Commit

Permalink
Fix support for private fields
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed Aug 17, 2023
1 parent 47be7f8 commit 46b0e7a
Show file tree
Hide file tree
Showing 14 changed files with 214 additions and 44 deletions.
99 changes: 55 additions & 44 deletions packages/babel-helper-member-expression-to-functions/src/index.ts
Expand Up @@ -169,12 +169,12 @@ const handle = {
const willEndPathCastToBoolean = willPathCastToBoolean(endPath);

const rootParentPath = endPath.parentPath;
if (
rootParentPath.isUpdateExpression({ argument: node }) ||
rootParentPath.isAssignmentExpression({ left: node })
) {
throw member.buildCodeFrameError(`can't handle assignment`);
if (rootParentPath.isUpdateExpression({ argument: node })) {
throw member.buildCodeFrameError(`can't handle update expression`);
}
const isAssignment = rootParentPath.isAssignmentExpression({
left: endPath.node,
});
const isDeleteOperation = rootParentPath.isUnaryExpression({
operator: "delete",
});
Expand Down Expand Up @@ -252,6 +252,9 @@ const handle = {
parentPath.isUnaryExpression({ operator: "delete" })
) {
parentPath.replaceWith(this.delete(member));
} else if (parentPath.isAssignmentExpression()) {
// `a?.#b = c` to `(a == null ? void 0 : a.#b = c)`
handleAssignment(this, member, parentPath);
} else {
member.replaceWith(this.get(member));
}
Expand Down Expand Up @@ -295,7 +298,7 @@ const handle = {
}

let replacementPath: NodePath = endPath;
if (isDeleteOperation) {
if (isDeleteOperation || isAssignment) {
replacementPath = endParentPath;
regular = endParentPath.node;
}
Expand Down Expand Up @@ -432,44 +435,7 @@ const handle = {
// MEMBER += VALUE -> _set(MEMBER, _get(MEMBER) + VALUE)
// MEMBER ??= VALUE -> _get(MEMBER) ?? _set(MEMBER, VALUE)
if (parentPath.isAssignmentExpression({ left: node })) {
if (this.simpleSet) {
member.replaceWith(this.simpleSet(member));
return;
}

const { operator, right: value } = parentPath.node;

if (operator === "=") {
parentPath.replaceWith(this.set(member, value));
} else {
const operatorTrunc = operator.slice(0, -1);
if (LOGICAL_OPERATORS.includes(operatorTrunc)) {
// Give the state handler a chance to memoise the member, since we'll
// reference it twice. The first access (the get) should do the memo
// assignment.
this.memoise(member, 1);
parentPath.replaceWith(
logicalExpression(
operatorTrunc as t.LogicalExpression["operator"],
this.get(member),
this.set(member, value),
),
);
} else {
// Here, the second access (the set) is evaluated first.
this.memoise(member, 2);
parentPath.replaceWith(
this.set(
member,
binaryExpression(
operatorTrunc as t.BinaryExpression["operator"],
this.get(member),
value,
),
),
);
}
}
handleAssignment(this, member, parentPath);
return;
}

Expand Down Expand Up @@ -549,6 +515,51 @@ const handle = {
},
};

function handleAssignment(
state: HandlerState,
member: NodePath<t.MemberExpression | t.OptionalMemberExpression>,
parentPath: NodePath<t.AssignmentExpression>,
) {
if (state.simpleSet) {
member.replaceWith(state.simpleSet(member));
return;
}

const { operator, right: value } = parentPath.node;

if (operator === "=") {
parentPath.replaceWith(state.set(member, value));
} else {
const operatorTrunc = operator.slice(0, -1);
if (LOGICAL_OPERATORS.includes(operatorTrunc)) {
// Give the state handler a chance to memoise the member, since we'll
// reference it twice. The first access (the get) should do the memo
// assignment.
state.memoise(member, 1);
parentPath.replaceWith(
logicalExpression(
operatorTrunc as t.LogicalExpression["operator"],
state.get(member),
state.set(member, value),
),
);
} else {
// Here, the second access (the set) is evaluated first.
state.memoise(member, 2);
parentPath.replaceWith(
state.set(
member,
binaryExpression(
operatorTrunc as t.BinaryExpression["operator"],
state.get(member),
value,
),
),
);
}
}
}

export interface Handler<State> {
memoise?(
this: HandlerState<State> & State,
Expand Down
@@ -0,0 +1,12 @@
class A {
#x;

method() {
obj?.#x = 1;
obj?.#x += 2;
obj?.#x ??= 3;
obj?.#x.y = 4;
obj?.#x.y += 5;
obj?.#x.y ??= 6;
}
}
@@ -0,0 +1,6 @@
{
"plugins": [
["proposal-optional-chaining-assign", { "version": "2023-07" }],
"transform-class-properties"
]
}
@@ -0,0 +1,18 @@
var _x = /*#__PURE__*/new WeakMap();
class A {
constructor() {
babelHelpers.classPrivateFieldInitSpec(this, _x, {
writable: true,
value: void 0
});
}
method() {
var _obj, _obj2, _obj3, _obj4, _obj5, _obj6;
(_obj = obj) == null ? void 0 : babelHelpers.classPrivateFieldSet(_obj, _x, 1);
(_obj2 = obj) == null ? void 0 : babelHelpers.classPrivateFieldSet(_obj2, _x, babelHelpers.classPrivateFieldGet(_obj2, _x) + 2);
(_obj3 = obj) == null ? void 0 : babelHelpers.classPrivateFieldGet(_obj3, _x) ?? babelHelpers.classPrivateFieldSet(_obj3, _x, 3);
(_obj4 = obj) == null ? void 0 : babelHelpers.classPrivateFieldGet(_obj4, _x).y = 4;
(_obj5 = obj) == null ? void 0 : babelHelpers.classPrivateFieldGet(_obj5, _x).y += 5;
(_obj6 = obj) == null ? void 0 : babelHelpers.classPrivateFieldGet(_obj6, _x).y ??= 6;
}
}
@@ -0,0 +1,12 @@
class A {
#x;

method() {
obj?.#x = 1;
obj?.#x += 2;
obj?.#x ??= 3;
obj?.#x.y = 4;
obj?.#x.y += 5;
obj?.#x.y ??= 6;
}
}
@@ -0,0 +1,12 @@
class A {
#x;
method() {
var _obj, _obj2, _obj3, _obj4, _obj5, _obj6;
(_obj = obj) == null ? void 0 : _obj.#x = 1;
(_obj2 = obj) == null ? void 0 : _obj2.#x += 2;
(_obj3 = obj) == null ? void 0 : _obj3.#x ??= 3;
(_obj4 = obj) == null ? void 0 : _obj4.#x.y = 4;
(_obj5 = obj) == null ? void 0 : _obj5.#x.y += 5;
(_obj6 = obj) == null ? void 0 : _obj6.#x.y ??= 6;
}
}
@@ -0,0 +1,12 @@
class A {
#x;

method() {
obj?.#x = 1;
obj?.#x += 2;
obj?.#x ??= 3;
obj?.#x.y = 4;
obj?.#x.y += 5;
obj?.#x.y ??= 6;
}
}
@@ -0,0 +1,9 @@
{
"plugins": [
["proposal-optional-chaining-assign", { "version": "2023-07" }],
"transform-class-properties"
],
"assumptions": {
"privateFieldsAsProperties": true
}
}
@@ -0,0 +1,18 @@
var _x = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("x");
class A {
constructor() {
Object.defineProperty(this, _x, {
writable: true,
value: void 0
});
}
method() {
var _obj, _obj2, _obj3, _obj4, _obj5, _obj6;
(_obj = obj) === null || _obj === void 0 ? void 0 : babelHelpers.classPrivateFieldLooseBase(_obj, _x)[_x] = 1;
(_obj2 = obj) === null || _obj2 === void 0 ? void 0 : babelHelpers.classPrivateFieldLooseBase(_obj2, _x)[_x] += 2;
(_obj3 = obj) === null || _obj3 === void 0 ? void 0 : babelHelpers.classPrivateFieldLooseBase(_obj3, _x)[_x] ??= 3;
(_obj4 = obj) === null || _obj4 === void 0 ? void 0 : babelHelpers.classPrivateFieldLooseBase(_obj4, _x)[_x].y = 4;
(_obj5 = obj) === null || _obj5 === void 0 ? void 0 : babelHelpers.classPrivateFieldLooseBase(_obj5, _x)[_x].y += 5;
(_obj6 = obj) === null || _obj6 === void 0 ? void 0 : babelHelpers.classPrivateFieldLooseBase(_obj6, _x)[_x].y ??= 6;
}
}
@@ -0,0 +1,12 @@
class A {
#x;

method() {
obj?.#x = 1;
obj?.#x += 2;
obj?.#x ??= 3;
obj?.#x.y = 4;
obj?.#x.y += 5;
obj?.#x.y ??= 6;
}
}
@@ -0,0 +1,6 @@
{
"plugins": [
["proposal-optional-chaining-assign", { "version": "2023-07" }],
"transform-class-properties"
]
}
@@ -0,0 +1,18 @@
var _x = /*#__PURE__*/new WeakMap();
class A {
constructor() {
babelHelpers.classPrivateFieldInitSpec(this, _x, {
writable: true,
value: void 0
});
}
method() {
var _obj, _obj2, _obj3, _obj4, _obj5, _obj6;
(_obj = obj) === null || _obj === void 0 ? void 0 : babelHelpers.classPrivateFieldSet(_obj, _x, 1);
(_obj2 = obj) === null || _obj2 === void 0 ? void 0 : babelHelpers.classPrivateFieldSet(_obj2, _x, babelHelpers.classPrivateFieldGet(_obj2, _x) + 2);
(_obj3 = obj) === null || _obj3 === void 0 ? void 0 : babelHelpers.classPrivateFieldGet(_obj3, _x) ?? babelHelpers.classPrivateFieldSet(_obj3, _x, 3);
(_obj4 = obj) === null || _obj4 === void 0 ? void 0 : babelHelpers.classPrivateFieldGet(_obj4, _x).y = 4;
(_obj5 = obj) === null || _obj5 === void 0 ? void 0 : babelHelpers.classPrivateFieldGet(_obj5, _x).y += 5;
(_obj6 = obj) === null || _obj6 === void 0 ? void 0 : babelHelpers.classPrivateFieldGet(_obj6, _x).y ??= 6;
}
}
@@ -0,0 +1,12 @@
class A {
#x;

method() {
obj?.#x = 1;
obj?.#x += 2;
obj?.#x ??= 3;
obj?.#x.y = 4;
obj?.#x.y += 5;
obj?.#x.y ??= 6;
}
}
@@ -0,0 +1,12 @@
class A {
#x;
method() {
var _obj, _obj2, _obj3, _obj4, _obj5, _obj6;
(_obj = obj) === null || _obj === void 0 ? void 0 : _obj.#x = 1;
(_obj2 = obj) === null || _obj2 === void 0 ? void 0 : _obj2.#x += 2;
(_obj3 = obj) === null || _obj3 === void 0 ? void 0 : _obj3.#x ??= 3;
(_obj4 = obj) === null || _obj4 === void 0 ? void 0 : _obj4.#x.y = 4;
(_obj5 = obj) === null || _obj5 === void 0 ? void 0 : _obj5.#x.y += 5;
(_obj6 = obj) === null || _obj6 === void 0 ? void 0 : _obj6.#x.y ??= 6;
}
}

0 comments on commit 46b0e7a

Please sign in to comment.