Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add debug API for call stack selection changes (63943) #179132

Merged
merged 13 commits into from
Apr 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 24 additions & 1 deletion src/vs/workbench/api/browser/mainThreadDebugService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { URI as uri, UriComponents } from 'vs/base/common/uri';
import { IDebugService, IConfig, IDebugConfigurationProvider, IBreakpoint, IFunctionBreakpoint, IBreakpointData, IDebugAdapter, IDebugAdapterDescriptorFactory, IDebugSession, IDebugAdapterFactory, IDataBreakpoint, IDebugSessionOptions, IInstructionBreakpoint, DebugConfigurationProviderTriggerKind } from 'vs/workbench/contrib/debug/common/debug';
import {
ExtHostContext, ExtHostDebugServiceShape, MainThreadDebugServiceShape, DebugSessionUUID, MainContext,
IBreakpointsDeltaDto, ISourceMultiBreakpointDto, ISourceBreakpointDto, IFunctionBreakpointDto, IDebugSessionDto, IDataBreakpointDto, IStartDebuggingOptions, IDebugConfiguration
IBreakpointsDeltaDto, ISourceMultiBreakpointDto, ISourceBreakpointDto, IFunctionBreakpointDto, IDebugSessionDto, IDataBreakpointDto, IStartDebuggingOptions, IDebugConfiguration, IThreadFocusDto, IStackFrameFocusDto
} from 'vs/workbench/api/common/extHost.protocol';
import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers';
import severity from 'vs/base/common/severity';
Expand Down Expand Up @@ -56,6 +56,29 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb
this._debugConfigurationProviders = new Map();
this._debugAdapterDescriptorFactories = new Map();
this._sessions = new Set();

this._toDispose.add(this.debugService.getViewModel().onDidFocusThread(({ thread, explicit, session }) => {
if (session) {
const dto: IThreadFocusDto = {
kind: 'thread',
threadId: thread?.threadId,
sessionId: session!.getId(),
};
this._proxy.$acceptStackFrameFocus(dto);
}
}));

this._toDispose.add(this.debugService.getViewModel().onDidFocusStackFrame(({ stackFrame, explicit, session }) => {
if (session) {
const dto: IStackFrameFocusDto = {
kind: 'stackFrame',
threadId: stackFrame?.thread.threadId,
frameId: stackFrame?.frameId,
sessionId: session.getId(),
};
this._proxy.$acceptStackFrameFocus(dto);
}
}));
}

public dispose(): void {
Expand Down
6 changes: 6 additions & 0 deletions src/vs/workbench/api/common/extHost.api.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
get breakpoints() {
return extHostDebugService.breakpoints;
},
get stackFrameFocus() {
return extHostDebugService.stackFrameFocus;
},
onDidStartDebugSession(listener, thisArg?, disposables?) {
return extHostDebugService.onDidStartDebugSession(listener, thisArg, disposables);
},
Expand All @@ -1120,6 +1123,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
onDidChangeBreakpoints(listener, thisArgs?, disposables?) {
return extHostDebugService.onDidChangeBreakpoints(listener, thisArgs, disposables);
},
onDidChangeStackFrameFocus(listener, thisArg?, disposables?) {
return extHostDebugService.onDidChangeStackFrameFocus(listener, thisArg, disposables);
},
registerDebugConfigurationProvider(debugType: string, provider: vscode.DebugConfigurationProvider, triggerKind?: vscode.DebugConfigurationProviderTriggerKind) {
return extHostDebugService.registerDebugConfigurationProvider(debugType, provider, triggerKind || DebugConfigurationProviderTriggerKind.Initial);
},
Expand Down
15 changes: 15 additions & 0 deletions src/vs/workbench/api/common/extHost.protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2032,6 +2032,20 @@ export interface IDebugSessionFullDto {

export type IDebugSessionDto = IDebugSessionFullDto | DebugSessionUUID;

export interface IThreadFocusDto {
kind: 'thread';
sessionId: string;
threadId: number | undefined;
}

export interface IStackFrameFocusDto {
kind: 'stackFrame';
sessionId: string;
threadId: number | undefined;
frameId: number | undefined;
}


export interface ExtHostDebugServiceShape {
$substituteVariables(folder: UriComponents | undefined, config: IConfig): Promise<IConfig>;
$runInTerminal(args: DebugProtocol.RunInTerminalRequestArguments, sessionId: string): Promise<number | undefined>;
Expand All @@ -2048,6 +2062,7 @@ export interface ExtHostDebugServiceShape {
$acceptDebugSessionCustomEvent(session: IDebugSessionDto, event: any): void;
$acceptBreakpointsDelta(delta: IBreakpointsDeltaDto): void;
$acceptDebugSessionNameChanged(session: IDebugSessionDto, name: string): void;
$acceptStackFrameFocus(focus: IThreadFocusDto | IStackFrameFocusDto | undefined): void;
}


Expand Down
44 changes: 43 additions & 1 deletion src/vs/workbench/api/common/extHostDebugService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { ISignService } from 'vs/platform/sign/common/sign';
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { DebugSessionUUID, ExtHostDebugServiceShape, IBreakpointsDeltaDto, IDebugSessionDto, IFunctionBreakpointDto, ISourceMultiBreakpointDto, MainContext, MainThreadDebugServiceShape } from 'vs/workbench/api/common/extHost.protocol';
import { DebugSessionUUID, ExtHostDebugServiceShape, IBreakpointsDeltaDto, IThreadFocusDto, IStackFrameFocusDto, IDebugSessionDto, IFunctionBreakpointDto, ISourceMultiBreakpointDto, MainContext, MainThreadDebugServiceShape } from 'vs/workbench/api/common/extHost.protocol';
import { IExtHostEditorTabs } from 'vs/workbench/api/common/extHostEditorTabs';
import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
Expand Down Expand Up @@ -41,6 +41,8 @@ export interface IExtHostDebugService extends ExtHostDebugServiceShape {
onDidReceiveDebugSessionCustomEvent: Event<vscode.DebugSessionCustomEvent>;
onDidChangeBreakpoints: Event<vscode.BreakpointsChangeEvent>;
breakpoints: vscode.Breakpoint[];
onDidChangeStackFrameFocus: Event<vscode.ThreadFocus | vscode.StackFrameFocus | undefined>;
stackFrameFocus: vscode.ThreadFocus | vscode.StackFrameFocus | undefined;

addBreakpoints(breakpoints0: readonly vscode.Breakpoint[]): Promise<void>;
removeBreakpoints(breakpoints0: readonly vscode.Breakpoint[]): Promise<void>;
Expand Down Expand Up @@ -91,6 +93,9 @@ export abstract class ExtHostDebugServiceBase implements IExtHostDebugService, E

private readonly _onDidChangeBreakpoints: Emitter<vscode.BreakpointsChangeEvent>;

private _stackFrameFocus: vscode.ThreadFocus | vscode.StackFrameFocus | undefined;
private readonly _onDidChangeStackFrameFocus: Emitter<vscode.ThreadFocus | vscode.StackFrameFocus | undefined>;

private _debugAdapters: Map<number, IDebugAdapter>;
private _debugAdaptersTrackers: Map<number, vscode.DebugAdapterTracker>;

Expand Down Expand Up @@ -129,6 +134,8 @@ export abstract class ExtHostDebugServiceBase implements IExtHostDebugService, E
}
});

this._onDidChangeStackFrameFocus = new Emitter<vscode.ThreadFocus | vscode.StackFrameFocus | undefined>();

this._activeDebugConsole = new ExtHostDebugConsole(this._debugServiceProxy);

this._breakpoints = new Map<string, vscode.Breakpoint>();
Expand Down Expand Up @@ -190,6 +197,15 @@ export abstract class ExtHostDebugServiceBase implements IExtHostDebugService, E

// extension debug API


get stackFrameFocus(): vscode.ThreadFocus | vscode.StackFrameFocus | undefined {
return this._stackFrameFocus;
}

get onDidChangeStackFrameFocus(): Event<vscode.ThreadFocus | vscode.StackFrameFocus | undefined> {
return this._onDidChangeStackFrameFocus.event;
}

get onDidChangeBreakpoints(): Event<vscode.BreakpointsChangeEvent> {
return this._onDidChangeBreakpoints.event;
}
Expand Down Expand Up @@ -584,6 +600,32 @@ export abstract class ExtHostDebugServiceBase implements IExtHostDebugService, E
this.fireBreakpointChanges(a, r, c);
}

public async $acceptStackFrameFocus(focusDto: IThreadFocusDto | IStackFrameFocusDto): Promise<void> {
let focus: vscode.ThreadFocus | vscode.StackFrameFocus;
const session = focusDto.sessionId ? await this.getSession(focusDto.sessionId) : undefined;
if (!session) {
throw new Error('no DebugSession found for debug focus context');
}

if (focusDto.kind === 'thread') {
focus = {
kind: focusDto.kind,
threadId: focusDto.threadId,
session,
};
} else {
focus = {
kind: focusDto.kind,
threadId: focusDto.threadId,
frameId: focusDto.frameId,
session,
};
}

this._stackFrameFocus = focus;
this._onDidChangeStackFrameFocus.fire(focus);
}

public $provideDebugConfigurations(configProviderHandle: number, folderUri: UriComponents | undefined, token: CancellationToken): Promise<vscode.DebugConfiguration[]> {
return asPromise(async () => {
const provider = this.getConfigProviderByHandle(configProviderHandle);
Expand Down
3 changes: 2 additions & 1 deletion src/vs/workbench/contrib/debug/common/debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,8 @@ export interface IViewModel extends ITreeElement {
isMultiSessionView(): boolean;

onDidFocusSession: Event<IDebugSession | undefined>;
onDidFocusStackFrame: Event<{ stackFrame: IStackFrame | undefined; explicit: boolean }>;
onDidFocusThread: Event<{ thread: IThread | undefined; explicit: boolean; session: IDebugSession | undefined }>;
onDidFocusStackFrame: Event<{ stackFrame: IStackFrame | undefined; explicit: boolean; session: IDebugSession | undefined }>;
onDidSelectExpression: Event<{ expression: IExpression; settingWatch: boolean } | undefined>;
onDidEvaluateLazyExpression: Event<IExpressionContainer>;
onWillUpdateViews: Event<void>;
Expand Down
17 changes: 14 additions & 3 deletions src/vs/workbench/contrib/debug/common/debugViewModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ export class ViewModel implements IViewModel {
private _focusedThread: IThread | undefined;
private selectedExpression: { expression: IExpression; settingWatch: boolean } | undefined;
private readonly _onDidFocusSession = new Emitter<IDebugSession | undefined>();
private readonly _onDidFocusStackFrame = new Emitter<{ stackFrame: IStackFrame | undefined; explicit: boolean }>();
private readonly _onDidFocusThread = new Emitter<{ thread: IThread | undefined; explicit: boolean; session: IDebugSession | undefined }>();
private readonly _onDidFocusStackFrame = new Emitter<{ stackFrame: IStackFrame | undefined; explicit: boolean; session: IDebugSession | undefined }>();
private readonly _onDidSelectExpression = new Emitter<{ expression: IExpression; settingWatch: boolean } | undefined>();
private readonly _onDidEvaluateLazyExpression = new Emitter<IExpressionContainer>();
private readonly _onWillUpdateViews = new Emitter<void>();
Expand Down Expand Up @@ -74,6 +75,8 @@ export class ViewModel implements IViewModel {
setFocus(stackFrame: IStackFrame | undefined, thread: IThread | undefined, session: IDebugSession | undefined, explicit: boolean): void {
const shouldEmitForStackFrame = this._focusedStackFrame !== stackFrame;
const shouldEmitForSession = this._focusedSession !== session;
const shouldEmitForThread = this._focusedThread !== thread;


this._focusedStackFrame = stackFrame;
this._focusedThread = thread;
Expand All @@ -98,16 +101,24 @@ export class ViewModel implements IViewModel {
if (shouldEmitForSession) {
this._onDidFocusSession.fire(session);
}

// should not call onDidFocusThread if onDidFocusStackFrame is called.
if (shouldEmitForStackFrame) {
this._onDidFocusStackFrame.fire({ stackFrame, explicit });
this._onDidFocusStackFrame.fire({ stackFrame, explicit, session });
} else if (shouldEmitForThread) {
this._onDidFocusThread.fire({ thread, explicit, session });
}
}

get onDidFocusSession(): Event<IDebugSession | undefined> {
return this._onDidFocusSession.event;
}

get onDidFocusStackFrame(): Event<{ stackFrame: IStackFrame | undefined; explicit: boolean }> {
get onDidFocusThread(): Event<{ thread: IThread | undefined; explicit: boolean; session: IDebugSession | undefined }> {
return this._onDidFocusThread.event;
}

get onDidFocusStackFrame(): Event<{ stackFrame: IStackFrame | undefined; explicit: boolean; session: IDebugSession | undefined }> {
return this._onDidFocusStackFrame.event;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const allApiProposals = Object.freeze({
contribViewsRemote: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribViewsRemote.d.ts',
contribViewsWelcome: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribViewsWelcome.d.ts',
customEditorMove: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.customEditorMove.d.ts',
debugFocus: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.debugFocus.d.ts',
diffCommand: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.diffCommand.d.ts',
diffContentOptions: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.diffContentOptions.d.ts',
documentFiltersExclusive: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.documentFiltersExclusive.d.ts',
Expand Down
55 changes: 55 additions & 0 deletions src/vscode-dts/vscode.proposed.debugFocus.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

declare module 'vscode' {

// See https://github.com/microsoft/vscode/issues/63943

export interface ThreadFocus {
kind: 'thread';

/**
* Debug session for thread.
*/
readonly session: DebugSession;

/**
* Id of the associated thread (DAP id). May be undefined if thread has become unselected.
*/
readonly threadId: number | undefined;
}

export interface StackFrameFocus {
kind: 'stackFrame';

/**
* Debug session for thread.
*/
readonly session: DebugSession;

/**
* Id of the associated thread (DAP id). May be undefined if a frame is unselected.
*/
readonly threadId: number | undefined;
/**
* Id of the stack frame (DAP id). May be undefined if a frame is unselected.
*/
readonly frameId: number | undefined;
}


export namespace debug {
/**
* The currently focused thread or stack frame id, or `undefined` if this has not been set. (e.g. not in debug mode).
*/
export let stackFrameFocus: ThreadFocus | StackFrameFocus | undefined;

/**
* An {@link Event} which fires when the {@link debug.stackFrameFocus} changes. Provides a sessionId. threadId is not undefined
* when a thread of frame has gained focus. frameId is defined when a stackFrame has gained focus.
*/
export const onDidChangeStackFrameFocus: Event<ThreadFocus | StackFrameFocus | undefined>;
}
}