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