@theia/debug 1.29.0-next.6 → 1.29.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-marker.d.ts +1 -1
- package/lib/browser/breakpoint/breakpoint-marker.d.ts.map +1 -1
- package/lib/browser/console/debug-console-items.d.ts +1 -1
- package/lib/browser/console/debug-console-items.d.ts.map +1 -1
- package/lib/browser/console/debug-console-session.d.ts +1 -1
- package/lib/browser/console/debug-console-session.d.ts.map +1 -1
- package/lib/browser/debug-configuration-manager.d.ts +15 -7
- package/lib/browser/debug-configuration-manager.d.ts.map +1 -1
- package/lib/browser/debug-configuration-manager.js +81 -31
- package/lib/browser/debug-configuration-manager.js.map +1 -1
- package/lib/browser/debug-configuration-model.d.ts +3 -0
- package/lib/browser/debug-configuration-model.d.ts.map +1 -1
- package/lib/browser/debug-configuration-model.js +17 -10
- package/lib/browser/debug-configuration-model.js.map +1 -1
- package/lib/browser/debug-contribution.d.ts +1 -1
- package/lib/browser/debug-contribution.d.ts.map +1 -1
- package/lib/browser/debug-frontend-application-contribution.d.ts.map +1 -1
- package/lib/browser/debug-frontend-application-contribution.js +6 -3
- 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-schema-updater.d.ts.map +1 -1
- package/lib/browser/debug-schema-updater.js +55 -4
- package/lib/browser/debug-schema-updater.js.map +1 -1
- package/lib/browser/debug-session-connection.d.ts +1 -1
- package/lib/browser/debug-session-connection.d.ts.map +1 -1
- package/lib/browser/debug-session-contribution.d.ts +2 -2
- package/lib/browser/debug-session-contribution.d.ts.map +1 -1
- package/lib/browser/debug-session-contribution.js.map +1 -1
- package/lib/browser/debug-session-manager.d.ts +10 -4
- package/lib/browser/debug-session-manager.d.ts.map +1 -1
- package/lib/browser/debug-session-manager.js +64 -7
- package/lib/browser/debug-session-manager.js.map +1 -1
- package/lib/browser/debug-session-options.d.ts +36 -6
- package/lib/browser/debug-session-options.d.ts.map +1 -1
- package/lib/browser/debug-session-options.js +53 -10
- package/lib/browser/debug-session-options.js.map +1 -1
- package/lib/browser/debug-session.d.ts +4 -4
- package/lib/browser/debug-session.d.ts.map +1 -1
- package/lib/browser/debug-session.js +7 -0
- package/lib/browser/debug-session.js.map +1 -1
- package/lib/browser/disassembly-view/disassembly-view-instruction-renderer.d.ts +1 -1
- package/lib/browser/disassembly-view/disassembly-view-instruction-renderer.d.ts.map +1 -1
- package/lib/browser/disassembly-view/disassembly-view-utilities.d.ts +1 -1
- package/lib/browser/disassembly-view/disassembly-view-utilities.d.ts.map +1 -1
- package/lib/browser/editor/debug-breakpoint-widget.d.ts +3 -1
- package/lib/browser/editor/debug-breakpoint-widget.d.ts.map +1 -1
- package/lib/browser/editor/debug-breakpoint-widget.js +5 -4
- package/lib/browser/editor/debug-breakpoint-widget.js.map +1 -1
- package/lib/browser/editor/debug-editor-model.d.ts +1 -1
- package/lib/browser/editor/debug-editor-model.d.ts.map +1 -1
- package/lib/browser/editor/debug-exception-widget.d.ts +2 -0
- package/lib/browser/editor/debug-exception-widget.d.ts.map +1 -1
- package/lib/browser/editor/debug-exception-widget.js +6 -5
- package/lib/browser/editor/debug-exception-widget.js.map +1 -1
- package/lib/browser/editor/debug-hover-widget.d.ts.map +1 -1
- package/lib/browser/editor/debug-hover-widget.js +35 -9
- package/lib/browser/editor/debug-hover-widget.js.map +1 -1
- package/lib/browser/model/debug-breakpoint.d.ts +1 -1
- package/lib/browser/model/debug-breakpoint.d.ts.map +1 -1
- package/lib/browser/model/debug-source-breakpoint.d.ts +1 -1
- package/lib/browser/model/debug-source-breakpoint.d.ts.map +1 -1
- package/lib/browser/model/debug-source.d.ts +1 -1
- package/lib/browser/model/debug-source.d.ts.map +1 -1
- package/lib/browser/model/debug-stack-frame.d.ts +1 -1
- package/lib/browser/model/debug-stack-frame.d.ts.map +1 -1
- package/lib/browser/model/debug-thread.d.ts +1 -1
- package/lib/browser/model/debug-thread.d.ts.map +1 -1
- package/lib/browser/view/debug-configuration-select.d.ts +4 -1
- package/lib/browser/view/debug-configuration-select.d.ts.map +1 -1
- package/lib/browser/view/debug-configuration-select.js +36 -14
- package/lib/browser/view/debug-configuration-select.js.map +1 -1
- package/lib/browser/view/debug-configuration-widget.d.ts +3 -2
- package/lib/browser/view/debug-configuration-widget.d.ts.map +1 -1
- package/lib/browser/view/debug-configuration-widget.js +5 -1
- package/lib/browser/view/debug-configuration-widget.js.map +1 -1
- package/lib/browser/view/debug-toolbar-widget.d.ts +8 -7
- package/lib/browser/view/debug-toolbar-widget.d.ts.map +1 -1
- package/lib/browser/view/debug-toolbar-widget.js +5 -1
- package/lib/browser/view/debug-toolbar-widget.js.map +1 -1
- package/lib/browser/view/debug-watch-expression.d.ts +1 -1
- package/lib/browser/view/debug-watch-expression.d.ts.map +1 -1
- package/lib/common/debug-compound.d.ts +15 -0
- package/lib/common/debug-compound.d.ts.map +1 -0
- package/lib/common/debug-compound.js +27 -0
- package/lib/common/debug-compound.js.map +1 -0
- package/lib/common/debug-configuration.d.ts +2 -2
- package/lib/common/debug-configuration.d.ts.map +1 -1
- package/lib/common/debug-configuration.js.map +1 -1
- package/lib/node/debug-adapter-factory.d.ts.map +1 -1
- package/lib/node/debug-adapter-factory.js +1 -2
- package/lib/node/debug-adapter-factory.js.map +1 -1
- package/package.json +17 -17
- package/src/browser/breakpoint/breakpoint-marker.ts +1 -1
- package/src/browser/console/debug-console-items.tsx +1 -1
- package/src/browser/console/debug-console-session.ts +1 -1
- package/src/browser/debug-configuration-manager.ts +92 -40
- package/src/browser/debug-configuration-model.ts +19 -10
- package/src/browser/debug-contribution.ts +1 -1
- package/src/browser/debug-frontend-application-contribution.ts +10 -3
- package/src/browser/debug-prefix-configuration.ts +3 -3
- package/src/browser/debug-schema-updater.ts +56 -5
- package/src/browser/debug-session-connection.ts +1 -1
- package/src/browser/debug-session-contribution.ts +2 -2
- package/src/browser/debug-session-manager.ts +79 -8
- package/src/browser/debug-session-options.ts +72 -15
- package/src/browser/debug-session.tsx +9 -3
- package/src/browser/disassembly-view/disassembly-view-instruction-renderer.ts +1 -1
- package/src/browser/disassembly-view/disassembly-view-utilities.ts +1 -1
- package/src/browser/disassembly-view/disassembly-view-widget.ts +1 -1
- package/src/browser/editor/debug-breakpoint-widget.tsx +7 -5
- package/src/browser/editor/debug-editor-model.ts +1 -1
- package/src/browser/editor/debug-exception-widget.tsx +7 -5
- package/src/browser/editor/debug-hover-widget.ts +43 -9
- package/src/browser/model/debug-breakpoint.tsx +1 -1
- package/src/browser/model/debug-source-breakpoint.tsx +1 -1
- package/src/browser/model/debug-source.ts +1 -1
- package/src/browser/model/debug-stack-frame.tsx +1 -1
- package/src/browser/model/debug-thread.tsx +1 -1
- package/src/browser/view/debug-configuration-select.tsx +42 -20
- package/src/browser/view/debug-configuration-widget.tsx +7 -2
- package/src/browser/view/debug-toolbar-widget.tsx +7 -2
- package/src/browser/view/debug-watch-expression.tsx +1 -1
- package/src/common/debug-adapter-session.ts +1 -1
- package/src/common/debug-compound.ts +32 -0
- package/src/common/debug-configuration.ts +2 -2
- package/src/node/debug-adapter-factory.ts +2 -3
|
@@ -30,7 +30,7 @@ import { LabelProvider, PreferenceScope, PreferenceService, QuickPickValue, Stor
|
|
|
30
30
|
import { QuickPickService } from '@theia/core/lib/common/quick-pick-service';
|
|
31
31
|
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
|
|
32
32
|
import { DebugConfigurationModel } from './debug-configuration-model';
|
|
33
|
-
import { DebugSessionOptions } from './debug-session-options';
|
|
33
|
+
import { DebugSessionOptions, DynamicDebugConfigurationSessionOptions } from './debug-session-options';
|
|
34
34
|
import { DebugService } from '../common/debug-service';
|
|
35
35
|
import { ContextKey, ContextKeyService } from '@theia/core/lib/browser/context-key-service';
|
|
36
36
|
import { DebugConfiguration } from '../common/debug-common';
|
|
@@ -41,6 +41,7 @@ import * as monaco from '@theia/monaco-editor-core';
|
|
|
41
41
|
import { ICommandService } from '@theia/monaco-editor-core/esm/vs/platform/commands/common/commands';
|
|
42
42
|
import { StandaloneServices } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices';
|
|
43
43
|
import { nls } from '@theia/core';
|
|
44
|
+
import { DebugCompound } from '../common/debug-compound';
|
|
44
45
|
|
|
45
46
|
export interface WillProvideDebugConfiguration extends WaitUntilEvent {
|
|
46
47
|
}
|
|
@@ -94,7 +95,7 @@ export class DebugConfigurationManager {
|
|
|
94
95
|
|
|
95
96
|
protected initialized: Promise<void>;
|
|
96
97
|
|
|
97
|
-
protected recentDynamicOptionsTracker:
|
|
98
|
+
protected recentDynamicOptionsTracker: DynamicDebugConfigurationSessionOptions[] = [];
|
|
98
99
|
|
|
99
100
|
@postConstruct()
|
|
100
101
|
protected async init(): Promise<void> {
|
|
@@ -141,10 +142,10 @@ export class DebugConfigurationManager {
|
|
|
141
142
|
protected *getAll(): IterableIterator<DebugSessionOptions> {
|
|
142
143
|
for (const model of this.models.values()) {
|
|
143
144
|
for (const configuration of model.configurations) {
|
|
144
|
-
yield
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
145
|
+
yield this.configurationToOptions(configuration, model.workspaceFolderUri);
|
|
146
|
+
}
|
|
147
|
+
for (const compound of model.compounds) {
|
|
148
|
+
yield this.compoundToOptions(compound, model.workspaceFolderUri);
|
|
148
149
|
}
|
|
149
150
|
}
|
|
150
151
|
}
|
|
@@ -159,7 +160,7 @@ export class DebugConfigurationManager {
|
|
|
159
160
|
}
|
|
160
161
|
protected *doGetSupported(debugTypes: Set<string>): IterableIterator<DebugSessionOptions> {
|
|
161
162
|
for (const options of this.getAll()) {
|
|
162
|
-
if (debugTypes.has(options.configuration.type)) {
|
|
163
|
+
if (options.configuration && debugTypes.has(options.configuration.type)) {
|
|
163
164
|
yield options;
|
|
164
165
|
}
|
|
165
166
|
}
|
|
@@ -171,8 +172,7 @@ export class DebugConfigurationManager {
|
|
|
171
172
|
}
|
|
172
173
|
|
|
173
174
|
async getSelectedConfiguration(): Promise<DebugSessionOptions | undefined> {
|
|
174
|
-
|
|
175
|
-
if (!this._currentOptions?.providerType) {
|
|
175
|
+
if (!DebugSessionOptions.isDynamic(this._currentOptions)) {
|
|
176
176
|
return this._currentOptions;
|
|
177
177
|
}
|
|
178
178
|
|
|
@@ -188,7 +188,7 @@ export class DebugConfigurationManager {
|
|
|
188
188
|
throw new Error(message);
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
-
return { configuration, providerType };
|
|
191
|
+
return { name, configuration, providerType };
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
set current(option: DebugSessionOptions | undefined) {
|
|
@@ -197,7 +197,7 @@ export class DebugConfigurationManager {
|
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
protected updateRecentlyUsedDynamicConfigurationOptions(option: DebugSessionOptions | undefined): void {
|
|
200
|
-
if (option
|
|
200
|
+
if (DebugSessionOptions.isDynamic(option)) {
|
|
201
201
|
// Removing an item already present in the list
|
|
202
202
|
const index = this.recentDynamicOptionsTracker.findIndex(item => this.dynamicOptionsMatch(item, option));
|
|
203
203
|
if (index > -1) {
|
|
@@ -212,32 +212,33 @@ export class DebugConfigurationManager {
|
|
|
212
212
|
}
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
-
protected dynamicOptionsMatch(one:
|
|
215
|
+
protected dynamicOptionsMatch(one: DynamicDebugConfigurationSessionOptions, other: DynamicDebugConfigurationSessionOptions): boolean {
|
|
216
216
|
return one.providerType !== undefined
|
|
217
|
-
|
|
218
|
-
|
|
217
|
+
&& one.configuration.name === other.configuration.name
|
|
218
|
+
&& one.providerType === other.providerType;
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
-
get recentDynamicOptions(): readonly
|
|
221
|
+
get recentDynamicOptions(): readonly DynamicDebugConfigurationSessionOptions[] {
|
|
222
222
|
return this.recentDynamicOptionsTracker;
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
protected updateCurrent(options: DebugSessionOptions | undefined = this._currentOptions): void {
|
|
226
|
-
|
|
226
|
+
if (DebugSessionOptions.isCompound(options)) {
|
|
227
|
+
this._currentOptions = options && this.find(options.compound, options.workspaceFolderUri);
|
|
228
|
+
} else {
|
|
229
|
+
this._currentOptions = options && this.find(options.configuration, options.workspaceFolderUri, options.providerType);
|
|
230
|
+
}
|
|
227
231
|
|
|
228
232
|
if (!this._currentOptions) {
|
|
229
233
|
const model = this.getModel();
|
|
230
234
|
if (model) {
|
|
231
235
|
const configuration = model.configurations[0];
|
|
232
236
|
if (configuration) {
|
|
233
|
-
this._currentOptions =
|
|
234
|
-
configuration,
|
|
235
|
-
workspaceFolderUri: model.workspaceFolderUri
|
|
236
|
-
};
|
|
237
|
+
this._currentOptions = this.configurationToOptions(configuration, model.workspaceFolderUri);
|
|
237
238
|
}
|
|
238
239
|
}
|
|
239
240
|
}
|
|
240
|
-
this.debugConfigurationTypeKey.set(this.current && this.current.configuration
|
|
241
|
+
this.debugConfigurationTypeKey.set(this.current && this.current.configuration?.type);
|
|
241
242
|
this.onDidChangeEmitter.fire(undefined);
|
|
242
243
|
}
|
|
243
244
|
|
|
@@ -248,24 +249,57 @@ export class DebugConfigurationManager {
|
|
|
248
249
|
/**
|
|
249
250
|
* Find / Resolve DebugSessionOptions from a given target debug configuration
|
|
250
251
|
*/
|
|
251
|
-
find(
|
|
252
|
-
find(
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
const
|
|
252
|
+
find(compound: DebugCompound, workspaceFolderUri?: string): DebugSessionOptions | undefined;
|
|
253
|
+
find(configuration: DebugConfiguration, workspaceFolderUri?: string, providerType?: string): DebugSessionOptions | undefined;
|
|
254
|
+
find(name: string, workspaceFolderUri?: string, providerType?: string): DebugSessionOptions | undefined;
|
|
255
|
+
find(nameOrConfigurationOrCompound: string | DebugConfiguration | DebugCompound, workspaceFolderUri?: string, providerType?: string): DebugSessionOptions | undefined {
|
|
256
|
+
if (DebugConfiguration.is(nameOrConfigurationOrCompound) && providerType) {
|
|
257
|
+
// providerType is only applicable to dynamic debug configurations and may only be created if we have a configuration given
|
|
258
|
+
return this.configurationToOptions(nameOrConfigurationOrCompound, workspaceFolderUri, providerType);
|
|
259
|
+
}
|
|
260
|
+
const name = typeof nameOrConfigurationOrCompound === 'string' ? nameOrConfigurationOrCompound : nameOrConfigurationOrCompound.name;
|
|
261
|
+
const configuration = this.findConfiguration(name, workspaceFolderUri);
|
|
262
|
+
if (configuration) {
|
|
263
|
+
return this.configurationToOptions(configuration, workspaceFolderUri);
|
|
264
|
+
}
|
|
265
|
+
const compound = this.findCompound(name, workspaceFolderUri);
|
|
266
|
+
if (compound) {
|
|
267
|
+
return this.compoundToOptions(compound, workspaceFolderUri);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
findConfigurations(name: string, workspaceFolderUri?: string): DebugConfiguration[] {
|
|
272
|
+
const matches = [];
|
|
261
273
|
for (const model of this.models.values()) {
|
|
262
274
|
if (model.workspaceFolderUri === workspaceFolderUri) {
|
|
263
275
|
for (const configuration of model.configurations) {
|
|
264
276
|
if (configuration.name === name) {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
277
|
+
matches.push(configuration);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return matches;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
findConfiguration(name: string, workspaceFolderUri?: string): DebugConfiguration | undefined {
|
|
286
|
+
for (const model of this.models.values()) {
|
|
287
|
+
if (model.workspaceFolderUri === workspaceFolderUri) {
|
|
288
|
+
for (const configuration of model.configurations) {
|
|
289
|
+
if (configuration.name === name) {
|
|
290
|
+
return configuration;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
findCompound(name: string, workspaceFolderUri?: string): DebugCompound | undefined {
|
|
298
|
+
for (const model of this.models.values()) {
|
|
299
|
+
if (model.workspaceFolderUri === workspaceFolderUri) {
|
|
300
|
+
for (const compound of model.compounds) {
|
|
301
|
+
if (compound.name === name) {
|
|
302
|
+
return compound;
|
|
269
303
|
}
|
|
270
304
|
}
|
|
271
305
|
}
|
|
@@ -279,6 +313,14 @@ export class DebugConfigurationManager {
|
|
|
279
313
|
}
|
|
280
314
|
}
|
|
281
315
|
|
|
316
|
+
protected configurationToOptions(configuration: DebugConfiguration, workspaceFolderUri?: string, providerType?: string): DebugSessionOptions {
|
|
317
|
+
return { name: configuration.name, configuration, providerType, workspaceFolderUri };
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
protected compoundToOptions(compound: DebugCompound, workspaceFolderUri?: string): DebugSessionOptions {
|
|
321
|
+
return { name: compound.name, compound, workspaceFolderUri };
|
|
322
|
+
}
|
|
323
|
+
|
|
282
324
|
async addConfiguration(): Promise<void> {
|
|
283
325
|
let rootUri: URI | undefined = undefined;
|
|
284
326
|
if (this.workspaceService.saved && this.workspaceService.tryGetRoots().length > 1) {
|
|
@@ -345,7 +387,8 @@ export class DebugConfigurationManager {
|
|
|
345
387
|
});
|
|
346
388
|
}
|
|
347
389
|
const root = await this.quickPickService.show(items, {
|
|
348
|
-
placeholder: nls.localize('theia/debug/addConfigurationPlaceholder', 'Select workspace root to add configuration to')
|
|
390
|
+
placeholder: nls.localize('theia/debug/addConfigurationPlaceholder', 'Select workspace root to add configuration to'),
|
|
391
|
+
ignoreFocusOut: true
|
|
349
392
|
});
|
|
350
393
|
return root?.value;
|
|
351
394
|
}
|
|
@@ -469,17 +512,26 @@ export class DebugConfigurationManager {
|
|
|
469
512
|
|
|
470
513
|
// Between versions v1.26 and v1.27, the expected format of the data changed so that old stored data
|
|
471
514
|
// may not contain the configuration key.
|
|
472
|
-
if (
|
|
515
|
+
if (DebugSessionOptions.isConfiguration(data.current)) {
|
|
516
|
+
// ensure options name is reflected from old configurations data
|
|
517
|
+
data.current.name = data.current.name ?? data.current.configuration?.name;
|
|
473
518
|
this.current = this.find(data.current.configuration, data.current.workspaceFolderUri, data.current.providerType);
|
|
519
|
+
} else if (DebugSessionOptions.isCompound(data.current)) {
|
|
520
|
+
this.current = this.find(data.current.name, data.current.workspaceFolderUri);
|
|
474
521
|
}
|
|
475
522
|
}
|
|
476
523
|
|
|
477
|
-
protected resolveRecentDynamicOptionsFromData(options?:
|
|
524
|
+
protected resolveRecentDynamicOptionsFromData(options?: DynamicDebugConfigurationSessionOptions[]): void {
|
|
478
525
|
if (!options || this.recentDynamicOptionsTracker.length !== 0) {
|
|
479
526
|
return;
|
|
480
527
|
}
|
|
481
528
|
|
|
482
|
-
|
|
529
|
+
// ensure options name is reflected from old configurations data
|
|
530
|
+
const dynamicOptions = options.map(option => {
|
|
531
|
+
option.name = option.name ?? option.configuration.name;
|
|
532
|
+
return option;
|
|
533
|
+
}).filter(DebugSessionOptions.isDynamic);
|
|
534
|
+
this.recentDynamicOptionsTracker = dynamicOptions;
|
|
483
535
|
}
|
|
484
536
|
|
|
485
537
|
save(): void {
|
|
@@ -502,6 +554,6 @@ export class DebugConfigurationManager {
|
|
|
502
554
|
export namespace DebugConfigurationManager {
|
|
503
555
|
export interface Data {
|
|
504
556
|
current?: DebugSessionOptions,
|
|
505
|
-
recentDynamicOptions?:
|
|
557
|
+
recentDynamicOptions?: DynamicDebugConfigurationSessionOptions[]
|
|
506
558
|
}
|
|
507
559
|
}
|
|
@@ -19,6 +19,7 @@ import { Emitter, Event } from '@theia/core/lib/common/event';
|
|
|
19
19
|
import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable';
|
|
20
20
|
import { DebugConfiguration } from '../common/debug-common';
|
|
21
21
|
import { PreferenceService } from '@theia/core/lib/browser/preferences/preference-service';
|
|
22
|
+
import { DebugCompound } from '../common/debug-compound';
|
|
22
23
|
|
|
23
24
|
export class DebugConfigurationModel implements Disposable {
|
|
24
25
|
|
|
@@ -58,6 +59,10 @@ export class DebugConfigurationModel implements Disposable {
|
|
|
58
59
|
return this.json.configurations;
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
get compounds(): DebugCompound[] {
|
|
63
|
+
return this.json.compounds;
|
|
64
|
+
}
|
|
65
|
+
|
|
61
66
|
async reconcile(): Promise<void> {
|
|
62
67
|
this.json = this.parseConfigurations();
|
|
63
68
|
this.onDidChangeEmitter.fire(undefined);
|
|
@@ -66,19 +71,22 @@ export class DebugConfigurationModel implements Disposable {
|
|
|
66
71
|
const configurations: DebugConfiguration[] = [];
|
|
67
72
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
68
73
|
const { configUri, value } = this.preferences.resolve<any>('launch', undefined, this.workspaceFolderUri);
|
|
69
|
-
if (value && typeof value === 'object' &&
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
if (value && typeof value === 'object' && Array.isArray(value.configurations)) {
|
|
75
|
+
for (const configuration of value.configurations) {
|
|
76
|
+
if (DebugConfiguration.is(configuration)) {
|
|
77
|
+
configurations.push(configuration);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const compounds: DebugCompound[] = [];
|
|
82
|
+
if (value && typeof value === 'object' && Array.isArray(value.compounds)) {
|
|
83
|
+
for (const compound of value.compounds) {
|
|
84
|
+
if (DebugCompound.is(compound)) {
|
|
85
|
+
compounds.push(compound);
|
|
75
86
|
}
|
|
76
87
|
}
|
|
77
88
|
}
|
|
78
|
-
return {
|
|
79
|
-
uri: configUri,
|
|
80
|
-
configurations
|
|
81
|
-
};
|
|
89
|
+
return { uri: configUri, configurations, compounds };
|
|
82
90
|
}
|
|
83
91
|
|
|
84
92
|
}
|
|
@@ -86,5 +94,6 @@ export namespace DebugConfigurationModel {
|
|
|
86
94
|
export interface JsonContent {
|
|
87
95
|
uri?: URI
|
|
88
96
|
configurations: DebugConfiguration[]
|
|
97
|
+
compounds: DebugCompound[]
|
|
89
98
|
}
|
|
90
99
|
}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
import { DebugProtocol } from 'vscode
|
|
17
|
+
import { DebugProtocol } from '@vscode/debugprotocol';
|
|
18
18
|
import { DebugSessionConnection } from './debug-session-connection';
|
|
19
19
|
|
|
20
20
|
export const DebugContribution = Symbol('DebugContribution');
|
|
@@ -1122,8 +1122,9 @@ export class DebugFrontendApplicationContribution extends AbstractViewContributi
|
|
|
1122
1122
|
await this.configurations.addConfiguration();
|
|
1123
1123
|
return;
|
|
1124
1124
|
}
|
|
1125
|
-
|
|
1126
|
-
|
|
1125
|
+
|
|
1126
|
+
if (noDebug !== undefined) {
|
|
1127
|
+
if (current.configuration) {
|
|
1127
1128
|
current = {
|
|
1128
1129
|
...current,
|
|
1129
1130
|
configuration: {
|
|
@@ -1131,9 +1132,15 @@ export class DebugFrontendApplicationContribution extends AbstractViewContributi
|
|
|
1131
1132
|
noDebug
|
|
1132
1133
|
}
|
|
1133
1134
|
};
|
|
1135
|
+
} else {
|
|
1136
|
+
current = {
|
|
1137
|
+
...current,
|
|
1138
|
+
noDebug
|
|
1139
|
+
};
|
|
1134
1140
|
}
|
|
1135
|
-
await this.manager.start(current);
|
|
1136
1141
|
}
|
|
1142
|
+
|
|
1143
|
+
await this.manager.start(current);
|
|
1137
1144
|
}
|
|
1138
1145
|
|
|
1139
1146
|
get threads(): DebugThreadsWidget | undefined {
|
|
@@ -113,7 +113,7 @@ export class DebugPrefixConfiguration implements CommandContribution, CommandHan
|
|
|
113
113
|
|
|
114
114
|
for (const config of configurations) {
|
|
115
115
|
items.push({
|
|
116
|
-
label: config.
|
|
116
|
+
label: config.name,
|
|
117
117
|
description: this.workspaceService.isMultiRootWorkspaceOpened
|
|
118
118
|
? this.labelProvider.getName(new URI(config.workspaceFolderUri))
|
|
119
119
|
: '',
|
|
@@ -134,7 +134,7 @@ export class DebugPrefixConfiguration implements CommandContribution, CommandHan
|
|
|
134
134
|
for (const configuration of dynamicConfigurations) {
|
|
135
135
|
items.push({
|
|
136
136
|
label: configuration.name,
|
|
137
|
-
execute: () => this.runConfiguration({ configuration, providerType })
|
|
137
|
+
execute: () => this.runConfiguration({ name: configuration.name, configuration, providerType })
|
|
138
138
|
});
|
|
139
139
|
}
|
|
140
140
|
}
|
|
@@ -170,7 +170,7 @@ export class DebugPrefixConfiguration implements CommandContribution, CommandHan
|
|
|
170
170
|
*/
|
|
171
171
|
protected updateStatusBar(): void {
|
|
172
172
|
const text: string = this.debugConfigurationManager.current
|
|
173
|
-
? this.debugConfigurationManager.current.
|
|
173
|
+
? this.debugConfigurationManager.current.name
|
|
174
174
|
: '';
|
|
175
175
|
const icon = '$(codicon-debug-alt-small)';
|
|
176
176
|
this.statusBar.setElement(this.statusBarId, {
|
|
@@ -16,13 +16,14 @@
|
|
|
16
16
|
|
|
17
17
|
import { injectable, inject, postConstruct } from '@theia/core/shared/inversify';
|
|
18
18
|
import { JsonSchemaRegisterContext, JsonSchemaContribution } from '@theia/core/lib/browser/json-schema-store';
|
|
19
|
-
import { InMemoryResources, deepClone } from '@theia/core/lib/common';
|
|
19
|
+
import { InMemoryResources, deepClone, nls } from '@theia/core/lib/common';
|
|
20
20
|
import { IJSONSchema } from '@theia/core/lib/common/json-schema';
|
|
21
21
|
import URI from '@theia/core/lib/common/uri';
|
|
22
22
|
import { DebugService } from '../common/debug-service';
|
|
23
23
|
import { debugPreferencesSchema } from './debug-preferences';
|
|
24
24
|
import { inputsSchema } from '@theia/variable-resolver/lib/browser/variable-input-schema';
|
|
25
25
|
import { WorkspaceService } from '@theia/workspace/lib/browser';
|
|
26
|
+
import { defaultCompound } from '../common/debug-compound';
|
|
26
27
|
|
|
27
28
|
@injectable()
|
|
28
29
|
export class DebugSchemaUpdater implements JsonSchemaContribution {
|
|
@@ -73,24 +74,74 @@ export const launchSchemaId = 'vscode://schemas/launch';
|
|
|
73
74
|
const launchSchema: IJSONSchema = {
|
|
74
75
|
$id: launchSchemaId,
|
|
75
76
|
type: 'object',
|
|
76
|
-
title: 'Launch',
|
|
77
|
+
title: nls.localizeByDefault('Launch'),
|
|
77
78
|
required: [],
|
|
78
|
-
default: { version: '0.2.0', configurations: [] },
|
|
79
|
+
default: { version: '0.2.0', configurations: [], compounds: [] },
|
|
79
80
|
properties: {
|
|
80
81
|
version: {
|
|
81
82
|
type: 'string',
|
|
82
|
-
description: 'Version of this file format.',
|
|
83
|
+
description: nls.localizeByDefault('Version of this file format.'),
|
|
83
84
|
default: '0.2.0'
|
|
84
85
|
},
|
|
85
86
|
configurations: {
|
|
86
87
|
type: 'array',
|
|
87
|
-
description: 'List of configurations. Add new configurations or edit existing ones by using IntelliSense.',
|
|
88
|
+
description: nls.localizeByDefault('List of configurations. Add new configurations or edit existing ones by using IntelliSense.'),
|
|
88
89
|
items: {
|
|
89
90
|
defaultSnippets: [],
|
|
90
91
|
'type': 'object',
|
|
91
92
|
oneOf: []
|
|
92
93
|
}
|
|
93
94
|
},
|
|
95
|
+
compounds: {
|
|
96
|
+
type: 'array',
|
|
97
|
+
description: nls.localizeByDefault('List of compounds. Each compound references multiple configurations which will get launched together.'),
|
|
98
|
+
items: {
|
|
99
|
+
type: 'object',
|
|
100
|
+
required: ['name', 'configurations'],
|
|
101
|
+
properties: {
|
|
102
|
+
name: {
|
|
103
|
+
type: 'string',
|
|
104
|
+
description: nls.localizeByDefault('Name of compound. Appears in the launch configuration drop down menu.')
|
|
105
|
+
},
|
|
106
|
+
configurations: {
|
|
107
|
+
type: 'array',
|
|
108
|
+
default: [],
|
|
109
|
+
items: {
|
|
110
|
+
oneOf: [{
|
|
111
|
+
type: 'string',
|
|
112
|
+
description: nls.localizeByDefault('Please use unique configuration names.')
|
|
113
|
+
}, {
|
|
114
|
+
type: 'object',
|
|
115
|
+
required: ['name'],
|
|
116
|
+
properties: {
|
|
117
|
+
name: {
|
|
118
|
+
enum: [],
|
|
119
|
+
description: nls.localizeByDefault('Name of compound. Appears in the launch configuration drop down menu.')
|
|
120
|
+
},
|
|
121
|
+
folder: {
|
|
122
|
+
enum: [],
|
|
123
|
+
description: nls.localizeByDefault('Name of folder in which the compound is located.')
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}]
|
|
127
|
+
},
|
|
128
|
+
description: nls.localizeByDefault('Names of configurations that will be started as part of this compound.')
|
|
129
|
+
},
|
|
130
|
+
stopAll: {
|
|
131
|
+
type: 'boolean',
|
|
132
|
+
default: false,
|
|
133
|
+
description: nls.localizeByDefault('Controls whether manually terminating one session will stop all of the compound sessions.')
|
|
134
|
+
},
|
|
135
|
+
preLaunchTask: {
|
|
136
|
+
type: 'string',
|
|
137
|
+
default: '',
|
|
138
|
+
description: nls.localizeByDefault('Task to run before any of the compound configurations start.')
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
default: defaultCompound
|
|
142
|
+
},
|
|
143
|
+
default: [defaultCompound]
|
|
144
|
+
},
|
|
94
145
|
inputs: inputsSchema.definitions!.inputs
|
|
95
146
|
},
|
|
96
147
|
allowComments: true,
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
18
18
|
|
|
19
|
-
import { DebugProtocol } from 'vscode
|
|
19
|
+
import { DebugProtocol } from '@vscode/debugprotocol';
|
|
20
20
|
import { Deferred } from '@theia/core/lib/common/promise-util';
|
|
21
21
|
import { Event, Emitter, DisposableCollection, Disposable, MaybePromise } from '@theia/core';
|
|
22
22
|
import { OutputChannel } from '@theia/output/lib/browser/output-channel';
|
|
@@ -22,7 +22,7 @@ import { TerminalService } from '@theia/terminal/lib/browser/base/terminal-servi
|
|
|
22
22
|
import { WebSocketConnectionProvider } from '@theia/core/lib/browser/messaging/ws-connection-provider';
|
|
23
23
|
import { DebugSession } from './debug-session';
|
|
24
24
|
import { BreakpointManager } from './breakpoint/breakpoint-manager';
|
|
25
|
-
import { DebugSessionOptions } from './debug-session-options';
|
|
25
|
+
import { DebugConfigurationSessionOptions, DebugSessionOptions } from './debug-session-options';
|
|
26
26
|
import { OutputChannelManager, OutputChannel } from '@theia/output/lib/browser/output-channel';
|
|
27
27
|
import { DebugPreferences } from './debug-preferences';
|
|
28
28
|
import { DebugSessionConnection } from './debug-session-connection';
|
|
@@ -118,7 +118,7 @@ export class DefaultDebugSessionFactory implements DebugSessionFactory {
|
|
|
118
118
|
@inject(WorkspaceService)
|
|
119
119
|
protected readonly workspaceService: WorkspaceService;
|
|
120
120
|
|
|
121
|
-
get(sessionId: string, options:
|
|
121
|
+
get(sessionId: string, options: DebugConfigurationSessionOptions, parentSession?: DebugSession): DebugSession {
|
|
122
122
|
const connection = new DebugSessionConnection(
|
|
123
123
|
sessionId,
|
|
124
124
|
() => new Promise<DebugChannel>(resolve =>
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
import { DisposableCollection, Emitter, Event, MessageService, ProgressService, WaitUntilEvent } from '@theia/core';
|
|
17
|
+
import { DisposableCollection, Emitter, Event, MessageService, nls, ProgressService, WaitUntilEvent } from '@theia/core';
|
|
18
18
|
import { LabelProvider, ApplicationShell } from '@theia/core/lib/browser';
|
|
19
19
|
import { ContextKey, ContextKeyService } from '@theia/core/lib/browser/context-key-service';
|
|
20
20
|
import URI from '@theia/core/lib/common/uri';
|
|
@@ -29,7 +29,7 @@ import { BreakpointManager } from './breakpoint/breakpoint-manager';
|
|
|
29
29
|
import { DebugConfigurationManager } from './debug-configuration-manager';
|
|
30
30
|
import { DebugSession, DebugState } from './debug-session';
|
|
31
31
|
import { DebugSessionContributionRegistry, DebugSessionFactory } from './debug-session-contribution';
|
|
32
|
-
import { DebugSessionOptions, InternalDebugSessionOptions } from './debug-session-options';
|
|
32
|
+
import { DebugCompoundRoot, DebugCompoundSessionOptions, DebugConfigurationSessionOptions, DebugSessionOptions, InternalDebugSessionOptions } from './debug-session-options';
|
|
33
33
|
import { DebugStackFrame } from './model/debug-stack-frame';
|
|
34
34
|
import { DebugThread } from './model/debug-thread';
|
|
35
35
|
import { TaskIdentifier } from '@theia/task/lib/common';
|
|
@@ -191,7 +191,19 @@ export class DebugSessionManager {
|
|
|
191
191
|
}
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
-
async start(options:
|
|
194
|
+
async start(options: DebugCompoundSessionOptions): Promise<boolean | undefined>;
|
|
195
|
+
async start(options: DebugConfigurationSessionOptions): Promise<DebugSession | undefined>;
|
|
196
|
+
async start(options: DebugSessionOptions): Promise<DebugSession | boolean | undefined>;
|
|
197
|
+
async start(name: string): Promise<DebugSession | boolean | undefined>;
|
|
198
|
+
async start(optionsOrName: DebugSessionOptions | string): Promise<DebugSession | boolean | undefined> {
|
|
199
|
+
if (typeof optionsOrName === 'string') {
|
|
200
|
+
const options = this.debugConfigurationManager.find(optionsOrName);
|
|
201
|
+
return !!options && this.start(options);
|
|
202
|
+
}
|
|
203
|
+
return optionsOrName.configuration ? this.startConfiguration(optionsOrName) : this.startCompound(optionsOrName);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
protected async startConfiguration(options: DebugConfigurationSessionOptions): Promise<DebugSession | undefined> {
|
|
195
207
|
return this.progressService.withProgress('Start...', 'debug', async () => {
|
|
196
208
|
try {
|
|
197
209
|
if (!await this.saveAll()) {
|
|
@@ -200,7 +212,7 @@ export class DebugSessionManager {
|
|
|
200
212
|
await this.fireWillStartDebugSession();
|
|
201
213
|
const resolved = await this.resolveConfiguration(options);
|
|
202
214
|
|
|
203
|
-
if (!resolved) {
|
|
215
|
+
if (!resolved || !resolved.configuration) {
|
|
204
216
|
// As per vscode API: https://code.visualstudio.com/api/references/vscode-api#DebugConfigurationProvider
|
|
205
217
|
// "Returning the value 'undefined' prevents the debug session from starting.
|
|
206
218
|
// Returning the value 'null' prevents the debug session from starting and opens the
|
|
@@ -236,13 +248,70 @@ export class DebugSessionManager {
|
|
|
236
248
|
});
|
|
237
249
|
}
|
|
238
250
|
|
|
251
|
+
protected async startCompound(options: DebugCompoundSessionOptions): Promise<boolean | undefined> {
|
|
252
|
+
let configurations: DebugConfigurationSessionOptions[] = [];
|
|
253
|
+
try {
|
|
254
|
+
configurations = this.getCompoundConfigurations(options);
|
|
255
|
+
} catch (error) {
|
|
256
|
+
this.messageService.error(error.message);
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (options.compound.preLaunchTask) {
|
|
261
|
+
const taskRun = await this.runTask(options.workspaceFolderUri, options.compound.preLaunchTask, true);
|
|
262
|
+
if (!taskRun) {
|
|
263
|
+
return undefined;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Compound launch is a success only if each configuration launched successfully
|
|
268
|
+
const values = await Promise.all(configurations.map(configuration => this.startConfiguration(configuration)));
|
|
269
|
+
const result = values.every(success => !!success);
|
|
270
|
+
return result;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
protected getCompoundConfigurations(options: DebugCompoundSessionOptions): DebugConfigurationSessionOptions[] {
|
|
274
|
+
const compound = options.compound;
|
|
275
|
+
if (!compound.configurations) {
|
|
276
|
+
throw new Error(nls.localizeByDefault('Compound must have "configurations" attribute set in order to start multiple configurations.'));
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const compoundRoot = compound.stopAll ? new DebugCompoundRoot() : undefined;
|
|
280
|
+
const configurations: DebugConfigurationSessionOptions[] = [];
|
|
281
|
+
for (const configData of compound.configurations) {
|
|
282
|
+
const name = typeof configData === 'string' ? configData : configData.name;
|
|
283
|
+
if (name === compound.name) {
|
|
284
|
+
throw new Error(nls.localize('theia/debug/compound-cycle', "Launch configuration '{0}' contains a cycle with itself", name));
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const workspaceFolderUri = typeof configData === 'string' ? options.workspaceFolderUri : configData.folder;
|
|
288
|
+
const matchingOptions = [...this.debugConfigurationManager.all]
|
|
289
|
+
.filter(option => option.name === name && !!option.configuration && option.workspaceFolderUri === workspaceFolderUri);
|
|
290
|
+
if (matchingOptions.length === 1) {
|
|
291
|
+
const match = matchingOptions[0];
|
|
292
|
+
if (DebugSessionOptions.isConfiguration(match)) {
|
|
293
|
+
configurations.push({ ...match, compoundRoot, configuration: { ...match.configuration, noDebug: options.noDebug } });
|
|
294
|
+
} else {
|
|
295
|
+
throw new Error(nls.localizeByDefault("Could not find launch configuration '{0}' in the workspace.", name));
|
|
296
|
+
}
|
|
297
|
+
} else {
|
|
298
|
+
throw new Error(matchingOptions.length === 0
|
|
299
|
+
? workspaceFolderUri
|
|
300
|
+
? nls.localizeByDefault("Can not find folder with name '{0}' for configuration '{1}' in compound '{2}'.", workspaceFolderUri, name, compound.name)
|
|
301
|
+
: nls.localizeByDefault("Could not find launch configuration '{0}' in the workspace.", name)
|
|
302
|
+
: nls.localizeByDefault("There are multiple launch configurations '{0}' in the workspace. Use folder name to qualify the configuration.", name));
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return configurations;
|
|
306
|
+
}
|
|
307
|
+
|
|
239
308
|
protected async fireWillStartDebugSession(): Promise<void> {
|
|
240
309
|
await WaitUntilEvent.fire(this.onWillStartDebugSessionEmitter, {});
|
|
241
310
|
}
|
|
242
311
|
|
|
243
312
|
protected configurationIds = new Map<string, number>();
|
|
244
313
|
protected async resolveConfiguration(
|
|
245
|
-
options: Readonly<
|
|
314
|
+
options: Readonly<DebugConfigurationSessionOptions>
|
|
246
315
|
): Promise<InternalDebugSessionOptions | undefined | null> {
|
|
247
316
|
if (InternalDebugSessionOptions.is(options)) {
|
|
248
317
|
return options;
|
|
@@ -275,10 +344,12 @@ export class DebugSessionManager {
|
|
|
275
344
|
const key = configuration.name + workspaceFolderUri;
|
|
276
345
|
const id = this.configurationIds.has(key) ? this.configurationIds.get(key)! + 1 : 0;
|
|
277
346
|
this.configurationIds.set(key, id);
|
|
347
|
+
|
|
278
348
|
return {
|
|
279
349
|
id,
|
|
280
|
-
|
|
281
|
-
|
|
350
|
+
...options,
|
|
351
|
+
name: configuration.name,
|
|
352
|
+
configuration
|
|
282
353
|
};
|
|
283
354
|
}
|
|
284
355
|
|
|
@@ -301,7 +372,7 @@ export class DebugSessionManager {
|
|
|
301
372
|
return this.debug.resolveDebugConfigurationWithSubstitutedVariables(configuration, workspaceFolderUri);
|
|
302
373
|
}
|
|
303
374
|
|
|
304
|
-
protected async doStart(sessionId: string, options:
|
|
375
|
+
protected async doStart(sessionId: string, options: DebugConfigurationSessionOptions): Promise<DebugSession> {
|
|
305
376
|
const parentSession = options.configuration.parentSession && this._sessions.get(options.configuration.parentSession.id);
|
|
306
377
|
const contrib = this.sessionContributionRegistry.get(options.configuration.type);
|
|
307
378
|
const sessionFactory = contrib ? contrib.debugSessionFactory() : this.debugSessionFactory;
|