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:
Huáng Jùnliàng 2021-03-01 17:49:59 -05:00 committed by GitHub
parent 78d1950aed
commit 82e089c7dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 254 additions and 17 deletions

View File

@ -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"), [

View File

@ -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);

View File

@ -0,0 +1,10 @@
let counter = 0;
class Foo {
constructor() {
this.#privateFieldValue = ++counter;
}
get #privateFieldValue() {
return 42;
}
}

View File

@ -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;
};

View File

@ -14,7 +14,7 @@ class Cl {
value: 0
});
this.publicField = babelHelpers.writeOnlyError("#privateFieldValue");
this.publicField = (this, babelHelpers.writeOnlyError("#privateFieldValue"));
}
}

View 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]);

View 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;
}
}

View 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;
};

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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();

View File

@ -0,0 +1,13 @@
let counter = 0;
class Foo {
constructor() {
this.#privateMethod = ++counter;
}
#privateMethod() {
return 42;
}
}
expect(() => new Foo).toThrow();
expect(counter).toBe(1);

View File

@ -0,0 +1,10 @@
let counter = 0;
class Foo {
constructor() {
this.#privateMethod = ++counter;
}
#privateMethod() {
return 42;
}
}

View File

@ -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;
};

View File

@ -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;

View File

@ -1,7 +1,12 @@
class A {
counter = 0;
#method() {}
self() {
this.counter++;
return this;
}
run() {
this.#method = 2;
constructor() {
this.self().#method = 2;
}
}

View File

@ -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");
}
}

View 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]);

View File

@ -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;
}
}

View File

@ -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;
};