mirror of https://github.com/tc39/test262.git
Add various private field and private method tests
This adds tests for implementation bugs in SpiderMonkey [1], plus additional tests for implementation bugs in V8 and JSC. [1] https://bugzilla.mozilla.org/show_bug.cgi?id=1723155
This commit is contained in:
parent
b74b15c49c
commit
d00039593d
|
@ -0,0 +1,27 @@
|
|||
// Copyright (C) 2021 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
Can't nest `in` expressions when the left-hand side is PrivateIdentifier.
|
||||
info: |
|
||||
Syntax
|
||||
RelationalExpression[In, Yield, Await]:
|
||||
[...]
|
||||
[+In]PrivateIdentifier in ShiftExpression[?Yield, ?Await]
|
||||
esid: sec-relational-operators
|
||||
negative:
|
||||
phase: parse
|
||||
type: SyntaxError
|
||||
features: [class-fields-private, class-fields-private-in]
|
||||
---*/
|
||||
|
||||
$DONOTEVALUATE();
|
||||
|
||||
class C {
|
||||
#field;
|
||||
|
||||
constructor() {
|
||||
#field in #field in this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright (C) 2021 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
Private identifiers aren't valid simple assignment references.
|
||||
info: |
|
||||
Syntax
|
||||
for ( LeftHandSideExpression in Expression ) Statement
|
||||
esid: sec-for-in-and-for-of-statements-static-semantics-early-errors
|
||||
negative:
|
||||
phase: parse
|
||||
type: SyntaxError
|
||||
features: [class-fields-private, class-fields-private-in]
|
||||
---*/
|
||||
|
||||
$DONOTEVALUATE();
|
||||
|
||||
class C {
|
||||
#field;
|
||||
|
||||
m() {
|
||||
for (#field in []) ;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (C) 2021 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Trying to get a private member without getter throws TypeError
|
||||
esid: sec-privatefieldget
|
||||
info: |
|
||||
PrivateFieldGet ( P, O )
|
||||
1. Assert: P is a Private Name.
|
||||
2. If O is not an object, throw a TypeError exception.
|
||||
3. If P.[[Kind]] is "field",
|
||||
a. Let entry be PrivateFieldFind(P, O).
|
||||
b. If entry is empty, throw a TypeError exception.
|
||||
c. Return entry.[[PrivateFieldValue]].
|
||||
4. Perform ? PrivateBrandCheck(O, P).
|
||||
5. If P.[[Kind]] is "method",
|
||||
a. Return P.[[Value]].
|
||||
6. Else,
|
||||
a. Assert: P.[[Kind]] is "accessor".
|
||||
b. If P does not have a [[Get]] field, throw a TypeError exception.
|
||||
c. Let getter be P.[[Get]].
|
||||
d. Return ? Call(getter, O).
|
||||
features: [class-static-methods-private, class]
|
||||
---*/
|
||||
|
||||
class C {
|
||||
static set #f(v) {
|
||||
throw new Test262Error();
|
||||
}
|
||||
|
||||
static getAccess() {
|
||||
return this.#f;
|
||||
}
|
||||
}
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
C.getAccess();
|
||||
}, 'get operation on private accessor without getter should throw TypeError');
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (C) 2021 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
Throws TypeError when attempting to install private methods multiple times.
|
||||
esid: sec-privatemethodoraccessoradd
|
||||
info: |
|
||||
7.3.28 PrivateMethodOrAccessorAdd ( method, O )
|
||||
1. Assert: method.[[Kind]] is either method or accessor.
|
||||
2. Let entry be ! PrivateElementFind(method.[[Key]], O).
|
||||
3. If entry is not empty, throw a TypeError exception.
|
||||
...
|
||||
|
||||
features: [class, class-methods-private]
|
||||
---*/
|
||||
|
||||
class Base {
|
||||
constructor(o) {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
class C extends Base {
|
||||
get #p() {}
|
||||
set #p(x) {}
|
||||
}
|
||||
|
||||
var obj = {};
|
||||
|
||||
new C(obj);
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
new C(obj);
|
||||
});
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (C) 2021 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
Throws TypeError when attempting to install private methods multiple times.
|
||||
esid: sec-privatemethodoraccessoradd
|
||||
info: |
|
||||
7.3.28 PrivateMethodOrAccessorAdd ( method, O )
|
||||
1. Assert: method.[[Kind]] is either method or accessor.
|
||||
2. Let entry be ! PrivateElementFind(method.[[Key]], O).
|
||||
3. If entry is not empty, throw a TypeError exception.
|
||||
...
|
||||
|
||||
features: [class, class-methods-private]
|
||||
---*/
|
||||
|
||||
class Base {
|
||||
constructor(o) {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
class C extends Base {
|
||||
get #p() {}
|
||||
}
|
||||
|
||||
var obj = {};
|
||||
|
||||
new C(obj);
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
new C(obj);
|
||||
});
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (C) 2021 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
Throws TypeError when attempting to install private methods multiple times.
|
||||
esid: sec-privatemethodoraccessoradd
|
||||
info: |
|
||||
7.3.28 PrivateMethodOrAccessorAdd ( method, O )
|
||||
1. Assert: method.[[Kind]] is either method or accessor.
|
||||
2. Let entry be ! PrivateElementFind(method.[[Key]], O).
|
||||
3. If entry is not empty, throw a TypeError exception.
|
||||
...
|
||||
|
||||
features: [class, class-methods-private]
|
||||
---*/
|
||||
|
||||
class Base {
|
||||
constructor(o) {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
class C extends Base {
|
||||
set #p(x) {}
|
||||
}
|
||||
|
||||
var obj = {};
|
||||
|
||||
new C(obj);
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
new C(obj);
|
||||
});
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (C) 2021 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
Throws TypeError when attempting to install private methods multiple times.
|
||||
esid: sec-privatemethodoraccessoradd
|
||||
info: |
|
||||
7.3.28 PrivateMethodOrAccessorAdd ( method, O )
|
||||
1. Assert: method.[[Kind]] is either method or accessor.
|
||||
2. Let entry be ! PrivateElementFind(method.[[Key]], O).
|
||||
3. If entry is not empty, throw a TypeError exception.
|
||||
...
|
||||
|
||||
features: [class, class-methods-private]
|
||||
---*/
|
||||
|
||||
class Base {
|
||||
constructor(o) {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
class C extends Base {
|
||||
#m() {}
|
||||
}
|
||||
|
||||
var obj = {};
|
||||
|
||||
new C(obj);
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
new C(obj);
|
||||
});
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (C) 2021 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
Throws TypeError when attempting to overwrite a private method.
|
||||
esid: sec-privateset
|
||||
info: |
|
||||
7.3.30 PrivateSet ( P, O, value )
|
||||
1. Let entry be ! PrivateElementFind(P, O).
|
||||
2. If entry is empty, throw a TypeError exception.
|
||||
3. If entry.[[Kind]] is field, then
|
||||
...
|
||||
4. Else if entry.[[Kind]] is method, then
|
||||
a. Throw a TypeError exception.
|
||||
5. ...
|
||||
|
||||
features: [class, class-methods-private]
|
||||
---*/
|
||||
|
||||
class C {
|
||||
#m() {}
|
||||
|
||||
assign() {
|
||||
this.#m = 0;
|
||||
}
|
||||
}
|
||||
|
||||
var obj = new C();
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
obj.assign();
|
||||
});
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright (C) 2021 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
Throws TypeError when attempting to overwrite a private static method.
|
||||
esid: sec-privateset
|
||||
info: |
|
||||
7.3.30 PrivateSet ( P, O, value )
|
||||
1. Let entry be ! PrivateElementFind(P, O).
|
||||
2. If entry is empty, throw a TypeError exception.
|
||||
3. If entry.[[Kind]] is field, then
|
||||
...
|
||||
4. Else if entry.[[Kind]] is method, then
|
||||
a. Throw a TypeError exception.
|
||||
5. ...
|
||||
|
||||
features: [class, class-static-methods-private]
|
||||
---*/
|
||||
|
||||
class C {
|
||||
static #m() {}
|
||||
|
||||
static assign() {
|
||||
this.#m = 0;
|
||||
}
|
||||
}
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
C.assign();
|
||||
});
|
|
@ -0,0 +1,43 @@
|
|||
// Copyright (C) 2021 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
Evaluation order when resolving private fields.
|
||||
esid: sec-runtime-semantics-keyeddestructuringassignmentevaluation
|
||||
info: |
|
||||
13.15.5.6 Runtime Semantics: KeyedDestructuringAssignmentEvaluation
|
||||
1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral, then
|
||||
a. Let lref be the result of evaluating DestructuringAssignmentTarget.
|
||||
b. ReturnIfAbrupt(lref).
|
||||
2. ...
|
||||
|
||||
9.1.1.3.4 GetThisBinding ( )
|
||||
1. Assert: envRec.[[ThisBindingStatus]] is not lexical.
|
||||
2. If envRec.[[ThisBindingStatus]] is uninitialized, throw a ReferenceError exception.
|
||||
3. ...
|
||||
|
||||
features: [class, class-fields-private]
|
||||
---*/
|
||||
|
||||
class C extends class {} {
|
||||
#field;
|
||||
|
||||
constructor() {
|
||||
var init = () => super();
|
||||
|
||||
var object = {
|
||||
get a() {
|
||||
init();
|
||||
}
|
||||
};
|
||||
|
||||
// Accessing |this| should throw a ReferenceError before there's an attempt
|
||||
// to invoke the getter.
|
||||
({a: this.#field} = object);
|
||||
}
|
||||
}
|
||||
|
||||
assert.throws(ReferenceError, function() {
|
||||
new C();
|
||||
});
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (C) 2021 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
Evaluation order when resolving private fields.
|
||||
esid: sec-runtime-semantics-keyeddestructuringassignmentevaluation
|
||||
info: |
|
||||
13.15.5.6 Runtime Semantics: KeyedDestructuringAssignmentEvaluation
|
||||
1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral, then
|
||||
a. Let lref be the result of evaluating DestructuringAssignmentTarget.
|
||||
b. ReturnIfAbrupt(lref).
|
||||
2. Let v be ? GetV(value, propertyName).
|
||||
3. ...
|
||||
|
||||
features: [class, class-fields-private]
|
||||
---*/
|
||||
|
||||
class C {
|
||||
#field;
|
||||
|
||||
m() {
|
||||
var object = {
|
||||
get a() {
|
||||
throw new Test262Error();
|
||||
}
|
||||
};
|
||||
|
||||
// The getter is executed before the check if the private field is present.
|
||||
({a: this.#field} = object);
|
||||
}
|
||||
}
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
C.prototype.m.call({});
|
||||
});
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (C) 2021 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
Evaluation order when resolving private fields.
|
||||
esid: sec-runtime-semantics-keyeddestructuringassignmentevaluation
|
||||
info: |
|
||||
13.15.5.6 Runtime Semantics: KeyedDestructuringAssignmentEvaluation
|
||||
1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral, then
|
||||
a. Let lref be the result of evaluating DestructuringAssignmentTarget.
|
||||
b. ReturnIfAbrupt(lref).
|
||||
2. Let v be ? GetV(value, propertyName).
|
||||
3. ...
|
||||
|
||||
features: [class, class-fields-private]
|
||||
---*/
|
||||
|
||||
class Base {
|
||||
constructor(o) {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
class C extends Base {
|
||||
#field;
|
||||
|
||||
m() {
|
||||
var init = () => new C(this);
|
||||
|
||||
var object = {
|
||||
get a() {
|
||||
init();
|
||||
|
||||
return "pass";
|
||||
}
|
||||
};
|
||||
|
||||
({a: this.#field} = object);
|
||||
|
||||
assert.sameValue(this.#field, "pass");
|
||||
}
|
||||
}
|
||||
|
||||
C.prototype.m.call({});
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (C) 2021 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
TypeError when setting private field not in `this`'s [[PrivateFieldValues]]
|
||||
esid: sec-putvalue
|
||||
info: |
|
||||
PutValue ( V, W )
|
||||
...
|
||||
6. Else if IsPropertyReference(V), then
|
||||
...
|
||||
b. If IsPrivateReference(V), then
|
||||
i. Let env be the running execution context's PrivateNameEnvironment.
|
||||
ii. Let field be ? ResolveBinding(GetReferencedName(V), env).
|
||||
iii. Assert: field is a Private Name.
|
||||
iv. Perform ? PrivateFieldSet(field, base, W).
|
||||
|
||||
PrivateFieldSet (P, O, value )
|
||||
1. Assert: P is a Private Name value.
|
||||
2. If O is not an object, throw a TypeError exception.
|
||||
3. Let entry be PrivateFieldFind(P, O).
|
||||
4. If entry is empty, throw a TypeError exception.
|
||||
|
||||
PrivateFieldFind (P, O)
|
||||
1. Assert: P is a Private Name value.
|
||||
2. Assert: O is an object with a [[PrivateFieldValues]] internal slot.
|
||||
3. For each element entry in O.[[PrivateFieldValues]],
|
||||
a. If entry.[[PrivateName]] is P, return entry.
|
||||
4. Return empty.
|
||||
|
||||
features: [class, class-fields-private]
|
||||
---*/
|
||||
|
||||
class C {
|
||||
#field;
|
||||
|
||||
m() {
|
||||
[...this.#field] = [];
|
||||
}
|
||||
}
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
C.prototype.m.call({});
|
||||
});
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (C) 2021 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
TypeError when setting private field not in `this`'s [[PrivateFieldValues]]
|
||||
esid: sec-putvalue
|
||||
info: |
|
||||
PutValue ( V, W )
|
||||
...
|
||||
6. Else if IsPropertyReference(V), then
|
||||
...
|
||||
b. If IsPrivateReference(V), then
|
||||
i. Let env be the running execution context's PrivateNameEnvironment.
|
||||
ii. Let field be ? ResolveBinding(GetReferencedName(V), env).
|
||||
iii. Assert: field is a Private Name.
|
||||
iv. Perform ? PrivateFieldSet(field, base, W).
|
||||
|
||||
PrivateFieldSet (P, O, value )
|
||||
1. Assert: P is a Private Name value.
|
||||
2. If O is not an object, throw a TypeError exception.
|
||||
3. Let entry be PrivateFieldFind(P, O).
|
||||
4. If entry is empty, throw a TypeError exception.
|
||||
|
||||
PrivateFieldFind (P, O)
|
||||
1. Assert: P is a Private Name value.
|
||||
2. Assert: O is an object with a [[PrivateFieldValues]] internal slot.
|
||||
3. For each element entry in O.[[PrivateFieldValues]],
|
||||
a. If entry.[[PrivateName]] is P, return entry.
|
||||
4. Return empty.
|
||||
|
||||
features: [class, class-fields-private]
|
||||
---*/
|
||||
|
||||
class C {
|
||||
#field;
|
||||
|
||||
m() {
|
||||
({...this.#field} = {});
|
||||
}
|
||||
}
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
C.prototype.m.call({});
|
||||
});
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (C) 2021 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
TypeError when setting private field not in `this`'s [[PrivateFieldValues]]
|
||||
esid: sec-putvalue
|
||||
info: |
|
||||
PutValue ( V, W )
|
||||
...
|
||||
6. Else if IsPropertyReference(V), then
|
||||
...
|
||||
b. If IsPrivateReference(V), then
|
||||
i. Let env be the running execution context's PrivateNameEnvironment.
|
||||
ii. Let field be ? ResolveBinding(GetReferencedName(V), env).
|
||||
iii. Assert: field is a Private Name.
|
||||
iv. Perform ? PrivateFieldSet(field, base, W).
|
||||
|
||||
PrivateFieldSet (P, O, value )
|
||||
1. Assert: P is a Private Name value.
|
||||
2. If O is not an object, throw a TypeError exception.
|
||||
3. Let entry be PrivateFieldFind(P, O).
|
||||
4. If entry is empty, throw a TypeError exception.
|
||||
|
||||
PrivateFieldFind (P, O)
|
||||
1. Assert: P is a Private Name value.
|
||||
2. Assert: O is an object with a [[PrivateFieldValues]] internal slot.
|
||||
3. For each element entry in O.[[PrivateFieldValues]],
|
||||
a. If entry.[[PrivateName]] is P, return entry.
|
||||
4. Return empty.
|
||||
|
||||
features: [class, class-fields-private]
|
||||
---*/
|
||||
|
||||
class C {
|
||||
#field;
|
||||
|
||||
m() {
|
||||
for (this.#field of [1]) ;
|
||||
}
|
||||
}
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
C.prototype.m.call({});
|
||||
});
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (C) 2021 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
TypeError when setting private field not in `this`'s [[PrivateFieldValues]]
|
||||
esid: sec-putvalue
|
||||
info: |
|
||||
PutValue ( V, W )
|
||||
...
|
||||
6. Else if IsPropertyReference(V), then
|
||||
...
|
||||
b. If IsPrivateReference(V), then
|
||||
i. Let env be the running execution context's PrivateNameEnvironment.
|
||||
ii. Let field be ? ResolveBinding(GetReferencedName(V), env).
|
||||
iii. Assert: field is a Private Name.
|
||||
iv. Perform ? PrivateFieldSet(field, base, W).
|
||||
|
||||
PrivateFieldSet (P, O, value )
|
||||
1. Assert: P is a Private Name value.
|
||||
2. If O is not an object, throw a TypeError exception.
|
||||
3. Let entry be PrivateFieldFind(P, O).
|
||||
4. If entry is empty, throw a TypeError exception.
|
||||
|
||||
PrivateFieldFind (P, O)
|
||||
1. Assert: P is a Private Name value.
|
||||
2. Assert: O is an object with a [[PrivateFieldValues]] internal slot.
|
||||
3. For each element entry in O.[[PrivateFieldValues]],
|
||||
a. If entry.[[PrivateName]] is P, return entry.
|
||||
4. Return empty.
|
||||
|
||||
features: [class, class-fields-private]
|
||||
---*/
|
||||
|
||||
class C {
|
||||
#field;
|
||||
|
||||
m() {
|
||||
for (this.#field in {a: 0}) ;
|
||||
}
|
||||
}
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
C.prototype.m.call({});
|
||||
});
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (C) 2021 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
TypeError when setting private field not in `this`'s [[PrivateFieldValues]]
|
||||
esid: sec-putvalue
|
||||
info: |
|
||||
PutValue ( V, W )
|
||||
...
|
||||
6. Else if IsPropertyReference(V), then
|
||||
...
|
||||
b. If IsPrivateReference(V), then
|
||||
i. Let env be the running execution context's PrivateNameEnvironment.
|
||||
ii. Let field be ? ResolveBinding(GetReferencedName(V), env).
|
||||
iii. Assert: field is a Private Name.
|
||||
iv. Perform ? PrivateFieldSet(field, base, W).
|
||||
|
||||
PrivateFieldSet (P, O, value )
|
||||
1. Assert: P is a Private Name value.
|
||||
2. If O is not an object, throw a TypeError exception.
|
||||
3. Let entry be PrivateFieldFind(P, O).
|
||||
4. If entry is empty, throw a TypeError exception.
|
||||
|
||||
PrivateFieldFind (P, O)
|
||||
1. Assert: P is a Private Name value.
|
||||
2. Assert: O is an object with a [[PrivateFieldValues]] internal slot.
|
||||
3. For each element entry in O.[[PrivateFieldValues]],
|
||||
a. If entry.[[PrivateName]] is P, return entry.
|
||||
4. Return empty.
|
||||
|
||||
features: [class, class-fields-private]
|
||||
---*/
|
||||
|
||||
class C {
|
||||
#field;
|
||||
|
||||
m() {
|
||||
[this.#field] = [1];
|
||||
}
|
||||
}
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
C.prototype.m.call({});
|
||||
});
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (C) 2021 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
TypeError when setting private field not in `this`'s [[PrivateFieldValues]]
|
||||
esid: sec-putvalue
|
||||
info: |
|
||||
PutValue ( V, W )
|
||||
...
|
||||
6. Else if IsPropertyReference(V), then
|
||||
...
|
||||
b. If IsPrivateReference(V), then
|
||||
i. Let env be the running execution context's PrivateNameEnvironment.
|
||||
ii. Let field be ? ResolveBinding(GetReferencedName(V), env).
|
||||
iii. Assert: field is a Private Name.
|
||||
iv. Perform ? PrivateFieldSet(field, base, W).
|
||||
|
||||
PrivateFieldSet (P, O, value )
|
||||
1. Assert: P is a Private Name value.
|
||||
2. If O is not an object, throw a TypeError exception.
|
||||
3. Let entry be PrivateFieldFind(P, O).
|
||||
4. If entry is empty, throw a TypeError exception.
|
||||
|
||||
PrivateFieldFind (P, O)
|
||||
1. Assert: P is a Private Name value.
|
||||
2. Assert: O is an object with a [[PrivateFieldValues]] internal slot.
|
||||
3. For each element entry in O.[[PrivateFieldValues]],
|
||||
a. If entry.[[PrivateName]] is P, return entry.
|
||||
4. Return empty.
|
||||
|
||||
features: [class, class-fields-private]
|
||||
---*/
|
||||
|
||||
class C {
|
||||
#field;
|
||||
|
||||
m() {
|
||||
({a: this.#field} = {a: 0});
|
||||
}
|
||||
}
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
C.prototype.m.call({});
|
||||
});
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (C) 2021 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Trying to set a private member without setter throws TypeError
|
||||
esid: sec-privatefieldset
|
||||
info: |
|
||||
PrivateFieldSet ( P, O, value )
|
||||
1. Assert: P is a Private Name.
|
||||
2. If O is not an object, throw a TypeError exception.
|
||||
3. If P.[[Kind]] is "field",
|
||||
a. Let entry be PrivateFieldFind(P, O).
|
||||
b. If entry is empty, throw a TypeError exception.
|
||||
c. Set entry.[[PrivateFieldValue]] to value.
|
||||
d. Return.
|
||||
4. If P.[[Kind]] is "method", throw a TypeError exception.
|
||||
5. Else,
|
||||
a. Assert: P.[[Kind]] is "accessor".
|
||||
b. If O.[[PrivateFieldBrands]] does not contain P.[[Brand]], throw a TypeError exception.
|
||||
c. If P does not have a [[Set]] field, throw a TypeError exception.
|
||||
d. Let setter be P.[[Set]].
|
||||
e. Perform ? Call(setter, O, value).
|
||||
f. Return.
|
||||
features: [class-static-methods-private, class]
|
||||
---*/
|
||||
|
||||
class C {
|
||||
static get #f() {
|
||||
throw new Test262Error();
|
||||
}
|
||||
|
||||
static setAccess() {
|
||||
this.#f = 'Test262';
|
||||
}
|
||||
}
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
C.setAccess();
|
||||
}, 'set operation on private accessor without setter should throw TypeError');
|
Loading…
Reference in New Issue