123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- /*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
- import { isArray, isObject, isUndefinedOrNull } from './types.js';
- export function deepClone(obj) {
- if (!obj || typeof obj !== 'object') {
- return obj;
- }
- if (obj instanceof RegExp) {
- // See https://github.com/microsoft/TypeScript/issues/10990
- return obj;
- }
- const result = Array.isArray(obj) ? [] : {};
- Object.keys(obj).forEach((key) => {
- if (obj[key] && typeof obj[key] === 'object') {
- result[key] = deepClone(obj[key]);
- }
- else {
- result[key] = obj[key];
- }
- });
- 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)) {
- 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 (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 (let 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 getOrDefault(obj, fn, defaultValue) {
- const result = fn(obj);
- return typeof result === 'undefined' ? defaultValue : result;
- }
|