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

[vscode] Implement stubbed API for activeStackFrame API #13900

Merged
merged 1 commit into from
Jul 25, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- [core] introduce `FRONTEND_CONNECTION_TIMEOUT` environment variable to override application connexion settings. [#13936](https://github.com/eclipse-theia/theia/pull/13936) - Contributed on behalf of STMicroelectronics
- [core] tab selected should be adjacent when closing last one [#13912](https://github.com/eclipse-theia/theia/pull/13912) - contributed on behalf of STMicroelectronics
- [core] upgraded ws to 8.18.0 [#13903](https://github.com/eclipse-theia/theia/pull/13903) - contributed on behalf of STMicroelectronics
- [debug] implement activeStackItem and related change event in debug namespace [#13900](https://github.com/eclipse-theia/theia/pull/13900) - contributed on behalf of STMicroelectronics

<a name="breaking_changes_not_yet_released">[Breaking Changes:](#breaking_changes_not_yet_released)</a>

Expand Down
15 changes: 8 additions & 7 deletions packages/debug/src/browser/debug-session-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,6 @@ export interface DidChangeBreakpointsEvent {
uri: URI
}

export interface DidFocusStackFrameEvent {
session: DebugSession;
frame: DebugStackFrame | undefined;
}

export interface DebugSessionCustomEvent {
readonly body?: any // eslint-disable-line @typescript-eslint/no-explicit-any
readonly event: string
Expand Down Expand Up @@ -94,9 +89,12 @@ export class DebugSessionManager {
protected readonly onDidReceiveDebugSessionCustomEventEmitter = new Emitter<DebugSessionCustomEvent>();
readonly onDidReceiveDebugSessionCustomEvent: Event<DebugSessionCustomEvent> = this.onDidReceiveDebugSessionCustomEventEmitter.event;

protected readonly onDidFocusStackFrameEmitter = new Emitter<DidFocusStackFrameEvent>();
protected readonly onDidFocusStackFrameEmitter = new Emitter<DebugStackFrame | undefined>();
readonly onDidFocusStackFrame = this.onDidFocusStackFrameEmitter.event;

protected readonly onDidFocusThreadEmitter = new Emitter<DebugThread | undefined>();
readonly onDidFocusThread = this.onDidFocusThreadEmitter.event;

protected readonly onDidChangeBreakpointsEmitter = new Emitter<DidChangeBreakpointsEvent>();
readonly onDidChangeBreakpoints = this.onDidChangeBreakpointsEmitter.event;
protected fireDidChangeBreakpoints(event: DidChangeBreakpointsEvent): void {
Expand Down Expand Up @@ -518,7 +516,10 @@ export class DebugSessionManager {
}
this.fireDidChange(current);
}));
this.disposeOnCurrentSessionChanged.push(current.onDidFocusStackFrame(frame => this.onDidFocusStackFrameEmitter.fire({ session: current, frame })));
this.disposeOnCurrentSessionChanged.push(current.onDidFocusStackFrame(frame => this.onDidFocusStackFrameEmitter.fire(frame)));
this.disposeOnCurrentSessionChanged.push(current.onDidFocusThread(thread => this.onDidFocusThreadEmitter.fire(thread)));
const { currentThread } = current;
this.onDidFocusThreadEmitter.fire(currentThread);
}
this.updateBreakpoints(previous, current);
this.open();
Expand Down
9 changes: 9 additions & 0 deletions packages/debug/src/browser/debug-session.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ export class DebugSession implements CompositeTreeElement {
return this.onDidFocusStackFrameEmitter.event;
}

protected readonly onDidFocusThreadEmitter = new Emitter<DebugThread | undefined>();
get onDidFocusThread(): Event<DebugThread | undefined> {
return this.onDidFocusThreadEmitter.event;
}

protected readonly onDidChangeBreakpointsEmitter = new Emitter<URI>();
readonly onDidChangeBreakpoints: Event<URI> = this.onDidChangeBreakpointsEmitter.event;
protected fireDidChangeBreakpoints(uri: URI): void {
Expand Down Expand Up @@ -254,8 +259,12 @@ export class DebugSession implements CompositeTreeElement {
return this._currentThread;
}
set currentThread(thread: DebugThread | undefined) {
if (this._currentThread?.id === thread?.id) {
return;
}
this.toDisposeOnCurrentThread.dispose();
this._currentThread = thread;
this.onDidFocusThreadEmitter.fire(thread);
this.fireDidChange();
if (thread) {
this.toDisposeOnCurrentThread.push(thread.onDidChanged(() => this.fireDidChange()));
Expand Down
7 changes: 7 additions & 0 deletions packages/debug/src/browser/model/debug-stack-frame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ export class DebugStackFrame extends DebugStackFrameData implements TreeElement
return this.session.id + ':' + this.thread.id + ':' + this.raw.id;
}

/**
* Returns the frame identifier from the debug protocol.
*/
get frameId(): number {
return this.raw.id;
}

protected _source: DebugSource | undefined;
get source(): DebugSource | undefined {
return this._source;
Expand Down
7 changes: 7 additions & 0 deletions packages/debug/src/browser/model/debug-thread.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,18 @@ export class DebugThread extends DebugThreadData implements TreeElement {
return this.session.id + ':' + this.raw.id;
}

get threadId(): number {
return this.raw.id;
}

protected _currentFrame: DebugStackFrame | undefined;
get currentFrame(): DebugStackFrame | undefined {
return this._currentFrame;
}
set currentFrame(frame: DebugStackFrame | undefined) {
if (this._currentFrame?.id === frame?.id) {
return;
}
this._currentFrame = frame;
this.onDidChangedEmitter.fire(undefined);
this.onDidFocusStackFrameEmitter.fire(frame);
Expand Down
1 change: 1 addition & 0 deletions packages/debug/src/browser/view/debug-threads-widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ export class DebugThreadsWidget extends SourceTreeWidget {
this.viewModel.currentSession = node.element;
this.debugCallStackItemTypeKey.set('session');
} else if (node.element instanceof DebugThread) {
this.viewModel.currentSession = node.element.session;
node.element.session.currentThread = node.element;
this.debugCallStackItemTypeKey.set('thread');
}
Expand Down
10 changes: 10 additions & 0 deletions packages/plugin-ext/src/common/plugin-api-rpc-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -895,3 +895,13 @@ export interface InlineCompletionsProvider<T extends InlineCompletions = InlineC
freeInlineCompletions(completions: T): void;
}

export interface DebugStackFrameDTO {
readonly sessionId: string,
readonly frameId: number,
readonly threadId: number
}

export interface DebugThreadDTO {
readonly sessionId: string,
readonly threadId: number
}
6 changes: 5 additions & 1 deletion packages/plugin-ext/src/common/plugin-api-rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ import {
InlineCompletionContext,
DocumentDropEdit,
DataTransferDTO,
DocumentDropEditProviderMetadata
DocumentDropEditProviderMetadata,
DebugStackFrameDTO,
DebugThreadDTO
} from './plugin-api-rpc-model';
import { ExtPluginApi } from './plugin-ext-api-contribution';
import { KeysToAnyValues, KeysToKeysToAnyValue } from './types';
Expand Down Expand Up @@ -1981,6 +1983,8 @@ export interface DebugExt {
debugConfiguration: DebugConfiguration
): Promise<theia.DebugConfiguration | undefined | null>;

$onDidChangeActiveFrame(frame: DebugStackFrameDTO | undefined): void;
$onDidChangeActiveThread(thread: DebugThreadDTO | undefined): void;
$createDebugSession(debugConfiguration: DebugConfiguration, workspaceFolder: string | undefined): Promise<string>;
$terminateDebugSession(sessionId: string): Promise<void>;
$getTerminalCreationOptions(debugType: string): Promise<TerminalOptionsExt | undefined>;
Expand Down
23 changes: 21 additions & 2 deletions packages/plugin-ext/src/main/browser/debug/debug-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
MAIN_RPC_CONTEXT
} from '../../../common/plugin-api-rpc';
import { DebugSessionManager } from '@theia/debug/lib/browser/debug-session-manager';
import { Breakpoint, WorkspaceFolder } from '../../../common/plugin-api-rpc-model';
import { Breakpoint, DebugStackFrameDTO, DebugThreadDTO, WorkspaceFolder } from '../../../common/plugin-api-rpc-model';
import { LabelProvider } from '@theia/core/lib/browser';
import { EditorManager } from '@theia/editor/lib/browser';
import { BreakpointManager, BreakpointsChangeEvent } from '@theia/debug/lib/browser/breakpoint/breakpoint-manager';
Expand Down Expand Up @@ -56,6 +56,8 @@ import { DebugContribution } from '@theia/debug/lib/browser/debug-contribution';
import { ConnectionImpl } from '../../../common/connection';
import { WorkspaceService } from '@theia/workspace/lib/browser';
import { DebugSessionOptions as TheiaDebugSessionOptions } from '@theia/debug/lib/browser/debug-session-options';
import { DebugStackFrame } from '@theia/debug/lib/browser/model/debug-stack-frame';
import { DebugThread } from '@theia/debug/lib/browser/model/debug-thread';

export class DebugMainImpl implements DebugMain, Disposable {
private readonly debugExt: DebugExt;
Expand Down Expand Up @@ -117,7 +119,9 @@ export class DebugMainImpl implements DebugMain, Disposable {
this.sessionManager.onDidStartDebugSession(debugSession => this.debugExt.$sessionDidStart(debugSession.id)),
this.sessionManager.onDidDestroyDebugSession(debugSession => this.debugExt.$sessionDidDestroy(debugSession.id)),
this.sessionManager.onDidChangeActiveDebugSession(event => this.debugExt.$sessionDidChange(event.current && event.current.id)),
this.sessionManager.onDidReceiveDebugSessionCustomEvent(event => this.debugExt.$onSessionCustomEvent(event.session.id, event.event, event.body))
this.sessionManager.onDidReceiveDebugSessionCustomEvent(event => this.debugExt.$onSessionCustomEvent(event.session.id, event.event, event.body)),
this.sessionManager.onDidFocusStackFrame(stackFrame => this.debugExt.$onDidChangeActiveFrame(this.toDebugStackFrameDTO(stackFrame))),
this.sessionManager.onDidFocusThread(debugThread => this.debugExt.$onDidChangeActiveThread(this.toDebugThreadDTO(debugThread))),
]);
}

Expand Down Expand Up @@ -340,6 +344,21 @@ export class DebugMainImpl implements DebugMain, Disposable {
}
}

private toDebugStackFrameDTO(stackFrame: DebugStackFrame | undefined): DebugStackFrameDTO | undefined {
return stackFrame ? {
sessionId: stackFrame.session.id,
frameId: stackFrame.frameId,
threadId: stackFrame.thread.threadId
} : undefined;
}

private toDebugThreadDTO(debugThread: DebugThread | undefined): DebugThreadDTO | undefined {
return debugThread ? {
sessionId: debugThread.session.id,
threadId: debugThread.threadId
} : undefined;
}

private toTheiaPluginApiBreakpoints(breakpoints: (SourceBreakpoint | FunctionBreakpoint)[]): Breakpoint[] {
return breakpoints.map(b => this.toTheiaPluginApiBreakpoint(b));
}
Expand Down
45 changes: 43 additions & 2 deletions packages/plugin-ext/src/plugin/debug/debug-ext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ import { Emitter } from '@theia/core/lib/common/event';
import { Path } from '@theia/core/lib/common/path';
import * as theia from '@theia/plugin';
import { URI } from '@theia/core/shared/vscode-uri';
import { Breakpoint } from '../../common/plugin-api-rpc-model';
import { Breakpoint, DebugStackFrameDTO, DebugThreadDTO } from '../../common/plugin-api-rpc-model';
import { DebugConfigurationProviderTriggerKind, DebugExt, DebugMain, PLUGIN_RPC_CONTEXT as Ext, TerminalOptionsExt } from '../../common/plugin-api-rpc';
import { PluginPackageDebuggersContribution } from '../../common/plugin-protocol';
import { RPCProtocol } from '../../common/rpc-protocol';
import { CommandRegistryImpl } from '../command-registry';
import { ConnectionImpl } from '../../common/connection';
import { DEBUG_SCHEME, SCHEME_PATTERN } from '@theia/debug/lib/common/debug-uri-utils';
import { Disposable, Breakpoint as BreakpointExt, SourceBreakpoint, FunctionBreakpoint, Location, Range, URI as URIImpl } from '../types-impl';
import { Disposable, Breakpoint as BreakpointExt, SourceBreakpoint, FunctionBreakpoint, Location, Range, URI as URIImpl, DebugStackFrame, DebugThread } from '../types-impl';
import { PluginDebugAdapterSession } from './plugin-debug-adapter-session';
import { PluginDebugAdapterTracker } from './plugin-debug-adapter-tracker';
import { generateUuid } from '@theia/core/lib/common/uuid';
Expand Down Expand Up @@ -79,6 +79,9 @@ export class DebugExtImpl implements DebugExt {
activeDebugSession: theia.DebugSession | undefined;
activeDebugConsole: theia.DebugConsole;

_activeStackItem: theia.DebugStackFrame | theia.DebugThread | undefined;
private readonly onDidChangeActiveStackItemEmitter = new Emitter<theia.DebugStackFrame | theia.DebugThread | undefined>();

private readonly _breakpoints = new Map<string, theia.Breakpoint>();

private frontendAdapterCreator = new PluginDebugAdapterCreator();
Expand Down Expand Up @@ -149,6 +152,10 @@ export class DebugExtImpl implements DebugExt {
return this.onDidStartDebugSessionEmitter.event;
}

get onDidChangeActiveStackItem(): theia.Event<theia.DebugStackFrame | theia.DebugThread | undefined> {
return this.onDidChangeActiveStackItemEmitter.event;
}

get onDidChangeBreakpoints(): theia.Event<theia.BreakpointsChangeEvent> {
return this.onDidChangeBreakpointsEmitter.event;
}
Expand Down Expand Up @@ -262,6 +269,40 @@ export class DebugExtImpl implements DebugExt {
});
}

set activeStackItem(stackItem: theia.DebugStackFrame | theia.DebugThread | undefined) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should check whether the active item actually changed before sending notifications.

if (this._activeStackItem === stackItem) {
return;
}
this._activeStackItem = stackItem;
this.onDidChangeActiveStackItemEmitter.fire(this.activeStackItem);
}

get activeStackItem(): theia.DebugStackFrame | theia.DebugThread | undefined {
return this._activeStackItem;
}

async $onDidChangeActiveThread(debugThread: DebugThreadDTO | undefined): Promise<void> {
if (!debugThread) {
this.activeStackItem = undefined;
return;
}
const session = this.sessions.get(debugThread.sessionId);
if (session) {
this.activeStackItem = new DebugThread(session, debugThread.threadId);
}
}

async $onDidChangeActiveFrame(debugFrame: DebugStackFrameDTO | undefined): Promise<void> {
if (!debugFrame) {
this.activeStackItem = undefined;
return;
}
const session = this.sessions.get(debugFrame!.sessionId);
if (session) {
this.activeStackItem = new DebugStackFrame(session, debugFrame.threadId, debugFrame.frameId);
}
}

async $onSessionCustomEvent(sessionId: string, event: string, body?: any): Promise<void> {
const session = this.sessions.get(sessionId);
if (session) {
Expand Down
6 changes: 2 additions & 4 deletions packages/plugin-ext/src/plugin/plugin-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1101,13 +1101,11 @@ export function createAPIFactory(
get onDidChangeBreakpoints(): theia.Event<theia.BreakpointsChangeEvent> {
return debugExt.onDidChangeBreakpoints;
},
/** @stubbed */
get activeStackItem(): DebugThread | DebugStackFrame | undefined {
return undefined;
return debugExt.activeStackItem;
},
/** @stubbed */
get onDidChangeActiveStackItem(): theia.Event<DebugThread | DebugStackFrame | undefined> {
return Event.None;
return debugExt.onDidChangeActiveStackItem;
},
registerDebugAdapterDescriptorFactory(debugType: string, factory: theia.DebugAdapterDescriptorFactory): Disposable {
return debugExt.registerDebugAdapterDescriptorFactory(debugType, factory);
Expand Down
8 changes: 4 additions & 4 deletions packages/plugin-ext/src/plugin/types-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3031,12 +3031,12 @@ export class FunctionBreakpoint extends Breakpoint {
}
}

export class DebugThread {
private constructor(readonly session: theia.DebugSession, readonly threadId: number) { }
export class DebugThread implements theia.DebugThread {
constructor(readonly session: theia.DebugSession, readonly threadId: number) { }
}

export class DebugStackFrame {
private constructor(readonly session: theia.DebugSession, readonly threadId: number, readonly frameId: number) { }
export class DebugStackFrame implements theia.DebugStackFrame {
constructor(readonly session: theia.DebugSession, readonly threadId: number, readonly frameId: number) { }
}

@es5ClassCompat
Expand Down
2 changes: 0 additions & 2 deletions packages/plugin/src/theia.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12548,13 +12548,11 @@ export module '@theia/plugin' {
* thread or stack is focused. A thread can be focused any time there is
* an active debug session, while a stack frame can only be focused when
* a session is paused and the call stack has been retrieved.
* @stubbed
*/
export const activeStackItem: DebugThread | DebugStackFrame | undefined;

/**
* An event which fires when the {@link debug.activeStackItem} has changed.
* @stubbed
*/
export const onDidChangeActiveStackItem: Event<DebugThread | DebugStackFrame | undefined>;

Expand Down
Loading