Skip to content

Commit

Permalink
Merge pull request #1252 from zloirock/symbol-predicates
Browse files Browse the repository at this point in the history
  • Loading branch information
zloirock committed Jun 2, 2023
2 parents 309a29b + 5300ea3 commit dba4bd2
Show file tree
Hide file tree
Showing 26 changed files with 213 additions and 68 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
- [Iterator Helpers Stage 3 proposal](https://github.com/tc39/proposal-iterator-helpers):
- Changed `Symbol.iterator` fallback from callable check to `undefined` / `null` check, May 2023 TC39 meeting, [proposal-iterator-helpers/272](https://github.com/tc39/proposal-iterator-helpers/pull/272)
- Removed `IsCallable` check on `NextMethod`, deferring errors to `Call` site, May 2023 TC39 meeting, [proposal-iterator-helpers/274](https://github.com/tc39/proposal-iterator-helpers/pull/274)
- [`Symbol` predicates stage 2 proposal](https://github.com/tc39/proposal-symbol-predicates):
- The methods renamed to end with `Symbol`, [May 2023 TC39 meeting](https://github.com/babel/proposals/issues/88#issuecomment-1548219580):
- `Symbol.isRegistered` -> `Symbol.isRegisteredSymbol`
- `Symbol.isWellKnown` -> `Symbol.isWellKnownSymbol`
- Fixed some cases of increasing buffer size in `ArrayBuffer.prototype.{ transfer, transferToFixedLength }` polyfills
- Fixed awaiting async `AsyncDisposableStack.prototype.adopt` callback, [#1258](https://github.com/zloirock/core-js/issues/1258)
- Compat data improvements:
Expand Down
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2610,27 +2610,27 @@ core-js(-pure)/full/async-disposable-stack
core-js(-pure)/full/async-iterator/async-dispose
```
##### [`Symbol` predicates](https://github.com/tc39/proposal-symbol-predicates)[⬆](#index)
Modules [`esnext.symbol.is-registered`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.symbol.is-registered.js), [`esnext.symbol.is-well-known`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.symbol.is-well-known.js).
Modules [`esnext.symbol.is-registered-symbol`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.symbol.is-registered-symbol.js), [`esnext.symbol.is-well-known-symbol`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.symbol.is-well-known-symbol.js).
```js
class Symbol {
static isRegistered(value: any): boolean;
static isWellKnown(value: any): boolean;
static isRegisteredSymbol(value: any): boolean;
static isWellKnownSymbol(value: any): boolean;
}
```
```
[*CommonJS entry points:*](#commonjs-api)
```js
core-js/proposals/symbol-predicates
core-js(-pure)/full/symbol/is-registered
core-js(-pure)/full/symbol/is-well-known
core-js/proposals/symbol-predicates-v2
core-js(-pure)/full/symbol/is-registered-symbol
core-js(-pure)/full/symbol/is-well-known-symbol
```
[*Example*](https://tinyurl.com/2cuwpu8d):
[*Example*](https://tinyurl.com/2oqoaq7t):
```js
Symbol.isRegistered(Symbol.for('key')); // => true
Symbol.isRegistered(Symbol('key')); // => false
Symbol.isRegisteredSymbol(Symbol.for('key')); // => true
Symbol.isRegisteredSymbol(Symbol('key')); // => false
Symbol.isWellKnown(Symbol.iterator); // => true
Symbol.isWellKnown(Symbol('key')); // => false
Symbol.isWellKnownSymbol(Symbol.iterator); // => true
Symbol.isWellKnownSymbol(Symbol('key')); // => false
```

#### Stage 1 proposals[⬆](#index)
Expand Down
7 changes: 7 additions & 0 deletions packages/core-js-compat/src/data.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2236,8 +2236,15 @@ export const data = {
},
'esnext.symbol.dispose': {
},
'esnext.symbol.is-registered-symbol': {
},
// TODO: Remove from `core-js@4`
'esnext.symbol.is-registered': {
},
// We should patch it for newly added well-known symbols. If it's not required, this module just will not be injected
'esnext.symbol.is-well-known-symbol': {
},
// TODO: Remove from `core-js@4`
'esnext.symbol.is-well-known': {
},
'esnext.symbol.matcher': {
Expand Down
2 changes: 2 additions & 0 deletions packages/core-js-compat/src/modules-by-versions.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -206,5 +206,7 @@ export default {
'es.string.is-well-formed',
'es.string.to-well-formed',
'esnext.function.metadata',
'esnext.symbol.is-registered-symbol',
'esnext.symbol.is-well-known-symbol',
],
};
6 changes: 4 additions & 2 deletions packages/core-js/full/symbol/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
var parent = require('../../actual/symbol');
require('../../modules/esnext.symbol.async-dispose');
require('../../modules/esnext.symbol.is-registered');
require('../../modules/esnext.symbol.is-well-known');
require('../../modules/esnext.symbol.is-registered-symbol');
require('../../modules/esnext.symbol.is-well-known-symbol');
require('../../modules/esnext.symbol.matcher');
require('../../modules/esnext.symbol.observable');
// TODO: Remove from `core-js@4`
require('../../modules/esnext.symbol.is-registered');
require('../../modules/esnext.symbol.is-well-known');
require('../../modules/esnext.symbol.metadata-key');
require('../../modules/esnext.symbol.pattern-match');
require('../../modules/esnext.symbol.replace-all');
Expand Down
5 changes: 5 additions & 0 deletions packages/core-js/full/symbol/is-registered-symbol.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require('../../modules/es.symbol');
require('../../modules/esnext.symbol.is-registered-symbol');
var path = require('../../internals/path');

module.exports = path.Symbol.isRegisteredSymbol;
5 changes: 5 additions & 0 deletions packages/core-js/full/symbol/is-well-known-symbol.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require('../../modules/es.symbol');
require('../../modules/esnext.symbol.is-well-known-symbol');
var path = require('../../internals/path');

module.exports = path.Symbol.isWellKnownSymbol;
16 changes: 16 additions & 0 deletions packages/core-js/internals/symbol-is-registered.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
var getBuiltIn = require('../internals/get-built-in');
var uncurryThis = require('../internals/function-uncurry-this');

var Symbol = getBuiltIn('Symbol');
var keyFor = Symbol.keyFor;
var thisSymbolValue = uncurryThis(Symbol.prototype.valueOf);

// `Symbol.isRegisteredSymbol` method
// https://tc39.es/proposal-symbol-predicates/#sec-symbol-isregisteredsymbol
module.exports = Symbol.isRegisteredSymbol || function isRegisteredSymbol(value) {
try {
return keyFor(thisSymbolValue(value)) !== undefined;
} catch (error) {
return false;
}
};
33 changes: 33 additions & 0 deletions packages/core-js/internals/symbol-is-well-known.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
var shared = require('../internals/shared');
var getBuiltIn = require('../internals/get-built-in');
var uncurryThis = require('../internals/function-uncurry-this');
var isSymbol = require('../internals/is-symbol');
var wellKnownSymbol = require('../internals/well-known-symbol');

var Symbol = getBuiltIn('Symbol');
var $isWellKnownSymbol = Symbol.isWellKnownSymbol;
var getOwnPropertyNames = getBuiltIn('Object', 'getOwnPropertyNames');
var thisSymbolValue = uncurryThis(Symbol.prototype.valueOf);
var WellKnownSymbolsStore = shared('wks');

for (var i = 0, symbolKeys = getOwnPropertyNames(Symbol), symbolKeysLength = symbolKeys.length; i < symbolKeysLength; i++) {
// some old engines throws on access to some keys like `arguments` or `caller`
try {
var symbolKey = symbolKeys[i];
if (isSymbol(Symbol[symbolKey])) wellKnownSymbol(symbolKey);
} catch (error) { /* empty */ }
}

// `Symbol.isWellKnownSymbol` method
// https://tc39.es/proposal-symbol-predicates/#sec-symbol-iswellknownsymbol
// We should patch it for newly added well-known symbols. If it's not required, this module just will not be injected
module.exports = function isWellKnownSymbol(value) {
if ($isWellKnownSymbol && $isWellKnownSymbol(value)) return true;
try {
var symbol = thisSymbolValue(value);
for (var j = 0, keys = getOwnPropertyNames(WellKnownSymbolsStore), keysLength = keys.length; j < keysLength; j++) {
if (WellKnownSymbolsStore[keys[j]] == symbol) return true;
}
} catch (error) { /* empty */ }
return false;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
var $ = require('../internals/export');
var isRegisteredSymbol = require('../internals/symbol-is-registered');

// `Symbol.isRegisteredSymbol` method
// https://tc39.es/proposal-symbol-predicates/#sec-symbol-isregisteredsymbol
$({ target: 'Symbol', stat: true }, {
isRegisteredSymbol: isRegisteredSymbol
});
19 changes: 4 additions & 15 deletions packages/core-js/modules/esnext.symbol.is-registered.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
var $ = require('../internals/export');
var getBuiltIn = require('../internals/get-built-in');
var uncurryThis = require('../internals/function-uncurry-this');

var Symbol = getBuiltIn('Symbol');
var keyFor = Symbol.keyFor;
var thisSymbolValue = uncurryThis(Symbol.prototype.valueOf);
var isRegisteredSymbol = require('../internals/symbol-is-registered');

// `Symbol.isRegistered` method
// https://tc39.es/proposal-symbol-predicates/#sec-symbol-isregistered
$({ target: 'Symbol', stat: true }, {
isRegistered: function isRegistered(value) {
try {
return keyFor(thisSymbolValue(value)) !== undefined;
} catch (error) {
return false;
}
}
// obsolete version of https://tc39.es/proposal-symbol-predicates/#sec-symbol-isregisteredsymbol
$({ target: 'Symbol', stat: true, name: 'isRegisteredSymbol' }, {
isRegistered: isRegisteredSymbol
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
var $ = require('../internals/export');
var isWellKnownSymbol = require('../internals/symbol-is-well-known');

// `Symbol.isWellKnownSymbol` method
// https://tc39.es/proposal-symbol-predicates/#sec-symbol-iswellknownsymbol
// We should patch it for newly added well-known symbols. If it's not required, this module just will not be injected
$({ target: 'Symbol', stat: true, forced: true }, {
isWellKnownSymbol: isWellKnownSymbol
});
35 changes: 4 additions & 31 deletions packages/core-js/modules/esnext.symbol.is-well-known.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,9 @@
var $ = require('../internals/export');
var shared = require('../internals/shared');
var getBuiltIn = require('../internals/get-built-in');
var uncurryThis = require('../internals/function-uncurry-this');
var isSymbol = require('../internals/is-symbol');
var wellKnownSymbol = require('../internals/well-known-symbol');

var Symbol = getBuiltIn('Symbol');
var $isWellKnown = Symbol.isWellKnown;
var getOwnPropertyNames = getBuiltIn('Object', 'getOwnPropertyNames');
var thisSymbolValue = uncurryThis(Symbol.prototype.valueOf);
var WellKnownSymbolsStore = shared('wks');

for (var i = 0, symbolKeys = getOwnPropertyNames(Symbol), symbolKeysLength = symbolKeys.length; i < symbolKeysLength; i++) {
// some old engines throws on access to some keys like `arguments` or `caller`
try {
var symbolKey = symbolKeys[i];
if (isSymbol(Symbol[symbolKey])) wellKnownSymbol(symbolKey);
} catch (error) { /* empty */ }
}
var isWellKnownSymbol = require('../internals/symbol-is-well-known');

// `Symbol.isWellKnown` method
// https://tc39.es/proposal-symbol-predicates/#sec-symbol-iswellknown
// obsolete version of https://tc39.es/proposal-symbol-predicates/#sec-symbol-iswellknownsymbol
// We should patch it for newly added well-known symbols. If it's not required, this module just will not be injected
$({ target: 'Symbol', stat: true, forced: true }, {
isWellKnown: function isWellKnown(value) {
if ($isWellKnown && $isWellKnown(value)) return true;
try {
var symbol = thisSymbolValue(value);
for (var j = 0, keys = getOwnPropertyNames(WellKnownSymbolsStore), keysLength = keys.length; j < keysLength; j++) {
if (WellKnownSymbolsStore[keys[j]] == symbol) return true;
}
} catch (error) { /* empty */ }
return false;
}
$({ target: 'Symbol', stat: true, name: 'isWellKnownSymbol', forced: true }, {
isWellKnown: isWellKnownSymbol
});
3 changes: 3 additions & 0 deletions packages/core-js/proposals/symbol-predicates-v2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// https://github.com/tc39/proposal-symbol-predicates
require('../modules/esnext.symbol.is-registered-symbol');
require('../modules/esnext.symbol.is-well-known-symbol');
3 changes: 2 additions & 1 deletion packages/core-js/stage/2.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ require('../proposals/async-iterator-helpers');
require('../proposals/iterator-range');
require('../proposals/map-upsert-stage-2');
require('../proposals/string-dedent');
require('../proposals/symbol-predicates');
require('../proposals/symbol-predicates-v2');
// TODO: Obsolete versions, remove from `core-js@4`
require('../proposals/array-grouping');
require('../proposals/decorators');
require('../proposals/decorator-metadata');
require('../proposals/iterator-helpers');
require('../proposals/set-methods');
require('../proposals/symbol-predicates');
require('../proposals/using-statement');

module.exports = parent;
2 changes: 2 additions & 0 deletions tests/compat-data/tests-coverage.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ const ignore = new Set([
'esnext.set.symmetric-difference',
'esnext.set.union',
'esnext.string.at',
'esnext.symbol.is-registered',
'esnext.symbol.is-well-known',
'esnext.symbol.metadata',
'esnext.symbol.pattern-match',
'esnext.symbol.replace-all',
Expand Down
8 changes: 4 additions & 4 deletions tests/compat/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -1772,11 +1772,11 @@ GLOBAL.tests = {
'esnext.symbol.dispose': function () {
return Symbol.dispose;
},
'esnext.symbol.is-registered': function () {
return Symbol.isRegistered;
'esnext.symbol.is-registered-symbol': function () {
return Symbol.isRegisteredSymbol;
},
'esnext.symbol.is-well-known': function () {
return Symbol.isWellKnown;
'esnext.symbol.is-well-known-symbol': function () {
return Symbol.isWellKnownSymbol;
},
'esnext.symbol.matcher': function () {
return Symbol.matcher;
Expand Down
2 changes: 2 additions & 0 deletions tests/entries/unit.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,8 @@ for (PATH of ['core-js-pure', 'core-js']) {
` === 'a1b');
ok('next' in load(NS, 'string/code-points')('a'));
ok('next' in load(NS, 'string/virtual/code-points').call('a'));
ok(load(NS, 'symbol/is-registered-symbol')(1) === false);
ok(load(NS, 'symbol/is-well-known-symbol')(1) === false);
ok(load(NS, 'symbol/is-registered')(1) === false);
ok(load(NS, 'symbol/is-well-known')(1) === false);
ok(load(NS, 'symbol/matcher'));
Expand Down
20 changes: 20 additions & 0 deletions tests/unit-global/esnext.symbol.is-registered-symbol.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
QUnit.test('Symbol.isRegisteredSymbol', assert => {
const { isRegisteredSymbol } = Symbol;
assert.isFunction(isRegisteredSymbol, 'Symbol.isRegisteredSymbol is function');
assert.nonEnumerable(Symbol, 'isRegisteredSymbol');
assert.arity(isRegisteredSymbol, 1, 'Symbol.isRegisteredSymbol arity is 1');
assert.name(isRegisteredSymbol, 'isRegisteredSymbol', 'Symbol.isRegisteredSymbol.name is "isRegisteredSymbol"');
assert.looksNative(isRegisteredSymbol, 'isRegisteredSymbol looks like native');

assert.true(isRegisteredSymbol(Symbol.for('foo')), 'registered-1');
assert.true(isRegisteredSymbol(Object(Symbol.for('foo'))), 'registered-2');
assert.false(isRegisteredSymbol(Symbol()), 'non-registered');
assert.false(isRegisteredSymbol(Object(Symbol())), 'non-registered');
assert.false(isRegisteredSymbol(1), '1');
assert.false(isRegisteredSymbol(true), 'true');
assert.false(isRegisteredSymbol('1'), 'string');
assert.false(isRegisteredSymbol(null), 'null');
assert.false(isRegisteredSymbol(), 'undefined');
assert.false(isRegisteredSymbol({}), 'object');
assert.false(isRegisteredSymbol([]), 'array');
});
2 changes: 1 addition & 1 deletion tests/unit-global/esnext.symbol.is-registered.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ QUnit.test('Symbol.isRegistered', assert => {
assert.isFunction(isRegistered, 'Symbol.isRegistered is function');
assert.nonEnumerable(Symbol, 'isRegistered');
assert.arity(isRegistered, 1, 'Symbol.isRegistered arity is 1');
assert.name(isRegistered, 'isRegistered', 'Symbol.isRegistered.name is "isRegistered"');
assert.name(isRegistered, 'isRegisteredSymbol', 'Symbol.isRegistered.name is "isRegisteredSymbol"');
assert.looksNative(isRegistered, 'isRegistered looks like native');

assert.true(isRegistered(Symbol.for('foo')), 'registered-1');
Expand Down
22 changes: 22 additions & 0 deletions tests/unit-global/esnext.symbol.is-well-known-symbol.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
QUnit.test('Symbol.isWellKnownSymbol', assert => {
const { isWellKnownSymbol } = Symbol;
assert.isFunction(isWellKnownSymbol, 'Symbol.isWellKnownSymbol is function');
assert.nonEnumerable(Symbol, 'isWellKnownSymbol');
assert.arity(isWellKnownSymbol, 1, 'Symbol.isWellKnownSymbol arity is 1');
assert.name(isWellKnownSymbol, 'isWellKnownSymbol', 'Symbol.isWellKnownSymbol.name is "isWellKnownSymbol"');
assert.looksNative(isWellKnownSymbol, 'isWellKnownSymbol looks like native');

assert.true(isWellKnownSymbol(Symbol.iterator), 'registered-1');
assert.true(isWellKnownSymbol(Object(Symbol.iterator)), 'registered-2');
assert.true(isWellKnownSymbol(Symbol.patternMatch), 'registered-3');
assert.true(isWellKnownSymbol(Object(Symbol.patternMatch)), 'registered-4');
assert.false(isWellKnownSymbol(Symbol()), 'non-registered');
assert.false(isWellKnownSymbol(Object(Symbol())), 'non-registered');
assert.false(isWellKnownSymbol(1), '1');
assert.false(isWellKnownSymbol(true), 'true');
assert.false(isWellKnownSymbol('1'), 'string');
assert.false(isWellKnownSymbol(null), 'null');
assert.false(isWellKnownSymbol(), 'undefined');
assert.false(isWellKnownSymbol({}), 'object');
assert.false(isWellKnownSymbol([]), 'array');
});
2 changes: 1 addition & 1 deletion tests/unit-global/esnext.symbol.is-well-known.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ QUnit.test('Symbol.isWellKnown', assert => {
assert.isFunction(isWellKnown, 'Symbol.isWellKnown is function');
assert.nonEnumerable(Symbol, 'isWellKnown');
assert.arity(isWellKnown, 1, 'Symbol.isWellKnown arity is 1');
assert.name(isWellKnown, 'isWellKnown', 'Symbol.isWellKnown.name is "isWellKnown"');
assert.name(isWellKnown, 'isWellKnownSymbol', 'Symbol.isWellKnown.name is "isWellKnownSymbol"');
assert.looksNative(isWellKnown, 'isWellKnown looks like native');

assert.true(isWellKnown(Symbol.iterator), 'registered-1');
Expand Down
20 changes: 20 additions & 0 deletions tests/unit-pure/esnext.symbol.is-registered-symbol.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Symbol from 'core-js-pure/full/symbol';

QUnit.test('Symbol.isRegisteredSymbol', assert => {
const { isRegisteredSymbol } = Symbol;
assert.isFunction(isRegisteredSymbol, 'Symbol.isRegisteredSymbol is function');
assert.arity(isRegisteredSymbol, 1, 'Symbol.isRegisteredSymbol arity is 1');
assert.name(isRegisteredSymbol, 'isRegisteredSymbol', 'Symbol.isRegisteredSymbol.name is "isRegisteredSymbol"');

assert.true(isRegisteredSymbol(Symbol.for('foo')), 'registered-1');
assert.true(isRegisteredSymbol(Object(Symbol.for('foo'))), 'registered-2');
assert.false(isRegisteredSymbol(Symbol()), 'non-registered');
assert.false(isRegisteredSymbol(Object(Symbol())), 'non-registered');
assert.false(isRegisteredSymbol(1), '1');
assert.false(isRegisteredSymbol(true), 'true');
assert.false(isRegisteredSymbol('1'), 'string');
assert.false(isRegisteredSymbol(null), 'null');
assert.false(isRegisteredSymbol(), 'undefined');
assert.false(isRegisteredSymbol({}), 'object');
assert.false(isRegisteredSymbol([]), 'array');
});
2 changes: 1 addition & 1 deletion tests/unit-pure/esnext.symbol.is-registered.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ QUnit.test('Symbol.isRegistered', assert => {
const { isRegistered } = Symbol;
assert.isFunction(isRegistered, 'Symbol.isRegistered is function');
assert.arity(isRegistered, 1, 'Symbol.isRegistered arity is 1');
assert.name(isRegistered, 'isRegistered', 'Symbol.isRegistered.name is "isRegistered"');
assert.name(isRegistered, 'isRegisteredSymbol', 'Symbol.isRegistered.name is "isRegisteredSymbol"');

assert.true(isRegistered(Symbol.for('foo')), 'registered-1');
assert.true(isRegistered(Object(Symbol.for('foo'))), 'registered-2');
Expand Down

0 comments on commit dba4bd2

Please sign in to comment.