diff --git a/packages/babel-helper-member-expression-to-functions/src/index.ts b/packages/babel-helper-member-expression-to-functions/src/index.ts index 9fc0407e273c..fd629d54de30 100644 --- a/packages/babel-helper-member-expression-to-functions/src/index.ts +++ b/packages/babel-helper-member-expression-to-functions/src/index.ts @@ -16,11 +16,10 @@ import { logicalExpression, memberExpression, nullLiteral, - numericLiteral, optionalCallExpression, optionalMemberExpression, sequenceExpression, - unaryExpression, + updateExpression, } from "@babel/types"; import type * as t from "@babel/types"; import { willPathCastToBoolean } from "./util"; @@ -350,8 +349,8 @@ const handle = { return; } - // MEMBER++ -> _set(MEMBER, (_ref = (+_get(MEMBER))) + 1), _ref - // ++MEMBER -> _set(MEMBER, (+_get(MEMBER)) + 1) + // MEMBER++ -> _set(MEMBER, (ref = _get(MEMBER), ref2 = ref++, ref)), ref2 + // ++MEMBER -> _set(MEMBER, (ref = _get(MEMBER), ++ref)) if (isUpdateExpression(parent, { argument: node })) { if (this.simpleSet) { member.replaceWith(this.simpleSet(member)); @@ -365,31 +364,43 @@ const handle = { // assignment. this.memoise(member, 2); - const value = binaryExpression( - operator[0] as "+" | "-", - unaryExpression("+", this.get(member)), - numericLiteral(1), - ); + const ref = scope.generateUidIdentifierBasedOnNode(node); + scope.push({ id: ref }); + + const seq: t.Expression[] = [ + // ref = _get(MEMBER) + assignmentExpression("=", cloneNode(ref), this.get(member)), + ]; if (prefix) { + seq.push(updateExpression(operator, cloneNode(ref), prefix)); + + // (ref = _get(MEMBER), ++ref) + const value = sequenceExpression(seq); parentPath.replaceWith(this.set(member, value)); - } else { - const { scope } = member; - const ref = scope.generateUidIdentifierBasedOnNode(node); - scope.push({ id: ref }); - value.left = assignmentExpression( - "=", + return; + } else { + const ref2 = scope.generateUidIdentifierBasedOnNode(node); + scope.push({ id: ref2 }); + + seq.push( + assignmentExpression( + "=", + cloneNode(ref2), + updateExpression(operator, cloneNode(ref), prefix), + ), cloneNode(ref), - // @ts-expect-error todo(flow->ts) value.left is possibly PrivateName, which is not usable here - value.left, ); + // (ref = _get(MEMBER), ref2 = ref++, ref) + const value = sequenceExpression(seq); parentPath.replaceWith( - sequenceExpression([this.set(member, value), cloneNode(ref)]), + sequenceExpression([this.set(member, value), cloneNode(ref2)]), ); + + return; } - return; } // MEMBER = VALUE -> _set(MEMBER, VALUE) diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/update/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/update/output.js index cab004ed47e6..f9969af58c97 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/update/output.js +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/update/output.js @@ -14,12 +14,12 @@ var Foo = /*#__PURE__*/function () { babelHelpers.createClass(Foo, [{ key: "test", value: function test(other) { - var _this$foo, _other$obj, _other$obj$foo, _other$obj2; + var _this$foo, _this$foo2, _this$foo3, _other$obj, _other$obj$foo, _other$obj$foo2, _other$obj2, _other$obj$foo3; - babelHelpers.classPrivateFieldSet(this, _foo, (_this$foo = +babelHelpers.classPrivateFieldGet(this, _foo)) + 1), _this$foo; - babelHelpers.classPrivateFieldSet(this, _foo, +babelHelpers.classPrivateFieldGet(this, _foo) + 1); - babelHelpers.classPrivateFieldSet(_other$obj = other.obj, _foo, (_other$obj$foo = +babelHelpers.classPrivateFieldGet(_other$obj, _foo)) + 1), _other$obj$foo; - babelHelpers.classPrivateFieldSet(_other$obj2 = other.obj, _foo, +babelHelpers.classPrivateFieldGet(_other$obj2, _foo) + 1); + babelHelpers.classPrivateFieldSet(this, _foo, (_this$foo = babelHelpers.classPrivateFieldGet(this, _foo), _this$foo2 = _this$foo++, _this$foo)), _this$foo2; + babelHelpers.classPrivateFieldSet(this, _foo, (_this$foo3 = babelHelpers.classPrivateFieldGet(this, _foo), ++_this$foo3)); + babelHelpers.classPrivateFieldSet(_other$obj = other.obj, _foo, (_other$obj$foo = babelHelpers.classPrivateFieldGet(_other$obj, _foo), _other$obj$foo2 = _other$obj$foo++, _other$obj$foo)), _other$obj$foo2; + babelHelpers.classPrivateFieldSet(_other$obj2 = other.obj, _foo, (_other$obj$foo3 = babelHelpers.classPrivateFieldGet(_other$obj2, _foo), ++_other$obj$foo3)); } }]); return Foo; diff --git a/packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/updates-bigint/exec.js b/packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/updates-bigint/exec.js new file mode 100644 index 000000000000..37cce1c50e94 --- /dev/null +++ b/packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/updates-bigint/exec.js @@ -0,0 +1,50 @@ +class Cl { + #privateField = "top secret string"; + + constructor() { + this.publicField = "not secret string"; + } + + get #privateFieldValue() { + return this.#privateField; + } + + set #privateFieldValue(newValue) { + this.#privateField = newValue; + } + + publicGetPrivateField() { + return this.#privateFieldValue; + } + + publicSetPrivateField(newValue) { + this.#privateFieldValue = newValue; + } + + get publicFieldValue() { + return this.publicField; + } + + set publicFieldValue(newValue) { + this.publicField = newValue; + } + + testUpdates() { + this.#privateField = 0n; + this.publicField = 0n; + this.#privateFieldValue = this.#privateFieldValue++; + this.publicFieldValue = this.publicFieldValue++; + expect(this.#privateField).toEqual(this.publicField); + + ++this.#privateFieldValue; + ++this.publicFieldValue; + expect(this.#privateField).toEqual(this.publicField); + + this.#privateFieldValue += 1n; + this.publicFieldValue += 1n; + expect(this.#privateField).toEqual(this.publicField); + } +} + +const cl = new Cl(); +cl.testUpdates(); diff --git a/packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/updates-bigint/input.js b/packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/updates-bigint/input.js new file mode 100644 index 000000000000..aac3969ee6ca --- /dev/null +++ b/packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/updates-bigint/input.js @@ -0,0 +1,47 @@ +class Cl { + #privateField = "top secret string"; + + constructor() { + this.publicField = "not secret string"; + } + + get #privateFieldValue() { + return this.#privateField; + } + + set #privateFieldValue(newValue) { + this.#privateField = newValue; + } + + publicGetPrivateField() { + return this.#privateFieldValue; + } + + publicSetPrivateField(newValue) { + this.#privateFieldValue = newValue; + } + + get publicFieldValue() { + return this.publicField; + } + + set publicFieldValue(newValue) { + this.publicField = newValue; + } + + testUpdates() { + this.#privateField = 0n; + this.publicField = 0n; + this.#privateFieldValue = this.#privateFieldValue++; + this.publicFieldValue = this.publicFieldValue++; + + ++this.#privateFieldValue; + ++this.publicFieldValue; + + this.#privateFieldValue += 1n; + this.publicFieldValue += 1n; + + this.#privateFieldValue = -(this.#privateFieldValue ** this.#privateFieldValue); + this.publicFieldValue = -(this.publicFieldValue ** this.publicFieldValue); + } +} \ No newline at end of file diff --git a/packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/updates-bigint/options.json b/packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/updates-bigint/options.json new file mode 100644 index 000000000000..b0ccc0d14159 --- /dev/null +++ b/packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/updates-bigint/options.json @@ -0,0 +1,8 @@ +{ + "minNodeVersion": "10.0.0", + "plugins": [ + "proposal-private-methods", + "proposal-class-properties", + "transform-block-scoping" + ] +} diff --git a/packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/updates-bigint/output.js b/packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/updates-bigint/output.js new file mode 100644 index 000000000000..6ea8dce4c259 --- /dev/null +++ b/packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/updates-bigint/output.js @@ -0,0 +1,57 @@ +var _privateField = /*#__PURE__*/new WeakMap(); + +var _privateFieldValue = /*#__PURE__*/new WeakMap(); + +class Cl { + constructor() { + babelHelpers.classPrivateFieldInitSpec(this, _privateFieldValue, { + get: _get_privateFieldValue, + set: _set_privateFieldValue + }); + babelHelpers.classPrivateFieldInitSpec(this, _privateField, { + writable: true, + value: "top secret string" + }); + this.publicField = "not secret string"; + } + + publicGetPrivateField() { + return babelHelpers.classPrivateFieldGet(this, _privateFieldValue); + } + + publicSetPrivateField(newValue) { + babelHelpers.classPrivateFieldSet(this, _privateFieldValue, newValue); + } + + get publicFieldValue() { + return this.publicField; + } + + set publicFieldValue(newValue) { + this.publicField = newValue; + } + + testUpdates() { + var _this$privateFieldVal, _this$privateFieldVal2, _this$privateFieldVal3, _this$privateFieldVal4, _this$privateFieldVal5; + + babelHelpers.classPrivateFieldSet(this, _privateField, 0n); + this.publicField = 0n; + babelHelpers.classPrivateFieldSet(this, _privateFieldValue, (babelHelpers.classPrivateFieldSet(this, _privateFieldValue, (_this$privateFieldVal3 = babelHelpers.classPrivateFieldGet(this, _privateFieldValue), _this$privateFieldVal4 = _this$privateFieldVal3++, _this$privateFieldVal3)), _this$privateFieldVal4)); + this.publicFieldValue = this.publicFieldValue++; + babelHelpers.classPrivateFieldSet(this, _privateFieldValue, (_this$privateFieldVal5 = babelHelpers.classPrivateFieldGet(this, _privateFieldValue), ++_this$privateFieldVal5)); + ++this.publicFieldValue; + babelHelpers.classPrivateFieldSet(this, _privateFieldValue, babelHelpers.classPrivateFieldGet(this, _privateFieldValue) + 1n); + this.publicFieldValue += 1n; + babelHelpers.classPrivateFieldSet(this, _privateFieldValue, -(babelHelpers.classPrivateFieldGet(this, _privateFieldValue) ** babelHelpers.classPrivateFieldGet(this, _privateFieldValue))); + this.publicFieldValue = -(this.publicFieldValue ** this.publicFieldValue); + } + +} + +function _get_privateFieldValue() { + return babelHelpers.classPrivateFieldGet(this, _privateField); +} + +function _set_privateFieldValue(newValue) { + babelHelpers.classPrivateFieldSet(this, _privateField, newValue); +} diff --git a/packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/updates/output.js b/packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/updates/output.js index a3e609e11f35..a6c8998b0fb7 100644 --- a/packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/updates/output.js +++ b/packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/updates/output.js @@ -32,13 +32,13 @@ class Cl { } testUpdates() { - var _this$privateFieldVal, _this$privateFieldVal2; + var _this$privateFieldVal, _this$privateFieldVal2, _this$privateFieldVal3, _this$privateFieldVal4, _this$privateFieldVal5; babelHelpers.classPrivateFieldSet(this, _privateField, 0); this.publicField = 0; - babelHelpers.classPrivateFieldSet(this, _privateFieldValue, (babelHelpers.classPrivateFieldSet(this, _privateFieldValue, (_this$privateFieldVal2 = +babelHelpers.classPrivateFieldGet(this, _privateFieldValue)) + 1), _this$privateFieldVal2)); + babelHelpers.classPrivateFieldSet(this, _privateFieldValue, (babelHelpers.classPrivateFieldSet(this, _privateFieldValue, (_this$privateFieldVal3 = babelHelpers.classPrivateFieldGet(this, _privateFieldValue), _this$privateFieldVal4 = _this$privateFieldVal3++, _this$privateFieldVal3)), _this$privateFieldVal4)); this.publicFieldValue = this.publicFieldValue++; - babelHelpers.classPrivateFieldSet(this, _privateFieldValue, +babelHelpers.classPrivateFieldGet(this, _privateFieldValue) + 1); + babelHelpers.classPrivateFieldSet(this, _privateFieldValue, (_this$privateFieldVal5 = babelHelpers.classPrivateFieldGet(this, _privateFieldValue), ++_this$privateFieldVal5)); ++this.publicFieldValue; babelHelpers.classPrivateFieldSet(this, _privateFieldValue, babelHelpers.classPrivateFieldGet(this, _privateFieldValue) + 1); this.publicFieldValue += 1; diff --git a/packages/babel-plugin-proposal-private-methods/test/fixtures/static-accessors/updates/output.js b/packages/babel-plugin-proposal-private-methods/test/fixtures/static-accessors/updates/output.js index d019caca57c4..0842b31f1dec 100644 --- a/packages/babel-plugin-proposal-private-methods/test/fixtures/static-accessors/updates/output.js +++ b/packages/babel-plugin-proposal-private-methods/test/fixtures/static-accessors/updates/output.js @@ -16,13 +16,13 @@ class Cl { } static testUpdates() { - var _Cl$privateFieldValue, _Cl$privateFieldValue2; + var _Cl$privateFieldValue, _Cl$privateFieldValue2, _Cl$privateFieldValue3, _Cl$privateFieldValue4, _Cl$privateFieldValue5; babelHelpers.classStaticPrivateFieldSpecSet(Cl, Cl, _privateField, 0); Cl.publicField = 0; - babelHelpers.classStaticPrivateFieldSpecSet(Cl, Cl, _privateFieldValue, (babelHelpers.classStaticPrivateFieldSpecSet(Cl, Cl, _privateFieldValue, (_Cl$privateFieldValue2 = +babelHelpers.classStaticPrivateFieldSpecGet(Cl, Cl, _privateFieldValue)) + 1), _Cl$privateFieldValue2)); + babelHelpers.classStaticPrivateFieldSpecSet(Cl, Cl, _privateFieldValue, (babelHelpers.classStaticPrivateFieldSpecSet(Cl, Cl, _privateFieldValue, (_Cl$privateFieldValue3 = babelHelpers.classStaticPrivateFieldSpecGet(Cl, Cl, _privateFieldValue), _Cl$privateFieldValue4 = _Cl$privateFieldValue3++, _Cl$privateFieldValue3)), _Cl$privateFieldValue4)); Cl.publicFieldValue = Cl.publicFieldValue++; - babelHelpers.classStaticPrivateFieldSpecSet(Cl, Cl, _privateFieldValue, +babelHelpers.classStaticPrivateFieldSpecGet(Cl, Cl, _privateFieldValue) + 1); + babelHelpers.classStaticPrivateFieldSpecSet(Cl, Cl, _privateFieldValue, (_Cl$privateFieldValue5 = babelHelpers.classStaticPrivateFieldSpecGet(Cl, Cl, _privateFieldValue), ++_Cl$privateFieldValue5)); ++Cl.publicFieldValue; babelHelpers.classStaticPrivateFieldSpecSet(Cl, Cl, _privateFieldValue, babelHelpers.classStaticPrivateFieldSpecGet(Cl, Cl, _privateFieldValue) + 1); Cl.publicFieldValue += 1; diff --git a/packages/babel-plugin-transform-classes/test/fixtures/get-set-loose/memoized-update/output.js b/packages/babel-plugin-transform-classes/test/fixtures/get-set-loose/memoized-update/output.js index f1421dcab93b..9bcf813a64d2 100644 --- a/packages/babel-plugin-transform-classes/test/fixtures/get-set-loose/memoized-update/output.js +++ b/packages/babel-plugin-transform-classes/test/fixtures/get-set-loose/memoized-update/output.js @@ -30,15 +30,15 @@ let Obj = /*#__PURE__*/function (_Base) { var _proto = Obj.prototype; _proto.update = function update() { - var _proper$prop, _super$proper$prop; + var _proper$prop, _super$proper$prop, _super$proper$prop2; - this[_proper$prop = proper.prop] = (_super$proper$prop = +_Base.prototype[_proper$prop]) + 1, _super$proper$prop; + this[_proper$prop = proper.prop] = (_super$proper$prop = _Base.prototype[_proper$prop], _super$proper$prop2 = _super$proper$prop++, _super$proper$prop), _super$proper$prop2; }; _proto.update2 = function update2() { - var _i, _super$i; + var _i, _super$i, _super$i2; - this[_i = i] = (_super$i = +_Base.prototype[_i]) + 1, _super$i; + this[_i = i] = (_super$i = _Base.prototype[_i], _super$i2 = _super$i++, _super$i), _super$i2; }; return Obj; diff --git a/packages/babel-plugin-transform-classes/test/fixtures/get-set/memoized-update/output.js b/packages/babel-plugin-transform-classes/test/fixtures/get-set/memoized-update/output.js index 9f0d7a9e5b62..d5069853b069 100644 --- a/packages/babel-plugin-transform-classes/test/fixtures/get-set/memoized-update/output.js +++ b/packages/babel-plugin-transform-classes/test/fixtures/get-set/memoized-update/output.js @@ -34,16 +34,16 @@ let Obj = /*#__PURE__*/function (_Base) { babelHelpers.createClass(Obj, [{ key: "update", value: function update() { - var _proper$prop, _super$proper$prop; + var _proper$prop, _super$proper$prop, _super$proper$prop2; - babelHelpers.set(babelHelpers.getPrototypeOf(Obj.prototype), _proper$prop = proper.prop, (_super$proper$prop = +babelHelpers.get(babelHelpers.getPrototypeOf(Obj.prototype), _proper$prop, this)) + 1, this, true), _super$proper$prop; + babelHelpers.set(babelHelpers.getPrototypeOf(Obj.prototype), _proper$prop = proper.prop, (_super$proper$prop = babelHelpers.get(babelHelpers.getPrototypeOf(Obj.prototype), _proper$prop, this), _super$proper$prop2 = _super$proper$prop++, _super$proper$prop), this, true), _super$proper$prop2; } }, { key: "update2", value: function update2() { - var _i, _super$i; + var _i, _super$i, _super$i2; - babelHelpers.set(babelHelpers.getPrototypeOf(Obj.prototype), _i = i, (_super$i = +babelHelpers.get(babelHelpers.getPrototypeOf(Obj.prototype), _i, this)) + 1, this, true), _super$i; + babelHelpers.set(babelHelpers.getPrototypeOf(Obj.prototype), _i = i, (_super$i = babelHelpers.get(babelHelpers.getPrototypeOf(Obj.prototype), _i, this), _super$i2 = _super$i++, _super$i), this, true), _super$i2; } }]); return Obj; diff --git a/packages/babel-plugin-transform-object-super/test/fixtures/object-super/super-increment-postfix/output.js b/packages/babel-plugin-transform-object-super/test/fixtures/object-super/super-increment-postfix/output.js index 55103d5f2764..1c69749a4db3 100644 --- a/packages/babel-plugin-transform-object-super/test/fixtures/object-super/super-increment-postfix/output.js +++ b/packages/babel-plugin-transform-object-super/test/fixtures/object-super/super-increment-postfix/output.js @@ -5,9 +5,9 @@ var Base = { }; var obj = _obj = { bar: function () { - var _super$test; + var _super$test, _super$test2; - return babelHelpers.set(babelHelpers.getPrototypeOf(_obj), "test", (_super$test = +babelHelpers.get(babelHelpers.getPrototypeOf(_obj), "test", this)) + 1, this, false), _super$test; + return babelHelpers.set(babelHelpers.getPrototypeOf(_obj), "test", (_super$test = babelHelpers.get(babelHelpers.getPrototypeOf(_obj), "test", this), _super$test2 = _super$test++, _super$test), this, false), _super$test2; } }; Object.setPrototypeOf(obj, Base); diff --git a/packages/babel-plugin-transform-object-super/test/fixtures/object-super/super-increment-prefix/output.js b/packages/babel-plugin-transform-object-super/test/fixtures/object-super/super-increment-prefix/output.js index c901504c8941..e490d284892e 100644 --- a/packages/babel-plugin-transform-object-super/test/fixtures/object-super/super-increment-prefix/output.js +++ b/packages/babel-plugin-transform-object-super/test/fixtures/object-super/super-increment-prefix/output.js @@ -5,7 +5,9 @@ var Base = { }; var obj = _obj = { bar: function () { - return babelHelpers.set(babelHelpers.getPrototypeOf(_obj), "test", +babelHelpers.get(babelHelpers.getPrototypeOf(_obj), "test", this) + 1, this, false); + var _super$test; + + return babelHelpers.set(babelHelpers.getPrototypeOf(_obj), "test", (_super$test = babelHelpers.get(babelHelpers.getPrototypeOf(_obj), "test", this), ++_super$test), this, false); } }; Object.setPrototypeOf(obj, Base);