From 90f459ac8c49bb88a09ec5512300c582ce041da6 Mon Sep 17 00:00:00 2001 From: Remi Schnekenburger Date: Tue, 25 Apr 2023 23:40:04 +0200 Subject: [PATCH] fix review comments --- packages/core/src/common/objects.ts | 49 ++++++++++- packages/core/src/common/telemetry.ts | 1 - .../plugin-ext/src/common/plugin-api-rpc.ts | 1 - .../plugin-ext/src/plugin/telemetry-ext.ts | 84 ++----------------- 4 files changed, 53 insertions(+), 82 deletions(-) diff --git a/packages/core/src/common/objects.ts b/packages/core/src/common/objects.ts index 0e7859614faa8..a63fca5909040 100644 --- a/packages/core/src/common/objects.ts +++ b/packages/core/src/common/objects.ts @@ -14,7 +14,7 @@ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 // ***************************************************************************** -import { isObject } from './types'; +import { isObject, isUndefined } from './types'; export function deepClone(obj: T): T { if (!isObject(obj)) { @@ -70,3 +70,50 @@ export function notEmpty(arg: T | undefined | null): arg is T { export function isEmpty(arg: Object): boolean { return Object.keys(arg).length === 0 && arg.constructor === Object; } + +// copied and modified from https://github.com/microsoft/vscode/blob/1.76.0/src/vs/base/common/objects.ts#L45-L83 +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function cloneAndChange(obj: any, changer: (orig: any) => any, seen: Set): any { + // impossible to clone an undefined or null object + // eslint-disable-next-line no-null/no-null + if (isUndefined(obj) || obj === null) { + return obj; + } + + const changed = changer(obj); + if (!isUndefined(changed)) { + return changed; + } + + if (Array.isArray(obj)) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const r1: any[] = []; + 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)) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (r2 as any)[i2] = cloneAndChange(obj[i2], changer, seen); + } + } + seen.delete(obj); + return r2; + } + + return obj; +} diff --git a/packages/core/src/common/telemetry.ts b/packages/core/src/common/telemetry.ts index ae10429380784..3b143957fc280 100644 --- a/packages/core/src/common/telemetry.ts +++ b/packages/core/src/common/telemetry.ts @@ -42,5 +42,4 @@ interface TelemetrySender { } interface TelemetryLoggerOptions { - } diff --git a/packages/plugin-ext/src/common/plugin-api-rpc.ts b/packages/plugin-ext/src/common/plugin-api-rpc.ts index 80bc2d042cea2..670b927074a51 100644 --- a/packages/plugin-ext/src/common/plugin-api-rpc.ts +++ b/packages/plugin-ext/src/common/plugin-api-rpc.ts @@ -2079,7 +2079,6 @@ export interface TabsMain { } export interface TelemetryMain { - } export interface TelemetryExt { diff --git a/packages/plugin-ext/src/plugin/telemetry-ext.ts b/packages/plugin-ext/src/plugin/telemetry-ext.ts index 0243f592e1f44..c83f2ec487d2d 100644 --- a/packages/plugin-ext/src/plugin/telemetry-ext.ts +++ b/packages/plugin-ext/src/plugin/telemetry-ext.ts @@ -12,7 +12,10 @@ // https://www.gnu.org/software/classpath/license.html. // // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + import { Event, Emitter } from '@theia/core/lib/common/event'; +import { cloneAndChange } from '@theia/core'; +import { mixin } from '../common/types'; import { TelemetryTrustedValue, TelemetryLoggerOptions } from './types-impl'; export class TelemetryExtImpl { @@ -174,6 +177,7 @@ function mixInCommonPropsAndCleanData(data: Record, additionalPrope * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ + /** * Cleans a given stack of possible paths * @param stack The stack to sanitize @@ -214,7 +218,7 @@ function anonymizeFilePaths(stack: string, cleanupPatterns: RegExp[]): string { // Check to see if the any cleanupIndexes partially overlap with this match const overlappingRange = cleanUpIndexes.some(([start, end]) => result.index < end && start < fileRegex.lastIndex); - // anoynimize user file paths that do not need to be retained or cleaned up. + // anonymize user file paths that do not need to be retained or cleaned up. if (!nodeModulesRegex.test(result[0]) && !overlappingRange) { updatedStack += stack.substring(lastIndex, result.index) + ''; lastIndex = fileRegex.lastIndex; @@ -293,81 +297,3 @@ export function cleanData(data: Record, cleanUpPatterns: RegExp[]): }, new Set()); } -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function cloneAndChange(obj: any, changer: (orig: any) => any, seen: Set): any { - // impossible to clone a null or undefined object - if (isUndefined(obj) || obj === null) { - return obj; - } - - const changed = changer(obj); - if (!isUndefined(changed)) { - return changed; - } - - if (Array.isArray(obj)) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const r1: any[] = []; - 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 (Object.prototype.hasOwnProperty.call(obj, i2)) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (r2 as any)[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). - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export function mixin(destination: any, source: any, overwrite: boolean = true): any { - 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; -} - -type UnknownObject = Record & { [K in keyof T]: unknown }; - -export function isObject(value: unknown): value is UnknownObject { - // eslint-disable-next-line no-null/no-null - return typeof value === 'object' && value !== null; -} - -export function isUndefined(value: unknown): value is undefined { - return typeof value === 'undefined'; -}