diff options
Diffstat (limited to 'js/src/tests/test262/language/expressions/in')
38 files changed, 1220 insertions, 0 deletions
diff --git a/js/src/tests/test262/language/expressions/in/S11.8.7_A1.js b/js/src/tests/test262/language/expressions/in/S11.8.7_A1.js new file mode 100644 index 0000000000..b304c8f2ff --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/S11.8.7_A1.js @@ -0,0 +1,62 @@ +// Copyright 2009 the Sputnik authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +info: | + White Space and Line Terminator between RelationalExpression and "in" and + between "in" and ShiftExpression are allowed +es5id: 11.8.7_A1 +description: Checking by using eval +---*/ + +//CHECK#1 +if (eval("'MAX_VALUE'\u0009in\u0009Number") !== true) { + throw new Test262Error('#1: "MAX_VALUE"\\u0009in\\u0009Number === true'); +} + +//CHECK#2 +if (eval("'MAX_VALUE'\u000Bin\u000BNumber") !== true) { + throw new Test262Error('#2: "MAX_VALUE"\\u000Bin\\u000BNumber === true'); +} + +//CHECK#3 +if (eval("'MAX_VALUE'\u000Cin\u000CNumber") !== true) { + throw new Test262Error('#3: "MAX_VALUE"\\u000Cin\\u000CNumber === true'); +} + +//CHECK#4 +if (eval("'MAX_VALUE'\u0020in\u0020Number") !== true) { + throw new Test262Error('#4: "MAX_VALUE"\\u0020in\\u0020Number === true'); +} + +//CHECK#5 +if (eval("'MAX_VALUE'\u00A0in\u00A0Number") !== true) { + throw new Test262Error('#5: "MAX_VALUE"\\u00A0in\\u00A0Number === true'); +} + +//CHECK#6 +if (eval("'MAX_VALUE'\u000Ain\u000ANumber") !== true) { + throw new Test262Error('#6: "MAX_VALUE"\\u000Ain\\u000ANumber === true'); +} + +//CHECK#7 +if (eval("'MAX_VALUE'\u000Din\u000DNumber") !== true) { + throw new Test262Error('#7: "MAX_VALUE"\\u000Din\\u000DNumber === true'); +} + +//CHECK#8 +if (eval("'MAX_VALUE'\u2028in\u2028Number") !== true) { + throw new Test262Error('#8: "MAX_VALUE"\\u2028in\\u2028Number === true'); +} + +//CHECK#9 +if (eval("'MAX_VALUE'\u2029in\u2029Number") !== true) { + throw new Test262Error('#9: "MAX_VALUE"\\u2029in\\u2029Number === true'); +} + +//CHECK#10 +if (eval("'MAX_VALUE'\u0009\u000B\u000C\u0020\u00A0\u000A\u000D\u2028\u2029in\u0009\u000B\u000C\u0020\u00A0\u000A\u000D\u2028\u2029Number") !== true) { + throw new Test262Error('#10: "MAX_VALUE"\\u0009\\u000B\\u000C\\u0020\\u00A0\\u000A\\u000D\\u2028\\u2029in\\u0009\\u000B\\u000C\\u0020\\u00A0\\u000A\\u000D\\u2028\\u2029Number === true'); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/S11.8.7_A2.1_T1.js b/js/src/tests/test262/language/expressions/in/S11.8.7_A2.1_T1.js new file mode 100644 index 0000000000..97cff94304 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/S11.8.7_A2.1_T1.js @@ -0,0 +1,34 @@ +// Copyright 2009 the Sputnik authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +info: Operator "in" uses GetValue +es5id: 11.8.7_A2.1_T1 +description: Either Expression is not Reference or GetBase is not null +---*/ + +//CHECK#1 +if ("MAX_VALUE" in Number !== true) { + throw new Test262Error('#1: "MAX_VALUE" in Number === true'); +} + +//CHECK#2 +var x = "MAX_VALUE"; +if (x in Number !== true) { + throw new Test262Error('#2: var x = "MAX_VALUE"; x in Number === true'); +} + +//CHECK#3 +var y = Number; +if ("MAX_VALUE" in y !== true) { + throw new Test262Error('#3: var y = Number; "MAX_VALUE" in y === true'); +} + +//CHECK#4 +var x = "MAX_VALUE"; +var y = Number; +if (x in y !== true) { + throw new Test262Error('#4: var x = "MAX_VALUE"; var y = Number; x in y === true'); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/S11.8.7_A2.1_T2.js b/js/src/tests/test262/language/expressions/in/S11.8.7_A2.1_T2.js new file mode 100644 index 0000000000..76bca7149e --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/S11.8.7_A2.1_T2.js @@ -0,0 +1,21 @@ +// Copyright 2009 the Sputnik authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +info: Operator "in" uses GetValue +es5id: 11.8.7_A2.1_T2 +description: If GetBase(RelationalExpression) is null, throw ReferenceError +---*/ + +//CHECK#1 +try { + MAX_VALUE in Number; + throw new Test262Error('#1.1: MAX_VALUE in Number throw ReferenceError. Actual: ' + (MAX_VALUE in Number)); +} +catch (e) { + if ((e instanceof ReferenceError) !== true) { + throw new Test262Error('#1.2: MAX_VALUE in Number throw ReferenceError. Actual: ' + (e)); + } +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/S11.8.7_A2.1_T3.js b/js/src/tests/test262/language/expressions/in/S11.8.7_A2.1_T3.js new file mode 100644 index 0000000000..9b8129a6e6 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/S11.8.7_A2.1_T3.js @@ -0,0 +1,21 @@ +// Copyright 2009 the Sputnik authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +info: Operator "in" uses GetValue +es5id: 11.8.7_A2.1_T3 +description: If GetBase(ShiftExpression) is null, throw ReferenceError +---*/ + +//CHECK#1 +try { + "MAX_VALUE" in NUMBER; + throw new Test262Error('#1.1: "MAX_VALUE" in NUMBER throw ReferenceError. Actual: ' + ("MAX_VALUE" in NUMBER)); +} +catch (e) { + if ((e instanceof ReferenceError) !== true) { + throw new Test262Error('#1.2: "MAX_VALUE" in NUMBER throw ReferenceError. Actual: ' + (e)); + } +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/S11.8.7_A2.4_T1.js b/js/src/tests/test262/language/expressions/in/S11.8.7_A2.4_T1.js new file mode 100644 index 0000000000..60c526eba5 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/S11.8.7_A2.4_T1.js @@ -0,0 +1,22 @@ +// Copyright 2009 the Sputnik authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +info: First expression is evaluated first, and then second expression +es5id: 11.8.7_A2.4_T1 +description: Checking with "=" +---*/ + +//CHECK#1 +var NUMBER = 0; +if ((NUMBER = Number, "MAX_VALUE") in NUMBER !== true) { + throw new Test262Error('#1: var NUMBER = 0; (NUMBER = Number, "MAX_VALUE") in NUMBER === true'); +} + +//CHECK#2 +var max_value = "MAX_VALUE"; +if (max_value in (max_value = "none", Number) !== true) { + throw new Test262Error('#2: var max_value = "MAX_VALUE"; max_value in (max_value = "none", Number) === true'); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/S11.8.7_A2.4_T2.js b/js/src/tests/test262/language/expressions/in/S11.8.7_A2.4_T2.js new file mode 100644 index 0000000000..5abcc342bc --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/S11.8.7_A2.4_T2.js @@ -0,0 +1,26 @@ +// Copyright 2009 the Sputnik authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +info: First expression is evaluated first, and then second expression +es5id: 11.8.7_A2.4_T2 +description: Checking with "throw" +---*/ + +//CHECK#1 +var x = function () { throw "x"; }; +var y = function () { throw "y"; }; +try { + x() in y(); + throw new Test262Error('#1.1: var x = function () { throw "x"; }; var y = function () { throw "y"; }; x() in y() throw "x". Actual: ' + (x() in y())); +} catch (e) { + if (e === "y") { + throw new Test262Error('#1.2: First expression is evaluated first, and then second expression'); + } else { + if (e !== "x") { + throw new Test262Error('#1.3: var x = function () { throw "x"; }; var y = function () { throw "y"; }; x() in y() throw "x". Actual: ' + (e)); + } + } +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/S11.8.7_A2.4_T3.js b/js/src/tests/test262/language/expressions/in/S11.8.7_A2.4_T3.js new file mode 100644 index 0000000000..01aa3bff03 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/S11.8.7_A2.4_T3.js @@ -0,0 +1,21 @@ +// Copyright 2009 the Sputnik authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +info: First expression is evaluated first, and then second expression +es5id: 11.8.7_A2.4_T3 +description: Checking with undeclarated variables +---*/ + +//CHECK#1 +try { + max_value in (max_value = "MAX_VALUE", Number); + throw new Test262Error('#1.1: max_value in (max_value = "MAX_VALUE", Number) throw ReferenceError. Actual: ' + (max_value in (max_value = "MAX_VALUE", Number))); +} +catch (e) { + if ((e instanceof ReferenceError) !== true) { + throw new Test262Error('#1.2: max_value in (max_value = "MAX_VALUE", Number) throw ReferenceError. Actual: ' + (e)); + } +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/S11.8.7_A2.4_T4.js b/js/src/tests/test262/language/expressions/in/S11.8.7_A2.4_T4.js new file mode 100644 index 0000000000..bdcd86784a --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/S11.8.7_A2.4_T4.js @@ -0,0 +1,16 @@ +// Copyright 2009 the Sputnik authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +info: First expression is evaluated first, and then second expression +es5id: 11.8.7_A2.4_T4 +description: Checking with undeclarated variables +flags: [noStrict] +---*/ + +//CHECK#1 +if ((NUMBER = Number, "MAX_VALUE") in NUMBER !== true) { + throw new Test262Error('#1: (NUMBER = Number, "MAX_VALUE") in NUMBER !== true'); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/S11.8.7_A3.js b/js/src/tests/test262/language/expressions/in/S11.8.7_A3.js new file mode 100644 index 0000000000..ea2be192d4 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/S11.8.7_A3.js @@ -0,0 +1,65 @@ +// Copyright 2009 the Sputnik authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +info: If ShiftExpression is not an object, throw TypeError +es5id: 11.8.7_A3 +description: Checking all the types of primitives +---*/ + +//CHECK#1 +try { + "toString" in true; + throw new Test262Error('#1: "toString" in true throw TypeError'); +} +catch (e) { + if ((e instanceof TypeError) !== true) { + throw new Test262Error('#1: "toString" in true throw TypeError'); + } +} + +//CHECK#2 +try { + "MAX_VALUE" in 1; + throw new Test262Error('#2: "MAX_VALUE" in 1 throw TypeError'); +} +catch (e) { + if ((e instanceof TypeError) !== true) { + throw new Test262Error('#2: "MAX_VALUE" in 1 throw TypeError'); + } +} + +//CHECK#3 +try { + "length" in "string"; + throw new Test262Error('#3: "length" in "string" throw TypeError'); +} +catch (e) { + if ((e instanceof TypeError) !== true) { + throw new Test262Error('#3: "length" in "string" throw TypeError'); + } +} + +//CHECK#4 +try { + "toString" in undefined; + throw new Test262Error('#4: "toString" in undefined throw TypeError'); +} +catch (e) { + if ((e instanceof TypeError) !== true) { + throw new Test262Error('#4: "toString" in undefined throw TypeError'); + } +} + +//CHECK#5 +try { + "toString" in null; + throw new Test262Error('#5: "toString" in null throw TypeError'); +} +catch (e) { + if ((e instanceof TypeError) !== true) { + throw new Test262Error('#5: "toString" in null throw TypeError'); + } +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/S11.8.7_A4.js b/js/src/tests/test262/language/expressions/in/S11.8.7_A4.js new file mode 100644 index 0000000000..43c7f37227 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/S11.8.7_A4.js @@ -0,0 +1,38 @@ +// Copyright 2009 the Sputnik authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +info: Operator "in" calls ToString(ShiftExpression) +es5id: 11.8.7_A4 +description: Checking ToString coversion; +---*/ + +//CHECK#1 +var object = {}; +object["true"] = 1; +if (true in object !== "true" in object) { + throw new Test262Error('#1: "var object = {}; object["true"] = 1; true in object === "true" in object'); +} + +//CHECK#2 +var object = {}; +object.Infinity = 1; +if (Infinity in object !== "Infinity" in object) { + throw new Test262Error('#2: "var object = {}; object.Infinity = 1; Infinity in object === "Infinity" in object'); +} + +//CHECK#4 +var object = {}; +object.undefined = 1; +if (undefined in object !== "undefined" in object) { + throw new Test262Error('#4: "var object = {}; object.undefined = 1; undefined in object === "undefined" in object'); +} + +//CHECK#5 +var object = {}; +object["null"] = 1; +if (null in object !== "null" in object) { + throw new Test262Error('#5: "var object = {}; object["null"] = 1; null in object === "null" in object'); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/S8.12.6_A1.js b/js/src/tests/test262/language/expressions/in/S8.12.6_A1.js new file mode 100644 index 0000000000..13ffeb62a5 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/S8.12.6_A1.js @@ -0,0 +1,22 @@ +// Copyright 2009 the Sputnik authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +info: | + When the [[HasProperty]] method of O is called with property name P and + if O has a property with name P, return true +es5id: 8.12.6_A1 +description: Try find existent property of any Object +---*/ + +var __obj={fooProp:"fooooooo"}; + +////////////////////////////////////////////////////////////////////////////// +//CHECK#1 +if (!("fooProp" in __obj)) { + throw new Test262Error('#1: var __obj={fooProp:"fooooooo"}; "fooProp" in __obj'); +} +// +////////////////////////////////////////////////////////////////////////////// + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/S8.12.6_A2_T1.js b/js/src/tests/test262/language/expressions/in/S8.12.6_A2_T1.js new file mode 100644 index 0000000000..64e1b60517 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/S8.12.6_A2_T1.js @@ -0,0 +1,22 @@ +// Copyright 2009 the Sputnik authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +info: | + When the [[HasProperty]] method of O is called with property name P and if O has not a property with name P + then If the [[Prototype]] of O is null, return false or call the [[HasProperty]] method of [[Prototype]] with property name P +es5id: 8.12.6_A2_T1 +description: Try find not existent property of any Object +---*/ + +var __obj={}; + +////////////////////////////////////////////////////////////////////////////// +//CHECK#1 +if (!("valueOf" in __obj)) { + throw new Test262Error('#1: var __obj={}; "valueOf" in __obj'); +} +// +////////////////////////////////////////////////////////////////////////////// + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/S8.12.6_A2_T2.js b/js/src/tests/test262/language/expressions/in/S8.12.6_A2_T2.js new file mode 100644 index 0000000000..b662ecedd7 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/S8.12.6_A2_T2.js @@ -0,0 +1,46 @@ +// Copyright 2009 the Sputnik authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +info: | + When the [[HasProperty]] method of O is called with property name P and if O has not a property with name P + then If the [[Prototype]] of O is null, return false or call the [[HasProperty]] method of [[Prototype]] with property name P +es5id: 8.12.6_A2_T2 +description: > + Try find not existent property of any Object, but existent + property of this Object prototype +---*/ + +var __proto={phylum:"avis"}; + + +////////////////////////////////////////////////////////////////////////////// +//CHECK#1 +if (!("valueOf" in __proto)) { + throw new Test262Error('#1: var __proto={phylum:"avis"}; "valueOf" in __proto'); +} +// +////////////////////////////////////////////////////////////////////////////// + +function Robin(){this.name="robin"}; +Robin.prototype=__proto; + +var __my__robin = new Robin; + +////////////////////////////////////////////////////////////////////////////// +//CHECK#2 +if (!("phylum" in __my__robin)) { + throw new Test262Error('#2: var __proto={phylum:"avis"}; function Robin(){this.name="robin"}; Robin.prototype=__proto; var __my__robin = new Robin; "phylum" in __my__robin'); +} +// +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +//CHECK#3 +if (__my__robin.hasOwnProperty("phylum")) { + throw new Test262Error('#3: var __proto={phylum:"avis"}; function Robin(){this.name="robin"}; Robin.prototype=__proto; var __my__robin = new Robin; __my__robin.hasOwnProperty("phylum") === false. Actual: ' + (__my__robin.hasOwnProperty("phylum"))); +} +// +////////////////////////////////////////////////////////////////////////////// + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/S8.12.6_A3.js b/js/src/tests/test262/language/expressions/in/S8.12.6_A3.js new file mode 100644 index 0000000000..c9aca7c8d7 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/S8.12.6_A3.js @@ -0,0 +1,46 @@ +// Copyright 2009 the Sputnik authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +info: "[[hasProperty]] is sensitive to property existence but [[Get]] is not" +es5id: 8.12.6_A3 +description: > + Use [[hasProperty]] and [[Get]] for existent and not existent + properties +---*/ + +var __obj={}; __obj.hole=undefined; + +////////////////////////////////////////////////////////////////////////////// +//CHECK#1 +if (__obj.hole !== undefined) { + throw new Test262Error('#1: var __obj={}; __obj.hole=undefined; __obj.hole === undefined. Actual: ' + (__obj.hole)); +} +// +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +//CHECK#2 +if (__obj.notexist !== undefined) { + throw new Test262Error('#2: var __obj={}; __obj.hole=undefined; __obj.notexist === undefined. Actual: ' + (__obj.notexist)); +} +// +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +//CHECK#3 +if (!("hole" in __obj)) { + throw new Test262Error('#3: var __obj={}; __obj.hole=undefined; "hole" in __obj'); +} +// +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +//CHECK#4 +if (("notexist" in __obj)) { + throw new Test262Error('#4: var __obj={}; __obj.hole=undefined; "notexist" in __obj'); +} +// +////////////////////////////////////////////////////////////////////////////// + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/browser.js b/js/src/tests/test262/language/expressions/in/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/browser.js diff --git a/js/src/tests/test262/language/expressions/in/private-field-in-nested.js b/js/src/tests/test262/language/expressions/in/private-field-in-nested.js new file mode 100644 index 0000000000..d49304e62e --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/private-field-in-nested.js @@ -0,0 +1,28 @@ +// |reftest| error:SyntaxError +// 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; + } +} diff --git a/js/src/tests/test262/language/expressions/in/private-field-in.js b/js/src/tests/test262/language/expressions/in/private-field-in.js new file mode 100644 index 0000000000..31a47f55ec --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/private-field-in.js @@ -0,0 +1,27 @@ +// |reftest| error:SyntaxError +// 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; + } +} diff --git a/js/src/tests/test262/language/expressions/in/private-field-invalid-assignment-reference.js b/js/src/tests/test262/language/expressions/in/private-field-invalid-assignment-reference.js new file mode 100644 index 0000000000..687165cc8d --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/private-field-invalid-assignment-reference.js @@ -0,0 +1,26 @@ +// |reftest| error:SyntaxError +// 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 []) ; + } +} diff --git a/js/src/tests/test262/language/expressions/in/private-field-invalid-assignment-target.js b/js/src/tests/test262/language/expressions/in/private-field-invalid-assignment-target.js new file mode 100644 index 0000000000..d788f5d9e6 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/private-field-invalid-assignment-target.js @@ -0,0 +1,32 @@ +// |reftest| error:SyntaxError +// 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; + } +} diff --git a/js/src/tests/test262/language/expressions/in/private-field-invalid-identifier-complex.js b/js/src/tests/test262/language/expressions/in/private-field-invalid-identifier-complex.js new file mode 100644 index 0000000000..802f539efe --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/private-field-invalid-identifier-complex.js @@ -0,0 +1,32 @@ +// |reftest| error:SyntaxError +// 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 {}; + } +} diff --git a/js/src/tests/test262/language/expressions/in/private-field-invalid-identifier-simple.js b/js/src/tests/test262/language/expressions/in/private-field-invalid-identifier-simple.js new file mode 100644 index 0000000000..db3365eea9 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/private-field-invalid-identifier-simple.js @@ -0,0 +1,26 @@ +// |reftest| error:SyntaxError +// 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 {}; diff --git a/js/src/tests/test262/language/expressions/in/private-field-invalid-rhs.js b/js/src/tests/test262/language/expressions/in/private-field-invalid-rhs.js new file mode 100644 index 0000000000..fb8783d019 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/private-field-invalid-rhs.js @@ -0,0 +1,27 @@ +// |reftest| error:SyntaxError +// 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 () => {}; + } +} diff --git a/js/src/tests/test262/language/expressions/in/private-field-presence-accessor-shadowed.js b/js/src/tests/test262/language/expressions/in/private-field-presence-accessor-shadowed.js new file mode 100644 index 0000000000..29a33b9b2d --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/private-field-presence-accessor-shadowed.js @@ -0,0 +1,49 @@ +// 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'); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/private-field-presence-accessor.js b/js/src/tests/test262/language/expressions/in/private-field-presence-accessor.js new file mode 100644 index 0000000000..f684525631 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/private-field-presence-accessor.js @@ -0,0 +1,35 @@ +// 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); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/private-field-presence-field-shadowed.js b/js/src/tests/test262/language/expressions/in/private-field-presence-field-shadowed.js new file mode 100644 index 0000000000..805ce61193 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/private-field-presence-field-shadowed.js @@ -0,0 +1,38 @@ +// 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); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/private-field-presence-field.js b/js/src/tests/test262/language/expressions/in/private-field-presence-field.js new file mode 100644 index 0000000000..50a24a6aa5 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/private-field-presence-field.js @@ -0,0 +1,28 @@ +// 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); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/private-field-presence-method-shadowed.js b/js/src/tests/test262/language/expressions/in/private-field-presence-method-shadowed.js new file mode 100644 index 0000000000..7d12504b05 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/private-field-presence-method-shadowed.js @@ -0,0 +1,48 @@ +// 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'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/private-field-presence-method.js b/js/src/tests/test262/language/expressions/in/private-field-presence-method.js new file mode 100644 index 0000000000..c736fa5a95 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/private-field-presence-method.js @@ -0,0 +1,35 @@ +// 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); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/private-field-rhs-await-absent.js b/js/src/tests/test262/language/expressions/in/private-field-rhs-await-absent.js new file mode 100644 index 0000000000..c2b12ad402 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/private-field-rhs-await-absent.js @@ -0,0 +1,41 @@ +// 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); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/private-field-rhs-await-present.js b/js/src/tests/test262/language/expressions/in/private-field-rhs-await-present.js new file mode 100644 index 0000000000..a67c90218d --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/private-field-rhs-await-present.js @@ -0,0 +1,40 @@ +// |reftest| async +// 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); diff --git a/js/src/tests/test262/language/expressions/in/private-field-rhs-non-object.js b/js/src/tests/test262/language/expressions/in/private-field-rhs-non-object.js new file mode 100644 index 0000000000..db510e2106 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/private-field-rhs-non-object.js @@ -0,0 +1,53 @@ +// 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); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/private-field-rhs-unresolvable.js b/js/src/tests/test262/language/expressions/in/private-field-rhs-unresolvable.js new file mode 100644 index 0000000000..f76cd96882 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/private-field-rhs-unresolvable.js @@ -0,0 +1,32 @@ +// 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); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/private-field-rhs-yield-absent.js b/js/src/tests/test262/language/expressions/in/private-field-rhs-yield-absent.js new file mode 100644 index 0000000000..77ee26a61f --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/private-field-rhs-yield-absent.js @@ -0,0 +1,34 @@ +// |reftest| error:SyntaxError +// 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; + } +} diff --git a/js/src/tests/test262/language/expressions/in/private-field-rhs-yield-present.js b/js/src/tests/test262/language/expressions/in/private-field-rhs-yield-present.js new file mode 100644 index 0000000000..7ab2272328 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/private-field-rhs-yield-present.js @@ -0,0 +1,38 @@ +// 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); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/rhs-yield-absent-non-strict.js b/js/src/tests/test262/language/expressions/in/rhs-yield-absent-non-strict.js new file mode 100644 index 0000000000..7e5cbae2b2 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/rhs-yield-absent-non-strict.js @@ -0,0 +1,32 @@ +// 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 absent (without strict mode) +info: | + Syntax + RelationalExpression[In, Yield, Await]: + [...] + [+In] RelationalExpression[+In, ?Yield, ?Await] in ShiftExpression[?Yield, ?Await] + + [...] + + 1. Let lref be the result of evaluating RelationalExpression. + 2. Let lval be ? GetValue(lref). + 3. Let rref be the result of evaluating ShiftExpression. + 4. Let rval be ? GetValue(rref). + 5. If Type(rval) is not Object, throw a TypeError exception. + 6. Return ? HasProperty(rval, ? ToPropertyKey(lval)). +esid: sec-relational-operators +flags: [noStrict] +---*/ + +var yield; + +yield = {'': 0}; +assert.sameValue('' in (yield), true); + +yield = {}; +assert.sameValue('' in (yield), false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/rhs-yield-absent-strict-strict.js b/js/src/tests/test262/language/expressions/in/rhs-yield-absent-strict-strict.js new file mode 100644 index 0000000000..cac0db7e1d --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/rhs-yield-absent-strict-strict.js @@ -0,0 +1,22 @@ +// |reftest| error:SyntaxError +'use strict'; +// 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 absent (within strict mode) +info: | + Syntax + RelationalExpression[In, Yield, Await]: + [...] + [+In] RelationalExpression[+In, ?Yield, ?Await] in ShiftExpression[?Yield, ?Await] +esid: sec-relational-operators +negative: + phase: parse + type: SyntaxError +flags: [onlyStrict] +---*/ + +$DONOTEVALUATE(); + +'' in (yield); diff --git a/js/src/tests/test262/language/expressions/in/rhs-yield-present.js b/js/src/tests/test262/language/expressions/in/rhs-yield-present.js new file mode 100644 index 0000000000..e3fec252bd --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/rhs-yield-present.js @@ -0,0 +1,35 @@ +// 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] RelationalExpression[+In, ?Yield, ?Await] in ShiftExpression[?Yield, ?Await] + + [...] + + 1. Let lref be the result of evaluating RelationalExpression. + 2. Let lval be ? GetValue(lref). + 3. Let rref be the result of evaluating ShiftExpression. + 4. Let rval be ? GetValue(rref). + 5. If Type(rval) is not Object, throw a TypeError exception. + 6. Return ? HasProperty(rval, ? ToPropertyKey(lval)). +esid: sec-relational-operators-runtime-semantics-evaluation +---*/ + +function * isNameIn() { + return '' in (yield); +} + +let iter1 = isNameIn(); +iter1.next(); +assert.sameValue(iter1.next({'': 0}).value, true); + +let iter2 = isNameIn(); +iter2.next(); +assert.sameValue(iter2.next({}).value, false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/language/expressions/in/shell.js b/js/src/tests/test262/language/expressions/in/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/language/expressions/in/shell.js |