/**
* @NOTE side-effect file - no exports
*
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncFunction
* @file put hidden constructors as ROOT level constructors in this `Realm` (ecma262)
* @desc we do this to avoid babel messing up a whole application with *runtime
*/
import { wrapAttemptOr } from '../../../deps'
import { EMPTY_STRING, EMPTY_ARRAY } from './NATIVE_EMPTY_LIST'
import { MockArguments, MockIterator } from './HiddenRealmMocks'
import { ROOT } from './ROOT'
/**
* @todo this belongs not in here, but in exotic core
*/
const isNil = (x: any): x is null | undefined => x != null
// eslint-disable-next-line
const _callNewFunction = (functionContents: string) =>
new Function(functionContents)()
const callNewFunction = wrapAttemptOr(_callNewFunction)
/**
* @NOTE so first we do toObj
* @NOTE (does NOT @throw)
* @throws TypeError: Cannot convert undefined or null to object
*
* @param {*} x argument to get prototype constructor
* @return {Function|Object|*} constructor
*
* @example
*
* getConstructor(async function eh() {})
* //=> AsyncFunction() { [native code] }
*
*/
const getConstructor = (x: any) =>
isNil(x) ? x : Object.getPrototypeOf(Object(x)).constructor
/* prettier-ignore */
// [NO_OP_GENERATOR, GeneratorSyntaxException]
// eslint-disable-next-line
const [NO_OP_GENERATOR] = callNewFunction(`return function*() {/* NO_OP_GENERATOR */}`)
/* prettier-ignore */
// [NO_OP_ASYNC, AsyncSyntaxException]
// eslint-disable-next-line
const [NO_OP_ASYNC] = callNewFunction(`return async function() {/* NO_OP_ASYNC */}`)
function REGISTER_HIDDEN_CONSTRUCTORS(REALM: NodeJS.Global | Window) {
// eslint-disable-next-line
REALM['AsyncFunction'] = getConstructor(NO_OP_ASYNC)
REALM.GeneratorFunction = getConstructor(NO_OP_GENERATOR)
// @NOTE these can actually be used pretty easily for ===
const toIteratorPrototype = x => Object.getPrototypeOf(x[Symbol.iterator]())
const [MapIterator, SetIterator, StringIterator, ArrayIterator] = [
new Map(),
new Set(),
EMPTY_STRING,
EMPTY_ARRAY,
].map(toIteratorPrototype)
REALM.MapIterator = MapIterator
REALM.SetIterator = SetIterator
REALM.StringIterator = StringIterator
REALM.ArrayIterator = ArrayIterator
REALM.Undefined = undefined
REALM.Null = null
REALM.Arguments = MockArguments
REALM.Iterator = MockIterator
}
// REGISTER_HIDDEN_CONSTRUCTORS(ROOT || {})
if (typeof window !== 'undefined') {
REGISTER_HIDDEN_CONSTRUCTORS(window)
}
if (typeof global !== 'undefined') {
// if (global.window !== global) {
// REGISTER_HIDDEN_CONSTRUCTORS(global)
// }
REGISTER_HIDDEN_CONSTRUCTORS(global)
}
// if (typeof self !== 'undefined') {
// REGISTER_HIDDEN_CONSTRUCTORS(self)
// }
// if (typeof module !== 'undefined') {
// REGISTER_HIDDEN_CONSTRUCTORS(module.exports)
// }
// if (typeof exports !== 'undefined') {
// REGISTER_HIDDEN_CONSTRUCTORS(exports)
// }
// export { REGISTER_HIDDEN_CONSTRUCTORS }
// export default REGISTER_HIDDEN_CONSTRUCTORS