@theia/debug 1.67.0-next.86 → 1.67.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser/breakpoint/breakpoint-manager.js +1 -1
- package/lib/browser/breakpoint/breakpoint-manager.js.map +1 -1
- package/lib/browser/debug-commands.d.ts +153 -0
- package/lib/browser/debug-commands.d.ts.map +1 -0
- package/lib/browser/debug-commands.js +399 -0
- package/lib/browser/debug-commands.js.map +1 -0
- package/lib/browser/debug-frontend-application-contribution.d.ts +1 -150
- package/lib/browser/debug-frontend-application-contribution.d.ts.map +1 -1
- package/lib/browser/debug-frontend-application-contribution.js +155 -532
- package/lib/browser/debug-frontend-application-contribution.js.map +1 -1
- package/lib/browser/debug-prefix-configuration.js +3 -3
- package/lib/browser/debug-prefix-configuration.js.map +1 -1
- package/lib/browser/debug-session-contribution.d.ts +2 -1
- package/lib/browser/debug-session-contribution.d.ts.map +1 -1
- package/lib/browser/debug-session-contribution.js +5 -1
- package/lib/browser/debug-session-contribution.js.map +1 -1
- package/lib/browser/debug-session-manager.d.ts +4 -3
- package/lib/browser/debug-session-manager.d.ts.map +1 -1
- package/lib/browser/debug-session-manager.js +46 -8
- package/lib/browser/debug-session-manager.js.map +1 -1
- package/lib/browser/debug-session.d.ts +3 -2
- package/lib/browser/debug-session.d.ts.map +1 -1
- package/lib/browser/debug-session.js +4 -3
- package/lib/browser/debug-session.js.map +1 -1
- package/lib/browser/model/debug-breakpoint.d.ts +4 -2
- package/lib/browser/model/debug-breakpoint.d.ts.map +1 -1
- package/lib/browser/model/debug-breakpoint.js +10 -2
- package/lib/browser/model/debug-breakpoint.js.map +1 -1
- package/lib/browser/model/debug-data-breakpoint.d.ts +2 -0
- package/lib/browser/model/debug-data-breakpoint.d.ts.map +1 -1
- package/lib/browser/model/debug-data-breakpoint.js +16 -5
- package/lib/browser/model/debug-data-breakpoint.js.map +1 -1
- package/lib/browser/model/debug-function-breakpoint.d.ts +3 -0
- package/lib/browser/model/debug-function-breakpoint.d.ts.map +1 -1
- package/lib/browser/model/debug-function-breakpoint.js +17 -1
- package/lib/browser/model/debug-function-breakpoint.js.map +1 -1
- package/lib/browser/model/debug-instruction-breakpoint.d.ts +2 -0
- package/lib/browser/model/debug-instruction-breakpoint.d.ts.map +1 -1
- package/lib/browser/model/debug-instruction-breakpoint.js +13 -1
- package/lib/browser/model/debug-instruction-breakpoint.js.map +1 -1
- package/lib/browser/model/debug-source-breakpoint.d.ts +6 -1
- package/lib/browser/model/debug-source-breakpoint.d.ts.map +1 -1
- package/lib/browser/model/debug-source-breakpoint.js +17 -1
- package/lib/browser/model/debug-source-breakpoint.js.map +1 -1
- package/lib/browser/view/debug-action.d.ts +1 -0
- package/lib/browser/view/debug-action.d.ts.map +1 -1
- package/lib/browser/view/debug-action.js +2 -2
- package/lib/browser/view/debug-action.js.map +1 -1
- package/lib/browser/view/debug-breakpoints-source.d.ts +2 -0
- package/lib/browser/view/debug-breakpoints-source.d.ts.map +1 -1
- package/lib/browser/view/debug-breakpoints-source.js +6 -1
- package/lib/browser/view/debug-breakpoints-source.js.map +1 -1
- package/lib/browser/view/debug-configuration-widget.js +2 -2
- package/lib/browser/view/debug-configuration-widget.js.map +1 -1
- package/lib/browser/view/debug-exception-breakpoint.d.ts +9 -2
- package/lib/browser/view/debug-exception-breakpoint.d.ts.map +1 -1
- package/lib/browser/view/debug-exception-breakpoint.js +26 -5
- package/lib/browser/view/debug-exception-breakpoint.js.map +1 -1
- package/lib/browser/view/debug-session-widget.d.ts +0 -1
- package/lib/browser/view/debug-session-widget.d.ts.map +1 -1
- package/lib/browser/view/debug-session-widget.js +0 -4
- package/lib/browser/view/debug-session-widget.js.map +1 -1
- package/lib/browser/view/debug-threads-widget.d.ts +6 -1
- package/lib/browser/view/debug-threads-widget.d.ts.map +1 -1
- package/lib/browser/view/debug-threads-widget.js +69 -5
- package/lib/browser/view/debug-threads-widget.js.map +1 -1
- package/lib/browser/view/debug-toolbar-widget.d.ts +5 -18
- package/lib/browser/view/debug-toolbar-widget.d.ts.map +1 -1
- package/lib/browser/view/debug-toolbar-widget.js +14 -58
- package/lib/browser/view/debug-toolbar-widget.js.map +1 -1
- package/lib/browser/view/debug-view-model.d.ts.map +1 -1
- package/lib/browser/view/debug-view-model.js +8 -9
- package/lib/browser/view/debug-view-model.js.map +1 -1
- package/package.json +16 -16
- package/src/browser/breakpoint/breakpoint-manager.ts +1 -1
- package/src/browser/debug-commands.ts +402 -0
- package/src/browser/debug-frontend-application-contribution.ts +35 -410
- package/src/browser/debug-prefix-configuration.ts +1 -1
- package/src/browser/debug-session-contribution.ts +5 -2
- package/src/browser/debug-session-manager.ts +52 -9
- package/src/browser/debug-session.tsx +4 -3
- package/src/browser/model/debug-breakpoint.tsx +12 -3
- package/src/browser/model/debug-data-breakpoint.tsx +21 -6
- package/src/browser/model/debug-function-breakpoint.tsx +22 -1
- package/src/browser/model/debug-instruction-breakpoint.tsx +16 -1
- package/src/browser/model/debug-source-breakpoint.tsx +24 -3
- package/src/browser/style/index.css +13 -5
- package/src/browser/view/debug-action.tsx +3 -2
- package/src/browser/view/debug-breakpoints-source.tsx +5 -1
- package/src/browser/view/debug-configuration-widget.tsx +1 -1
- package/src/browser/view/debug-exception-breakpoint.tsx +30 -5
- package/src/browser/view/debug-session-widget.ts +0 -5
- package/src/browser/view/debug-threads-widget.ts +84 -6
- package/src/browser/view/debug-toolbar-widget.tsx +13 -60
- package/src/browser/view/debug-view-model.ts +8 -9
|
@@ -16,8 +16,9 @@
|
|
|
16
16
|
|
|
17
17
|
import { injectable, inject, postConstruct, interfaces, Container } from '@theia/core/shared/inversify';
|
|
18
18
|
import { MenuPath } from '@theia/core';
|
|
19
|
-
import { TreeNode, NodeProps, SelectableTreeNode } from '@theia/core/lib/browser';
|
|
19
|
+
import { TreeNode, NodeProps, SelectableTreeNode, CompositeTreeNode } from '@theia/core/lib/browser';
|
|
20
20
|
import { SourceTreeWidget, TreeElementNode } from '@theia/core/lib/browser/source-tree';
|
|
21
|
+
import { ExpandableTreeNode } from '@theia/core/lib/browser/tree/tree-expansion';
|
|
21
22
|
import { DebugThreadsSource } from './debug-threads-source';
|
|
22
23
|
import { DebugSession } from '../debug-session';
|
|
23
24
|
import { DebugThread } from '../model/debug-thread';
|
|
@@ -65,28 +66,105 @@ export class DebugThreadsWidget extends SourceTreeWidget {
|
|
|
65
66
|
this.toDispose.push(this.threads);
|
|
66
67
|
this.source = this.threads;
|
|
67
68
|
|
|
68
|
-
this.toDispose.push(this.viewModel.onDidChange(() =>
|
|
69
|
+
this.toDispose.push(this.viewModel.onDidChange(() => {
|
|
70
|
+
this.updateWidgetSelection();
|
|
71
|
+
}));
|
|
69
72
|
this.toDispose.push(this.model.onSelectionChanged(() => this.updateModelSelection()));
|
|
70
73
|
}
|
|
71
74
|
|
|
72
75
|
protected updatingSelection = false;
|
|
73
|
-
protected updateWidgetSelection(): void {
|
|
76
|
+
protected async updateWidgetSelection(): Promise<void> {
|
|
74
77
|
if (this.updatingSelection) {
|
|
75
78
|
return;
|
|
76
79
|
}
|
|
77
80
|
this.updatingSelection = true;
|
|
78
81
|
try {
|
|
82
|
+
await this.model.refresh();
|
|
83
|
+
|
|
79
84
|
const { currentThread } = this.viewModel;
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
|
|
86
|
+
// Check if current selection still exists in the tree
|
|
87
|
+
const selectedNode = this.model.selectedNodes[0];
|
|
88
|
+
const selectionStillValid = selectedNode && this.model.getNode(selectedNode.id);
|
|
89
|
+
|
|
90
|
+
// Only update selection if:
|
|
91
|
+
// 1. Current selection is invalid (node no longer in tree), OR
|
|
92
|
+
// 2. There's a stopped thread to show
|
|
93
|
+
if (selectionStillValid && (!currentThread || !currentThread.stopped)) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Try to select the current stopped thread, or clear if none
|
|
98
|
+
if (currentThread && currentThread.stopped) {
|
|
99
|
+
const node = await this.waitForNode(currentThread);
|
|
100
|
+
|
|
101
|
+
// Re-check stopped state after async wait
|
|
102
|
+
if (!currentThread.stopped) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (node && SelectableTreeNode.is(node)) {
|
|
83
107
|
this.model.selectNode(node);
|
|
108
|
+
|
|
109
|
+
// Set context key
|
|
110
|
+
if (TreeElementNode.is(node)) {
|
|
111
|
+
if (node.element instanceof DebugThread) {
|
|
112
|
+
this.debugCallStackItemTypeKey.set('thread');
|
|
113
|
+
} else if (node.element instanceof DebugSession) {
|
|
114
|
+
this.debugCallStackItemTypeKey.set('session');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
84
117
|
}
|
|
118
|
+
} else if (!selectionStillValid) {
|
|
119
|
+
// Selection is stale and no stopped thread to select
|
|
120
|
+
this.model.clearSelection();
|
|
85
121
|
}
|
|
86
122
|
} finally {
|
|
87
123
|
this.updatingSelection = false;
|
|
88
124
|
}
|
|
89
125
|
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Wait for a node to appear in the tree, expanding root children to populate the tree
|
|
129
|
+
*/
|
|
130
|
+
protected async waitForNode(thread: DebugThread): Promise<TreeNode | undefined> {
|
|
131
|
+
const maxAttempts = 10;
|
|
132
|
+
const delayMs = 50;
|
|
133
|
+
const threadId = thread.id;
|
|
134
|
+
|
|
135
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
136
|
+
// If thread continued during wait, abort
|
|
137
|
+
if (!thread.stopped) {
|
|
138
|
+
return undefined;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
await this.model.refresh();
|
|
142
|
+
|
|
143
|
+
const root = this.model.root;
|
|
144
|
+
|
|
145
|
+
// Expand all root's direct children to populate the tree
|
|
146
|
+
if (root && CompositeTreeNode.is(root)) {
|
|
147
|
+
for (const child of root.children) {
|
|
148
|
+
if (ExpandableTreeNode.is(child) && !child.expanded) {
|
|
149
|
+
await this.model.expandNode(child);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Now look directly for the thread node
|
|
155
|
+
const threadNode = this.model.getNode(threadId);
|
|
156
|
+
if (threadNode) {
|
|
157
|
+
return threadNode;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (attempt < maxAttempts - 1) {
|
|
161
|
+
await new Promise(resolve => setTimeout(resolve, delayMs));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
|
|
90
168
|
protected updateModelSelection(): void {
|
|
91
169
|
if (this.updatingSelection) {
|
|
92
170
|
return;
|
|
@@ -16,69 +16,38 @@
|
|
|
16
16
|
|
|
17
17
|
import * as React from '@theia/core/shared/react';
|
|
18
18
|
import { inject, postConstruct, injectable } from '@theia/core/shared/inversify';
|
|
19
|
-
import { CommandMenu,
|
|
19
|
+
import { CommandMenu, CompoundMenuNode, MenuModelRegistry, MenuPath } from '@theia/core';
|
|
20
|
+
import { KeybindingRegistry } from '@theia/core/lib/browser';
|
|
20
21
|
import { ContextKeyService } from '@theia/core/lib/browser/context-key-service';
|
|
21
22
|
import { ReactWidget } from '@theia/core/lib/browser/widgets';
|
|
22
23
|
import { DebugViewModel } from './debug-view-model';
|
|
23
|
-
import { DebugState } from '../debug-session';
|
|
24
24
|
import { DebugAction } from './debug-action';
|
|
25
|
-
import { nls } from '@theia/core/lib/common/nls';
|
|
26
25
|
|
|
27
26
|
@injectable()
|
|
28
27
|
export class DebugToolBar extends ReactWidget {
|
|
29
28
|
|
|
30
29
|
static readonly MENU: MenuPath = ['debug-toolbar-menu'];
|
|
30
|
+
static readonly CONTROLS: MenuPath = [...DebugToolBar.MENU, 'z_controls'];
|
|
31
31
|
|
|
32
|
-
@inject(CommandRegistry) protected readonly commandRegistry: CommandRegistry;
|
|
33
32
|
@inject(MenuModelRegistry) protected readonly menuModelRegistry: MenuModelRegistry;
|
|
33
|
+
@inject(KeybindingRegistry) protected readonly keybindingRegistry: KeybindingRegistry;
|
|
34
34
|
@inject(ContextKeyService) protected readonly contextKeyService: ContextKeyService;
|
|
35
35
|
@inject(DebugViewModel) protected readonly model: DebugViewModel;
|
|
36
36
|
|
|
37
|
-
protected readonly onRender = new DisposableCollection();
|
|
38
|
-
|
|
39
37
|
@postConstruct()
|
|
40
38
|
protected init(): void {
|
|
41
39
|
this.id = 'debug:toolbar:' + this.model.id;
|
|
42
40
|
this.addClass('debug-toolbar');
|
|
43
41
|
this.toDispose.push(this.model);
|
|
44
42
|
this.toDispose.push(this.model.onDidChange(() => this.update()));
|
|
43
|
+
this.toDispose.push(this.keybindingRegistry.onKeybindingsChanged(() => this.update()));
|
|
45
44
|
this.scrollOptions = undefined;
|
|
46
45
|
this.update();
|
|
47
46
|
}
|
|
48
47
|
|
|
49
|
-
focus(): void {
|
|
50
|
-
if (!this.doFocus()) {
|
|
51
|
-
this.onRender.push(Disposable.create(() => this.doFocus()));
|
|
52
|
-
this.update();
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
protected doFocus(): boolean {
|
|
56
|
-
if (!this.stepRef) {
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
this.stepRef.focus();
|
|
60
|
-
return true;
|
|
61
|
-
}
|
|
62
|
-
protected stepRef: DebugAction | undefined;
|
|
63
|
-
protected setStepRef = (stepRef: DebugAction | null) => {
|
|
64
|
-
this.stepRef = stepRef || undefined;
|
|
65
|
-
this.onRender.dispose();
|
|
66
|
-
};
|
|
67
|
-
|
|
68
48
|
protected render(): React.ReactNode {
|
|
69
|
-
const { state } = this.model;
|
|
70
49
|
return <React.Fragment>
|
|
71
50
|
{this.renderContributedCommands()}
|
|
72
|
-
{this.renderContinue()}
|
|
73
|
-
<DebugAction enabled={state === DebugState.Stopped} run={this.stepOver} label={nls.localizeByDefault('Step Over')}
|
|
74
|
-
iconClass='debug-step-over' ref={this.setStepRef} />
|
|
75
|
-
<DebugAction enabled={state === DebugState.Stopped} run={this.stepIn} label={nls.localizeByDefault('Step Into')}
|
|
76
|
-
iconClass='debug-step-into' />
|
|
77
|
-
<DebugAction enabled={state === DebugState.Stopped} run={this.stepOut} label={nls.localizeByDefault('Step Out')}
|
|
78
|
-
iconClass='debug-step-out' />
|
|
79
|
-
<DebugAction enabled={state !== DebugState.Inactive} run={this.restart} label={nls.localizeByDefault('Restart')}
|
|
80
|
-
iconClass='debug-restart' />
|
|
81
|
-
{this.renderStart()}
|
|
82
51
|
</React.Fragment>;
|
|
83
52
|
}
|
|
84
53
|
|
|
@@ -99,36 +68,20 @@ export class DebugToolBar extends ReactWidget {
|
|
|
99
68
|
}
|
|
100
69
|
|
|
101
70
|
protected debugAction(commandMenuNode: CommandMenu): React.ReactNode {
|
|
71
|
+
const accelerator = this.acceleratorFor(commandMenuNode.id);
|
|
72
|
+
const run = (effectiveMenuPath: MenuPath) => commandMenuNode.run(effectiveMenuPath).catch(e => console.error(e));
|
|
102
73
|
return <DebugAction
|
|
103
74
|
key={commandMenuNode.id}
|
|
104
|
-
enabled={
|
|
75
|
+
enabled={commandMenuNode.isEnabled(DebugToolBar.MENU)}
|
|
105
76
|
label={commandMenuNode.label}
|
|
77
|
+
tooltip={commandMenuNode.label + (accelerator ? ` (${accelerator})` : '')}
|
|
106
78
|
iconClass={commandMenuNode.icon || ''}
|
|
107
|
-
run={
|
|
79
|
+
run={run} />;
|
|
108
80
|
}
|
|
109
81
|
|
|
110
|
-
protected
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
return <DebugAction run={this.start} label={nls.localizeByDefault('Start')} iconClass='debug-start' />;
|
|
114
|
-
}
|
|
115
|
-
return <DebugAction enabled={state !== DebugState.Inactive} run={this.stop} label={nls.localizeByDefault('Stop')} iconClass='debug-stop' />;
|
|
116
|
-
}
|
|
117
|
-
protected renderContinue(): React.ReactNode {
|
|
118
|
-
const { state } = this.model;
|
|
119
|
-
if (state === DebugState.Stopped) {
|
|
120
|
-
return <DebugAction run={this.continue} label={nls.localizeByDefault('Continue')} iconClass='debug-continue' />;
|
|
121
|
-
}
|
|
122
|
-
return <DebugAction enabled={state === DebugState.Running} run={this.pause} label={nls.localizeByDefault('Pause')} iconClass='debug-pause' />;
|
|
82
|
+
protected acceleratorFor(commandId: string): string | undefined {
|
|
83
|
+
const keybindings = this.keybindingRegistry.getKeybindingsForCommand(commandId);
|
|
84
|
+
return keybindings.length ? this.keybindingRegistry.acceleratorFor(keybindings[0], '+').join(' ') : undefined;
|
|
123
85
|
}
|
|
124
86
|
|
|
125
|
-
protected start = () => this.model.start({ startedByUser: true });
|
|
126
|
-
protected restart = () => this.model.restart();
|
|
127
|
-
protected stop = () => this.model.terminate();
|
|
128
|
-
protected continue = () => this.model.currentThread && this.model.currentThread.continue();
|
|
129
|
-
protected pause = () => this.model.currentThread && this.model.currentThread.pause();
|
|
130
|
-
protected stepOver = () => this.model.currentThread && this.model.currentThread.stepOver();
|
|
131
|
-
protected stepIn = () => this.model.currentThread && this.model.currentThread.stepIn();
|
|
132
|
-
protected stepOut = () => this.model.currentThread && this.model.currentThread.stepOut();
|
|
133
|
-
|
|
134
87
|
}
|
|
@@ -96,14 +96,13 @@ export class DebugViewModel implements Disposable {
|
|
|
96
96
|
this.fireDidChange();
|
|
97
97
|
}));
|
|
98
98
|
this.toDispose.push(this.manager.onDidChange(current => {
|
|
99
|
-
if
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
// Always fire change to update views, even if session is not current
|
|
100
|
+
// This ensures threads view updates for all sessions
|
|
101
|
+
this.fireDidChange();
|
|
102
102
|
}));
|
|
103
103
|
this.toDispose.push(this.manager.onDidChangeBreakpoints(({ session, uri }) => {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
104
|
+
// Fire for all sessions since we now show breakpoints from all active sessions
|
|
105
|
+
this.fireDidChangeBreakpoints(uri);
|
|
107
106
|
}));
|
|
108
107
|
this.toDispose.push(this.manager.onDidResolveLazyVariable(({ session, variable }) => {
|
|
109
108
|
if (session === this.currentSession) {
|
|
@@ -140,15 +139,15 @@ export class DebugViewModel implements Disposable {
|
|
|
140
139
|
}
|
|
141
140
|
|
|
142
141
|
get breakpoints(): DebugSourceBreakpoint[] {
|
|
143
|
-
return this.manager.getBreakpoints(
|
|
142
|
+
return this.manager.getBreakpoints();
|
|
144
143
|
}
|
|
145
144
|
|
|
146
145
|
get functionBreakpoints(): DebugFunctionBreakpoint[] {
|
|
147
|
-
return this.manager.getFunctionBreakpoints(
|
|
146
|
+
return this.manager.getFunctionBreakpoints();
|
|
148
147
|
}
|
|
149
148
|
|
|
150
149
|
get instructionBreakpoints(): DebugInstructionBreakpoint[] {
|
|
151
|
-
return this.manager.getInstructionBreakpoints(
|
|
150
|
+
return this.manager.getInstructionBreakpoints();
|
|
152
151
|
}
|
|
153
152
|
|
|
154
153
|
get dataBreakpoints(): DebugDataBreakpoint[] {
|