Path: blob/main/extensions/copilot/src/util/vs/base/common/observableInternal/debugName.ts
13406 views
//!!! DO NOT modify, this file was COPIED from 'microsoft/vscode'12/*---------------------------------------------------------------------------------------------3* Copyright (c) Microsoft Corporation. All rights reserved.4* Licensed under the MIT License. See License.txt in the project root for license information.5*--------------------------------------------------------------------------------------------*/67export interface IDebugNameData {8/**9* The owner object of an observable.10* Used for debugging only, such as computing a name for the observable by iterating over the fields of the owner.11*/12readonly owner?: DebugOwner | undefined;1314/**15* A string or function that returns a string that represents the name of the observable.16* Used for debugging only.17*/18readonly debugName?: DebugNameSource | undefined;1920/**21* A function that points to the defining function of the object.22* Used for debugging only.23*/24readonly debugReferenceFn?: Function | undefined;25}2627export class DebugNameData {28constructor(29public readonly owner: DebugOwner | undefined,30public readonly debugNameSource: DebugNameSource | undefined,31public readonly referenceFn: Function | undefined,32) { }3334public getDebugName(target: object): string | undefined {35return getDebugName(target, this);36}37}3839/**40* The owning object of an observable.41* Is only used for debugging purposes, such as computing a name for the observable by iterating over the fields of the owner.42*/43export type DebugOwner = object | undefined;44export type DebugNameSource = string | (() => string | undefined);4546const countPerName = new Map<string, number>();47const cachedDebugName = new WeakMap<object, string>();4849export function getDebugName(target: object, data: DebugNameData): string | undefined {50const cached = cachedDebugName.get(target);51if (cached) {52return cached;53}5455const dbgName = computeDebugName(target, data);56if (dbgName) {57let count = countPerName.get(dbgName) ?? 0;58count++;59countPerName.set(dbgName, count);60const result = count === 1 ? dbgName : `${dbgName}#${count}`;61cachedDebugName.set(target, result);62return result;63}64return undefined;65}6667function computeDebugName(self: object, data: DebugNameData): string | undefined {68const cached = cachedDebugName.get(self);69if (cached) {70return cached;71}7273const ownerStr = data.owner ? formatOwner(data.owner) + `.` : '';7475let result: string | undefined;76const debugNameSource = data.debugNameSource;77if (debugNameSource !== undefined) {78if (typeof debugNameSource === 'function') {79result = debugNameSource();80if (result !== undefined) {81return ownerStr + result;82}83} else {84return ownerStr + debugNameSource;85}86}8788const referenceFn = data.referenceFn;89if (referenceFn !== undefined) {90result = getFunctionName(referenceFn);91if (result !== undefined) {92return ownerStr + result;93}94}9596if (data.owner !== undefined) {97const key = findKey(data.owner, self);98if (key !== undefined) {99return ownerStr + key;100}101}102return undefined;103}104105function findKey(obj: object, value: object): string | undefined {106for (const key in obj) {107if ((obj as Record<string, unknown>)[key] === value) {108return key;109}110}111return undefined;112}113114const countPerClassName = new Map<string, number>();115const ownerId = new WeakMap<object, string>();116117function formatOwner(owner: object): string {118const id = ownerId.get(owner);119if (id) {120return id;121}122const className = getClassName(owner) ?? 'Object';123let count = countPerClassName.get(className) ?? 0;124count++;125countPerClassName.set(className, count);126const result = count === 1 ? className : `${className}#${count}`;127ownerId.set(owner, result);128return result;129}130131export function getClassName(obj: object): string | undefined {132const ctor = obj.constructor;133if (ctor) {134if (ctor.name === 'Object') {135return undefined;136}137return ctor.name;138}139return undefined;140}141142export function getFunctionName(fn: Function): string | undefined {143const fnSrc = fn.toString();144// Pattern: /** @description ... */145const regexp = /\/\*\*\s*@description\s*([^*]*)\*\//;146const match = regexp.exec(fnSrc);147const result = match ? match[1] : undefined;148return result?.trim();149}150151152