Evaluate object and initializer when setting a private method (#12707)
* fix: evaluate initializer when a private method is set as a field * make legacy node happy * add accessor test cases * fix: evaluate object before RHS * fix: evaluate object before throwing writeOnlyError
This commit is contained in:
parent
78d1950aed
commit
82e089c7dd
@ -232,8 +232,11 @@ const privateNameHandlerSpec = {
|
|||||||
if (isAccessor) {
|
if (isAccessor) {
|
||||||
if (!getId && setId) {
|
if (!getId && setId) {
|
||||||
if (file.availableHelper("writeOnlyError")) {
|
if (file.availableHelper("writeOnlyError")) {
|
||||||
return t.callExpression(file.addHelper("writeOnlyError"), [
|
return t.sequenceExpression([
|
||||||
|
this.receiver(member),
|
||||||
|
t.callExpression(file.addHelper("writeOnlyError"), [
|
||||||
t.stringLiteral(`#${name}`),
|
t.stringLiteral(`#${name}`),
|
||||||
|
]),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
console.warn(
|
console.warn(
|
||||||
@ -299,8 +302,12 @@ const privateNameHandlerSpec = {
|
|||||||
value,
|
value,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
return t.callExpression(file.addHelper("readOnlyError"), [
|
return t.sequenceExpression([
|
||||||
|
this.receiver(member),
|
||||||
|
value,
|
||||||
|
t.callExpression(file.addHelper("readOnlyError"), [
|
||||||
t.stringLiteral(`#${name}`),
|
t.stringLiteral(`#${name}`),
|
||||||
|
]),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
return t.callExpression(file.addHelper("classPrivateFieldSet"), [
|
return t.callExpression(file.addHelper("classPrivateFieldSet"), [
|
||||||
|
|||||||
@ -0,0 +1,13 @@
|
|||||||
|
let counter = 0;
|
||||||
|
class Foo {
|
||||||
|
constructor() {
|
||||||
|
this.#privateFieldValue = ++counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
get #privateFieldValue() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(() => new Foo).toThrow();
|
||||||
|
expect(counter).toBe(1);
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
let counter = 0;
|
||||||
|
class Foo {
|
||||||
|
constructor() {
|
||||||
|
this.#privateFieldValue = ++counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
get #privateFieldValue() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
var counter = 0;
|
||||||
|
|
||||||
|
var _privateFieldValue = babelHelpers.classPrivateFieldLooseKey("privateFieldValue");
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
constructor() {
|
||||||
|
Object.defineProperty(this, _privateFieldValue, {
|
||||||
|
get: _get_privateFieldValue,
|
||||||
|
set: void 0
|
||||||
|
});
|
||||||
|
babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue] = ++counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var _get_privateFieldValue = function () {
|
||||||
|
return 42;
|
||||||
|
};
|
||||||
@ -14,7 +14,7 @@ class Cl {
|
|||||||
value: 0
|
value: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
this.publicField = babelHelpers.writeOnlyError("#privateFieldValue");
|
this.publicField = (this, babelHelpers.writeOnlyError("#privateFieldValue"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
18
packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/reassignment/exec.js
vendored
Normal file
18
packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/reassignment/exec.js
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
let results = [];
|
||||||
|
class Foo {
|
||||||
|
constructor() {
|
||||||
|
this.self.#privateFieldValue = results.push(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
get self() {
|
||||||
|
results.push(1);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
get #privateFieldValue() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(() => new Foo).toThrow(TypeError);
|
||||||
|
expect(results).toStrictEqual([1, 2]);
|
||||||
15
packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/reassignment/input.js
vendored
Normal file
15
packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/reassignment/input.js
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
let results = [];
|
||||||
|
class Foo {
|
||||||
|
constructor() {
|
||||||
|
this.self.#privateFieldValue = results.push(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
get self() {
|
||||||
|
results.push(1);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
get #privateFieldValue() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/reassignment/output.js
vendored
Normal file
24
packages/babel-plugin-proposal-private-methods/test/fixtures/accessors/reassignment/output.js
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
var results = [];
|
||||||
|
|
||||||
|
var _privateFieldValue = new WeakMap();
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
constructor() {
|
||||||
|
_privateFieldValue.set(this, {
|
||||||
|
get: _get_privateFieldValue,
|
||||||
|
set: void 0
|
||||||
|
});
|
||||||
|
|
||||||
|
this.self, results.push(2), babelHelpers.readOnlyError("#privateFieldValue");
|
||||||
|
}
|
||||||
|
|
||||||
|
get self() {
|
||||||
|
results.push(1);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var _get_privateFieldValue = function () {
|
||||||
|
return 42;
|
||||||
|
};
|
||||||
@ -1,12 +1,19 @@
|
|||||||
class Cl {
|
class Cl {
|
||||||
#privateField = 0;
|
#privateField = 0;
|
||||||
|
counter = 0;
|
||||||
|
|
||||||
get #privateFieldValue() {
|
get #privateFieldValue() {
|
||||||
return this.#privateField;
|
return this.#privateField;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get self() {
|
||||||
|
this.counter++;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
expect(() => this.#privateFieldValue = 1).toThrow(TypeError);
|
expect(() => this.self.#privateFieldValue = 1).toThrow(TypeError);
|
||||||
|
expect(this.counter).toBe(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,19 @@
|
|||||||
class Cl {
|
class Cl {
|
||||||
#privateField = 0;
|
#privateField = 0;
|
||||||
|
counter = 0;
|
||||||
|
|
||||||
get #privateFieldValue() {
|
get #privateFieldValue() {
|
||||||
return this.#privateField;
|
return this.#privateField;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get self() {
|
||||||
|
this.counter++;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.#privateFieldValue = 1;
|
this.self.#privateFieldValue = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cl = new Cl();
|
||||||
|
|||||||
@ -3,6 +3,11 @@ var _privateField = new WeakMap();
|
|||||||
var _privateFieldValue = new WeakMap();
|
var _privateFieldValue = new WeakMap();
|
||||||
|
|
||||||
class Cl {
|
class Cl {
|
||||||
|
get self() {
|
||||||
|
this.counter++;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
_privateFieldValue.set(this, {
|
_privateFieldValue.set(this, {
|
||||||
get: _get_privateFieldValue,
|
get: _get_privateFieldValue,
|
||||||
@ -14,7 +19,8 @@ class Cl {
|
|||||||
value: 0
|
value: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
babelHelpers.readOnlyError("#privateFieldValue");
|
babelHelpers.defineProperty(this, "counter", 0);
|
||||||
|
this.self, 1, babelHelpers.readOnlyError("#privateFieldValue");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -22,3 +28,5 @@ class Cl {
|
|||||||
var _get_privateFieldValue = function () {
|
var _get_privateFieldValue = function () {
|
||||||
return babelHelpers.classPrivateFieldGet(this, _privateField);
|
return babelHelpers.classPrivateFieldGet(this, _privateField);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var cl = new Cl();
|
||||||
|
|||||||
@ -0,0 +1,13 @@
|
|||||||
|
let counter = 0;
|
||||||
|
class Foo {
|
||||||
|
constructor() {
|
||||||
|
this.#privateMethod = ++counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
#privateMethod() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(() => new Foo).toThrow();
|
||||||
|
expect(counter).toBe(1);
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
let counter = 0;
|
||||||
|
class Foo {
|
||||||
|
constructor() {
|
||||||
|
this.#privateMethod = ++counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
#privateMethod() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
var counter = 0;
|
||||||
|
|
||||||
|
var _privateMethod = babelHelpers.classPrivateFieldLooseKey("privateMethod");
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
constructor() {
|
||||||
|
Object.defineProperty(this, _privateMethod, {
|
||||||
|
value: _privateMethod2
|
||||||
|
});
|
||||||
|
babelHelpers.classPrivateFieldLooseBase(this, _privateMethod)[_privateMethod] = ++counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var _privateMethod2 = function _privateMethod2() {
|
||||||
|
return 42;
|
||||||
|
};
|
||||||
@ -1,9 +1,15 @@
|
|||||||
class A {
|
class A {
|
||||||
|
counter = 0;
|
||||||
#method() {}
|
#method() {}
|
||||||
|
self() {
|
||||||
|
this.counter++;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
run() {
|
constructor() {
|
||||||
this.#method = 2;
|
expect(() => this.self().#method = 2).toThrow(TypeError);
|
||||||
|
expect(this.counter).toBe(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(() => new A().run()).toThrow(TypeError);
|
new A;
|
||||||
|
|||||||
@ -1,7 +1,12 @@
|
|||||||
class A {
|
class A {
|
||||||
|
counter = 0;
|
||||||
#method() {}
|
#method() {}
|
||||||
|
self() {
|
||||||
|
this.counter++;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
run() {
|
constructor() {
|
||||||
this.#method = 2;
|
this.self().#method = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,16 @@
|
|||||||
var _method = new WeakSet();
|
var _method = new WeakSet();
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
constructor() {
|
self() {
|
||||||
_method.add(this);
|
this.counter++;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
run() {
|
constructor() {
|
||||||
babelHelpers.readOnlyError("#method");
|
_method.add(this);
|
||||||
|
|
||||||
|
babelHelpers.defineProperty(this, "counter", 0);
|
||||||
|
this.self(), 2, babelHelpers.readOnlyError("#method");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
18
packages/babel-plugin-proposal-private-methods/test/fixtures/private-method/reassignment/exec.js
vendored
Normal file
18
packages/babel-plugin-proposal-private-methods/test/fixtures/private-method/reassignment/exec.js
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
let results = [];
|
||||||
|
class Foo {
|
||||||
|
constructor() {
|
||||||
|
this.self.#privateFieldValue = results.push(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
get self() {
|
||||||
|
results.push(1);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#privateFieldValue() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(() => new Foo).toThrow(TypeError);
|
||||||
|
expect(results).toStrictEqual([1, 2]);
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
let results = [];
|
||||||
|
class Foo {
|
||||||
|
constructor() {
|
||||||
|
this.self.#privateFieldValue = results.push(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
get self() {
|
||||||
|
results.push(1);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#privateFieldValue() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
var results = [];
|
||||||
|
|
||||||
|
var _privateFieldValue = new WeakSet();
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
constructor() {
|
||||||
|
_privateFieldValue.add(this);
|
||||||
|
|
||||||
|
this.self, results.push(2), babelHelpers.readOnlyError("#privateFieldValue");
|
||||||
|
}
|
||||||
|
|
||||||
|
get self() {
|
||||||
|
results.push(1);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var _privateFieldValue2 = function _privateFieldValue2() {
|
||||||
|
return 42;
|
||||||
|
};
|
||||||
Loading…
x
Reference in New Issue
Block a user