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 (!getId && setId) {
|
||||
if (file.availableHelper("writeOnlyError")) {
|
||||
return t.callExpression(file.addHelper("writeOnlyError"), [
|
||||
return t.sequenceExpression([
|
||||
this.receiver(member),
|
||||
t.callExpression(file.addHelper("writeOnlyError"), [
|
||||
t.stringLiteral(`#${name}`),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
console.warn(
|
||||
@ -299,8 +302,12 @@ const privateNameHandlerSpec = {
|
||||
value,
|
||||
]);
|
||||
}
|
||||
return t.callExpression(file.addHelper("readOnlyError"), [
|
||||
return t.sequenceExpression([
|
||||
this.receiver(member),
|
||||
value,
|
||||
t.callExpression(file.addHelper("readOnlyError"), [
|
||||
t.stringLiteral(`#${name}`),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
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
|
||||
});
|
||||
|
||||
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 {
|
||||
#privateField = 0;
|
||||
counter = 0;
|
||||
|
||||
get #privateFieldValue() {
|
||||
return this.#privateField;
|
||||
}
|
||||
|
||||
get self() {
|
||||
this.counter++;
|
||||
return this;
|
||||
}
|
||||
|
||||
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 {
|
||||
#privateField = 0;
|
||||
counter = 0;
|
||||
|
||||
get #privateFieldValue() {
|
||||
return this.#privateField;
|
||||
}
|
||||
|
||||
get self() {
|
||||
this.counter++;
|
||||
return this;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this.#privateFieldValue = 1;
|
||||
this.self.#privateFieldValue = 1
|
||||
}
|
||||
}
|
||||
|
||||
const cl = new Cl();
|
||||
|
||||
@ -3,6 +3,11 @@ var _privateField = new WeakMap();
|
||||
var _privateFieldValue = new WeakMap();
|
||||
|
||||
class Cl {
|
||||
get self() {
|
||||
this.counter++;
|
||||
return this;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
_privateFieldValue.set(this, {
|
||||
get: _get_privateFieldValue,
|
||||
@ -14,7 +19,8 @@ class Cl {
|
||||
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 () {
|
||||
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 {
|
||||
counter = 0;
|
||||
#method() {}
|
||||
self() {
|
||||
this.counter++;
|
||||
return this;
|
||||
}
|
||||
|
||||
run() {
|
||||
this.#method = 2;
|
||||
constructor() {
|
||||
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 {
|
||||
counter = 0;
|
||||
#method() {}
|
||||
self() {
|
||||
this.counter++;
|
||||
return this;
|
||||
}
|
||||
|
||||
run() {
|
||||
this.#method = 2;
|
||||
constructor() {
|
||||
this.self().#method = 2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,16 @@
|
||||
var _method = new WeakSet();
|
||||
|
||||
class A {
|
||||
constructor() {
|
||||
_method.add(this);
|
||||
self() {
|
||||
this.counter++;
|
||||
return this;
|
||||
}
|
||||
|
||||
run() {
|
||||
babelHelpers.readOnlyError("#method");
|
||||
constructor() {
|
||||
_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