diff --git a/features.txt b/features.txt index 7dfd79f455b..06ddd2b9bd5 100644 --- a/features.txt +++ b/features.txt @@ -170,6 +170,10 @@ String.prototype.replaceAll # https://github.com/tc39/proposal-for-in-order for-in-order +# Legacy RegExp features +# https://github.com/tc39/proposal-regexp-legacy-features +legacy-regexp + # Logical Assignment Operators # https://github.com/tc39/proposal-logical-assignment logical-assignment-operators diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/index/prop-desc.js b/test/annexB/built-ins/RegExp/legacy-accessors/index/prop-desc.js new file mode 100644 index 00000000000..2ed08f5ce88 --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/index/prop-desc.js @@ -0,0 +1,32 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Property descriptor for RegExp.$1-$9 +info: | + RegExp.$1-$9 are accessor properties with attributes + { + [[Enumerable]]: false, + [[Configurable]]: true, + [[Set]]: undefined, + } + + get RegExp.$1-$9 + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpParen1-9]]). +includes: [propertyHelper.js] +features: [legacy-regexp] +---*/ + +for (let i = 1; i <= 9; i++) { + const property = "$" + i; + const desc = Object.getOwnPropertyDescriptor(RegExp, property); + + assert.sameValue(desc.set, undefined, property + " setter"); + assert.sameValue(typeof desc.get, "function", property + " getter"); + + verifyProperty(RegExp, property, { + enumerable: false, + configurable: true + }); +} diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/index/this-cross-realm-constructor.js b/test/annexB/built-ins/RegExp/legacy-accessors/index/this-cross-realm-constructor.js new file mode 100644 index 00000000000..8ae80d34488 --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/index/this-cross-realm-constructor.js @@ -0,0 +1,30 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: RegExp.$1-$9 throw a TypeError for cross-realm receiver +info: | + get RegExp.$1-$9 + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpParen1-9]]). + + GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ). + + 1. Assert C is an object that has an internal slot named internalSlotName. + 2. If SameValue(C, thisValue) is false, throw a TypeError exception. + 3. ... +features: [legacy-regexp,cross-realm,Reflect] +---*/ + +const other = $262.createRealm().global; + +for (let i = 1; i <= 9; i++) { + const property = "$" + i; + assert.throws( + TypeError, + function () { + Reflect.get(RegExp, property, other.RegExp); + }, + "RegExp." + property + " getter throws for cross-realm receiver" + ); +} diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/index/this-not-regexp-constructor.js b/test/annexB/built-ins/RegExp/legacy-accessors/index/this-not-regexp-constructor.js new file mode 100644 index 00000000000..81426cfae70 --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/index/this-not-regexp-constructor.js @@ -0,0 +1,60 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: RegExp.$1-$9 throw a TypeError for non-%RegExp% receiver +info: | + get RegExp.$1-$9 + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpParen1-9]]). + + GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ). + + 1. Assert C is an object that has an internal slot named internalSlotName. + 2. If SameValue(C, thisValue) is false, throw a TypeError exception. + 3. ... +features: [legacy-regexp] +---*/ + +for (let i = 1; i <= 9; i++) { + const property = "$" + i; + const desc = Object.getOwnPropertyDescriptor(RegExp, property); + + // Similar to the other test verifying the descriptor, but split as properties can be removed or changed + assert.sameValue(typeof desc.get, "function", property + " getter"); + + // If SameValue(C, thisValue) is false, throw a TypeError exception. + assert.throws( + TypeError, + function () { + desc.get(); + }, + "RegExp." + property + " getter throws for property descriptor receiver" + ); + + assert.throws( + TypeError, + function () { + desc.get.call(/ /); + }, + "RegExp." + property + " getter throws for RegExp instance receiver" + ); + + assert.throws( + TypeError, + function () { + desc.get.call(RegExp.prototype); + }, + "RegExp." + property + " getter throws for %RegExp.prototype% receiver" + ); + + [undefined, null, {}, true, false, 0, 1, "string"].forEach(function (value) { + assert.throws( + TypeError, + function () { + desc.get.call(value); + }, + "RegExp." + property + ' getter throws for primitive "' + value + '" receiver' + ); + }); +} diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/index/this-subclass-constructor.js b/test/annexB/built-ins/RegExp/legacy-accessors/index/this-subclass-constructor.js new file mode 100644 index 00000000000..e2a0c883ac2 --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/index/this-subclass-constructor.js @@ -0,0 +1,30 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: RegExp.$1-$9 throw a TypeError for subclass receiver +info: | + get RegExp.$1-$9 + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpParen1-9]]). + + GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ). + + 1. Assert C is an object that has an internal slot named internalSlotName. + 2. If SameValue(C, thisValue) is false, throw a TypeError exception. + 3. ... +features: [legacy-regexp,class] +---*/ + +class MyRegExp extends RegExp {} + +for (let i = 1; i <= 9; i++) { + const property = "$" + i; + assert.throws( + TypeError, + function () { + MyRegExp[property]; + }, + "RegExp." + property + " getter throws for subclass receiver" + ); +} diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/input/prop-desc.js b/test/annexB/built-ins/RegExp/legacy-accessors/input/prop-desc.js new file mode 100644 index 00000000000..37a60dd51e2 --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/input/prop-desc.js @@ -0,0 +1,42 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Property descriptor for RegExp.input +info: | + RegExp.input is an accessor property with attributes: + { + [[Enumerable]]: false, + [[Configurable]]: true, + } + + get RegExp.input + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpInput]]). + + set RegExp.input = val + + 1. Return ? SetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpInput]], val). +includes: [propertyHelper.js] +features: [legacy-regexp] +---*/ + +var desc = Object.getOwnPropertyDescriptor(RegExp, "input"); + +assert.sameValue(typeof desc.get, "function", "`get` property"); +assert.sameValue(typeof desc.set, "function", "`set` property"); + +verifyProperty(RegExp, "input", { + enumerable: false, + configurable: true +}); + +desc = Object.getOwnPropertyDescriptor(RegExp, "$_"); + +assert.sameValue(typeof desc.get, "function", "`get` property"); +assert.sameValue(typeof desc.set, "function", "`set` property"); + +verifyProperty(RegExp, "$_", { + enumerable: false, + configurable: true +}); diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/input/this-cross-realm-constructor.js b/test/annexB/built-ins/RegExp/legacy-accessors/input/this-cross-realm-constructor.js new file mode 100644 index 00000000000..912de0e0a75 --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/input/this-cross-realm-constructor.js @@ -0,0 +1,61 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: RegExp.input throws a TypeError for cross-realm receiver +info: | + get RegExp.input + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpInput]]). + + set RegExp.input = val + + 1. Return ? SetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpInput]], val). + + GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ). + + 1. Assert C is an object that has an internal slot named internalSlotName. + 2. If SameValue(C, thisValue) is false, throw a TypeError exception. + 3. ... + + SetLegacyRegExpStaticProperty( C, thisValue, internalSlotName, val ). + + 1. Assert C is an object that has an internal slot named internalSlotName. + 2. If SameValue(C, thisValue) is false, throw a TypeError exception. + 3. ... +features: [legacy-regexp,cross-realm,Reflect,Reflect.set] +---*/ + +const other = $262.createRealm().global; + +assert.throws( + TypeError, + function () { + Reflect.get(RegExp, "input", other.RegExp); + }, + "RegExp.input getter throws for cross-realm receiver" +); + +assert.throws( + TypeError, + function () { + Reflect.set(RegExp, "input", "", other.RegExp); + }, + "RegExp.input setter throws for cross-realm receiver" +); + +assert.throws( + TypeError, + function () { + Reflect.get(RegExp, "$_", other.RegExp); + }, + "RegExp.$_ getter throws for cross-realm receiver" +); + +assert.throws( + TypeError, + function () { + Reflect.set(RegExp, "$_", "", other.RegExp); + }, + "RegExp.$_ setter throws for cross-realm receiver" +); diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/input/this-not-regexp-constructor.js b/test/annexB/built-ins/RegExp/legacy-accessors/input/this-not-regexp-constructor.js new file mode 100644 index 00000000000..37fb1911687 --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/input/this-not-regexp-constructor.js @@ -0,0 +1,73 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: RegExp.input throws a TypeError for non-%RegExp% receiver +info: | + get RegExp.input + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpInput]]). + + set RegExp.input = val + + 1. Return ? SetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpInput]], val). + + GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ). + + 1. Assert C is an object that has an internal slot named internalSlotName. + 2. If SameValue(C, thisValue) is false, throw a TypeError exception. + 3. ... + + SetLegacyRegExpStaticProperty( C, thisValue, internalSlotName, val ). + + 1. Assert C is an object that has an internal slot named internalSlotName. + 2. If SameValue(C, thisValue) is false, throw a TypeError exception. + 3. ... +features: [legacy-regexp] +---*/ + +["input", "$_"].forEach(function (property) { + const desc = Object.getOwnPropertyDescriptor(RegExp, property); + + ["get", "set"].forEach(function (accessor) { + const messagePrefix = "RegExp." + property + " " + accessor + "ter"; + + // Similar to the other test verifying the descriptor, but split as properties can be removed or changed + assert.sameValue(typeof desc[accessor], "function", messagePrefix); + + // If SameValue(C, thisValue) is false, throw a TypeError exception. + assert.throws( + TypeError, + function () { + desc[accessor](); + }, + messagePrefix + " throws for property descriptor receiver" + ); + + assert.throws( + TypeError, + function () { + desc[accessor].call(/ /); + }, + messagePrefix + " throws for RegExp instance receiver" + ); + + assert.throws( + TypeError, + function () { + desc[accessor].call(RegExp.prototype); + }, + messagePrefix + " throws for %RegExp.prototype% receiver" + ); + + [undefined, null, {}, true, false, 0, 1, "string"].forEach(function (value) { + assert.throws( + TypeError, + function () { + desc[accessor].call(value); + }, + messagePrefix + ' throws for primitive "' + value + '" receiver' + ); + }); + }); +}); diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/input/this-subclass-constructor.js b/test/annexB/built-ins/RegExp/legacy-accessors/input/this-subclass-constructor.js new file mode 100644 index 00000000000..665aff16918 --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/input/this-subclass-constructor.js @@ -0,0 +1,61 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: RegExp.input throws a TypeError for subclass receiver +info: | + get RegExp.input + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpInput]]). + + set RegExp.input = val + + 1. Return ? SetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpInput]], val). + + GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ). + + 1. Assert C is an object that has an internal slot named internalSlotName. + 2. If SameValue(C, thisValue) is false, throw a TypeError exception. + 3. ... + + SetLegacyRegExpStaticProperty( C, thisValue, internalSlotName, val ). + + 1. Assert C is an object that has an internal slot named internalSlotName. + 2. If SameValue(C, thisValue) is false, throw a TypeError exception. + 3. ... +features: [legacy-regexp,class] +---*/ + +class MyRegExp extends RegExp {} + +assert.throws( + TypeError, + function () { + MyRegExp.input; + }, + "RegExp.input getter throws for subclass receiver" +); + +assert.throws( + TypeError, + function () { + MyRegExp.input = ""; + }, + "RegExp.input setter throws for subclass receiver" +); + +assert.throws( + TypeError, + function () { + MyRegExp.$_; + }, + "RegExp.$_ getter throws for subclass receiver" +); + +assert.throws( + TypeError, + function () { + MyRegExp.$_ = ""; + }, + "RegExp.$_ setter throws for subclass receiver" +); diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/lastMatch/prop-desc.js b/test/annexB/built-ins/RegExp/legacy-accessors/lastMatch/prop-desc.js new file mode 100644 index 00000000000..4aae87e79ea --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/lastMatch/prop-desc.js @@ -0,0 +1,39 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Property descriptor for RegExp.lastMatch +info: | + RegExp.lastMatch is an accessor property with attributes: + { + [[Enumerable]]: false, + [[Configurable]]: true, + [[Set]]: undefined, + } + + get RegExp.lastMatch + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLastMatch]]). +includes: [propertyHelper.js] +features: [legacy-regexp] +---*/ + +var desc = Object.getOwnPropertyDescriptor(RegExp, "lastMatch"); + +assert.sameValue(desc.set, undefined, "`set` property"); +assert.sameValue(typeof desc.get, "function", "`get` property"); + +verifyProperty(RegExp, "lastMatch", { + enumerable: false, + configurable: true +}); + +desc = Object.getOwnPropertyDescriptor(RegExp, "$&"); + +assert.sameValue(desc.set, undefined, "`set` property"); +assert.sameValue(typeof desc.get, "function", "`get` property"); + +verifyProperty(RegExp, "$&", { + enumerable: false, + configurable: true +}); diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/lastMatch/this-cross-realm-constructor.js b/test/annexB/built-ins/RegExp/legacy-accessors/lastMatch/this-cross-realm-constructor.js new file mode 100644 index 00000000000..3fab3dd54f9 --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/lastMatch/this-cross-realm-constructor.js @@ -0,0 +1,35 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: RegExp.lastMatch throws a TypeError for cross-realm receiver +info: | + get RegExp.lastMatch + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLastMatch]]). + + GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ). + + 1. Assert C is an object that has an internal slot named internalSlotName. + 2. If SameValue(C, thisValue) is false, throw a TypeError exception. + 3. ... +features: [legacy-regexp,cross-realm,Reflect] +---*/ + +const other = $262.createRealm().global; + +assert.throws( + TypeError, + function () { + Reflect.get(RegExp, "lastMatch", other.RegExp); + }, + "RegExp.lastMatch getter throws for cross-realm receiver" +); + +assert.throws( + TypeError, + function () { + Reflect.get(RegExp, "$&", other.RegExp); + }, + "RegExp.$& getter throws for cross-realm receiver" +); diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/lastMatch/this-not-regexp-constructor.js b/test/annexB/built-ins/RegExp/legacy-accessors/lastMatch/this-not-regexp-constructor.js new file mode 100644 index 00000000000..5deb4a7933e --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/lastMatch/this-not-regexp-constructor.js @@ -0,0 +1,59 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: RegExp.lastMatch throws a TypeError for non-%RegExp% receiver +info: | + get RegExp.lastMatch + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLastMatch]]). + + GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ). + + 1. Assert C is an object that has an internal slot named internalSlotName. + 2. If SameValue(C, thisValue) is false, throw a TypeError exception. + 3. ... +features: [legacy-regexp] +---*/ + +["lastMatch", "$&"].forEach(function (property) { + const desc = Object.getOwnPropertyDescriptor(RegExp, property); + + // Similar to the other test verifying the descriptor, but split as properties can be removed or changed + assert.sameValue(typeof desc.get, "function", property + " getter"); + + // If SameValue(C, thisValue) is false, throw a TypeError exception. + assert.throws( + TypeError, + function () { + desc.get(); + }, + "RegExp." + property + " getter throws for property descriptor receiver" + ); + + assert.throws( + TypeError, + function () { + desc.get.call(/ /); + }, + "RegExp." + property + " getter throws for RegExp instance receiver" + ); + + assert.throws( + TypeError, + function () { + desc.get.call(RegExp.prototype); + }, + "RegExp." + property + " getter throws for %RegExp.prototype% receiver" + ); + + [undefined, null, {}, true, false, 0, 1, "string"].forEach(function (value) { + assert.throws( + TypeError, + function () { + desc.get.call(value); + }, + "RegExp." + property + ' getter throws for primitive "' + value + '" receiver' + ); + }); +}); diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/lastMatch/this-subclass-constructor.js b/test/annexB/built-ins/RegExp/legacy-accessors/lastMatch/this-subclass-constructor.js new file mode 100644 index 00000000000..8579f166930 --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/lastMatch/this-subclass-constructor.js @@ -0,0 +1,35 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: RegExp.lastMatch throws a TypeError for subclass receiver +info: | + get RegExp.lastMatch + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLastMatch]]). + + GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ). + + 1. Assert C is an object that has an internal slot named internalSlotName. + 2. If SameValue(C, thisValue) is false, throw a TypeError exception. + 3. ... +features: [legacy-regexp,class] +---*/ + +class MyRegExp extends RegExp {} + +assert.throws( + TypeError, + function () { + MyRegExp.lastMatch; + }, + "RegExp.lastMatch getter throws for subclass receiver" +); + +assert.throws( + TypeError, + function () { + MyRegExp["$&"]; + }, + "RegExp.$& getter throws for subclass receiver" +); diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/lastParen/prop-desc.js b/test/annexB/built-ins/RegExp/legacy-accessors/lastParen/prop-desc.js new file mode 100644 index 00000000000..c4f76a3a565 --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/lastParen/prop-desc.js @@ -0,0 +1,39 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Property descriptor for RegExp.lastParen +info: | + RegExp.lastParen is an accessor property with attributes: + { + [[Enumerable]]: false, + [[Configurable]]: true, + [[Set]]: undefined, + } + + get RegExp.lastParen + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLastParen]]). +includes: [propertyHelper.js] +features: [legacy-regexp] +---*/ + +var desc = Object.getOwnPropertyDescriptor(RegExp, "lastParen"); + +assert.sameValue(desc.set, undefined, "`set` property"); +assert.sameValue(typeof desc.get, "function", "`get` property"); + +verifyProperty(RegExp, "lastParen", { + enumerable: false, + configurable: true +}); + +desc = Object.getOwnPropertyDescriptor(RegExp, "$+"); + +assert.sameValue(desc.set, undefined, "`set` property"); +assert.sameValue(typeof desc.get, "function", "`get` property"); + +verifyProperty(RegExp, "$+", { + enumerable: false, + configurable: true +}); diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/lastParen/this-cross-realm-constructor.js b/test/annexB/built-ins/RegExp/legacy-accessors/lastParen/this-cross-realm-constructor.js new file mode 100644 index 00000000000..d2202bc7392 --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/lastParen/this-cross-realm-constructor.js @@ -0,0 +1,35 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: RegExp.lastParen throws a TypeError for cross-realm receiver +info: | + get RegExp.lastParen + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLastParen]]). + + GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ). + + 1. Assert C is an object that has an internal slot named internalSlotName. + 2. If SameValue(C, thisValue) is false, throw a TypeError exception. + 3. ... +features: [legacy-regexp,cross-realm,Reflect] +---*/ + +const other = $262.createRealm().global; + +assert.throws( + TypeError, + function () { + Reflect.get(RegExp, "lastParen", other.RegExp); + }, + "RegExp.lastParen getter throws for cross-realm receiver" +); + +assert.throws( + TypeError, + function () { + Reflect.get(RegExp, "$+", other.RegExp); + }, + "RegExp.$+ getter throws for cross-realm receiver" +); diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/lastParen/this-not-regexp-constructor.js b/test/annexB/built-ins/RegExp/legacy-accessors/lastParen/this-not-regexp-constructor.js new file mode 100644 index 00000000000..640a5745346 --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/lastParen/this-not-regexp-constructor.js @@ -0,0 +1,59 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: RegExp.lastParen throws a TypeError for non-%RegExp% receiver +info: | + get RegExp.lastParen + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLastParen]]). + + GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ). + + 1. Assert C is an object that has an internal slot named internalSlotName. + 2. If SameValue(C, thisValue) is false, throw a TypeError exception. + 3. ... +features: [legacy-regexp] +---*/ + +["lastParen", "$+"].forEach(function (property) { + const desc = Object.getOwnPropertyDescriptor(RegExp, property); + + // Similar to the other test verifying the descriptor, but split as properties can be removed or changed + assert.sameValue(typeof desc.get, "function", property + " getter"); + + // If SameValue(C, thisValue) is false, throw a TypeError exception. + assert.throws( + TypeError, + function () { + desc.get(); + }, + "RegExp." + property + " getter throws for property descriptor receiver" + ); + + assert.throws( + TypeError, + function () { + desc.get.call(/ /); + }, + "RegExp." + property + " getter throws for RegExp instance receiver" + ); + + assert.throws( + TypeError, + function () { + desc.get.call(RegExp.prototype); + }, + "RegExp." + property + " getter throws for %RegExp.prototype% receiver" + ); + + [undefined, null, {}, true, false, 0, 1, "string"].forEach(function (value) { + assert.throws( + TypeError, + function () { + desc.get.call(value); + }, + "RegExp." + property + ' getter throws for primitive "' + value + '" receiver' + ); + }); +}); diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/lastParen/this-subclass-constructor.js b/test/annexB/built-ins/RegExp/legacy-accessors/lastParen/this-subclass-constructor.js new file mode 100644 index 00000000000..b938e94a7cc --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/lastParen/this-subclass-constructor.js @@ -0,0 +1,35 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: RegExp.lastParen throws a TypeError for subclass receiver +info: | + get RegExp.lastParen + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLastParen]]). + + GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ). + + 1. Assert C is an object that has an internal slot named internalSlotName. + 2. If SameValue(C, thisValue) is false, throw a TypeError exception. + 3. ... +features: [legacy-regexp,class] +---*/ + +class MyRegExp extends RegExp {} + +assert.throws( + TypeError, + function () { + MyRegExp.lastParen; + }, + "RegExp.lastParen getter throws for subclass receiver" +); + +assert.throws( + TypeError, + function () { + MyRegExp["$+"]; + }, + "RegExp.$+ getter throws for subclass receiver" +); diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/leftContext/prop-desc.js b/test/annexB/built-ins/RegExp/legacy-accessors/leftContext/prop-desc.js new file mode 100644 index 00000000000..1d76ca6011d --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/leftContext/prop-desc.js @@ -0,0 +1,39 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Property descriptor for RegExp.leftContext +info: | + RegExp.leftContext is an accessor property with attributes: + { + [[Enumerable]]: false, + [[Configurable]]: true, + [[Set]]: undefined, + } + + get RegExp.leftContext + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLeftContext]]). +includes: [propertyHelper.js] +features: [legacy-regexp] +---*/ + +var desc = Object.getOwnPropertyDescriptor(RegExp, "leftContext"); + +assert.sameValue(desc.set, undefined, "`set` property"); +assert.sameValue(typeof desc.get, "function", "`get` property"); + +verifyProperty(RegExp, "leftContext", { + enumerable: false, + configurable: true +}); + +desc = Object.getOwnPropertyDescriptor(RegExp, "$`"); + +assert.sameValue(desc.set, undefined, "`set` property"); +assert.sameValue(typeof desc.get, "function", "`get` property"); + +verifyProperty(RegExp, "$`", { + enumerable: false, + configurable: true +}); diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/leftContext/this-cross-realm-constructor.js b/test/annexB/built-ins/RegExp/legacy-accessors/leftContext/this-cross-realm-constructor.js new file mode 100644 index 00000000000..e6c9199e4a5 --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/leftContext/this-cross-realm-constructor.js @@ -0,0 +1,35 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: RegExp.leftContext throws a TypeError for cross-realm receiver +info: | + get RegExp.leftContext + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLeftContext]]). + + GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ). + + 1. Assert C is an object that has an internal slot named internalSlotName. + 2. If SameValue(C, thisValue) is false, throw a TypeError exception. + 3. ... +features: [legacy-regexp,cross-realm,Reflect] +---*/ + +const other = $262.createRealm().global; + +assert.throws( + TypeError, + function () { + Reflect.get(RegExp, "leftContext", other.RegExp); + }, + "RegExp.leftContext getter throws for cross-realm receiver" +); + +assert.throws( + TypeError, + function () { + Reflect.get(RegExp, "$`", other.RegExp); + }, + "RegExp.$` getter throws for cross-realm receiver" +); diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/leftContext/this-not-regexp-constructor.js b/test/annexB/built-ins/RegExp/legacy-accessors/leftContext/this-not-regexp-constructor.js new file mode 100644 index 00000000000..d1a554a605f --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/leftContext/this-not-regexp-constructor.js @@ -0,0 +1,59 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: RegExp.leftContext throws a TypeError for non-%RegExp% receiver +info: | + get RegExp.leftContext + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLeftContext]]). + + GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ). + + 1. Assert C is an object that has an internal slot named internalSlotName. + 2. If SameValue(C, thisValue) is false, throw a TypeError exception. + 3. ... +features: [legacy-regexp] +---*/ + +["leftContext", "$`"].forEach(function (property) { + const desc = Object.getOwnPropertyDescriptor(RegExp, property); + + // Similar to the other test verifying the descriptor, but split as properties can be removed or changed + assert.sameValue(typeof desc.get, "function", property + " getter"); + + // If SameValue(C, thisValue) is false, throw a TypeError exception. + assert.throws( + TypeError, + function () { + desc.get(); + }, + "RegExp." + property + " getter throws for property descriptor receiver" + ); + + assert.throws( + TypeError, + function () { + desc.get.call(/ /); + }, + "RegExp." + property + " getter throws for RegExp instance receiver" + ); + + assert.throws( + TypeError, + function () { + desc.get.call(RegExp.prototype); + }, + "RegExp." + property + " getter throws for %RegExp.prototype% receiver" + ); + + [undefined, null, {}, true, false, 0, 1, "string"].forEach(function (value) { + assert.throws( + TypeError, + function () { + desc.get.call(value); + }, + "RegExp." + property + ' getter throws for primitive "' + value + '" receiver' + ); + }); +}); diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/leftContext/this-subclass-constructor.js b/test/annexB/built-ins/RegExp/legacy-accessors/leftContext/this-subclass-constructor.js new file mode 100644 index 00000000000..04f834285ab --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/leftContext/this-subclass-constructor.js @@ -0,0 +1,35 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: RegExp.leftContext throws a TypeError for subclass receiver +info: | + get RegExp.leftContext + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLeftContext]]). + + GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ). + + 1. Assert C is an object that has an internal slot named internalSlotName. + 2. If SameValue(C, thisValue) is false, throw a TypeError exception. + 3. ... +features: [legacy-regexp,class] +---*/ + +class MyRegExp extends RegExp {} + +assert.throws( + TypeError, + function () { + MyRegExp.leftContext; + }, + "RegExp.leftContext getter throws for subclass receiver" +); + +assert.throws( + TypeError, + function () { + MyRegExp["$`"]; + }, + "RegExp.$` getter throws for subclass receiver" +); diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/rightContext/prop-desc.js b/test/annexB/built-ins/RegExp/legacy-accessors/rightContext/prop-desc.js new file mode 100644 index 00000000000..d154c5de3d4 --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/rightContext/prop-desc.js @@ -0,0 +1,39 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Property descriptor for RegExp.rightContext +info: | + RegExp.rightContext is an accessor property with attributes: + { + [[Enumerable]]: false, + [[Configurable]]: true, + [[Set]]: undefined, + } + + get RegExp.rightContext + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpRightContext]]). +includes: [propertyHelper.js] +features: [legacy-regexp] +---*/ + +var desc = Object.getOwnPropertyDescriptor(RegExp, "rightContext"); + +assert.sameValue(desc.set, undefined, "`set` property"); +assert.sameValue(typeof desc.get, "function", "`get` property"); + +verifyProperty(RegExp, "rightContext", { + enumerable: false, + configurable: true +}); + +desc = Object.getOwnPropertyDescriptor(RegExp, "$'"); + +assert.sameValue(desc.set, undefined, "`set` property"); +assert.sameValue(typeof desc.get, "function", "`get` property"); + +verifyProperty(RegExp, "$'", { + enumerable: false, + configurable: true +}); diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/rightContext/this-cross-realm-constructor.js b/test/annexB/built-ins/RegExp/legacy-accessors/rightContext/this-cross-realm-constructor.js new file mode 100644 index 00000000000..63ca8753fb2 --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/rightContext/this-cross-realm-constructor.js @@ -0,0 +1,35 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: RegExp.rightContext throws a TypeError for cross-realm receiver +info: | + get RegExp.rightContext + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpRightContext]]). + + GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ). + + 1. Assert C is an object that has an internal slot named internalSlotName. + 2. If SameValue(C, thisValue) is false, throw a TypeError exception. + 3. ... +features: [legacy-regexp,cross-realm,Reflect] +---*/ + +const other = $262.createRealm().global; + +assert.throws( + TypeError, + function () { + Reflect.get(RegExp, "rightContext", other.RegExp); + }, + "RegExp.rightContext getter throws for cross-realm receiver" +); + +assert.throws( + TypeError, + function () { + Reflect.get(RegExp, "$'", other.RegExp); + }, + "RegExp.$' getter throws for cross-realm receiver" +); diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/rightContext/this-not-regexp-constructor.js b/test/annexB/built-ins/RegExp/legacy-accessors/rightContext/this-not-regexp-constructor.js new file mode 100644 index 00000000000..2bd9db1fea3 --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/rightContext/this-not-regexp-constructor.js @@ -0,0 +1,59 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: RegExp.rightContext throws a TypeError for non-%RegExp% receiver +info: | + get RegExp.rightContext + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpRightContext]]). + + GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ). + + 1. Assert C is an object that has an internal slot named internalSlotName. + 2. If SameValue(C, thisValue) is false, throw a TypeError exception. + 3. ... +features: [legacy-regexp] +---*/ + +["rightContext", "$'"].forEach(function (property) { + const desc = Object.getOwnPropertyDescriptor(RegExp, property); + + // Similar to the other test verifying the descriptor, but split as properties can be removed or changed + assert.sameValue(typeof desc.get, "function", property + " getter"); + + // If SameValue(C, thisValue) is false, throw a TypeError exception. + assert.throws( + TypeError, + function () { + desc.get(); + }, + "RegExp." + property + " getter throws for property descriptor receiver" + ); + + assert.throws( + TypeError, + function () { + desc.get.call(/ /); + }, + "RegExp." + property + " getter throws for RegExp instance receiver" + ); + + assert.throws( + TypeError, + function () { + desc.get.call(RegExp.prototype); + }, + "RegExp." + property + " getter throws for %RegExp.prototype% receiver" + ); + + [undefined, null, {}, true, false, 0, 1, "string"].forEach(function (value) { + assert.throws( + TypeError, + function () { + desc.get.call(value); + }, + "RegExp." + property + ' getter throws for primitive "' + value + '" receiver' + ); + }); +}); diff --git a/test/annexB/built-ins/RegExp/legacy-accessors/rightContext/this-subclass-constructor.js b/test/annexB/built-ins/RegExp/legacy-accessors/rightContext/this-subclass-constructor.js new file mode 100644 index 00000000000..93f4e214504 --- /dev/null +++ b/test/annexB/built-ins/RegExp/legacy-accessors/rightContext/this-subclass-constructor.js @@ -0,0 +1,35 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: RegExp.rightContext throws a TypeError for subclass receiver +info: | + get RegExp.rightContext + + 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpRightContext]]). + + GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ). + + 1. Assert C is an object that has an internal slot named internalSlotName. + 2. If SameValue(C, thisValue) is false, throw a TypeError exception. + 3. ... +features: [legacy-regexp,class] +---*/ + +class MyRegExp extends RegExp {} + +assert.throws( + TypeError, + function () { + MyRegExp.rightContext; + }, + "RegExp.rightContext getter throws for subclass receiver" +); + +assert.throws( + TypeError, + function () { + MyRegExp["$'"]; + }, + "RegExp.$' getter throws for subclass receiver" +); diff --git a/test/annexB/built-ins/RegExp/prototype/compile/this-cross-realm-instance.js b/test/annexB/built-ins/RegExp/prototype/compile/this-cross-realm-instance.js new file mode 100644 index 00000000000..cab609967fe --- /dev/null +++ b/test/annexB/built-ins/RegExp/prototype/compile/this-cross-realm-instance.js @@ -0,0 +1,34 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-regexp.prototype.compile +description: RegExp.prototype.compile throws a TypeError for cross-realm calls +features: [legacy-regexp,cross-realm] +---*/ + +const other = $262.createRealm().global; + +const regexp = new RegExp(""); +const otherRealm_regexp = new other.RegExp(""); + +assert.throws( + TypeError, + function () { + RegExp.prototype.compile.call(otherRealm_regexp); + }, + "`RegExp.prototype.compile.call(otherRealm_regexp)` throws TypeError" +); + +assert.throws( + TypeError, + function () { + other.RegExp.prototype.compile.call(regexp); + }, + "`other.RegExp.prototype.compile.call(regexp)` throws TypeError" +); + +assert.sameValue( + otherRealm_regexp.compile(), + otherRealm_regexp, + "`otherRealm_regexp.compile()` is SameValue with `otherRealm_regexp`" +); diff --git a/test/annexB/built-ins/RegExp/prototype/compile/this-subclass-instance.js b/test/annexB/built-ins/RegExp/prototype/compile/this-subclass-instance.js new file mode 100644 index 00000000000..ea44faa4b10 --- /dev/null +++ b/test/annexB/built-ins/RegExp/prototype/compile/this-subclass-instance.js @@ -0,0 +1,25 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-regexp.prototype.compile +description: RegExp.prototype.compile throws a TypeError for calls on subclasses +features: [legacy-regexp,class] +---*/ + +const subclass_regexp = new (class extends RegExp {})(""); + +assert.throws( + TypeError, + function () { + subclass_regexp.compile(); + }, + "`subclass_regexp.compile()` throws TypeError" +); + +assert.throws( + TypeError, + function () { + RegExp.prototype.compile.call(subclass_regexp); + }, + "`RegExp.prototype.compile.call(subclass_regexp)` throws TypeError" +);