| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- /*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
- import { isTypedArray, isObject, isUndefinedOrNull } from './types.js';
- export function deepClone(obj) {
- if (!obj || typeof obj !== 'object') {
- return obj;
- }
- if (obj instanceof RegExp) {
- return obj;
- }
- const result = Array.isArray(obj) ? [] : {};
- Object.entries(obj).forEach(([key, value]) => {
- result[key] = value && typeof value === 'object' ? deepClone(value) : value;
- });
- return result;
- }
- export function deepFreeze(obj) {
- if (!obj || typeof obj !== 'object') {
- return obj;
- }
- const stack = [obj];
- while (stack.length > 0) {
- const obj = stack.shift();
- Object.freeze(obj);
- for (const key in obj) {
- if (_hasOwnProperty.call(obj, key)) {
- const prop = obj[key];
- if (typeof prop === 'object' && !Object.isFrozen(prop) && !isTypedArray(prop)) {
- stack.push(prop);
- }
- }
- }
- }
- return obj;
- }
- const _hasOwnProperty = Object.prototype.hasOwnProperty;
- export function cloneAndChange(obj, changer) {
- return _cloneAndChange(obj, changer, new Set());
- }
- function _cloneAndChange(obj, changer, seen) {
- if (isUndefinedOrNull(obj)) {
- return obj;
- }
- const changed = changer(obj);
- if (typeof changed !== 'undefined') {
- return changed;
- }
- if (Array.isArray(obj)) {
- const r1 = [];
- for (const e of obj) {
- r1.push(_cloneAndChange(e, changer, seen));
- }
- return r1;
- }
- if (isObject(obj)) {
- if (seen.has(obj)) {
- throw new Error('Cannot clone recursive data-structure');
- }
- seen.add(obj);
- const r2 = {};
- for (const i2 in obj) {
- if (_hasOwnProperty.call(obj, i2)) {
- r2[i2] = _cloneAndChange(obj[i2], changer, seen);
- }
- }
- seen.delete(obj);
- return r2;
- }
- return obj;
- }
- /**
- * Copies all properties of source into destination. The optional parameter "overwrite" allows to control
- * if existing properties on the destination should be overwritten or not. Defaults to true (overwrite).
- */
- export function mixin(destination, source, overwrite = true) {
- if (!isObject(destination)) {
- return source;
- }
- if (isObject(source)) {
- Object.keys(source).forEach(key => {
- if (key in destination) {
- if (overwrite) {
- if (isObject(destination[key]) && isObject(source[key])) {
- mixin(destination[key], source[key], overwrite);
- }
- else {
- destination[key] = source[key];
- }
- }
- }
- else {
- destination[key] = source[key];
- }
- });
- }
- return destination;
- }
- export function equals(one, other) {
- if (one === other) {
- return true;
- }
- if (one === null || one === undefined || other === null || other === undefined) {
- return false;
- }
- if (typeof one !== typeof other) {
- return false;
- }
- if (typeof one !== 'object') {
- return false;
- }
- if ((Array.isArray(one)) !== (Array.isArray(other))) {
- return false;
- }
- let i;
- let key;
- if (Array.isArray(one)) {
- if (one.length !== other.length) {
- return false;
- }
- for (i = 0; i < one.length; i++) {
- if (!equals(one[i], other[i])) {
- return false;
- }
- }
- }
- else {
- const oneKeys = [];
- for (key in one) {
- oneKeys.push(key);
- }
- oneKeys.sort();
- const otherKeys = [];
- for (key in other) {
- otherKeys.push(key);
- }
- otherKeys.sort();
- if (!equals(oneKeys, otherKeys)) {
- return false;
- }
- for (i = 0; i < oneKeys.length; i++) {
- if (!equals(one[oneKeys[i]], other[oneKeys[i]])) {
- return false;
- }
- }
- }
- return true;
- }
- export function getAllPropertyNames(obj) {
- let res = [];
- let proto = Object.getPrototypeOf(obj);
- while (Object.prototype !== proto) {
- res = res.concat(Object.getOwnPropertyNames(proto));
- proto = Object.getPrototypeOf(proto);
- }
- return res;
- }
- export function getAllMethodNames(obj) {
- const methods = [];
- for (const prop of getAllPropertyNames(obj)) {
- if (typeof obj[prop] === 'function') {
- methods.push(prop);
- }
- }
- return methods;
- }
- export function createProxyObject(methodNames, invoke) {
- const createProxyMethod = (method) => {
- return function () {
- const args = Array.prototype.slice.call(arguments, 0);
- return invoke(method, args);
- };
- };
- const result = {};
- for (const methodName of methodNames) {
- result[methodName] = createProxyMethod(methodName);
- }
- return result;
- }
|