blob: 7586b0074ac75beb9772dd08ca607faf3e715a35 [file] [log] [blame]
Leo Repp58b9f112021-11-22 11:57:47 +01001'use strict';
2
3/* globals
4 AggregateError,
5 Atomics,
6 FinalizationRegistry,
7 SharedArrayBuffer,
8 WeakRef,
9*/
10
11var undefined;
12
13var $SyntaxError = SyntaxError;
14var $Function = Function;
15var $TypeError = TypeError;
16
17// eslint-disable-next-line consistent-return
18var 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
25var $gOPD = Object.getOwnPropertyDescriptor;
26if ($gOPD) {
27 try {
28 $gOPD({}, '');
29 } catch (e) {
30 $gOPD = null; // this is IE 8, which has a broken gOPD
31 }
32}
33
34var throwTypeError = function () {
35 throw new $TypeError();
36};
37var 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
54var hasSymbols = require('has-symbols')();
55
56var getProto = Object.getPrototypeOf || function (x) { return x.__proto__; }; // eslint-disable-line no-proto
57
58var asyncGenFunction = getEvalledConstructor('async function* () {}');
59var asyncGenFunctionPrototype = asyncGenFunction ? asyncGenFunction.prototype : undefined;
60var asyncGenPrototype = asyncGenFunctionPrototype ? asyncGenFunctionPrototype.prototype : undefined;
61
62var TypedArray = typeof Uint8Array === 'undefined' ? undefined : getProto(Uint8Array);
63
64var 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
131var 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
185var bind = require('function-bind');
186var hasOwn = require('has');
187var $concat = bind.call(Function.call, Array.prototype.concat);
188var $spliceApply = bind.call(Function.apply, Array.prototype.splice);
189var $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 */
192var rePropName = /[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g;
193var reEscapeChar = /\\(\\)?/g; /** Used to match backslashes in property paths. */
194var 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
203var 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
227module.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};