Path: blob/main/src/vs/workbench/contrib/debug/common/debugStorage.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Disposable } from '../../../../base/common/lifecycle.js';6import { ISettableObservable, observableValue } from '../../../../base/common/observable.js';7import { URI } from '../../../../base/common/uri.js';8import { ILogService } from '../../../../platform/log/common/log.js';9import { IStorageService, StorageScope, StorageTarget } from '../../../../platform/storage/common/storage.js';10import { IUriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentity.js';11import { IDebugModel, IEvaluate, IExpression } from './debug.js';12import { Breakpoint, DataBreakpoint, ExceptionBreakpoint, Expression, FunctionBreakpoint } from './debugModel.js';13import { ITextFileService } from '../../../services/textfile/common/textfiles.js';14import { mapValues } from '../../../../base/common/objects.js';1516const DEBUG_BREAKPOINTS_KEY = 'debug.breakpoint';17const DEBUG_FUNCTION_BREAKPOINTS_KEY = 'debug.functionbreakpoint';18const DEBUG_DATA_BREAKPOINTS_KEY = 'debug.databreakpoint';19const DEBUG_EXCEPTION_BREAKPOINTS_KEY = 'debug.exceptionbreakpoint';20const DEBUG_WATCH_EXPRESSIONS_KEY = 'debug.watchexpressions';21const DEBUG_CHOSEN_ENVIRONMENTS_KEY = 'debug.chosenenvironment';22const DEBUG_UX_STATE_KEY = 'debug.uxstate';2324export interface IChosenEnvironment {25type: string;26dynamicLabel?: string;27}2829export class DebugStorage extends Disposable {30public readonly breakpoints: ISettableObservable<Breakpoint[]>;31public readonly functionBreakpoints: ISettableObservable<FunctionBreakpoint[]>;32public readonly exceptionBreakpoints: ISettableObservable<ExceptionBreakpoint[]>;33public readonly dataBreakpoints: ISettableObservable<DataBreakpoint[]>;34public readonly watchExpressions: ISettableObservable<Expression[]>;3536constructor(37@IStorageService private readonly storageService: IStorageService,38@ITextFileService private readonly textFileService: ITextFileService,39@IUriIdentityService private readonly uriIdentityService: IUriIdentityService,40@ILogService private readonly logService: ILogService41) {42super();43this.breakpoints = observableValue(this, this.loadBreakpoints());44this.functionBreakpoints = observableValue(this, this.loadFunctionBreakpoints());45this.exceptionBreakpoints = observableValue(this, this.loadExceptionBreakpoints());46this.dataBreakpoints = observableValue(this, this.loadDataBreakpoints());47this.watchExpressions = observableValue(this, this.loadWatchExpressions());4849this._register(storageService.onDidChangeValue(StorageScope.WORKSPACE, undefined, this._store)(e => {50if (e.external) {51switch (e.key) {52case DEBUG_BREAKPOINTS_KEY:53return this.breakpoints.set(this.loadBreakpoints(), undefined);54case DEBUG_FUNCTION_BREAKPOINTS_KEY:55return this.functionBreakpoints.set(this.loadFunctionBreakpoints(), undefined);56case DEBUG_EXCEPTION_BREAKPOINTS_KEY:57return this.exceptionBreakpoints.set(this.loadExceptionBreakpoints(), undefined);58case DEBUG_DATA_BREAKPOINTS_KEY:59return this.dataBreakpoints.set(this.loadDataBreakpoints(), undefined);60case DEBUG_WATCH_EXPRESSIONS_KEY:61return this.watchExpressions.set(this.loadWatchExpressions(), undefined);62}63}64}));65}6667loadDebugUxState(): 'simple' | 'default' {68return this.storageService.get(DEBUG_UX_STATE_KEY, StorageScope.WORKSPACE, 'default') as 'simple' | 'default';69}7071storeDebugUxState(value: 'simple' | 'default'): void {72this.storageService.store(DEBUG_UX_STATE_KEY, value, StorageScope.WORKSPACE, StorageTarget.MACHINE);73}7475private loadBreakpoints(): Breakpoint[] {76let result: Breakpoint[] | undefined;77try {78result = JSON.parse(this.storageService.get(DEBUG_BREAKPOINTS_KEY, StorageScope.WORKSPACE, '[]')).map((breakpoint: ReturnType<Breakpoint['toJSON']>) => {79breakpoint.uri = URI.revive(breakpoint.uri);80return new Breakpoint(breakpoint, this.textFileService, this.uriIdentityService, this.logService, breakpoint.id);81});82} catch (e) { }8384return result || [];85}8687private loadFunctionBreakpoints(): FunctionBreakpoint[] {88let result: FunctionBreakpoint[] | undefined;89try {90result = JSON.parse(this.storageService.get(DEBUG_FUNCTION_BREAKPOINTS_KEY, StorageScope.WORKSPACE, '[]')).map((fb: ReturnType<FunctionBreakpoint['toJSON']>) => {91return new FunctionBreakpoint(fb, fb.id);92});93} catch (e) { }9495return result || [];96}9798private loadExceptionBreakpoints(): ExceptionBreakpoint[] {99let result: ExceptionBreakpoint[] | undefined;100try {101result = JSON.parse(this.storageService.get(DEBUG_EXCEPTION_BREAKPOINTS_KEY, StorageScope.WORKSPACE, '[]')).map((exBreakpoint: ReturnType<ExceptionBreakpoint['toJSON']>) => {102return new ExceptionBreakpoint(exBreakpoint, exBreakpoint.id);103});104} catch (e) { }105106return result || [];107}108109private loadDataBreakpoints(): DataBreakpoint[] {110let result: DataBreakpoint[] | undefined;111try {112result = JSON.parse(this.storageService.get(DEBUG_DATA_BREAKPOINTS_KEY, StorageScope.WORKSPACE, '[]')).map((dbp: ReturnType<DataBreakpoint['toJSON']>) => {113return new DataBreakpoint(dbp, dbp.id);114});115} catch (e) { }116117return result || [];118}119120private loadWatchExpressions(): Expression[] {121let result: Expression[] | undefined;122try {123result = JSON.parse(this.storageService.get(DEBUG_WATCH_EXPRESSIONS_KEY, StorageScope.WORKSPACE, '[]')).map((watchStoredData: { name: string; id: string }) => {124return new Expression(watchStoredData.name, watchStoredData.id);125});126} catch (e) { }127128return result || [];129}130131loadChosenEnvironments(): Record<string, IChosenEnvironment> {132const obj = JSON.parse(this.storageService.get(DEBUG_CHOSEN_ENVIRONMENTS_KEY, StorageScope.WORKSPACE, '{}'));133// back compat from when this was a string map:134return mapValues(obj, (value): IChosenEnvironment => typeof value === 'string' ? { type: value } : value);135}136137storeChosenEnvironments(environments: Record<string, IChosenEnvironment>): void {138this.storageService.store(DEBUG_CHOSEN_ENVIRONMENTS_KEY, JSON.stringify(environments), StorageScope.WORKSPACE, StorageTarget.MACHINE);139}140141storeWatchExpressions(watchExpressions: (IExpression & IEvaluate)[]): void {142if (watchExpressions.length) {143this.storageService.store(DEBUG_WATCH_EXPRESSIONS_KEY, JSON.stringify(watchExpressions.map(we => ({ name: we.name, id: we.getId() }))), StorageScope.WORKSPACE, StorageTarget.MACHINE);144} else {145this.storageService.remove(DEBUG_WATCH_EXPRESSIONS_KEY, StorageScope.WORKSPACE);146}147}148149storeBreakpoints(debugModel: IDebugModel): void {150const breakpoints = debugModel.getBreakpoints();151if (breakpoints.length) {152this.storageService.store(DEBUG_BREAKPOINTS_KEY, JSON.stringify(breakpoints), StorageScope.WORKSPACE, StorageTarget.MACHINE);153} else {154this.storageService.remove(DEBUG_BREAKPOINTS_KEY, StorageScope.WORKSPACE);155}156157const functionBreakpoints = debugModel.getFunctionBreakpoints();158if (functionBreakpoints.length) {159this.storageService.store(DEBUG_FUNCTION_BREAKPOINTS_KEY, JSON.stringify(functionBreakpoints), StorageScope.WORKSPACE, StorageTarget.MACHINE);160} else {161this.storageService.remove(DEBUG_FUNCTION_BREAKPOINTS_KEY, StorageScope.WORKSPACE);162}163164const dataBreakpoints = debugModel.getDataBreakpoints().filter(dbp => dbp.canPersist);165if (dataBreakpoints.length) {166this.storageService.store(DEBUG_DATA_BREAKPOINTS_KEY, JSON.stringify(dataBreakpoints), StorageScope.WORKSPACE, StorageTarget.MACHINE);167} else {168this.storageService.remove(DEBUG_DATA_BREAKPOINTS_KEY, StorageScope.WORKSPACE);169}170171const exceptionBreakpoints = debugModel.getExceptionBreakpoints();172if (exceptionBreakpoints.length) {173this.storageService.store(DEBUG_EXCEPTION_BREAKPOINTS_KEY, JSON.stringify(exceptionBreakpoints), StorageScope.WORKSPACE, StorageTarget.MACHINE);174} else {175this.storageService.remove(DEBUG_EXCEPTION_BREAKPOINTS_KEY, StorageScope.WORKSPACE);176}177}178}179180181