mirror of https://github.com/tc39/test262.git
Add tests for stage 3 proposal "private fields in" (#2963)
This commit is contained in:
parent
6e61dd7754
commit
61c6f8214b
|
@ -299,3 +299,7 @@ __setter__
|
|||
|
||||
IsHTMLDDA
|
||||
host-gc-required
|
||||
|
||||
# Ergonomic brand checks for Private Fields
|
||||
# https://github.com/tc39/proposal-private-fields-in-in
|
||||
class-fields-private-in
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Requires the `In` parsing parameter
|
||||
info: |
|
||||
Syntax
|
||||
RelationalExpression[In, Yield, Await]:
|
||||
[...]
|
||||
[+In]PrivateIdentifier in ShiftExpression[?Yield, ?Await]
|
||||
esid: sec-relational-operators-runtime-semantics-evaluation
|
||||
negative:
|
||||
phase: parse
|
||||
type: SyntaxError
|
||||
features: [class-fields-private, class-fields-private-in]
|
||||
---*/
|
||||
|
||||
$DONOTEVALUATE();
|
||||
|
||||
class C {
|
||||
#field;
|
||||
|
||||
constructor() {
|
||||
for (#field in value;;) break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Rejected as assignment target
|
||||
info: |
|
||||
12.10.5 Static Semantics: AllPrivateIdentifiersValid
|
||||
|
||||
AllPrivateIdentifiersValid is an abstract operation which takes names as an argument.
|
||||
|
||||
RelationalExpression:PrivateIdentifierinShiftExpression
|
||||
|
||||
1. If StringValue of PrivateIdentifier is in names, return true.
|
||||
2. Return false.
|
||||
|
||||
esid: sec-relational-operators-runtime-semantics-evaluation
|
||||
negative:
|
||||
phase: parse
|
||||
type: SyntaxError
|
||||
features: [class-fields-private, class-fields-private-in]
|
||||
---*/
|
||||
|
||||
$DONOTEVALUATE();
|
||||
|
||||
class C {
|
||||
#field;
|
||||
|
||||
constructor() {
|
||||
#field in {} = 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Invalid private identifier - complex case
|
||||
info: |
|
||||
12.10.5 Static Semantics: AllPrivateIdentifiersValid
|
||||
|
||||
AllPrivateIdentifiersValid is an abstract operation which takes names as an argument.
|
||||
|
||||
RelationalExpression:PrivateIdentifierinShiftExpression
|
||||
|
||||
1. If StringValue of PrivateIdentifier is in names, return true.
|
||||
2. Return false.
|
||||
|
||||
esid: sec-relational-operators-runtime-semantics-evaluation
|
||||
negative:
|
||||
phase: parse
|
||||
type: SyntaxError
|
||||
features: [class-fields-private, class-fields-private-in]
|
||||
---*/
|
||||
|
||||
$DONOTEVALUATE();
|
||||
|
||||
class C {
|
||||
#a;
|
||||
|
||||
constructor() {
|
||||
#b in {};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Invalid private identifier - simple case
|
||||
info: |
|
||||
12.10.5 Static Semantics: AllPrivateIdentifiersValid
|
||||
|
||||
AllPrivateIdentifiersValid is an abstract operation which takes names as an argument.
|
||||
|
||||
RelationalExpression:PrivateIdentifierinShiftExpression
|
||||
|
||||
1. If StringValue of PrivateIdentifier is in names, return true.
|
||||
2. Return false.
|
||||
|
||||
esid: sec-relational-operators-runtime-semantics-evaluation
|
||||
negative:
|
||||
phase: parse
|
||||
type: SyntaxError
|
||||
features: [class-fields-private, class-fields-private-in]
|
||||
---*/
|
||||
|
||||
$DONOTEVALUATE();
|
||||
|
||||
#name in {};
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Syntactic grammar restricts right-hand side
|
||||
info: |
|
||||
Syntax
|
||||
RelationalExpression[In, Yield, Await]:
|
||||
[...]
|
||||
[+In]PrivateIdentifier in ShiftExpression[?Yield, ?Await]
|
||||
esid: sec-relational-operators-runtime-semantics-evaluation
|
||||
negative:
|
||||
phase: parse
|
||||
type: SyntaxError
|
||||
features: [class-fields-private, class-fields-private-in]
|
||||
---*/
|
||||
|
||||
$DONOTEVALUATE();
|
||||
|
||||
class C {
|
||||
#field;
|
||||
|
||||
constructor() {
|
||||
#field in () => {};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Value when private name describes an accessor method
|
||||
info: |
|
||||
7. Let privateName be ? GetValue(privateNameBinding).
|
||||
8. Assert: privateName is a Private Name.
|
||||
[...]
|
||||
10. Else,
|
||||
a. Assert: privateName.[[Kind]] is "method" or "accessor".
|
||||
b. If PrivateBrandCheck(rval, privateName) is not an abrupt completion,
|
||||
then return true.
|
||||
11. Return false.
|
||||
esid: sec-relational-operators-runtime-semantics-evaluation
|
||||
features: [class-static-methods-private, class-fields-private-in]
|
||||
---*/
|
||||
|
||||
let Child;
|
||||
let parentCount = 0;
|
||||
let childCount = 0;
|
||||
|
||||
class Parent {
|
||||
get #accessor() {
|
||||
parentCount += 1;
|
||||
}
|
||||
|
||||
static init() {
|
||||
Child = class {
|
||||
get #accessor() {
|
||||
childCount += 1;
|
||||
}
|
||||
|
||||
static isNameIn(value) {
|
||||
return #accessor in value;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Parent.init();
|
||||
|
||||
assert.sameValue(Child.isNameIn(new Parent()), false);
|
||||
assert.sameValue(parentCount, 0, 'parent accessor not invoked');
|
||||
assert.sameValue(Child.isNameIn(new Child()), true);
|
||||
assert.sameValue(childCount, 0, 'child accessor not invoked');
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Value when private name describes an accessor method
|
||||
info: |
|
||||
7. Let privateName be ? GetValue(privateNameBinding).
|
||||
8. Assert: privateName is a Private Name.
|
||||
[...]
|
||||
10. Else,
|
||||
a. Assert: privateName.[[Kind]] is "method" or "accessor".
|
||||
b. If PrivateBrandCheck(rval, privateName) is not an abrupt completion,
|
||||
then return true.
|
||||
11. Return false.
|
||||
esid: sec-relational-operators-runtime-semantics-evaluation
|
||||
features: [class-static-methods-private, class-fields-private-in]
|
||||
---*/
|
||||
|
||||
let count = 0;
|
||||
|
||||
class Class {
|
||||
get #accessor() {
|
||||
count += 1;
|
||||
}
|
||||
|
||||
static isNameIn(value) {
|
||||
return #accessor in value;
|
||||
}
|
||||
}
|
||||
|
||||
assert.sameValue(Class.isNameIn({}), false);
|
||||
assert.sameValue(Class.isNameIn(new Class()), true);
|
||||
assert.sameValue(count, 0);
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Value when private name describes a field
|
||||
info: |
|
||||
7. Let privateName be ? GetValue(privateNameBinding).
|
||||
8. Assert: privateName is a Private Name.
|
||||
9. If privateName.[[Kind]] is "field",
|
||||
a. If ! PrivateFieldFind(privateName, rval) is not empty, then return true.
|
||||
[...]
|
||||
11. Return false.
|
||||
esid: sec-relational-operators-runtime-semantics-evaluation
|
||||
features: [class-fields-private, class-fields-private-in]
|
||||
---*/
|
||||
|
||||
let Child;
|
||||
|
||||
class Parent {
|
||||
#field;
|
||||
|
||||
static init() {
|
||||
Child = class {
|
||||
#field;
|
||||
|
||||
static isNameIn(value) {
|
||||
return #field in value;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Parent.init();
|
||||
|
||||
assert.sameValue(Child.isNameIn(new Parent()), false);
|
||||
assert.sameValue(Child.isNameIn(new Child()), true);
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Value when private name describes a field
|
||||
info: |
|
||||
7. Let privateName be ? GetValue(privateNameBinding).
|
||||
8. Assert: privateName is a Private Name.
|
||||
9. If privateName.[[Kind]] is "field",
|
||||
a. If ! PrivateFieldFind(privateName, rval) is not empty, then return true.
|
||||
[...]
|
||||
11. Return false.
|
||||
esid: sec-relational-operators-runtime-semantics-evaluation
|
||||
features: [class-fields-private, class-fields-private-in]
|
||||
---*/
|
||||
|
||||
class Class {
|
||||
#field;
|
||||
|
||||
static isNameIn(value) {
|
||||
return #field in value;
|
||||
}
|
||||
}
|
||||
|
||||
assert.sameValue(Class.isNameIn({}), false);
|
||||
assert.sameValue(Class.isNameIn(new Class()), true);
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Value when private name describes a method
|
||||
info: |
|
||||
7. Let privateName be ? GetValue(privateNameBinding).
|
||||
8. Assert: privateName is a Private Name.
|
||||
[...]
|
||||
10. Else,
|
||||
a. Assert: privateName.[[Kind]] is "method" or "accessor".
|
||||
b. If PrivateBrandCheck(rval, privateName) is not an abrupt completion,
|
||||
then return true.
|
||||
11. Return false.
|
||||
esid: sec-relational-operators-runtime-semantics-evaluation
|
||||
features: [class-methods-private, class-fields-private-in]
|
||||
---*/
|
||||
|
||||
let Child;
|
||||
let parentCount = 0;
|
||||
let childCount = 0;
|
||||
|
||||
class Parent {
|
||||
#method() {
|
||||
parentCount += 1;
|
||||
}
|
||||
|
||||
static init() {
|
||||
Child = class {
|
||||
#method() {
|
||||
childCount += 1;
|
||||
}
|
||||
|
||||
static isNameIn(value) {
|
||||
return #method in value;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Parent.init();
|
||||
|
||||
assert.sameValue(Child.isNameIn(new Parent()), false);
|
||||
assert.sameValue(parentCount, 0, 'parent method not invoked');
|
||||
assert.sameValue(Child.isNameIn(new Child()), true);
|
||||
assert.sameValue(childCount, 0, 'child method not invoked');
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Value when private name describes a method
|
||||
info: |
|
||||
7. Let privateName be ? GetValue(privateNameBinding).
|
||||
8. Assert: privateName is a Private Name.
|
||||
[...]
|
||||
10. Else,
|
||||
a. Assert: privateName.[[Kind]] is "method" or "accessor".
|
||||
b. If PrivateBrandCheck(rval, privateName) is not an abrupt completion,
|
||||
then return true.
|
||||
11. Return false.
|
||||
esid: sec-relational-operators-runtime-semantics-evaluation
|
||||
features: [class-methods-private, class-fields-private-in]
|
||||
---*/
|
||||
|
||||
let count = 0;
|
||||
|
||||
class Class {
|
||||
#method() {
|
||||
count += 1;
|
||||
}
|
||||
|
||||
static isNameIn(value) {
|
||||
return #method in value;
|
||||
}
|
||||
}
|
||||
|
||||
assert.sameValue(Class.isNameIn({}), false);
|
||||
assert.sameValue(Class.isNameIn(new Class()), true);
|
||||
assert.sameValue(count, 0);
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Parsing observes the `Await` production parameter when absent
|
||||
info: |
|
||||
Syntax
|
||||
RelationalExpression[In, Yield, Await]:
|
||||
[...]
|
||||
[+In]PrivateIdentifier in ShiftExpression[?Yield, ?Await]
|
||||
|
||||
[...]
|
||||
|
||||
1. Let privateIdentifier be the StringValue of PrivateIdentifier.
|
||||
2. Let rref be the result of evaluating ShiftExpression.
|
||||
3. Let rval be ? GetValue(rref).
|
||||
4. If Type(rval) is not Object, throw a TypeError exception.
|
||||
esid: sec-relational-operators-runtime-semantics-evaluation
|
||||
features: [class-fields-private, class-fields-private-in]
|
||||
---*/
|
||||
|
||||
let value;
|
||||
function await() {
|
||||
return value;
|
||||
}
|
||||
|
||||
class C {
|
||||
#field;
|
||||
|
||||
static isNameIn() {
|
||||
return #field in await(null);
|
||||
}
|
||||
}
|
||||
|
||||
value = new C();
|
||||
assert.sameValue(C.isNameIn(), true);
|
||||
|
||||
value = {};
|
||||
assert.sameValue(C.isNameIn(), false);
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Parsing observes the `Await` production parameter when present
|
||||
info: |
|
||||
Syntax
|
||||
RelationalExpression[In, Yield, Await]:
|
||||
[...]
|
||||
[+In]PrivateIdentifier in ShiftExpression[?Yield, ?Await]
|
||||
|
||||
[...]
|
||||
|
||||
1. Let privateIdentifier be the StringValue of PrivateIdentifier.
|
||||
2. Let rref be the result of evaluating ShiftExpression.
|
||||
3. Let rval be ? GetValue(rref).
|
||||
4. If Type(rval) is not Object, throw a TypeError exception.
|
||||
esid: sec-relational-operators-runtime-semantics-evaluation
|
||||
features: [class-fields-private, class-fields-private-in]
|
||||
flags: [async]
|
||||
---*/
|
||||
|
||||
class C {
|
||||
#field;
|
||||
|
||||
static async isNameIn(value) {
|
||||
return #field in await(value);
|
||||
}
|
||||
}
|
||||
|
||||
C.isNameIn(new C())
|
||||
.then(function(result) {
|
||||
assert.sameValue(result, true);
|
||||
|
||||
return C.isNameIn({});
|
||||
})
|
||||
.then(function(result) {
|
||||
assert.sameValue(result, false);
|
||||
}).then($DONE, $DONE);
|
|
@ -0,0 +1,51 @@
|
|||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Algorithm interrupted by non-object right-hand side
|
||||
info: |
|
||||
Syntax
|
||||
RelationalExpression[In, Yield, Await]:
|
||||
[...]
|
||||
[+In]PrivateIdentifier in ShiftExpression[?Yield, ?Await]
|
||||
|
||||
[...]
|
||||
|
||||
1. Let privateIdentifier be the StringValue of PrivateIdentifier.
|
||||
2. Let rref be the result of evaluating ShiftExpression.
|
||||
3. Let rval be ? GetValue(rref).
|
||||
4. If Type(rval) is not Object, throw a TypeError exception.
|
||||
esid: sec-relational-operators-runtime-semantics-evaluation
|
||||
features: [class-fields-private, class-fields-private-in]
|
||||
---*/
|
||||
|
||||
let caught = null;
|
||||
|
||||
class C {
|
||||
#field;
|
||||
|
||||
constructor() {
|
||||
try {
|
||||
/**
|
||||
* Using a ShiftExpression to produce the non-object value verifies that
|
||||
* the implementation uses the operator precedence implied by the
|
||||
* syntactic grammar. In other words, the following statement should be
|
||||
* interpreted as:
|
||||
*
|
||||
* #field in ({} << 0);
|
||||
*
|
||||
* ...rather than:
|
||||
*
|
||||
* (#field in {}) << 0;
|
||||
*/
|
||||
#field in {} << 0;
|
||||
} catch (error) {
|
||||
caught = error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
new C();
|
||||
|
||||
assert.notSameValue(caught, null);
|
||||
assert.sameValue(caught.constructor, TypeError);
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Algorithm interrupted by unresolvable reference
|
||||
info: |
|
||||
1. Let privateIdentifier be the StringValue of PrivateIdentifier.
|
||||
2. Let rref be the result of evaluating ShiftExpression.
|
||||
3. Let rval be ? GetValue(rref).
|
||||
esid: sec-relational-operators-runtime-semantics-evaluation
|
||||
features: [class-fields-private, class-fields-private-in]
|
||||
---*/
|
||||
|
||||
let caught = null;
|
||||
|
||||
class C {
|
||||
#field;
|
||||
constructor() {
|
||||
try {
|
||||
#field in test262unresolvable;
|
||||
} catch (error) {
|
||||
caught = error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
new C();
|
||||
|
||||
assert.notSameValue(caught, null);
|
||||
assert.sameValue(caught.constructor, ReferenceError);
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Parsing observes the `Yield` production parameter when present
|
||||
info: |
|
||||
Syntax
|
||||
RelationalExpression[In, Yield, Await]:
|
||||
[...]
|
||||
[+In]PrivateIdentifier in ShiftExpression[?Yield, ?Await]
|
||||
|
||||
[...]
|
||||
|
||||
1. Let privateIdentifier be the StringValue of PrivateIdentifier.
|
||||
2. Let rref be the result of evaluating ShiftExpression.
|
||||
3. Let rval be ? GetValue(rref).
|
||||
4. If Type(rval) is not Object, throw a TypeError exception.
|
||||
esid: sec-relational-operators-runtime-semantics-evaluation
|
||||
negative:
|
||||
phase: parse
|
||||
type: SyntaxError
|
||||
features: [class-fields-private, class-fields-private-in]
|
||||
---*/
|
||||
|
||||
$DONOTEVALUATE();
|
||||
|
||||
class C {
|
||||
#field;
|
||||
|
||||
static method() {
|
||||
#field in yield;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Parsing observes the `Yield` production parameter when present
|
||||
info: |
|
||||
Syntax
|
||||
RelationalExpression[In, Yield, Await]:
|
||||
[...]
|
||||
[+In]PrivateIdentifier in ShiftExpression[?Yield, ?Await]
|
||||
|
||||
[...]
|
||||
|
||||
1. Let privateIdentifier be the StringValue of PrivateIdentifier.
|
||||
2. Let rref be the result of evaluating ShiftExpression.
|
||||
3. Let rval be ? GetValue(rref).
|
||||
4. If Type(rval) is not Object, throw a TypeError exception.
|
||||
esid: sec-relational-operators-runtime-semantics-evaluation
|
||||
features: [class-fields-private, class-fields-private-in]
|
||||
---*/
|
||||
|
||||
class C {
|
||||
#field;
|
||||
|
||||
static *isNameIn() {
|
||||
return #field in (yield);
|
||||
}
|
||||
}
|
||||
|
||||
let iter1 = C.isNameIn();
|
||||
iter1.next();
|
||||
assert.sameValue(iter1.next(new C()).value, true);
|
||||
|
||||
let iter2 = C.isNameIn();
|
||||
iter2.next();
|
||||
assert.sameValue(iter2.next({}).value, false);
|
Loading…
Reference in New Issue