feat: a lot of typescript corelibs translated to java
This commit is contained in:
@@ -2,12 +2,17 @@ interface Environment {
|
||||
global: typeof globalThis & Record<string, any>;
|
||||
proto(name: string): object;
|
||||
setProto(name: string, val: object): void;
|
||||
symbol(name: string): symbol;
|
||||
}
|
||||
interface Internals {
|
||||
object: ObjectConstructor;
|
||||
function: FunctionConstructor;
|
||||
promise: typeof Promise;
|
||||
|
||||
markSpecial(...funcs: Function[]): void;
|
||||
getEnv(func: Function): Environment | undefined;
|
||||
setEnv<T>(func: T, env: Environment): T;
|
||||
apply(func: Function, thisArg: any, args: any[]): any;
|
||||
apply(func: Function, thisArg: any, args: any[], env?: Environment): any;
|
||||
delay(timeout: number, callback: Function): () => void;
|
||||
pushMessage(micro: boolean, func: Function, thisArg: any, args: any[]): void;
|
||||
|
||||
@@ -55,6 +60,7 @@ try {
|
||||
run('timeout');
|
||||
|
||||
env.global.log = log;
|
||||
env.global.NewObject = internals.object;
|
||||
|
||||
log('Loaded polyfills!');
|
||||
}
|
||||
|
||||
371
lib/promise.ts
371
lib/promise.ts
@@ -1,203 +1,208 @@
|
||||
define("promise", () => {
|
||||
const syms = {
|
||||
callbacks: internals.symbol('Promise.callbacks'),
|
||||
state: internals.symbol('Promise.state'),
|
||||
value: internals.symbol('Promise.value'),
|
||||
handled: internals.symbol('Promise.handled'),
|
||||
} as {
|
||||
readonly callbacks: unique symbol,
|
||||
readonly state: unique symbol,
|
||||
readonly value: unique symbol,
|
||||
readonly handled: unique symbol,
|
||||
}
|
||||
var Promise = env.global.Promise = internals.promise
|
||||
return;
|
||||
|
||||
type Callback<T> = [ PromiseFulfillFunc<T>, PromiseRejectFunc ];
|
||||
enum State {
|
||||
Pending,
|
||||
Fulfilled,
|
||||
Rejected,
|
||||
}
|
||||
// const syms = {
|
||||
// callbacks: internals.symbol('Promise.callbacks'),
|
||||
// state: internals.symbol('Promise.state'),
|
||||
// value: internals.symbol('Promise.value'),
|
||||
// handled: internals.symbol('Promise.handled'),
|
||||
// } as {
|
||||
// readonly callbacks: unique symbol,
|
||||
// readonly state: unique symbol,
|
||||
// readonly value: unique symbol,
|
||||
// readonly handled: unique symbol,
|
||||
// }
|
||||
|
||||
function isAwaitable(val: unknown): val is Thenable<any> {
|
||||
return (
|
||||
typeof val === 'object' &&
|
||||
val !== null &&
|
||||
'then' in val &&
|
||||
typeof val.then === 'function'
|
||||
);
|
||||
}
|
||||
function resolve(promise: Promise<any>, v: any, state: State) {
|
||||
if (promise[syms.state] === State.Pending) {
|
||||
if (typeof v === 'object' && v !== null && 'then' in v && typeof v.then === 'function') {
|
||||
v.then(
|
||||
(res: any) => resolve(promise, res, state),
|
||||
(res: any) => resolve(promise, res, State.Rejected)
|
||||
);
|
||||
return;
|
||||
}
|
||||
promise[syms.value] = v;
|
||||
promise[syms.state] = state;
|
||||
// type Callback<T> = [ PromiseFulfillFunc<T>, PromiseRejectFunc ];
|
||||
// enum State {
|
||||
// Pending,
|
||||
// Fulfilled,
|
||||
// Rejected,
|
||||
// }
|
||||
|
||||
for (let i = 0; i < promise[syms.callbacks]!.length; i++) {
|
||||
promise[syms.handled] = true;
|
||||
promise[syms.callbacks]![i][state - 1](v);
|
||||
}
|
||||
// function isAwaitable(val: unknown): val is Thenable<any> {
|
||||
// return (
|
||||
// typeof val === 'object' &&
|
||||
// val !== null &&
|
||||
// 'then' in val &&
|
||||
// typeof val.then === 'function'
|
||||
// );
|
||||
// }
|
||||
// function resolve(promise: Promise<any>, v: any, state: State) {
|
||||
// if (promise[syms.state] === State.Pending) {
|
||||
// if (typeof v === 'object' && v !== null && 'then' in v && typeof v.then === 'function') {
|
||||
// v.then(
|
||||
// (res: any) => resolve(promise, res, state),
|
||||
// (res: any) => resolve(promise, res, State.Rejected)
|
||||
// );
|
||||
// return;
|
||||
// }
|
||||
// promise[syms.value] = v;
|
||||
// promise[syms.state] = state;
|
||||
|
||||
promise[syms.callbacks] = undefined;
|
||||
// for (let i = 0; i < promise[syms.callbacks]!.length; i++) {
|
||||
// promise[syms.handled] = true;
|
||||
// promise[syms.callbacks]![i][state - 1](v);
|
||||
// }
|
||||
|
||||
internals.pushMessage(true, internals.setEnv(() => {
|
||||
if (!promise[syms.handled] && state === State.Rejected) {
|
||||
log('Uncaught (in promise) ' + promise[syms.value]);
|
||||
}
|
||||
}, env), undefined, []);
|
||||
}
|
||||
}
|
||||
// promise[syms.callbacks] = undefined;
|
||||
|
||||
class Promise<T> {
|
||||
public static isAwaitable(val: unknown): val is Thenable<any> {
|
||||
return isAwaitable(val);
|
||||
}
|
||||
// internals.pushMessage(true, internals.setEnv(() => {
|
||||
// if (!promise[syms.handled] && state === State.Rejected) {
|
||||
// log('Uncaught (in promise) ' + promise[syms.value]);
|
||||
// }
|
||||
// }, env), undefined, []);
|
||||
// }
|
||||
// }
|
||||
|
||||
public static resolve<T>(val: T): Promise<Awaited<T>> {
|
||||
return new Promise(res => res(val as any));
|
||||
}
|
||||
public static reject<T>(val: T): Promise<Awaited<T>> {
|
||||
return new Promise((_, rej) => rej(val as any));
|
||||
}
|
||||
// class _Promise<T> {
|
||||
// public static isAwaitable(val: unknown): val is Thenable<any> {
|
||||
// return isAwaitable(val);
|
||||
// }
|
||||
|
||||
public static race<T>(vals: T[]): Promise<Awaited<T>> {
|
||||
if (typeof vals.length !== 'number') throw new TypeError('vals must be an array. Note that Promise.race is not variadic.');
|
||||
return new Promise((res, rej) => {
|
||||
for (let i = 0; i < vals.length; i++) {
|
||||
const val = vals[i];
|
||||
if (this.isAwaitable(val)) val.then(res, rej);
|
||||
else res(val as any);
|
||||
}
|
||||
});
|
||||
}
|
||||
public static any<T>(vals: T[]): Promise<Awaited<T>> {
|
||||
if (typeof vals.length !== 'number') throw new TypeError('vals must be an array. Note that Promise.any is not variadic.');
|
||||
return new Promise((res, rej) => {
|
||||
let n = 0;
|
||||
// public static resolve<T>(val: T): Promise<Awaited<T>> {
|
||||
// return new Promise(res => res(val as any));
|
||||
// }
|
||||
// public static reject<T>(val: T): Promise<Awaited<T>> {
|
||||
// return new Promise((_, rej) => rej(val as any));
|
||||
// }
|
||||
|
||||
for (let i = 0; i < vals.length; i++) {
|
||||
const val = vals[i];
|
||||
if (this.isAwaitable(val)) val.then(res, (err) => {
|
||||
n++;
|
||||
if (n === vals.length) throw Error('No promise resolved.');
|
||||
});
|
||||
else res(val as any);
|
||||
}
|
||||
// public static race<T>(vals: T[]): Promise<Awaited<T>> {
|
||||
// if (typeof vals.length !== 'number') throw new env.global.TypeError('vals must be an array. Note that Promise.race is not variadic.');
|
||||
// return new Promise((res, rej) => {
|
||||
// for (let i = 0; i < vals.length; i++) {
|
||||
// const val = vals[i];
|
||||
// if (this.isAwaitable(val)) val.then(res, rej);
|
||||
// else res(val as any);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// public static any<T>(vals: T[]): Promise<Awaited<T>> {
|
||||
// if (typeof vals.length !== 'number') throw new env.global.TypeError('vals must be an array. Note that Promise.any is not variadic.');
|
||||
// return new Promise((res, rej) => {
|
||||
// let n = 0;
|
||||
|
||||
if (vals.length === 0) throw Error('No promise resolved.');
|
||||
});
|
||||
}
|
||||
public static all(vals: any[]): Promise<any[]> {
|
||||
if (typeof vals.length !== 'number') throw new TypeError('vals must be an array. Note that Promise.all is not variadic.');
|
||||
return new Promise((res, rej) => {
|
||||
const result: any[] = [];
|
||||
let n = 0;
|
||||
// for (let i = 0; i < vals.length; i++) {
|
||||
// const val = vals[i];
|
||||
// if (this.isAwaitable(val)) val.then(res, (err) => {
|
||||
// n++;
|
||||
// if (n === vals.length) throw Error('No promise resolved.');
|
||||
// });
|
||||
// else res(val as any);
|
||||
// }
|
||||
|
||||
for (let i = 0; i < vals.length; i++) {
|
||||
const val = vals[i];
|
||||
if (this.isAwaitable(val)) val.then(
|
||||
val => {
|
||||
n++;
|
||||
result[i] = val;
|
||||
if (n === vals.length) res(result);
|
||||
},
|
||||
rej
|
||||
);
|
||||
else {
|
||||
n++;
|
||||
result[i] = val;
|
||||
}
|
||||
}
|
||||
// if (vals.length === 0) throw Error('No promise resolved.');
|
||||
// });
|
||||
// }
|
||||
// public static all(vals: any[]): Promise<any[]> {
|
||||
// if (typeof vals.length !== 'number') throw new env.global.TypeError('vals must be an array. Note that Promise.all is not variadic.');
|
||||
// return new Promise((res, rej) => {
|
||||
// const result: any[] = [];
|
||||
// let n = 0;
|
||||
|
||||
if (vals.length === n) res(result);
|
||||
});
|
||||
}
|
||||
public static allSettled(vals: any[]): Promise<any[]> {
|
||||
if (typeof vals.length !== 'number') throw new TypeError('vals must be an array. Note that Promise.allSettled is not variadic.');
|
||||
return new Promise((res, rej) => {
|
||||
const result: any[] = [];
|
||||
let n = 0;
|
||||
// for (let i = 0; i < vals.length; i++) {
|
||||
// const val = vals[i];
|
||||
// if (this.isAwaitable(val)) val.then(
|
||||
// val => {
|
||||
// n++;
|
||||
// result[i] = val;
|
||||
// if (n === vals.length) res(result);
|
||||
// },
|
||||
// rej
|
||||
// );
|
||||
// else {
|
||||
// n++;
|
||||
// result[i] = val;
|
||||
// }
|
||||
// }
|
||||
|
||||
for (let i = 0; i < vals.length; i++) {
|
||||
const value = vals[i];
|
||||
if (this.isAwaitable(value)) value.then(
|
||||
value => {
|
||||
n++;
|
||||
result[i] = { status: 'fulfilled', value };
|
||||
if (n === vals.length) res(result);
|
||||
},
|
||||
reason => {
|
||||
n++;
|
||||
result[i] = { status: 'rejected', reason };
|
||||
if (n === vals.length) res(result);
|
||||
},
|
||||
);
|
||||
else {
|
||||
n++;
|
||||
result[i] = { status: 'fulfilled', value };
|
||||
}
|
||||
}
|
||||
// if (vals.length === n) res(result);
|
||||
// });
|
||||
// }
|
||||
// public static allSettled(vals: any[]): Promise<any[]> {
|
||||
// if (typeof vals.length !== 'number') throw new env.global.TypeError('vals must be an array. Note that Promise.allSettled is not variadic.');
|
||||
// return new Promise((res, rej) => {
|
||||
// const result: any[] = [];
|
||||
// let n = 0;
|
||||
|
||||
if (vals.length === n) res(result);
|
||||
});
|
||||
}
|
||||
// for (let i = 0; i < vals.length; i++) {
|
||||
// const value = vals[i];
|
||||
// if (this.isAwaitable(value)) value.then(
|
||||
// value => {
|
||||
// n++;
|
||||
// result[i] = { status: 'fulfilled', value };
|
||||
// if (n === vals.length) res(result);
|
||||
// },
|
||||
// reason => {
|
||||
// n++;
|
||||
// result[i] = { status: 'rejected', reason };
|
||||
// if (n === vals.length) res(result);
|
||||
// },
|
||||
// );
|
||||
// else {
|
||||
// n++;
|
||||
// result[i] = { status: 'fulfilled', value };
|
||||
// }
|
||||
// }
|
||||
|
||||
[syms.callbacks]?: Callback<T>[] = [];
|
||||
[syms.handled] = false;
|
||||
[syms.state] = State.Pending;
|
||||
[syms.value]?: T | unknown;
|
||||
// if (vals.length === n) res(result);
|
||||
// });
|
||||
// }
|
||||
|
||||
public then(onFulfil?: PromiseFulfillFunc<T>, onReject?: PromiseRejectFunc) {
|
||||
return new Promise((resolve, reject) => {
|
||||
onFulfil ??= v => v;
|
||||
onReject ??= v => v;
|
||||
// [syms.callbacks]?: Callback<T>[] = [];
|
||||
// [syms.handled] = false;
|
||||
// [syms.state] = State.Pending;
|
||||
// [syms.value]?: T | unknown;
|
||||
|
||||
const callback = (func: (val: any) => any) => (v: any) => {
|
||||
try { resolve(func(v)); }
|
||||
catch (e) { reject(e); }
|
||||
}
|
||||
switch (this[syms.state]) {
|
||||
case State.Pending:
|
||||
this[syms.callbacks]![this[syms.callbacks]!.length] = [callback(onFulfil), callback(onReject)];
|
||||
break;
|
||||
case State.Fulfilled:
|
||||
this[syms.handled] = true;
|
||||
callback(onFulfil)(this[syms.value]);
|
||||
break;
|
||||
case State.Rejected:
|
||||
this[syms.handled] = true;
|
||||
callback(onReject)(this[syms.value]);
|
||||
break;
|
||||
}
|
||||
})
|
||||
}
|
||||
public catch(func: PromiseRejectFunc) {
|
||||
return this.then(undefined, func);
|
||||
}
|
||||
public finally(func: () => void) {
|
||||
return this.then(
|
||||
v => {
|
||||
func();
|
||||
return v;
|
||||
},
|
||||
v => {
|
||||
func();
|
||||
throw v;
|
||||
}
|
||||
);
|
||||
}
|
||||
// public then(onFulfil?: PromiseFulfillFunc<T>, onReject?: PromiseRejectFunc) {
|
||||
// return new Promise((resolve, reject) => {
|
||||
// onFulfil ??= v => v;
|
||||
// onReject ??= v => v;
|
||||
|
||||
public constructor(func: PromiseFunc<T>) {
|
||||
internals.pushMessage(true, func, undefined, [
|
||||
((v) => resolve(this, v, State.Fulfilled)) as PromiseFulfillFunc<T>,
|
||||
((err) => resolve(this, err, State.Rejected)) as PromiseRejectFunc
|
||||
]);
|
||||
}
|
||||
}
|
||||
env.global.Promise = Promise as any;
|
||||
// const callback = (func: (val: any) => any) => (v: any) => {
|
||||
// try {
|
||||
// resolve(func(v));
|
||||
// }
|
||||
// catch (e) { reject(e); }
|
||||
// }
|
||||
// switch (this[syms.state]) {
|
||||
// case State.Pending:
|
||||
// this[syms.callbacks]![this[syms.callbacks]!.length] = [callback(onFulfil), callback(onReject)];
|
||||
// break;
|
||||
// case State.Fulfilled:
|
||||
// this[syms.handled] = true;
|
||||
// callback(onFulfil)(this[syms.value]);
|
||||
// break;
|
||||
// case State.Rejected:
|
||||
// this[syms.handled] = true;
|
||||
// callback(onReject)(this[syms.value]);
|
||||
// break;
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// public catch(func: PromiseRejectFunc) {
|
||||
// return this.then(undefined, func);
|
||||
// }
|
||||
// public finally(func: () => void) {
|
||||
// return this.then(
|
||||
// v => {
|
||||
// func();
|
||||
// return v;
|
||||
// },
|
||||
// v => {
|
||||
// func();
|
||||
// throw v;
|
||||
// }
|
||||
// );
|
||||
// }
|
||||
|
||||
// public constructor(func: PromiseFunc<T>) {
|
||||
// internals.pushMessage(true, func, undefined, [
|
||||
// ((v) => resolve(this, v, State.Fulfilled)) as PromiseFulfillFunc<T>,
|
||||
// ((err) => resolve(this, err, State.Rejected)) as PromiseRejectFunc
|
||||
// ]);
|
||||
// }
|
||||
// }
|
||||
// env.global.Promise = Promise as any;
|
||||
});
|
||||
|
||||
@@ -4,14 +4,14 @@ define("timeout", () => {
|
||||
let timeoutI = 0, intervalI = 0;
|
||||
|
||||
env.global.setTimeout = (func, delay, ...args) => {
|
||||
if (typeof func !== 'function') throw new TypeError("func must be a function.");
|
||||
if (typeof func !== 'function') throw new env.global.TypeError("func must be a function.");
|
||||
delay = (delay ?? 0) - 0;
|
||||
const cancelFunc = internals.delay(delay, () => internals.apply(func, undefined, args));
|
||||
timeouts[++timeoutI] = cancelFunc;
|
||||
return timeoutI;
|
||||
};
|
||||
env.global.setInterval = (func, delay, ...args) => {
|
||||
if (typeof func !== 'function') throw new TypeError("func must be a function.");
|
||||
if (typeof func !== 'function') throw new env.global.TypeError("func must be a function.");
|
||||
delay = (delay ?? 0) - 0;
|
||||
|
||||
const i = ++intervalI;
|
||||
|
||||
@@ -1,140 +1,5 @@
|
||||
define("values/function", () => {
|
||||
var Function = env.global.Function = function() {
|
||||
throw 'Using the constructor Function() is forbidden.';
|
||||
} as unknown as FunctionConstructor;
|
||||
|
||||
var Function = env.global.Function = internals.function;
|
||||
env.setProto('function', Function.prototype);
|
||||
setConstr(Function.prototype, Function);
|
||||
|
||||
setProps(Function.prototype, {
|
||||
apply(thisArg, args) {
|
||||
if (typeof args !== 'object') throw 'Expected arguments to be an array-like object.';
|
||||
var len = args.length - 0;
|
||||
let newArgs: any[];
|
||||
if (internals.isArray(args)) newArgs = args;
|
||||
else {
|
||||
newArgs = [];
|
||||
|
||||
while (len >= 0) {
|
||||
len--;
|
||||
newArgs[len] = args[len];
|
||||
}
|
||||
}
|
||||
|
||||
return internals.apply(this, thisArg, newArgs);
|
||||
},
|
||||
call(thisArg, ...args) {
|
||||
return this.apply(thisArg, args);
|
||||
},
|
||||
bind(thisArg, ...args) {
|
||||
const func = this;
|
||||
const res = function() {
|
||||
const resArgs = [];
|
||||
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
resArgs[i] = args[i];
|
||||
}
|
||||
for (let i = 0; i < arguments.length; i++) {
|
||||
resArgs[i + args.length] = arguments[i];
|
||||
}
|
||||
|
||||
return func.apply(thisArg, resArgs);
|
||||
};
|
||||
res.name = "<bound> " + func.name;
|
||||
return res;
|
||||
},
|
||||
toString() {
|
||||
return 'function (...) { ... }';
|
||||
},
|
||||
});
|
||||
setProps(Function, {
|
||||
async(func) {
|
||||
if (typeof func !== 'function') throw new TypeError('Expected func to be function.');
|
||||
|
||||
return function (this: any) {
|
||||
const args = arguments;
|
||||
|
||||
return new Promise((res, rej) => {
|
||||
const gen = internals.apply(internals.generator(func as any), this, args as any);
|
||||
|
||||
(function next(type: 'none' | 'err' | 'ret', val?: any) {
|
||||
try {
|
||||
let result;
|
||||
|
||||
switch (type) {
|
||||
case 'err': result = gen.throw(val); break;
|
||||
case 'ret': result = gen.next(val); break;
|
||||
case 'none': result = gen.next(); break;
|
||||
}
|
||||
if (result.done) res(result.value);
|
||||
else Promise.resolve(result.value).then(
|
||||
v => next('ret', v),
|
||||
v => next('err', v)
|
||||
)
|
||||
}
|
||||
catch (e) {
|
||||
rej(e);
|
||||
}
|
||||
})('none');
|
||||
});
|
||||
};
|
||||
},
|
||||
asyncGenerator(func) {
|
||||
if (typeof func !== 'function') throw new TypeError('Expected func to be function.');
|
||||
|
||||
return function(this: any, ...args: any[]) {
|
||||
const gen = internals.apply(internals.generator((_yield) => func(
|
||||
val => _yield(['await', val]) as any,
|
||||
val => _yield(['yield', val])
|
||||
)), this, args) as Generator<['await' | 'yield', any]>;
|
||||
|
||||
const next = (resolve: Function, reject: Function, type: 'none' | 'val' | 'ret' | 'err', val?: any) => {
|
||||
let res;
|
||||
|
||||
try {
|
||||
switch (type) {
|
||||
case 'val': res = gen.next(val); break;
|
||||
case 'ret': res = gen.return(val); break;
|
||||
case 'err': res = gen.throw(val); break;
|
||||
default: res = gen.next(); break;
|
||||
}
|
||||
}
|
||||
catch (e) { return reject(e); }
|
||||
|
||||
if (res.done) return { done: true, res: <any>res };
|
||||
else if (res.value[0] === 'await') Promise.resolve(res.value[1]).then(
|
||||
v => next(resolve, reject, 'val', v),
|
||||
v => next(resolve, reject, 'err', v),
|
||||
)
|
||||
else resolve({ done: false, value: res.value[1] });
|
||||
};
|
||||
|
||||
return {
|
||||
next() {
|
||||
const args = arguments;
|
||||
if (arguments.length === 0) return new Promise((res, rej) => next(res, rej, 'none'));
|
||||
else return new Promise((res, rej) => next(res, rej, 'val', args[0]));
|
||||
},
|
||||
return: (value) => new Promise((res, rej) => next(res, rej, 'ret', value)),
|
||||
throw: (value) => new Promise((res, rej) => next(res, rej, 'err', value)),
|
||||
[env.global.Symbol.asyncIterator]() { return this; }
|
||||
}
|
||||
}
|
||||
},
|
||||
generator(func) {
|
||||
if (typeof func !== 'function') throw new TypeError('Expected func to be function.');
|
||||
const gen = internals.generator(func);
|
||||
return function(this: any, ...args: any[]) {
|
||||
const it = internals.apply(gen, this, args);
|
||||
|
||||
return {
|
||||
next: (...args) => internals.apply(it.next, it, args),
|
||||
return: (val) => internals.apply(it.next, it, [val]),
|
||||
throw: (val) => internals.apply(it.next, it, [val]),
|
||||
[env.global.Symbol.iterator]() { return this; }
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
internals.markSpecial(Function);
|
||||
});
|
||||
@@ -1,226 +1,5 @@
|
||||
define("values/object", () => {
|
||||
var Object = env.global.Object = function(arg: any) {
|
||||
if (arg === undefined || arg === null) return {};
|
||||
else if (typeof arg === 'boolean') return new Boolean(arg);
|
||||
else if (typeof arg === 'number') return new Number(arg);
|
||||
else if (typeof arg === 'string') return new String(arg);
|
||||
return arg;
|
||||
} as ObjectConstructor;
|
||||
|
||||
env.setProto('object', Object.prototype);
|
||||
var Object = env.global.Object = internals.object;
|
||||
(Object.prototype as any).__proto__ = null;
|
||||
setConstr(Object.prototype, Object as any);
|
||||
|
||||
function throwNotObject(obj: any, name: string) {
|
||||
if (obj === null || typeof obj !== 'object' && typeof obj !== 'function') {
|
||||
throw new TypeError(`Object.${name} may only be used for objects.`);
|
||||
}
|
||||
}
|
||||
function check(obj: any) {
|
||||
return typeof obj === 'object' && obj !== null || typeof obj === 'function';
|
||||
}
|
||||
|
||||
setProps(Object, {
|
||||
assign(dst, ...src) {
|
||||
throwNotObject(dst, 'assign');
|
||||
for (let i = 0; i < src.length; i++) {
|
||||
const obj = src[i];
|
||||
throwNotObject(obj, 'assign');
|
||||
for (const key of Object.keys(obj)) {
|
||||
(dst as any)[key] = (obj as any)[key];
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
},
|
||||
create(obj, props) {
|
||||
props ??= {};
|
||||
return Object.defineProperties({ __proto__: obj }, props as any) as any;
|
||||
},
|
||||
|
||||
defineProperty(obj, key, attrib) {
|
||||
throwNotObject(obj, 'defineProperty');
|
||||
if (typeof attrib !== 'object') throw new TypeError('Expected attributes to be an object.');
|
||||
|
||||
if ('value' in attrib) {
|
||||
if ('get' in attrib || 'set' in attrib) throw new TypeError('Cannot specify a value and accessors for a property.');
|
||||
if (!internals.defineField(
|
||||
obj, key,
|
||||
attrib.value,
|
||||
!!attrib.writable,
|
||||
!!attrib.enumerable,
|
||||
!!attrib.configurable
|
||||
)) throw new TypeError('Can\'t define property \'' + key + '\'.');
|
||||
}
|
||||
else {
|
||||
if (typeof attrib.get !== 'function' && attrib.get !== undefined) throw new TypeError('Get accessor must be a function.');
|
||||
if (typeof attrib.set !== 'function' && attrib.set !== undefined) throw new TypeError('Set accessor must be a function.');
|
||||
|
||||
if (!internals.defineProp(
|
||||
obj, key,
|
||||
attrib.get,
|
||||
attrib.set,
|
||||
!!attrib.enumerable,
|
||||
!!attrib.configurable
|
||||
)) throw new TypeError('Can\'t define property \'' + key + '\'.');
|
||||
}
|
||||
|
||||
return obj;
|
||||
},
|
||||
defineProperties(obj, attrib) {
|
||||
throwNotObject(obj, 'defineProperties');
|
||||
if (typeof attrib !== 'object' && typeof attrib !== 'function') throw 'Expected second argument to be an object.';
|
||||
|
||||
for (var key in attrib) {
|
||||
Object.defineProperty(obj, key, attrib[key]);
|
||||
}
|
||||
|
||||
return obj;
|
||||
},
|
||||
|
||||
keys(obj, onlyString) {
|
||||
return internals.keys(obj, !!(onlyString ?? true));
|
||||
},
|
||||
entries(obj, onlyString) {
|
||||
const res = [];
|
||||
const keys = internals.keys(obj, !!(onlyString ?? true));
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
res[i] = [ keys[i], (obj as any)[keys[i]] ];
|
||||
}
|
||||
|
||||
return keys;
|
||||
},
|
||||
values(obj, onlyString) {
|
||||
const res = [];
|
||||
const keys = internals.keys(obj, !!(onlyString ?? true));
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
res[i] = (obj as any)[keys[i]];
|
||||
}
|
||||
|
||||
return keys;
|
||||
},
|
||||
|
||||
getOwnPropertyDescriptor(obj, key) {
|
||||
return internals.ownProp(obj, key) as any;
|
||||
},
|
||||
getOwnPropertyDescriptors(obj) {
|
||||
const res = [];
|
||||
const keys = internals.ownPropKeys(obj);
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
res[i] = internals.ownProp(obj, keys[i]);
|
||||
}
|
||||
|
||||
return res;
|
||||
},
|
||||
|
||||
getOwnPropertyNames(obj) {
|
||||
const arr = internals.ownPropKeys(obj);
|
||||
const res = [];
|
||||
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (typeof arr[i] === 'symbol') continue;
|
||||
res[res.length] = arr[i];
|
||||
}
|
||||
|
||||
return res as any;
|
||||
},
|
||||
getOwnPropertySymbols(obj) {
|
||||
const arr = internals.ownPropKeys(obj);
|
||||
const res = [];
|
||||
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (typeof arr[i] !== 'symbol') continue;
|
||||
res[res.length] = arr[i];
|
||||
}
|
||||
|
||||
return res as any;
|
||||
},
|
||||
hasOwn(obj, key) {
|
||||
const keys = internals.ownPropKeys(obj);
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
if (keys[i] === key) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
getPrototypeOf(obj) {
|
||||
return obj.__proto__;
|
||||
},
|
||||
setPrototypeOf(obj, proto) {
|
||||
(obj as any).__proto__ = proto;
|
||||
return obj;
|
||||
},
|
||||
|
||||
fromEntries(iterable) {
|
||||
const res = {} as any;
|
||||
|
||||
for (const el of iterable) {
|
||||
res[el[0]] = el[1];
|
||||
}
|
||||
|
||||
return res;
|
||||
},
|
||||
|
||||
preventExtensions(obj) {
|
||||
throwNotObject(obj, 'preventExtensions');
|
||||
internals.lock(obj, 'ext');
|
||||
return obj;
|
||||
},
|
||||
seal(obj) {
|
||||
throwNotObject(obj, 'seal');
|
||||
internals.lock(obj, 'seal');
|
||||
return obj;
|
||||
},
|
||||
freeze(obj) {
|
||||
throwNotObject(obj, 'freeze');
|
||||
internals.lock(obj, 'freeze');
|
||||
return obj;
|
||||
},
|
||||
|
||||
isExtensible(obj) {
|
||||
if (!check(obj)) return false;
|
||||
return internals.extensible(obj);
|
||||
},
|
||||
isSealed(obj) {
|
||||
if (!check(obj)) return true;
|
||||
if (internals.extensible(obj)) return false;
|
||||
const keys = internals.ownPropKeys(obj);
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
if (internals.ownProp(obj, keys[i]).configurable) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
isFrozen(obj) {
|
||||
if (!check(obj)) return true;
|
||||
if (internals.extensible(obj)) return false;
|
||||
const keys = internals.ownPropKeys(obj);
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const prop = internals.ownProp(obj, keys[i]);
|
||||
if (prop.configurable) return false;
|
||||
if ('writable' in prop && prop.writable) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
setProps(Object.prototype, {
|
||||
valueOf() {
|
||||
return this;
|
||||
},
|
||||
toString() {
|
||||
return '[object ' + (this[env.global.Symbol.typeName] ?? 'Unknown') + ']';
|
||||
},
|
||||
hasOwnProperty(key) {
|
||||
return Object.hasOwn(this, key);
|
||||
},
|
||||
});
|
||||
internals.markSpecial(Object);
|
||||
env.setProto('object', Object.prototype);
|
||||
});
|
||||
@@ -2,8 +2,8 @@ define("values/symbol", () => {
|
||||
const symbols: Record<string, symbol> = { };
|
||||
|
||||
var Symbol = env.global.Symbol = function(this: any, val?: string) {
|
||||
if (this !== undefined && this !== null) throw new TypeError("Symbol may not be called with 'new'.");
|
||||
if (typeof val !== 'string' && val !== undefined) throw new TypeError('val must be a string or undefined.');
|
||||
if (this !== undefined && this !== null) throw new env.global.TypeError("Symbol may not be called with 'new'.");
|
||||
if (typeof val !== 'string' && val !== undefined) throw new env.global.TypeError('val must be a string or undefined.');
|
||||
return internals.symbol(val);
|
||||
} as SymbolConstructor;
|
||||
|
||||
@@ -12,23 +12,23 @@ define("values/symbol", () => {
|
||||
|
||||
setProps(Symbol, {
|
||||
for(key) {
|
||||
if (typeof key !== 'string' && key !== undefined) throw new TypeError('key must be a string or undefined.');
|
||||
if (typeof key !== 'string' && key !== undefined) throw new env.global.TypeError('key must be a string or undefined.');
|
||||
if (key in symbols) return symbols[key];
|
||||
else return symbols[key] = internals.symbol(key);
|
||||
},
|
||||
keyFor(sym) {
|
||||
if (typeof sym !== 'symbol') throw new TypeError('sym must be a symbol.');
|
||||
if (typeof sym !== 'symbol') throw new env.global.TypeError('sym must be a symbol.');
|
||||
return internals.symbolToString(sym);
|
||||
},
|
||||
|
||||
typeName: Symbol("Symbol.name") as any,
|
||||
replace: Symbol('Symbol.replace') as any,
|
||||
match: Symbol('Symbol.match') as any,
|
||||
matchAll: Symbol('Symbol.matchAll') as any,
|
||||
split: Symbol('Symbol.split') as any,
|
||||
search: Symbol('Symbol.search') as any,
|
||||
iterator: Symbol('Symbol.iterator') as any,
|
||||
asyncIterator: Symbol('Symbol.asyncIterator') as any,
|
||||
typeName: env.symbol("Symbol.typeName") as any,
|
||||
replace: env.symbol('Symbol.replace') as any,
|
||||
match: env.symbol('Symbol.match') as any,
|
||||
matchAll: env.symbol('Symbol.matchAll') as any,
|
||||
split: env.symbol('Symbol.split') as any,
|
||||
search: env.symbol('Symbol.search') as any,
|
||||
iterator: env.symbol('Symbol.iterator') as any,
|
||||
asyncIterator: env.symbol('Symbol.asyncIterator') as any,
|
||||
});
|
||||
|
||||
internals.defineField(env.global.Object.prototype, Symbol.typeName, 'Object', false, false, false);
|
||||
|
||||
Reference in New Issue
Block a user