Add tests for stage 3 proposal "private fields in" (#2963)

This commit is contained in:
jugglinmike 2021-04-19 10:50:52 -04:00 committed by GitHub
parent 6e61dd7754
commit 61c6f8214b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 592 additions and 0 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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