199da06d0Sopenharmony_ci/** 299da06d0Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 399da06d0Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 499da06d0Sopenharmony_ci * you may not use this file except in compliance with the License. 599da06d0Sopenharmony_ci * You may obtain a copy of the License at 699da06d0Sopenharmony_ci * 799da06d0Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 899da06d0Sopenharmony_ci * 999da06d0Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1099da06d0Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1199da06d0Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1299da06d0Sopenharmony_ci * See the License for the specific language governing permissions and 1399da06d0Sopenharmony_ci * limitations under the License. 1499da06d0Sopenharmony_ci */ 1599da06d0Sopenharmony_ci 1699da06d0Sopenharmony_ci/** 1799da06d0Sopenharmony_ci * @file: Deep copy 1899da06d0Sopenharmony_ci */ 1999da06d0Sopenharmony_ciimport Method from './Method'; 2099da06d0Sopenharmony_ci 2199da06d0Sopenharmony_ciconst mapType = '[object Map]'; 2299da06d0Sopenharmony_ciconst setType = '[object Set]'; 2399da06d0Sopenharmony_ciconst arrayType = '[object Array]'; 2499da06d0Sopenharmony_ciconst objectType = '[object Object]'; 2599da06d0Sopenharmony_ciconst argsType = '[object Arguments]'; 2699da06d0Sopenharmony_ciconst boolType = '[object Boolean]'; 2799da06d0Sopenharmony_ciconst dateType = '[object Date]'; 2899da06d0Sopenharmony_ciconst numberType = '[object Number]'; 2999da06d0Sopenharmony_ciconst stringType = '[object String]'; 3099da06d0Sopenharmony_ciconst symbolType = '[object Symbol]'; 3199da06d0Sopenharmony_ciconst errorType = '[object Error]'; 3299da06d0Sopenharmony_ciconst regexpType = '[object RegExp]'; 3399da06d0Sopenharmony_ciconst funcType = '[object Function]'; 3499da06d0Sopenharmony_ciconst deepType = [mapType, setType, arrayType, objectType, argsType]; 3599da06d0Sopenharmony_ci 3699da06d0Sopenharmony_ciexport default class Getclone { 3799da06d0Sopenharmony_ci private static getclone: Getclone = new Getclone(); 3899da06d0Sopenharmony_ci 3999da06d0Sopenharmony_ci public static getInstance(): Getclone { 4099da06d0Sopenharmony_ci return this.getclone; 4199da06d0Sopenharmony_ci } 4299da06d0Sopenharmony_ci 4399da06d0Sopenharmony_ci /** 4499da06d0Sopenharmony_ci * forEach 4599da06d0Sopenharmony_ci * 4699da06d0Sopenharmony_ci * @param { array } array 4799da06d0Sopenharmony_ci * 4899da06d0Sopenharmony_ci * @param { function } iteratee 4999da06d0Sopenharmony_ci */ 5099da06d0Sopenharmony_ci private forEach(array, iteratee) { 5199da06d0Sopenharmony_ci let index = -1; 5299da06d0Sopenharmony_ci const length = array.length; 5399da06d0Sopenharmony_ci 5499da06d0Sopenharmony_ci while (++index < length) { 5599da06d0Sopenharmony_ci iteratee(array[index], index); 5699da06d0Sopenharmony_ci } 5799da06d0Sopenharmony_ci return array; 5899da06d0Sopenharmony_ci } 5999da06d0Sopenharmony_ci 6099da06d0Sopenharmony_ci /** 6199da06d0Sopenharmony_ci * is object 6299da06d0Sopenharmony_ci * 6399da06d0Sopenharmony_ci * @param { any } target 6499da06d0Sopenharmony_ci */ 6599da06d0Sopenharmony_ci private isObject(target) { 6699da06d0Sopenharmony_ci const type = typeof target; 6799da06d0Sopenharmony_ci return target !== null && (type === 'object' || type === 'function'); 6899da06d0Sopenharmony_ci } 6999da06d0Sopenharmony_ci 7099da06d0Sopenharmony_ci /** 7199da06d0Sopenharmony_ci * get type 7299da06d0Sopenharmony_ci * 7399da06d0Sopenharmony_ci * @param { any } target 7499da06d0Sopenharmony_ci */ 7599da06d0Sopenharmony_ci private getType(target) { 7699da06d0Sopenharmony_ci return Object.prototype.toString.call(target); 7799da06d0Sopenharmony_ci } 7899da06d0Sopenharmony_ci 7999da06d0Sopenharmony_ci /** 8099da06d0Sopenharmony_ci * get init 8199da06d0Sopenharmony_ci * 8299da06d0Sopenharmony_ci * @param { any } target 8399da06d0Sopenharmony_ci */ 8499da06d0Sopenharmony_ci private getInit(target) { 8599da06d0Sopenharmony_ci const ctor = target.constructor; 8699da06d0Sopenharmony_ci return new ctor(); 8799da06d0Sopenharmony_ci } 8899da06d0Sopenharmony_ci 8999da06d0Sopenharmony_ci /** 9099da06d0Sopenharmony_ci * clone symbol 9199da06d0Sopenharmony_ci * 9299da06d0Sopenharmony_ci * @param { any } target 9399da06d0Sopenharmony_ci */ 9499da06d0Sopenharmony_ci private cloneSymbo(target) { 9599da06d0Sopenharmony_ci return Object(Symbol.prototype.valueOf.call(target)); 9699da06d0Sopenharmony_ci } 9799da06d0Sopenharmony_ci 9899da06d0Sopenharmony_ci /** 9999da06d0Sopenharmony_ci * clone reg 10099da06d0Sopenharmony_ci * 10199da06d0Sopenharmony_ci * @param { any } target 10299da06d0Sopenharmony_ci */ 10399da06d0Sopenharmony_ci private cloneRegister(target) { 10499da06d0Sopenharmony_ci const reFlags = /\w*$/; 10599da06d0Sopenharmony_ci const result = new target.constructor(target.source, reFlags.exec(target)); 10699da06d0Sopenharmony_ci result.lastIndex = target.lastIndex; 10799da06d0Sopenharmony_ci return result; 10899da06d0Sopenharmony_ci } 10999da06d0Sopenharmony_ci 11099da06d0Sopenharmony_ci /** 11199da06d0Sopenharmony_ci * clone function 11299da06d0Sopenharmony_ci * 11399da06d0Sopenharmony_ci * @param { function } func 11499da06d0Sopenharmony_ci */ 11599da06d0Sopenharmony_ci private cloneFunc(func) { 11699da06d0Sopenharmony_ci const bodyRegister = /(?<={)(.|\n)+(?=})/m; 11799da06d0Sopenharmony_ci const paramRegister = /(?<=\().+(?=\)\s+{)/; 11899da06d0Sopenharmony_ci const funcStr = func.toString(); 11999da06d0Sopenharmony_ci if (func.prototype) { 12099da06d0Sopenharmony_ci const param = paramRegister.exec(funcStr); 12199da06d0Sopenharmony_ci const bodys = bodyRegister.exec(funcStr); 12299da06d0Sopenharmony_ci if (bodys) { 12399da06d0Sopenharmony_ci if (param) { 12499da06d0Sopenharmony_ci const paramArray = param[0].split(','); 12599da06d0Sopenharmony_ci return new Function(...paramArray, bodys[0]); 12699da06d0Sopenharmony_ci } else { 12799da06d0Sopenharmony_ci return new Function(bodys[0]); 12899da06d0Sopenharmony_ci } 12999da06d0Sopenharmony_ci } else { 13099da06d0Sopenharmony_ci return null; 13199da06d0Sopenharmony_ci } 13299da06d0Sopenharmony_ci } else { 13399da06d0Sopenharmony_ci return eval(funcStr); 13499da06d0Sopenharmony_ci } 13599da06d0Sopenharmony_ci } 13699da06d0Sopenharmony_ci 13799da06d0Sopenharmony_ci /** 13899da06d0Sopenharmony_ci * clone other type 13999da06d0Sopenharmony_ci * 14099da06d0Sopenharmony_ci * @param { any } target 14199da06d0Sopenharmony_ci * 14299da06d0Sopenharmony_ci * @param { any } type - data type 14399da06d0Sopenharmony_ci */ 14499da06d0Sopenharmony_ci private cloneOtherType(target, type) { 14599da06d0Sopenharmony_ci const ctor = target.constructor; 14699da06d0Sopenharmony_ci switch (type) { 14799da06d0Sopenharmony_ci case boolType: 14899da06d0Sopenharmony_ci case numberType: 14999da06d0Sopenharmony_ci case stringType: 15099da06d0Sopenharmony_ci case errorType: 15199da06d0Sopenharmony_ci case dateType: 15299da06d0Sopenharmony_ci return new ctor(target); 15399da06d0Sopenharmony_ci case regexpType: 15499da06d0Sopenharmony_ci return this.cloneRegister(target); 15599da06d0Sopenharmony_ci case symbolType: 15699da06d0Sopenharmony_ci return this.cloneSymbo(target); 15799da06d0Sopenharmony_ci case funcType: 15899da06d0Sopenharmony_ci return this.cloneFunc(target); 15999da06d0Sopenharmony_ci default: 16099da06d0Sopenharmony_ci return null; 16199da06d0Sopenharmony_ci } 16299da06d0Sopenharmony_ci } 16399da06d0Sopenharmony_ci 16499da06d0Sopenharmony_ci /** 16599da06d0Sopenharmony_ci * clone 16699da06d0Sopenharmony_ci * 16799da06d0Sopenharmony_ci * @param { any } target 16899da06d0Sopenharmony_ci * 16999da06d0Sopenharmony_ci * @param { map } map 17099da06d0Sopenharmony_ci */ 17199da06d0Sopenharmony_ci public clone(target, map = new WeakMap()) { 17299da06d0Sopenharmony_ci if (!this.isObject(target)) { 17399da06d0Sopenharmony_ci return target; 17499da06d0Sopenharmony_ci } 17599da06d0Sopenharmony_ci 17699da06d0Sopenharmony_ci const type = this.getType(target); 17799da06d0Sopenharmony_ci let cloneTargets; 17899da06d0Sopenharmony_ci 17999da06d0Sopenharmony_ci if (Method.includes(deepType, type)) { 18099da06d0Sopenharmony_ci cloneTargets = this.getInit(target); 18199da06d0Sopenharmony_ci } else { 18299da06d0Sopenharmony_ci return this.cloneOtherType(target, type); 18399da06d0Sopenharmony_ci } 18499da06d0Sopenharmony_ci 18599da06d0Sopenharmony_ci if (map.get(target)) { 18699da06d0Sopenharmony_ci return map.get(target); 18799da06d0Sopenharmony_ci } 18899da06d0Sopenharmony_ci map.set(target, cloneTargets); 18999da06d0Sopenharmony_ci 19099da06d0Sopenharmony_ci if (type === setType) { 19199da06d0Sopenharmony_ci target.forEach((value) => { 19299da06d0Sopenharmony_ci cloneTargets.add(this.clone(value, map)); 19399da06d0Sopenharmony_ci }); 19499da06d0Sopenharmony_ci return cloneTargets; 19599da06d0Sopenharmony_ci } 19699da06d0Sopenharmony_ci 19799da06d0Sopenharmony_ci if (type === mapType) { 19899da06d0Sopenharmony_ci target.forEach((value, key) => { 19999da06d0Sopenharmony_ci cloneTargets.set(key, this.clone(value, map)); 20099da06d0Sopenharmony_ci }); 20199da06d0Sopenharmony_ci return cloneTargets; 20299da06d0Sopenharmony_ci } 20399da06d0Sopenharmony_ci 20499da06d0Sopenharmony_ci const keys = type === arrayType ? undefined : Object.keys(target); 20599da06d0Sopenharmony_ci this.forEach(keys || target, (value, key) => { 20699da06d0Sopenharmony_ci if (keys) { 20799da06d0Sopenharmony_ci key = value; 20899da06d0Sopenharmony_ci } 20999da06d0Sopenharmony_ci cloneTargets[key] = this.clone(target[key], map); 21099da06d0Sopenharmony_ci }); 21199da06d0Sopenharmony_ci 21299da06d0Sopenharmony_ci return cloneTargets; 21399da06d0Sopenharmony_ci } 21499da06d0Sopenharmony_ci}