You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
325 lines
13 KiB
325 lines
13 KiB
'use strict'; |
|
var $ = require('../internals/export'); |
|
var global = require('../internals/global'); |
|
var getBuiltIn = require('../internals/get-built-in'); |
|
var apply = require('../internals/function-apply'); |
|
var call = require('../internals/function-call'); |
|
var uncurryThis = require('../internals/function-uncurry-this'); |
|
var IS_PURE = require('../internals/is-pure'); |
|
var DESCRIPTORS = require('../internals/descriptors'); |
|
var NATIVE_SYMBOL = require('../internals/native-symbol'); |
|
var fails = require('../internals/fails'); |
|
var hasOwn = require('../internals/has-own-property'); |
|
var isArray = require('../internals/is-array'); |
|
var isCallable = require('../internals/is-callable'); |
|
var isObject = require('../internals/is-object'); |
|
var isPrototypeOf = require('../internals/object-is-prototype-of'); |
|
var isSymbol = require('../internals/is-symbol'); |
|
var anObject = require('../internals/an-object'); |
|
var toObject = require('../internals/to-object'); |
|
var toIndexedObject = require('../internals/to-indexed-object'); |
|
var toPropertyKey = require('../internals/to-property-key'); |
|
var $toString = require('../internals/to-string'); |
|
var createPropertyDescriptor = require('../internals/create-property-descriptor'); |
|
var nativeObjectCreate = require('../internals/object-create'); |
|
var objectKeys = require('../internals/object-keys'); |
|
var getOwnPropertyNamesModule = require('../internals/object-get-own-property-names'); |
|
var getOwnPropertyNamesExternal = require('../internals/object-get-own-property-names-external'); |
|
var getOwnPropertySymbolsModule = require('../internals/object-get-own-property-symbols'); |
|
var getOwnPropertyDescriptorModule = require('../internals/object-get-own-property-descriptor'); |
|
var definePropertyModule = require('../internals/object-define-property'); |
|
var definePropertiesModule = require('../internals/object-define-properties'); |
|
var propertyIsEnumerableModule = require('../internals/object-property-is-enumerable'); |
|
var arraySlice = require('../internals/array-slice'); |
|
var redefine = require('../internals/redefine'); |
|
var shared = require('../internals/shared'); |
|
var sharedKey = require('../internals/shared-key'); |
|
var hiddenKeys = require('../internals/hidden-keys'); |
|
var uid = require('../internals/uid'); |
|
var wellKnownSymbol = require('../internals/well-known-symbol'); |
|
var wrappedWellKnownSymbolModule = require('../internals/well-known-symbol-wrapped'); |
|
var defineWellKnownSymbol = require('../internals/define-well-known-symbol'); |
|
var setToStringTag = require('../internals/set-to-string-tag'); |
|
var InternalStateModule = require('../internals/internal-state'); |
|
var $forEach = require('../internals/array-iteration').forEach; |
|
|
|
var HIDDEN = sharedKey('hidden'); |
|
var SYMBOL = 'Symbol'; |
|
var PROTOTYPE = 'prototype'; |
|
var TO_PRIMITIVE = wellKnownSymbol('toPrimitive'); |
|
|
|
var setInternalState = InternalStateModule.set; |
|
var getInternalState = InternalStateModule.getterFor(SYMBOL); |
|
|
|
var ObjectPrototype = Object[PROTOTYPE]; |
|
var $Symbol = global.Symbol; |
|
var SymbolPrototype = $Symbol && $Symbol[PROTOTYPE]; |
|
var TypeError = global.TypeError; |
|
var QObject = global.QObject; |
|
var $stringify = getBuiltIn('JSON', 'stringify'); |
|
var nativeGetOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f; |
|
var nativeDefineProperty = definePropertyModule.f; |
|
var nativeGetOwnPropertyNames = getOwnPropertyNamesExternal.f; |
|
var nativePropertyIsEnumerable = propertyIsEnumerableModule.f; |
|
var push = uncurryThis([].push); |
|
|
|
var AllSymbols = shared('symbols'); |
|
var ObjectPrototypeSymbols = shared('op-symbols'); |
|
var StringToSymbolRegistry = shared('string-to-symbol-registry'); |
|
var SymbolToStringRegistry = shared('symbol-to-string-registry'); |
|
var WellKnownSymbolsStore = shared('wks'); |
|
|
|
// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173 |
|
var USE_SETTER = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild; |
|
|
|
// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687 |
|
var setSymbolDescriptor = DESCRIPTORS && fails(function () { |
|
return nativeObjectCreate(nativeDefineProperty({}, 'a', { |
|
get: function () { return nativeDefineProperty(this, 'a', { value: 7 }).a; } |
|
})).a != 7; |
|
}) ? function (O, P, Attributes) { |
|
var ObjectPrototypeDescriptor = nativeGetOwnPropertyDescriptor(ObjectPrototype, P); |
|
if (ObjectPrototypeDescriptor) delete ObjectPrototype[P]; |
|
nativeDefineProperty(O, P, Attributes); |
|
if (ObjectPrototypeDescriptor && O !== ObjectPrototype) { |
|
nativeDefineProperty(ObjectPrototype, P, ObjectPrototypeDescriptor); |
|
} |
|
} : nativeDefineProperty; |
|
|
|
var wrap = function (tag, description) { |
|
var symbol = AllSymbols[tag] = nativeObjectCreate(SymbolPrototype); |
|
setInternalState(symbol, { |
|
type: SYMBOL, |
|
tag: tag, |
|
description: description |
|
}); |
|
if (!DESCRIPTORS) symbol.description = description; |
|
return symbol; |
|
}; |
|
|
|
var $defineProperty = function defineProperty(O, P, Attributes) { |
|
if (O === ObjectPrototype) $defineProperty(ObjectPrototypeSymbols, P, Attributes); |
|
anObject(O); |
|
var key = toPropertyKey(P); |
|
anObject(Attributes); |
|
if (hasOwn(AllSymbols, key)) { |
|
if (!Attributes.enumerable) { |
|
if (!hasOwn(O, HIDDEN)) nativeDefineProperty(O, HIDDEN, createPropertyDescriptor(1, {})); |
|
O[HIDDEN][key] = true; |
|
} else { |
|
if (hasOwn(O, HIDDEN) && O[HIDDEN][key]) O[HIDDEN][key] = false; |
|
Attributes = nativeObjectCreate(Attributes, { enumerable: createPropertyDescriptor(0, false) }); |
|
} return setSymbolDescriptor(O, key, Attributes); |
|
} return nativeDefineProperty(O, key, Attributes); |
|
}; |
|
|
|
var $defineProperties = function defineProperties(O, Properties) { |
|
anObject(O); |
|
var properties = toIndexedObject(Properties); |
|
var keys = objectKeys(properties).concat($getOwnPropertySymbols(properties)); |
|
$forEach(keys, function (key) { |
|
if (!DESCRIPTORS || call($propertyIsEnumerable, properties, key)) $defineProperty(O, key, properties[key]); |
|
}); |
|
return O; |
|
}; |
|
|
|
var $create = function create(O, Properties) { |
|
return Properties === undefined ? nativeObjectCreate(O) : $defineProperties(nativeObjectCreate(O), Properties); |
|
}; |
|
|
|
var $propertyIsEnumerable = function propertyIsEnumerable(V) { |
|
var P = toPropertyKey(V); |
|
var enumerable = call(nativePropertyIsEnumerable, this, P); |
|
if (this === ObjectPrototype && hasOwn(AllSymbols, P) && !hasOwn(ObjectPrototypeSymbols, P)) return false; |
|
return enumerable || !hasOwn(this, P) || !hasOwn(AllSymbols, P) || hasOwn(this, HIDDEN) && this[HIDDEN][P] |
|
? enumerable : true; |
|
}; |
|
|
|
var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(O, P) { |
|
var it = toIndexedObject(O); |
|
var key = toPropertyKey(P); |
|
if (it === ObjectPrototype && hasOwn(AllSymbols, key) && !hasOwn(ObjectPrototypeSymbols, key)) return; |
|
var descriptor = nativeGetOwnPropertyDescriptor(it, key); |
|
if (descriptor && hasOwn(AllSymbols, key) && !(hasOwn(it, HIDDEN) && it[HIDDEN][key])) { |
|
descriptor.enumerable = true; |
|
} |
|
return descriptor; |
|
}; |
|
|
|
var $getOwnPropertyNames = function getOwnPropertyNames(O) { |
|
var names = nativeGetOwnPropertyNames(toIndexedObject(O)); |
|
var result = []; |
|
$forEach(names, function (key) { |
|
if (!hasOwn(AllSymbols, key) && !hasOwn(hiddenKeys, key)) push(result, key); |
|
}); |
|
return result; |
|
}; |
|
|
|
var $getOwnPropertySymbols = function getOwnPropertySymbols(O) { |
|
var IS_OBJECT_PROTOTYPE = O === ObjectPrototype; |
|
var names = nativeGetOwnPropertyNames(IS_OBJECT_PROTOTYPE ? ObjectPrototypeSymbols : toIndexedObject(O)); |
|
var result = []; |
|
$forEach(names, function (key) { |
|
if (hasOwn(AllSymbols, key) && (!IS_OBJECT_PROTOTYPE || hasOwn(ObjectPrototype, key))) { |
|
push(result, AllSymbols[key]); |
|
} |
|
}); |
|
return result; |
|
}; |
|
|
|
// `Symbol` constructor |
|
// https://tc39.es/ecma262/#sec-symbol-constructor |
|
if (!NATIVE_SYMBOL) { |
|
$Symbol = function Symbol() { |
|
if (isPrototypeOf(SymbolPrototype, this)) throw TypeError('Symbol is not a constructor'); |
|
var description = !arguments.length || arguments[0] === undefined ? undefined : $toString(arguments[0]); |
|
var tag = uid(description); |
|
var setter = function (value) { |
|
if (this === ObjectPrototype) call(setter, ObjectPrototypeSymbols, value); |
|
if (hasOwn(this, HIDDEN) && hasOwn(this[HIDDEN], tag)) this[HIDDEN][tag] = false; |
|
setSymbolDescriptor(this, tag, createPropertyDescriptor(1, value)); |
|
}; |
|
if (DESCRIPTORS && USE_SETTER) setSymbolDescriptor(ObjectPrototype, tag, { configurable: true, set: setter }); |
|
return wrap(tag, description); |
|
}; |
|
|
|
SymbolPrototype = $Symbol[PROTOTYPE]; |
|
|
|
redefine(SymbolPrototype, 'toString', function toString() { |
|
return getInternalState(this).tag; |
|
}); |
|
|
|
redefine($Symbol, 'withoutSetter', function (description) { |
|
return wrap(uid(description), description); |
|
}); |
|
|
|
propertyIsEnumerableModule.f = $propertyIsEnumerable; |
|
definePropertyModule.f = $defineProperty; |
|
definePropertiesModule.f = $defineProperties; |
|
getOwnPropertyDescriptorModule.f = $getOwnPropertyDescriptor; |
|
getOwnPropertyNamesModule.f = getOwnPropertyNamesExternal.f = $getOwnPropertyNames; |
|
getOwnPropertySymbolsModule.f = $getOwnPropertySymbols; |
|
|
|
wrappedWellKnownSymbolModule.f = function (name) { |
|
return wrap(wellKnownSymbol(name), name); |
|
}; |
|
|
|
if (DESCRIPTORS) { |
|
// https://github.com/tc39/proposal-Symbol-description |
|
nativeDefineProperty(SymbolPrototype, 'description', { |
|
configurable: true, |
|
get: function description() { |
|
return getInternalState(this).description; |
|
} |
|
}); |
|
if (!IS_PURE) { |
|
redefine(ObjectPrototype, 'propertyIsEnumerable', $propertyIsEnumerable, { unsafe: true }); |
|
} |
|
} |
|
} |
|
|
|
$({ global: true, wrap: true, forced: !NATIVE_SYMBOL, sham: !NATIVE_SYMBOL }, { |
|
Symbol: $Symbol |
|
}); |
|
|
|
$forEach(objectKeys(WellKnownSymbolsStore), function (name) { |
|
defineWellKnownSymbol(name); |
|
}); |
|
|
|
$({ target: SYMBOL, stat: true, forced: !NATIVE_SYMBOL }, { |
|
// `Symbol.for` method |
|
// https://tc39.es/ecma262/#sec-symbol.for |
|
'for': function (key) { |
|
var string = $toString(key); |
|
if (hasOwn(StringToSymbolRegistry, string)) return StringToSymbolRegistry[string]; |
|
var symbol = $Symbol(string); |
|
StringToSymbolRegistry[string] = symbol; |
|
SymbolToStringRegistry[symbol] = string; |
|
return symbol; |
|
}, |
|
// `Symbol.keyFor` method |
|
// https://tc39.es/ecma262/#sec-symbol.keyfor |
|
keyFor: function keyFor(sym) { |
|
if (!isSymbol(sym)) throw TypeError(sym + ' is not a symbol'); |
|
if (hasOwn(SymbolToStringRegistry, sym)) return SymbolToStringRegistry[sym]; |
|
}, |
|
useSetter: function () { USE_SETTER = true; }, |
|
useSimple: function () { USE_SETTER = false; } |
|
}); |
|
|
|
$({ target: 'Object', stat: true, forced: !NATIVE_SYMBOL, sham: !DESCRIPTORS }, { |
|
// `Object.create` method |
|
// https://tc39.es/ecma262/#sec-object.create |
|
create: $create, |
|
// `Object.defineProperty` method |
|
// https://tc39.es/ecma262/#sec-object.defineproperty |
|
defineProperty: $defineProperty, |
|
// `Object.defineProperties` method |
|
// https://tc39.es/ecma262/#sec-object.defineproperties |
|
defineProperties: $defineProperties, |
|
// `Object.getOwnPropertyDescriptor` method |
|
// https://tc39.es/ecma262/#sec-object.getownpropertydescriptors |
|
getOwnPropertyDescriptor: $getOwnPropertyDescriptor |
|
}); |
|
|
|
$({ target: 'Object', stat: true, forced: !NATIVE_SYMBOL }, { |
|
// `Object.getOwnPropertyNames` method |
|
// https://tc39.es/ecma262/#sec-object.getownpropertynames |
|
getOwnPropertyNames: $getOwnPropertyNames, |
|
// `Object.getOwnPropertySymbols` method |
|
// https://tc39.es/ecma262/#sec-object.getownpropertysymbols |
|
getOwnPropertySymbols: $getOwnPropertySymbols |
|
}); |
|
|
|
// Chrome 38 and 39 `Object.getOwnPropertySymbols` fails on primitives |
|
// https://bugs.chromium.org/p/v8/issues/detail?id=3443 |
|
$({ target: 'Object', stat: true, forced: fails(function () { getOwnPropertySymbolsModule.f(1); }) }, { |
|
getOwnPropertySymbols: function getOwnPropertySymbols(it) { |
|
return getOwnPropertySymbolsModule.f(toObject(it)); |
|
} |
|
}); |
|
|
|
// `JSON.stringify` method behavior with symbols |
|
// https://tc39.es/ecma262/#sec-json.stringify |
|
if ($stringify) { |
|
var FORCED_JSON_STRINGIFY = !NATIVE_SYMBOL || fails(function () { |
|
var symbol = $Symbol(); |
|
// MS Edge converts symbol values to JSON as {} |
|
return $stringify([symbol]) != '[null]' |
|
// WebKit converts symbol values to JSON as null |
|
|| $stringify({ a: symbol }) != '{}' |
|
// V8 throws on boxed symbols |
|
|| $stringify(Object(symbol)) != '{}'; |
|
}); |
|
|
|
$({ target: 'JSON', stat: true, forced: FORCED_JSON_STRINGIFY }, { |
|
// eslint-disable-next-line no-unused-vars -- required for `.length` |
|
stringify: function stringify(it, replacer, space) { |
|
var args = arraySlice(arguments); |
|
var $replacer = replacer; |
|
if (!isObject(replacer) && it === undefined || isSymbol(it)) return; // IE8 returns string on undefined |
|
if (!isArray(replacer)) replacer = function (key, value) { |
|
if (isCallable($replacer)) value = call($replacer, this, key, value); |
|
if (!isSymbol(value)) return value; |
|
}; |
|
args[1] = replacer; |
|
return apply($stringify, null, args); |
|
} |
|
}); |
|
} |
|
|
|
// `Symbol.prototype[@@toPrimitive]` method |
|
// https://tc39.es/ecma262/#sec-symbol.prototype-@@toprimitive |
|
if (!SymbolPrototype[TO_PRIMITIVE]) { |
|
var valueOf = SymbolPrototype.valueOf; |
|
// eslint-disable-next-line no-unused-vars -- required for .length |
|
redefine(SymbolPrototype, TO_PRIMITIVE, function (hint) { |
|
// TODO: improve hint logic |
|
return call(valueOf, this); |
|
}); |
|
} |
|
// `Symbol.prototype[@@toStringTag]` property |
|
// https://tc39.es/ecma262/#sec-symbol.prototype-@@tostringtag |
|
setToStringTag($Symbol, SYMBOL); |
|
|
|
hiddenKeys[HIDDEN] = true;
|
|
|