128 lines
3.4 KiB
JavaScript
128 lines
3.4 KiB
JavaScript
"use strict";
|
|
|
|
// Returns "Type(value) is Object" in ES terminology.
|
|
function isObject(value) {
|
|
return typeof value === "object" && value !== null || typeof value === "function";
|
|
}
|
|
|
|
function hasOwn(obj, prop) {
|
|
return Object.prototype.hasOwnProperty.call(obj, prop);
|
|
}
|
|
|
|
const getOwnPropertyDescriptors = typeof Object.getOwnPropertyDescriptors === "function" ?
|
|
Object.getOwnPropertyDescriptors :
|
|
// Polyfill exists until we require Node.js v8.x
|
|
// https://tc39.github.io/ecma262/#sec-object.getownpropertydescriptors
|
|
obj => {
|
|
if (obj === undefined || obj === null) {
|
|
throw new TypeError("Cannot convert undefined or null to object");
|
|
}
|
|
obj = Object(obj);
|
|
const ownKeys = Reflect.ownKeys(obj);
|
|
const descriptors = {};
|
|
for (const key of ownKeys) {
|
|
const descriptor = Reflect.getOwnPropertyDescriptor(obj, key);
|
|
if (descriptor !== undefined) {
|
|
Reflect.defineProperty(descriptors, key, {
|
|
value: descriptor,
|
|
writable: true,
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
}
|
|
}
|
|
return descriptors;
|
|
};
|
|
|
|
const wrapperSymbol = Symbol("wrapper");
|
|
const implSymbol = Symbol("impl");
|
|
const sameObjectCaches = Symbol("SameObject caches");
|
|
|
|
function getSameObject(wrapper, prop, creator) {
|
|
if (!wrapper[sameObjectCaches]) {
|
|
wrapper[sameObjectCaches] = Object.create(null);
|
|
}
|
|
|
|
if (prop in wrapper[sameObjectCaches]) {
|
|
return wrapper[sameObjectCaches][prop];
|
|
}
|
|
|
|
wrapper[sameObjectCaches][prop] = creator();
|
|
return wrapper[sameObjectCaches][prop];
|
|
}
|
|
|
|
function wrapperForImpl(impl) {
|
|
return impl ? impl[wrapperSymbol] : null;
|
|
}
|
|
|
|
function implForWrapper(wrapper) {
|
|
return wrapper ? wrapper[implSymbol] : null;
|
|
}
|
|
|
|
function tryWrapperForImpl(impl) {
|
|
const wrapper = wrapperForImpl(impl);
|
|
return wrapper ? wrapper : impl;
|
|
}
|
|
|
|
function tryImplForWrapper(wrapper) {
|
|
const impl = implForWrapper(wrapper);
|
|
return impl ? impl : wrapper;
|
|
}
|
|
|
|
const iterInternalSymbol = Symbol("internal");
|
|
const IteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()));
|
|
|
|
function isArrayIndexPropName(P) {
|
|
if (typeof P !== "string") {
|
|
return false;
|
|
}
|
|
const i = P >>> 0;
|
|
if (i === Math.pow(2, 32) - 1) {
|
|
return false;
|
|
}
|
|
const s = `${i}`;
|
|
if (P !== s) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
const supportsPropertyIndex = Symbol("supports property index");
|
|
const supportedPropertyIndices = Symbol("supported property indices");
|
|
const supportsPropertyName = Symbol("supports property name");
|
|
const supportedPropertyNames = Symbol("supported property names");
|
|
const indexedGet = Symbol("indexed property get");
|
|
const indexedSetNew = Symbol("indexed property set new");
|
|
const indexedSetExisting = Symbol("indexed property set existing");
|
|
const namedGet = Symbol("named property get");
|
|
const namedSetNew = Symbol("named property set new");
|
|
const namedSetExisting = Symbol("named property set existing");
|
|
const namedDelete = Symbol("named property delete");
|
|
|
|
module.exports = exports = {
|
|
isObject,
|
|
hasOwn,
|
|
getOwnPropertyDescriptors,
|
|
wrapperSymbol,
|
|
implSymbol,
|
|
getSameObject,
|
|
wrapperForImpl,
|
|
implForWrapper,
|
|
tryWrapperForImpl,
|
|
tryImplForWrapper,
|
|
iterInternalSymbol,
|
|
IteratorPrototype,
|
|
isArrayIndexPropName,
|
|
supportsPropertyIndex,
|
|
supportedPropertyIndices,
|
|
supportsPropertyName,
|
|
supportedPropertyNames,
|
|
indexedGet,
|
|
indexedSetNew,
|
|
indexedSetExisting,
|
|
namedGet,
|
|
namedSetNew,
|
|
namedSetExisting,
|
|
namedDelete
|
|
};
|