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.
330 lines
12 KiB
330 lines
12 KiB
'use strict'; |
|
|
|
var undefined; |
|
|
|
var $SyntaxError = SyntaxError; |
|
var $Function = Function; |
|
var $TypeError = TypeError; |
|
|
|
// eslint-disable-next-line consistent-return |
|
var getEvalledConstructor = function (expressionSyntax) { |
|
try { |
|
return $Function('"use strict"; return (' + expressionSyntax + ').constructor;')(); |
|
} catch (e) {} |
|
}; |
|
|
|
var $gOPD = Object.getOwnPropertyDescriptor; |
|
if ($gOPD) { |
|
try { |
|
$gOPD({}, ''); |
|
} catch (e) { |
|
$gOPD = null; // this is IE 8, which has a broken gOPD |
|
} |
|
} |
|
|
|
var throwTypeError = function () { |
|
throw new $TypeError(); |
|
}; |
|
var ThrowTypeError = $gOPD |
|
? (function () { |
|
try { |
|
// eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties |
|
arguments.callee; // IE 8 does not throw here |
|
return throwTypeError; |
|
} catch (calleeThrows) { |
|
try { |
|
// IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '') |
|
return $gOPD(arguments, 'callee').get; |
|
} catch (gOPDthrows) { |
|
return throwTypeError; |
|
} |
|
} |
|
}()) |
|
: throwTypeError; |
|
|
|
var hasSymbols = require('has-symbols')(); |
|
|
|
var getProto = Object.getPrototypeOf || function (x) { return x.__proto__; }; // eslint-disable-line no-proto |
|
|
|
var needsEval = {}; |
|
|
|
var TypedArray = typeof Uint8Array === 'undefined' ? undefined : getProto(Uint8Array); |
|
|
|
var INTRINSICS = { |
|
'%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError, |
|
'%Array%': Array, |
|
'%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer, |
|
'%ArrayIteratorPrototype%': hasSymbols ? getProto([][Symbol.iterator]()) : undefined, |
|
'%AsyncFromSyncIteratorPrototype%': undefined, |
|
'%AsyncFunction%': needsEval, |
|
'%AsyncGenerator%': needsEval, |
|
'%AsyncGeneratorFunction%': needsEval, |
|
'%AsyncIteratorPrototype%': needsEval, |
|
'%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics, |
|
'%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt, |
|
'%Boolean%': Boolean, |
|
'%DataView%': typeof DataView === 'undefined' ? undefined : DataView, |
|
'%Date%': Date, |
|
'%decodeURI%': decodeURI, |
|
'%decodeURIComponent%': decodeURIComponent, |
|
'%encodeURI%': encodeURI, |
|
'%encodeURIComponent%': encodeURIComponent, |
|
'%Error%': Error, |
|
'%eval%': eval, // eslint-disable-line no-eval |
|
'%EvalError%': EvalError, |
|
'%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array, |
|
'%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array, |
|
'%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry, |
|
'%Function%': $Function, |
|
'%GeneratorFunction%': needsEval, |
|
'%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array, |
|
'%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array, |
|
'%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array, |
|
'%isFinite%': isFinite, |
|
'%isNaN%': isNaN, |
|
'%IteratorPrototype%': hasSymbols ? getProto(getProto([][Symbol.iterator]())) : undefined, |
|
'%JSON%': typeof JSON === 'object' ? JSON : undefined, |
|
'%Map%': typeof Map === 'undefined' ? undefined : Map, |
|
'%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols ? undefined : getProto(new Map()[Symbol.iterator]()), |
|
'%Math%': Math, |
|
'%Number%': Number, |
|
'%Object%': Object, |
|
'%parseFloat%': parseFloat, |
|
'%parseInt%': parseInt, |
|
'%Promise%': typeof Promise === 'undefined' ? undefined : Promise, |
|
'%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy, |
|
'%RangeError%': RangeError, |
|
'%ReferenceError%': ReferenceError, |
|
'%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect, |
|
'%RegExp%': RegExp, |
|
'%Set%': typeof Set === 'undefined' ? undefined : Set, |
|
'%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols ? undefined : getProto(new Set()[Symbol.iterator]()), |
|
'%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer, |
|
'%String%': String, |
|
'%StringIteratorPrototype%': hasSymbols ? getProto(''[Symbol.iterator]()) : undefined, |
|
'%Symbol%': hasSymbols ? Symbol : undefined, |
|
'%SyntaxError%': $SyntaxError, |
|
'%ThrowTypeError%': ThrowTypeError, |
|
'%TypedArray%': TypedArray, |
|
'%TypeError%': $TypeError, |
|
'%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array, |
|
'%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray, |
|
'%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array, |
|
'%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array, |
|
'%URIError%': URIError, |
|
'%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap, |
|
'%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef, |
|
'%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet |
|
}; |
|
|
|
var doEval = function doEval(name) { |
|
var value; |
|
if (name === '%AsyncFunction%') { |
|
value = getEvalledConstructor('async function () {}'); |
|
} else if (name === '%GeneratorFunction%') { |
|
value = getEvalledConstructor('function* () {}'); |
|
} else if (name === '%AsyncGeneratorFunction%') { |
|
value = getEvalledConstructor('async function* () {}'); |
|
} else if (name === '%AsyncGenerator%') { |
|
var fn = doEval('%AsyncGeneratorFunction%'); |
|
if (fn) { |
|
value = fn.prototype; |
|
} |
|
} else if (name === '%AsyncIteratorPrototype%') { |
|
var gen = doEval('%AsyncGenerator%'); |
|
if (gen) { |
|
value = getProto(gen.prototype); |
|
} |
|
} |
|
|
|
INTRINSICS[name] = value; |
|
|
|
return value; |
|
}; |
|
|
|
var LEGACY_ALIASES = { |
|
'%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'], |
|
'%ArrayPrototype%': ['Array', 'prototype'], |
|
'%ArrayProto_entries%': ['Array', 'prototype', 'entries'], |
|
'%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'], |
|
'%ArrayProto_keys%': ['Array', 'prototype', 'keys'], |
|
'%ArrayProto_values%': ['Array', 'prototype', 'values'], |
|
'%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'], |
|
'%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'], |
|
'%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'], |
|
'%BooleanPrototype%': ['Boolean', 'prototype'], |
|
'%DataViewPrototype%': ['DataView', 'prototype'], |
|
'%DatePrototype%': ['Date', 'prototype'], |
|
'%ErrorPrototype%': ['Error', 'prototype'], |
|
'%EvalErrorPrototype%': ['EvalError', 'prototype'], |
|
'%Float32ArrayPrototype%': ['Float32Array', 'prototype'], |
|
'%Float64ArrayPrototype%': ['Float64Array', 'prototype'], |
|
'%FunctionPrototype%': ['Function', 'prototype'], |
|
'%Generator%': ['GeneratorFunction', 'prototype'], |
|
'%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'], |
|
'%Int8ArrayPrototype%': ['Int8Array', 'prototype'], |
|
'%Int16ArrayPrototype%': ['Int16Array', 'prototype'], |
|
'%Int32ArrayPrototype%': ['Int32Array', 'prototype'], |
|
'%JSONParse%': ['JSON', 'parse'], |
|
'%JSONStringify%': ['JSON', 'stringify'], |
|
'%MapPrototype%': ['Map', 'prototype'], |
|
'%NumberPrototype%': ['Number', 'prototype'], |
|
'%ObjectPrototype%': ['Object', 'prototype'], |
|
'%ObjProto_toString%': ['Object', 'prototype', 'toString'], |
|
'%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'], |
|
'%PromisePrototype%': ['Promise', 'prototype'], |
|
'%PromiseProto_then%': ['Promise', 'prototype', 'then'], |
|
'%Promise_all%': ['Promise', 'all'], |
|
'%Promise_reject%': ['Promise', 'reject'], |
|
'%Promise_resolve%': ['Promise', 'resolve'], |
|
'%RangeErrorPrototype%': ['RangeError', 'prototype'], |
|
'%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'], |
|
'%RegExpPrototype%': ['RegExp', 'prototype'], |
|
'%SetPrototype%': ['Set', 'prototype'], |
|
'%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'], |
|
'%StringPrototype%': ['String', 'prototype'], |
|
'%SymbolPrototype%': ['Symbol', 'prototype'], |
|
'%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'], |
|
'%TypedArrayPrototype%': ['TypedArray', 'prototype'], |
|
'%TypeErrorPrototype%': ['TypeError', 'prototype'], |
|
'%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'], |
|
'%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'], |
|
'%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'], |
|
'%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'], |
|
'%URIErrorPrototype%': ['URIError', 'prototype'], |
|
'%WeakMapPrototype%': ['WeakMap', 'prototype'], |
|
'%WeakSetPrototype%': ['WeakSet', 'prototype'] |
|
}; |
|
|
|
var bind = require('function-bind'); |
|
var hasOwn = require('has'); |
|
var $concat = bind.call(Function.call, Array.prototype.concat); |
|
var $spliceApply = bind.call(Function.apply, Array.prototype.splice); |
|
var $replace = bind.call(Function.call, String.prototype.replace); |
|
var $strSlice = bind.call(Function.call, String.prototype.slice); |
|
|
|
/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */ |
|
var rePropName = /[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g; |
|
var reEscapeChar = /\\(\\)?/g; /** Used to match backslashes in property paths. */ |
|
var stringToPath = function stringToPath(string) { |
|
var first = $strSlice(string, 0, 1); |
|
var last = $strSlice(string, -1); |
|
if (first === '%' && last !== '%') { |
|
throw new $SyntaxError('invalid intrinsic syntax, expected closing `%`'); |
|
} else if (last === '%' && first !== '%') { |
|
throw new $SyntaxError('invalid intrinsic syntax, expected opening `%`'); |
|
} |
|
var result = []; |
|
$replace(string, rePropName, function (match, number, quote, subString) { |
|
result[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match; |
|
}); |
|
return result; |
|
}; |
|
/* end adaptation */ |
|
|
|
var getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) { |
|
var intrinsicName = name; |
|
var alias; |
|
if (hasOwn(LEGACY_ALIASES, intrinsicName)) { |
|
alias = LEGACY_ALIASES[intrinsicName]; |
|
intrinsicName = '%' + alias[0] + '%'; |
|
} |
|
|
|
if (hasOwn(INTRINSICS, intrinsicName)) { |
|
var value = INTRINSICS[intrinsicName]; |
|
if (value === needsEval) { |
|
value = doEval(intrinsicName); |
|
} |
|
if (typeof value === 'undefined' && !allowMissing) { |
|
throw new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!'); |
|
} |
|
|
|
return { |
|
alias: alias, |
|
name: intrinsicName, |
|
value: value |
|
}; |
|
} |
|
|
|
throw new $SyntaxError('intrinsic ' + name + ' does not exist!'); |
|
}; |
|
|
|
module.exports = function GetIntrinsic(name, allowMissing) { |
|
if (typeof name !== 'string' || name.length === 0) { |
|
throw new $TypeError('intrinsic name must be a non-empty string'); |
|
} |
|
if (arguments.length > 1 && typeof allowMissing !== 'boolean') { |
|
throw new $TypeError('"allowMissing" argument must be a boolean'); |
|
} |
|
|
|
var parts = stringToPath(name); |
|
var intrinsicBaseName = parts.length > 0 ? parts[0] : ''; |
|
|
|
var intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing); |
|
var intrinsicRealName = intrinsic.name; |
|
var value = intrinsic.value; |
|
var skipFurtherCaching = false; |
|
|
|
var alias = intrinsic.alias; |
|
if (alias) { |
|
intrinsicBaseName = alias[0]; |
|
$spliceApply(parts, $concat([0, 1], alias)); |
|
} |
|
|
|
for (var i = 1, isOwn = true; i < parts.length; i += 1) { |
|
var part = parts[i]; |
|
var first = $strSlice(part, 0, 1); |
|
var last = $strSlice(part, -1); |
|
if ( |
|
( |
|
(first === '"' || first === "'" || first === '`') |
|
|| (last === '"' || last === "'" || last === '`') |
|
) |
|
&& first !== last |
|
) { |
|
throw new $SyntaxError('property names with quotes must have matching quotes'); |
|
} |
|
if (part === 'constructor' || !isOwn) { |
|
skipFurtherCaching = true; |
|
} |
|
|
|
intrinsicBaseName += '.' + part; |
|
intrinsicRealName = '%' + intrinsicBaseName + '%'; |
|
|
|
if (hasOwn(INTRINSICS, intrinsicRealName)) { |
|
value = INTRINSICS[intrinsicRealName]; |
|
} else if (value != null) { |
|
if (!(part in value)) { |
|
if (!allowMissing) { |
|
throw new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.'); |
|
} |
|
return void undefined; |
|
} |
|
if ($gOPD && (i + 1) >= parts.length) { |
|
var desc = $gOPD(value, part); |
|
isOwn = !!desc; |
|
|
|
// By convention, when a data property is converted to an accessor |
|
// property to emulate a data property that does not suffer from |
|
// the override mistake, that accessor's getter is marked with |
|
// an `originalValue` property. Here, when we detect this, we |
|
// uphold the illusion by pretending to see that original data |
|
// property, i.e., returning the value rather than the getter |
|
// itself. |
|
if (isOwn && 'get' in desc && !('originalValue' in desc.get)) { |
|
value = desc.get; |
|
} else { |
|
value = value[part]; |
|
} |
|
} else { |
|
isOwn = hasOwn(value, part); |
|
value = value[part]; |
|
} |
|
|
|
if (isOwn && !skipFurtherCaching) { |
|
INTRINSICS[intrinsicRealName] = value; |
|
} |
|
} |
|
} |
|
return value; |
|
};
|
|
|