| Leo Repp | 58b9f11 | 2021-11-22 11:57:47 +0100 | [diff] [blame^] | 1 | 'use strict'; |
| 2 | |
| 3 | /* globals |
| 4 | AggregateError, |
| 5 | Atomics, |
| 6 | FinalizationRegistry, |
| 7 | SharedArrayBuffer, |
| 8 | WeakRef, |
| 9 | */ |
| 10 | |
| 11 | var undefined; |
| 12 | |
| 13 | var $SyntaxError = SyntaxError; |
| 14 | var $Function = Function; |
| 15 | var $TypeError = TypeError; |
| 16 | |
| 17 | // eslint-disable-next-line consistent-return |
| 18 | var getEvalledConstructor = function (expressionSyntax) { |
| 19 | try { |
| 20 | // eslint-disable-next-line no-new-func |
| 21 | return Function('"use strict"; return (' + expressionSyntax + ').constructor;')(); |
| 22 | } catch (e) {} |
| 23 | }; |
| 24 | |
| 25 | var $gOPD = Object.getOwnPropertyDescriptor; |
| 26 | if ($gOPD) { |
| 27 | try { |
| 28 | $gOPD({}, ''); |
| 29 | } catch (e) { |
| 30 | $gOPD = null; // this is IE 8, which has a broken gOPD |
| 31 | } |
| 32 | } |
| 33 | |
| 34 | var throwTypeError = function () { |
| 35 | throw new $TypeError(); |
| 36 | }; |
| 37 | var ThrowTypeError = $gOPD |
| 38 | ? (function () { |
| 39 | try { |
| 40 | // eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties |
| 41 | arguments.callee; // IE 8 does not throw here |
| 42 | return throwTypeError; |
| 43 | } catch (calleeThrows) { |
| 44 | try { |
| 45 | // IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '') |
| 46 | return $gOPD(arguments, 'callee').get; |
| 47 | } catch (gOPDthrows) { |
| 48 | return throwTypeError; |
| 49 | } |
| 50 | } |
| 51 | }()) |
| 52 | : throwTypeError; |
| 53 | |
| 54 | var hasSymbols = require('has-symbols')(); |
| 55 | |
| 56 | var getProto = Object.getPrototypeOf || function (x) { return x.__proto__; }; // eslint-disable-line no-proto |
| 57 | |
| 58 | var asyncGenFunction = getEvalledConstructor('async function* () {}'); |
| 59 | var asyncGenFunctionPrototype = asyncGenFunction ? asyncGenFunction.prototype : undefined; |
| 60 | var asyncGenPrototype = asyncGenFunctionPrototype ? asyncGenFunctionPrototype.prototype : undefined; |
| 61 | |
| 62 | var TypedArray = typeof Uint8Array === 'undefined' ? undefined : getProto(Uint8Array); |
| 63 | |
| 64 | var INTRINSICS = { |
| 65 | '%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError, |
| 66 | '%Array%': Array, |
| 67 | '%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer, |
| 68 | '%ArrayIteratorPrototype%': hasSymbols ? getProto([][Symbol.iterator]()) : undefined, |
| 69 | '%AsyncFromSyncIteratorPrototype%': undefined, |
| 70 | '%AsyncFunction%': getEvalledConstructor('async function () {}'), |
| 71 | '%AsyncGenerator%': asyncGenFunctionPrototype, |
| 72 | '%AsyncGeneratorFunction%': asyncGenFunction, |
| 73 | '%AsyncIteratorPrototype%': asyncGenPrototype ? getProto(asyncGenPrototype) : undefined, |
| 74 | '%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics, |
| 75 | '%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt, |
| 76 | '%Boolean%': Boolean, |
| 77 | '%DataView%': typeof DataView === 'undefined' ? undefined : DataView, |
| 78 | '%Date%': Date, |
| 79 | '%decodeURI%': decodeURI, |
| 80 | '%decodeURIComponent%': decodeURIComponent, |
| 81 | '%encodeURI%': encodeURI, |
| 82 | '%encodeURIComponent%': encodeURIComponent, |
| 83 | '%Error%': Error, |
| 84 | '%eval%': eval, // eslint-disable-line no-eval |
| 85 | '%EvalError%': EvalError, |
| 86 | '%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array, |
| 87 | '%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array, |
| 88 | '%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry, |
| 89 | '%Function%': $Function, |
| 90 | '%GeneratorFunction%': getEvalledConstructor('function* () {}'), |
| 91 | '%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array, |
| 92 | '%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array, |
| 93 | '%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array, |
| 94 | '%isFinite%': isFinite, |
| 95 | '%isNaN%': isNaN, |
| 96 | '%IteratorPrototype%': hasSymbols ? getProto(getProto([][Symbol.iterator]())) : undefined, |
| 97 | '%JSON%': typeof JSON === 'object' ? JSON : undefined, |
| 98 | '%Map%': typeof Map === 'undefined' ? undefined : Map, |
| 99 | '%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols ? undefined : getProto(new Map()[Symbol.iterator]()), |
| 100 | '%Math%': Math, |
| 101 | '%Number%': Number, |
| 102 | '%Object%': Object, |
| 103 | '%parseFloat%': parseFloat, |
| 104 | '%parseInt%': parseInt, |
| 105 | '%Promise%': typeof Promise === 'undefined' ? undefined : Promise, |
| 106 | '%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy, |
| 107 | '%RangeError%': RangeError, |
| 108 | '%ReferenceError%': ReferenceError, |
| 109 | '%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect, |
| 110 | '%RegExp%': RegExp, |
| 111 | '%Set%': typeof Set === 'undefined' ? undefined : Set, |
| 112 | '%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols ? undefined : getProto(new Set()[Symbol.iterator]()), |
| 113 | '%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer, |
| 114 | '%String%': String, |
| 115 | '%StringIteratorPrototype%': hasSymbols ? getProto(''[Symbol.iterator]()) : undefined, |
| 116 | '%Symbol%': hasSymbols ? Symbol : undefined, |
| 117 | '%SyntaxError%': $SyntaxError, |
| 118 | '%ThrowTypeError%': ThrowTypeError, |
| 119 | '%TypedArray%': TypedArray, |
| 120 | '%TypeError%': $TypeError, |
| 121 | '%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array, |
| 122 | '%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray, |
| 123 | '%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array, |
| 124 | '%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array, |
| 125 | '%URIError%': URIError, |
| 126 | '%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap, |
| 127 | '%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef, |
| 128 | '%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet |
| 129 | }; |
| 130 | |
| 131 | var LEGACY_ALIASES = { |
| 132 | '%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'], |
| 133 | '%ArrayPrototype%': ['Array', 'prototype'], |
| 134 | '%ArrayProto_entries%': ['Array', 'prototype', 'entries'], |
| 135 | '%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'], |
| 136 | '%ArrayProto_keys%': ['Array', 'prototype', 'keys'], |
| 137 | '%ArrayProto_values%': ['Array', 'prototype', 'values'], |
| 138 | '%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'], |
| 139 | '%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'], |
| 140 | '%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'], |
| 141 | '%BooleanPrototype%': ['Boolean', 'prototype'], |
| 142 | '%DataViewPrototype%': ['DataView', 'prototype'], |
| 143 | '%DatePrototype%': ['Date', 'prototype'], |
| 144 | '%ErrorPrototype%': ['Error', 'prototype'], |
| 145 | '%EvalErrorPrototype%': ['EvalError', 'prototype'], |
| 146 | '%Float32ArrayPrototype%': ['Float32Array', 'prototype'], |
| 147 | '%Float64ArrayPrototype%': ['Float64Array', 'prototype'], |
| 148 | '%FunctionPrototype%': ['Function', 'prototype'], |
| 149 | '%Generator%': ['GeneratorFunction', 'prototype'], |
| 150 | '%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'], |
| 151 | '%Int8ArrayPrototype%': ['Int8Array', 'prototype'], |
| 152 | '%Int16ArrayPrototype%': ['Int16Array', 'prototype'], |
| 153 | '%Int32ArrayPrototype%': ['Int32Array', 'prototype'], |
| 154 | '%JSONParse%': ['JSON', 'parse'], |
| 155 | '%JSONStringify%': ['JSON', 'stringify'], |
| 156 | '%MapPrototype%': ['Map', 'prototype'], |
| 157 | '%NumberPrototype%': ['Number', 'prototype'], |
| 158 | '%ObjectPrototype%': ['Object', 'prototype'], |
| 159 | '%ObjProto_toString%': ['Object', 'prototype', 'toString'], |
| 160 | '%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'], |
| 161 | '%PromisePrototype%': ['Promise', 'prototype'], |
| 162 | '%PromiseProto_then%': ['Promise', 'prototype', 'then'], |
| 163 | '%Promise_all%': ['Promise', 'all'], |
| 164 | '%Promise_reject%': ['Promise', 'reject'], |
| 165 | '%Promise_resolve%': ['Promise', 'resolve'], |
| 166 | '%RangeErrorPrototype%': ['RangeError', 'prototype'], |
| 167 | '%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'], |
| 168 | '%RegExpPrototype%': ['RegExp', 'prototype'], |
| 169 | '%SetPrototype%': ['Set', 'prototype'], |
| 170 | '%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'], |
| 171 | '%StringPrototype%': ['String', 'prototype'], |
| 172 | '%SymbolPrototype%': ['Symbol', 'prototype'], |
| 173 | '%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'], |
| 174 | '%TypedArrayPrototype%': ['TypedArray', 'prototype'], |
| 175 | '%TypeErrorPrototype%': ['TypeError', 'prototype'], |
| 176 | '%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'], |
| 177 | '%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'], |
| 178 | '%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'], |
| 179 | '%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'], |
| 180 | '%URIErrorPrototype%': ['URIError', 'prototype'], |
| 181 | '%WeakMapPrototype%': ['WeakMap', 'prototype'], |
| 182 | '%WeakSetPrototype%': ['WeakSet', 'prototype'] |
| 183 | }; |
| 184 | |
| 185 | var bind = require('function-bind'); |
| 186 | var hasOwn = require('has'); |
| 187 | var $concat = bind.call(Function.call, Array.prototype.concat); |
| 188 | var $spliceApply = bind.call(Function.apply, Array.prototype.splice); |
| 189 | var $replace = bind.call(Function.call, String.prototype.replace); |
| 190 | |
| 191 | /* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */ |
| 192 | var rePropName = /[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g; |
| 193 | var reEscapeChar = /\\(\\)?/g; /** Used to match backslashes in property paths. */ |
| 194 | var stringToPath = function stringToPath(string) { |
| 195 | var result = []; |
| 196 | $replace(string, rePropName, function (match, number, quote, subString) { |
| 197 | result[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match; |
| 198 | }); |
| 199 | return result; |
| 200 | }; |
| 201 | /* end adaptation */ |
| 202 | |
| 203 | var getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) { |
| 204 | var intrinsicName = name; |
| 205 | var alias; |
| 206 | if (hasOwn(LEGACY_ALIASES, intrinsicName)) { |
| 207 | alias = LEGACY_ALIASES[intrinsicName]; |
| 208 | intrinsicName = '%' + alias[0] + '%'; |
| 209 | } |
| 210 | |
| 211 | if (hasOwn(INTRINSICS, intrinsicName)) { |
| 212 | var value = INTRINSICS[intrinsicName]; |
| 213 | if (typeof value === 'undefined' && !allowMissing) { |
| 214 | throw new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!'); |
| 215 | } |
| 216 | |
| 217 | return { |
| 218 | alias: alias, |
| 219 | name: intrinsicName, |
| 220 | value: value |
| 221 | }; |
| 222 | } |
| 223 | |
| 224 | throw new $SyntaxError('intrinsic ' + name + ' does not exist!'); |
| 225 | }; |
| 226 | |
| 227 | module.exports = function GetIntrinsic(name, allowMissing) { |
| 228 | if (typeof name !== 'string' || name.length === 0) { |
| 229 | throw new $TypeError('intrinsic name must be a non-empty string'); |
| 230 | } |
| 231 | if (arguments.length > 1 && typeof allowMissing !== 'boolean') { |
| 232 | throw new $TypeError('"allowMissing" argument must be a boolean'); |
| 233 | } |
| 234 | |
| 235 | var parts = stringToPath(name); |
| 236 | var intrinsicBaseName = parts.length > 0 ? parts[0] : ''; |
| 237 | |
| 238 | var intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing); |
| 239 | var intrinsicRealName = intrinsic.name; |
| 240 | var value = intrinsic.value; |
| 241 | var skipFurtherCaching = false; |
| 242 | |
| 243 | var alias = intrinsic.alias; |
| 244 | if (alias) { |
| 245 | intrinsicBaseName = alias[0]; |
| 246 | $spliceApply(parts, $concat([0, 1], alias)); |
| 247 | } |
| 248 | |
| 249 | for (var i = 1, isOwn = true; i < parts.length; i += 1) { |
| 250 | var part = parts[i]; |
| 251 | if (part === 'constructor' || !isOwn) { |
| 252 | skipFurtherCaching = true; |
| 253 | } |
| 254 | |
| 255 | intrinsicBaseName += '.' + part; |
| 256 | intrinsicRealName = '%' + intrinsicBaseName + '%'; |
| 257 | |
| 258 | if (hasOwn(INTRINSICS, intrinsicRealName)) { |
| 259 | value = INTRINSICS[intrinsicRealName]; |
| 260 | } else if (value != null) { |
| 261 | if ($gOPD && (i + 1) >= parts.length) { |
| 262 | var desc = $gOPD(value, part); |
| 263 | isOwn = !!desc; |
| 264 | |
| 265 | if (!allowMissing && !(part in value)) { |
| 266 | throw new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.'); |
| 267 | } |
| 268 | // By convention, when a data property is converted to an accessor |
| 269 | // property to emulate a data property that does not suffer from |
| 270 | // the override mistake, that accessor's getter is marked with |
| 271 | // an `originalValue` property. Here, when we detect this, we |
| 272 | // uphold the illusion by pretending to see that original data |
| 273 | // property, i.e., returning the value rather than the getter |
| 274 | // itself. |
| 275 | if (isOwn && 'get' in desc && !('originalValue' in desc.get)) { |
| 276 | value = desc.get; |
| 277 | } else { |
| 278 | value = value[part]; |
| 279 | } |
| 280 | } else { |
| 281 | isOwn = hasOwn(value, part); |
| 282 | value = value[part]; |
| 283 | } |
| 284 | |
| 285 | if (isOwn && !skipFurtherCaching) { |
| 286 | INTRINSICS[intrinsicRealName] = value; |
| 287 | } |
| 288 | } |
| 289 | } |
| 290 | return value; |
| 291 | }; |