@theia/debug 1.18.0-next.0f7dec1a → 1.18.0-next.104
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/LICENSE +642 -0
- package/lib/browser/console/debug-console-items.d.ts +2 -1
- package/lib/browser/console/debug-console-items.d.ts.map +1 -1
- package/lib/browser/console/debug-console-items.js +4 -1
- package/lib/browser/console/debug-console-items.js.map +1 -1
- package/lib/browser/console/debug-console-session.d.ts +1 -1
- package/lib/browser/debug-configuration-manager.d.ts +7 -0
- package/lib/browser/debug-configuration-manager.d.ts.map +1 -1
- package/lib/browser/debug-configuration-manager.js +20 -8
- package/lib/browser/debug-configuration-manager.js.map +1 -1
- package/lib/browser/debug-frontend-application-contribution.d.ts +1 -0
- package/lib/browser/debug-frontend-application-contribution.d.ts.map +1 -1
- package/lib/browser/debug-frontend-application-contribution.js +3 -0
- package/lib/browser/debug-frontend-application-contribution.js.map +1 -1
- package/lib/browser/debug-preferences.d.ts +1 -0
- package/lib/browser/debug-preferences.d.ts.map +1 -1
- package/lib/browser/debug-preferences.js +10 -0
- package/lib/browser/debug-preferences.js.map +1 -1
- package/lib/browser/debug-prefix-configuration.d.ts +1 -1
- package/lib/browser/debug-prefix-configuration.d.ts.map +1 -1
- package/lib/browser/debug-prefix-configuration.js +20 -3
- package/lib/browser/debug-prefix-configuration.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 +1 -1
- package/lib/browser/debug-session-contribution.d.ts.map +1 -1
- package/lib/browser/debug-session-contribution.js +1 -1
- package/lib/browser/debug-session-contribution.js.map +1 -1
- package/lib/browser/view/debug-configuration-widget.d.ts +1 -1
- package/lib/browser/view/debug-configuration-widget.d.ts.map +1 -1
- package/lib/browser/view/debug-configuration-widget.js +2 -3
- package/lib/browser/view/debug-configuration-widget.js.map +1 -1
- package/lib/browser/view/debug-session-widget.d.ts +2 -1
- package/lib/browser/view/debug-session-widget.d.ts.map +1 -1
- package/lib/browser/view/debug-session-widget.js +12 -6
- package/lib/browser/view/debug-session-widget.js.map +1 -1
- package/lib/common/debug-configuration.d.ts +2 -0
- package/lib/common/debug-configuration.d.ts.map +1 -1
- package/lib/common/debug-configuration.js.map +1 -1
- package/lib/common/debug-service.d.ts +8 -0
- package/lib/common/debug-service.d.ts.map +1 -1
- package/lib/common/debug-service.js.map +1 -1
- package/lib/node/debug-adapter-contribution-registry.d.ts +1 -1
- package/lib/node/debug-adapter-contribution-registry.d.ts.map +1 -1
- package/lib/node/debug-adapter-contribution-registry.js +1 -1
- package/lib/node/debug-adapter-contribution-registry.js.map +1 -1
- package/lib/node/debug-adapter-factory.d.ts +1 -1
- package/lib/node/debug-adapter-factory.d.ts.map +1 -1
- package/lib/node/debug-adapter-factory.js +8 -10
- package/lib/node/debug-adapter-factory.js.map +1 -1
- package/lib/node/debug-adapter-session-manager.d.ts +1 -1
- package/lib/node/debug-adapter-session-manager.d.ts.map +1 -1
- package/lib/node/debug-adapter-session-manager.js +1 -1
- package/lib/node/debug-adapter-session-manager.js.map +1 -1
- package/lib/node/debug-adapter-session.d.ts +1 -7
- package/lib/node/debug-adapter-session.d.ts.map +1 -1
- package/lib/node/debug-adapter-session.js +4 -48
- package/lib/node/debug-adapter-session.js.map +1 -1
- package/lib/node/debug-backend-module.js +1 -1
- package/lib/node/debug-backend-module.js.map +1 -1
- package/lib/{common → node}/debug-model.d.ts +6 -5
- package/lib/node/debug-model.d.ts.map +1 -0
- package/lib/{common → node}/debug-model.js +0 -0
- package/lib/node/debug-model.js.map +1 -0
- package/lib/node/inline-communication-provider.d.ts +33 -0
- package/lib/node/inline-communication-provider.d.ts.map +1 -0
- package/lib/node/inline-communication-provider.js +43 -0
- package/lib/node/inline-communication-provider.js.map +1 -0
- package/lib/node/stream-communication-provider.d.ts +38 -0
- package/lib/node/stream-communication-provider.d.ts.map +1 -0
- package/lib/node/stream-communication-provider.js +88 -0
- package/lib/node/stream-communication-provider.js.map +1 -0
- package/lib/node/vscode/vscode-debug-adapter-contribution.d.ts +1 -1
- package/lib/node/vscode/vscode-debug-adapter-contribution.d.ts.map +1 -1
- package/package.json +22 -20
- package/src/browser/console/debug-console-items.tsx +6 -2
- package/src/browser/debug-configuration-manager.ts +26 -9
- package/src/browser/debug-frontend-application-contribution.ts +6 -2
- package/src/browser/debug-preferences.ts +11 -0
- package/src/browser/debug-prefix-configuration.ts +24 -3
- package/src/browser/debug-session-connection.ts +1 -1
- package/src/browser/debug-session-contribution.ts +1 -1
- package/src/browser/view/debug-configuration-widget.tsx +1 -2
- package/src/browser/view/debug-session-widget.ts +12 -6
- package/src/common/debug-configuration.ts +3 -0
- package/src/common/debug-service.ts +6 -0
- package/src/node/debug-adapter-contribution-registry.ts +1 -1
- package/src/node/debug-adapter-factory.ts +10 -11
- package/src/node/debug-adapter-session-manager.ts +1 -1
- package/src/node/debug-adapter-session.ts +8 -57
- package/src/node/debug-backend-module.ts +1 -1
- package/src/{common → node}/debug-model.ts +6 -4
- package/src/node/inline-communication-provider.ts +44 -0
- package/src/node/stream-communication-provider.ts +93 -0
- package/src/node/vscode/vscode-debug-adapter-contribution.ts +1 -1
- package/lib/common/debug-model.d.ts.map +0 -1
- package/lib/common/debug-model.js.map +0 -1
|
@@ -49,6 +49,16 @@ export const debugPreferencesSchema: PreferenceSchema = {
|
|
|
49
49
|
enum: ['never', 'always', 'onFirstSessionStart'],
|
|
50
50
|
description: 'Controls when the debug status bar should be visible.',
|
|
51
51
|
default: 'onFirstSessionStart'
|
|
52
|
+
},
|
|
53
|
+
'debug.confirmOnExit': {
|
|
54
|
+
description: 'Controls whether to confirm when the window closes if there are active debug sessions.',
|
|
55
|
+
type: 'string',
|
|
56
|
+
enum: ['never', 'always'],
|
|
57
|
+
enumDescriptions: [
|
|
58
|
+
'Never confirm.',
|
|
59
|
+
'Always confirm if there are debug sessions.',
|
|
60
|
+
],
|
|
61
|
+
default: 'never'
|
|
52
62
|
}
|
|
53
63
|
}
|
|
54
64
|
};
|
|
@@ -60,6 +70,7 @@ export class DebugConfiguration {
|
|
|
60
70
|
'debug.internalConsoleOptions': 'neverOpen' | 'openOnSessionStart' | 'openOnFirstSessionStart';
|
|
61
71
|
'debug.inlineValues': boolean;
|
|
62
72
|
'debug.showInStatusBar': 'never' | 'always' | 'onFirstSessionStart';
|
|
73
|
+
'debug.confirmOnExit': 'never' | 'always';
|
|
63
74
|
}
|
|
64
75
|
|
|
65
76
|
export const DebugPreferenceContribution = Symbol('DebugPreferenceContribution');
|
|
@@ -107,10 +107,11 @@ export class DebugPrefixConfiguration implements CommandContribution, CommandHan
|
|
|
107
107
|
});
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
getPicks(filter: string, token: CancellationToken): QuickPicks {
|
|
110
|
+
async getPicks(filter: string, token: CancellationToken): Promise<QuickPicks> {
|
|
111
111
|
const items: QuickPickItem[] = [];
|
|
112
112
|
const configurations = this.debugConfigurationManager.all;
|
|
113
|
-
|
|
113
|
+
|
|
114
|
+
for (const config of configurations) {
|
|
114
115
|
items.push({
|
|
115
116
|
label: config.configuration.name,
|
|
116
117
|
description: this.workspaceService.isMultiRootWorkspaceOpened
|
|
@@ -118,7 +119,27 @@ export class DebugPrefixConfiguration implements CommandContribution, CommandHan
|
|
|
118
119
|
: '',
|
|
119
120
|
execute: () => this.runConfiguration(config)
|
|
120
121
|
});
|
|
121
|
-
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Resolve dynamic configurations from providers
|
|
125
|
+
const configurationsByType = await this.debugConfigurationManager.provideDynamicDebugConfigurations();
|
|
126
|
+
for (const typeConfigurations of configurationsByType) {
|
|
127
|
+
const dynamicConfigurations = typeConfigurations.configurations;
|
|
128
|
+
if (dynamicConfigurations.length > 0) {
|
|
129
|
+
items.push({
|
|
130
|
+
label: typeConfigurations.type,
|
|
131
|
+
type: 'separator'
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
for (const configuration of dynamicConfigurations) {
|
|
136
|
+
items.push({
|
|
137
|
+
label: configuration.name,
|
|
138
|
+
execute: () => this.runConfiguration({configuration})
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
122
143
|
return filterItems(items, filter);
|
|
123
144
|
}
|
|
124
145
|
|
|
@@ -19,7 +19,7 @@
|
|
|
19
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
|
-
import { OutputChannel } from '@theia/output/lib/
|
|
22
|
+
import { OutputChannel } from '@theia/output/lib/browser/output-channel';
|
|
23
23
|
import { IWebSocket } from '@theia/core/shared/vscode-ws-jsonrpc';
|
|
24
24
|
|
|
25
25
|
export interface DebugExitEvent {
|
|
@@ -23,7 +23,7 @@ import { WebSocketConnectionProvider } from '@theia/core/lib/browser/messaging/w
|
|
|
23
23
|
import { DebugSession } from './debug-session';
|
|
24
24
|
import { BreakpointManager } from './breakpoint/breakpoint-manager';
|
|
25
25
|
import { DebugSessionOptions } from './debug-session-options';
|
|
26
|
-
import { OutputChannelManager, OutputChannel } from '@theia/output/lib/
|
|
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';
|
|
29
29
|
import { IWebSocket } from '@theia/core/shared/vscode-ws-jsonrpc';
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import * as React from '@theia/core/shared/react';
|
|
18
18
|
import { injectable, inject, postConstruct } from '@theia/core/shared/inversify';
|
|
19
|
-
import { Disposable } from '@theia/core/lib/common';
|
|
19
|
+
import { CommandRegistry, Disposable } from '@theia/core/lib/common';
|
|
20
20
|
import URI from '@theia/core/lib/common/uri';
|
|
21
21
|
import { ReactWidget } from '@theia/core/lib/browser';
|
|
22
22
|
import { WorkspaceService } from '@theia/workspace/lib/browser';
|
|
@@ -27,7 +27,6 @@ import { DebugAction } from './debug-action';
|
|
|
27
27
|
import { DebugViewModel } from './debug-view-model';
|
|
28
28
|
import { DebugSessionOptions } from '../debug-session-options';
|
|
29
29
|
import { DebugCommands } from '../debug-frontend-application-contribution';
|
|
30
|
-
import { CommandRegistry } from '@theia/core/lib/common';
|
|
31
30
|
|
|
32
31
|
@injectable()
|
|
33
32
|
export class DebugConfigurationWidget extends ReactWidget {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import { inject, injectable, postConstruct, interfaces, Container } from '@theia/core/shared/inversify';
|
|
18
18
|
import {
|
|
19
|
-
Message, ApplicationShell, Widget, BaseWidget, PanelLayout, StatefulWidget, ViewContainer, codicon
|
|
19
|
+
Message, ApplicationShell, Widget, BaseWidget, PanelLayout, StatefulWidget, ViewContainer, codicon, ViewContainerTitleOptions
|
|
20
20
|
} from '@theia/core/lib/browser';
|
|
21
21
|
import { DebugThreadsWidget } from './debug-threads-widget';
|
|
22
22
|
import { DebugStackFramesWidget } from './debug-stack-frames-widget';
|
|
@@ -28,6 +28,11 @@ import { DebugWatchWidget } from './debug-watch-widget';
|
|
|
28
28
|
|
|
29
29
|
export const DebugSessionWidgetFactory = Symbol('DebugSessionWidgetFactory');
|
|
30
30
|
export type DebugSessionWidgetFactory = (options: DebugViewOptions) => DebugSessionWidget;
|
|
31
|
+
export const DEBUG_VIEW_CONTAINER_TITLE_OPTIONS: ViewContainerTitleOptions = {
|
|
32
|
+
label: 'debug',
|
|
33
|
+
iconClass: codicon('debug-alt'),
|
|
34
|
+
closeable: true
|
|
35
|
+
};
|
|
31
36
|
|
|
32
37
|
@injectable()
|
|
33
38
|
export class DebugSessionWidget extends BaseWidget implements StatefulWidget, ApplicationShell.TrackableWidgetProvider {
|
|
@@ -88,11 +93,12 @@ export class DebugSessionWidget extends BaseWidget implements StatefulWidget, Ap
|
|
|
88
93
|
this.viewContainer = this.viewContainerFactory({
|
|
89
94
|
id: 'debug:view-container:' + this.model.id
|
|
90
95
|
});
|
|
91
|
-
this.viewContainer.
|
|
92
|
-
this.viewContainer.addWidget(this.
|
|
93
|
-
this.viewContainer.addWidget(this.
|
|
94
|
-
this.viewContainer.addWidget(this.
|
|
95
|
-
this.viewContainer.addWidget(this.
|
|
96
|
+
this.viewContainer.setTitleOptions(DEBUG_VIEW_CONTAINER_TITLE_OPTIONS);
|
|
97
|
+
this.viewContainer.addWidget(this.threads, { weight: 30, disableDraggingToOtherContainers: true });
|
|
98
|
+
this.viewContainer.addWidget(this.stackFrames, { weight: 20, disableDraggingToOtherContainers: true });
|
|
99
|
+
this.viewContainer.addWidget(this.variables, { weight: 10, disableDraggingToOtherContainers: true });
|
|
100
|
+
this.viewContainer.addWidget(this.watch, { weight: 10, disableDraggingToOtherContainers: true });
|
|
101
|
+
this.viewContainer.addWidget(this.breakpoints, { weight: 10, disableDraggingToOtherContainers: true });
|
|
96
102
|
|
|
97
103
|
this.toDispose.pushAll([
|
|
98
104
|
this.toolbar,
|
|
@@ -74,6 +74,9 @@ export interface DebugConfiguration {
|
|
|
74
74
|
|
|
75
75
|
/** Task to run after debug session ends */
|
|
76
76
|
postDebugTask?: string | TaskIdentifier;
|
|
77
|
+
|
|
78
|
+
/** Indicates if it's a dynamic debug configuration */
|
|
79
|
+
dynamic?: boolean;
|
|
77
80
|
}
|
|
78
81
|
export namespace DebugConfiguration {
|
|
79
82
|
export function is(arg: DebugConfiguration | any): arg is DebugConfiguration {
|
|
@@ -70,6 +70,12 @@ export interface DebugService extends Disposable {
|
|
|
70
70
|
*/
|
|
71
71
|
provideDebugConfigurations(debugType: string, workspaceFolderUri: string | undefined): Promise<DebugConfiguration[]>;
|
|
72
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Provides dynamic debug configurations by a provider debug type
|
|
75
|
+
* @returns An Array of objects containing the debug type and corresponding dynamic debug configurations array
|
|
76
|
+
*/
|
|
77
|
+
provideDynamicDebugConfigurations?(): Promise<{ type: string, configurations: DebugConfiguration[] }[]>;
|
|
78
|
+
|
|
73
79
|
/**
|
|
74
80
|
* Resolves a [debug configuration](#DebugConfiguration) by filling in missing values
|
|
75
81
|
* or by adding/changing/removing attributes before variable substitution.
|
|
@@ -19,7 +19,7 @@ import { ContributionProvider } from '@theia/core';
|
|
|
19
19
|
import { DebugConfiguration } from '../common/debug-configuration';
|
|
20
20
|
import { DebuggerDescription, DebugError } from '../common/debug-service';
|
|
21
21
|
|
|
22
|
-
import { DebugAdapterContribution, DebugAdapterExecutable, DebugAdapterSessionFactory } from '
|
|
22
|
+
import { DebugAdapterContribution, DebugAdapterExecutable, DebugAdapterSessionFactory } from './debug-model';
|
|
23
23
|
import { IJSONSchema, IJSONSchemaSnippet } from '@theia/core/lib/common/json-schema';
|
|
24
24
|
|
|
25
25
|
/**
|
|
@@ -37,9 +37,11 @@ import {
|
|
|
37
37
|
DebugAdapterSessionFactory,
|
|
38
38
|
DebugAdapterFactory,
|
|
39
39
|
DebugAdapterForkExecutable
|
|
40
|
-
} from '
|
|
40
|
+
} from './debug-model';
|
|
41
41
|
import { DebugAdapterSessionImpl } from './debug-adapter-session';
|
|
42
42
|
import { environment } from '@theia/core/shared/@theia/application-package';
|
|
43
|
+
import { StreamCommunicationProvider } from './stream-communication-provider';
|
|
44
|
+
import { Disposable } from '@theia/core/lib/common/disposable';
|
|
43
45
|
|
|
44
46
|
/**
|
|
45
47
|
* [DebugAdapterFactory](#DebugAdapterFactory) implementation based on
|
|
@@ -56,11 +58,9 @@ export class LaunchBasedDebugAdapterFactory implements DebugAdapterFactory {
|
|
|
56
58
|
const process = this.childProcess(executable);
|
|
57
59
|
|
|
58
60
|
// FIXME: propagate onError + onExit
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
dispose: () => process.kill()
|
|
63
|
-
};
|
|
61
|
+
const provider = new StreamCommunicationProvider(process.outputStream, process.inputStream);
|
|
62
|
+
provider.push(Disposable.create(() => process.kill()));
|
|
63
|
+
return provider;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
private childProcess(executable: DebugAdapterExecutable): RawProcess {
|
|
@@ -84,11 +84,10 @@ export class LaunchBasedDebugAdapterFactory implements DebugAdapterFactory {
|
|
|
84
84
|
connect(debugServerPort: number): CommunicationProvider {
|
|
85
85
|
const socket = net.createConnection(debugServerPort);
|
|
86
86
|
// FIXME: propagate socket.on('error', ...) + socket.on('close', ...)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
};
|
|
87
|
+
|
|
88
|
+
const provider = new StreamCommunicationProvider(socket, socket);
|
|
89
|
+
provider.push(Disposable.create(() => socket.end()));
|
|
90
|
+
return provider;
|
|
92
91
|
}
|
|
93
92
|
}
|
|
94
93
|
|
|
@@ -20,7 +20,7 @@ import { MessagingService } from '@theia/core/lib/node/messaging/messaging-servi
|
|
|
20
20
|
|
|
21
21
|
import { DebugAdapterPath } from '../common/debug-service';
|
|
22
22
|
import { DebugConfiguration } from '../common/debug-configuration';
|
|
23
|
-
import { DebugAdapterSession, DebugAdapterSessionFactory, DebugAdapterFactory } from '
|
|
23
|
+
import { DebugAdapterSession, DebugAdapterSessionFactory, DebugAdapterFactory } from './debug-model';
|
|
24
24
|
import { DebugAdapterContributionRegistry } from './debug-adapter-contribution-registry';
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
|
|
24
24
|
import {
|
|
25
25
|
CommunicationProvider,
|
|
26
|
-
DebugAdapterSession
|
|
27
|
-
} from '
|
|
26
|
+
DebugAdapterSession
|
|
27
|
+
} from './debug-model';
|
|
28
28
|
import { DebugProtocol } from 'vscode-debugprotocol';
|
|
29
29
|
import { IWebSocket } from '@theia/core/shared/vscode-ws-jsonrpc';
|
|
30
30
|
import { DisposableCollection, Disposable } from '@theia/core/lib/common/disposable';
|
|
@@ -34,25 +34,23 @@ import { DisposableCollection, Disposable } from '@theia/core/lib/common/disposa
|
|
|
34
34
|
*/
|
|
35
35
|
export class DebugAdapterSessionImpl implements DebugAdapterSession {
|
|
36
36
|
|
|
37
|
-
private static TWO_CRLF = '\r\n\r\n';
|
|
38
|
-
private static CONTENT_LENGTH = 'Content-Length';
|
|
39
|
-
|
|
40
37
|
private readonly toDispose = new DisposableCollection();
|
|
41
38
|
private channel: IWebSocket | undefined;
|
|
42
|
-
private contentLength: number;
|
|
43
|
-
private buffer: Buffer;
|
|
44
39
|
|
|
45
40
|
constructor(
|
|
46
41
|
readonly id: string,
|
|
47
42
|
protected readonly communicationProvider: CommunicationProvider
|
|
48
43
|
) {
|
|
49
|
-
this.contentLength = -1;
|
|
50
|
-
this.buffer = Buffer.alloc(0);
|
|
51
44
|
this.toDispose.pushAll([
|
|
52
45
|
this.communicationProvider,
|
|
53
46
|
Disposable.create(() => this.write(JSON.stringify({ seq: -1, type: 'request', command: 'disconnect' }))),
|
|
54
47
|
Disposable.create(() => this.write(JSON.stringify({ seq: -1, type: 'request', command: 'terminate' })))
|
|
55
48
|
]);
|
|
49
|
+
|
|
50
|
+
this.communicationProvider.onMessageReceived((message: string) => this.send(message));
|
|
51
|
+
this.communicationProvider.onClose(() => this.onDebugAdapterExit(1, undefined)); // FIXME pass a proper exit code
|
|
52
|
+
this.communicationProvider.onError(error => this.onDebugAdapterError(error));
|
|
53
|
+
|
|
56
54
|
}
|
|
57
55
|
|
|
58
56
|
async start(channel: IWebSocket): Promise<void> {
|
|
@@ -63,10 +61,6 @@ export class DebugAdapterSessionImpl implements DebugAdapterSession {
|
|
|
63
61
|
this.channel.onMessage((message: string) => this.write(message));
|
|
64
62
|
this.channel.onClose(() => this.channel = undefined);
|
|
65
63
|
|
|
66
|
-
this.communicationProvider.output.on('data', (data: Buffer) => this.handleData(data));
|
|
67
|
-
this.communicationProvider.output.on('close', () => this.onDebugAdapterExit(1, undefined)); // FIXME pass a proper exit code
|
|
68
|
-
this.communicationProvider.output.on('error', error => this.onDebugAdapterError(error));
|
|
69
|
-
this.communicationProvider.input.on('error', error => this.onDebugAdapterError(error));
|
|
70
64
|
}
|
|
71
65
|
|
|
72
66
|
protected onDebugAdapterExit(exitCode: number, signal: string | undefined): void {
|
|
@@ -91,49 +85,6 @@ export class DebugAdapterSessionImpl implements DebugAdapterSession {
|
|
|
91
85
|
this.send(JSON.stringify(event));
|
|
92
86
|
}
|
|
93
87
|
|
|
94
|
-
protected handleData(data: Buffer): void {
|
|
95
|
-
this.buffer = Buffer.concat([this.buffer, data]);
|
|
96
|
-
|
|
97
|
-
while (true) {
|
|
98
|
-
if (this.contentLength >= 0) {
|
|
99
|
-
if (this.buffer.length >= this.contentLength) {
|
|
100
|
-
const message = this.buffer.toString('utf8', 0, this.contentLength);
|
|
101
|
-
this.buffer = this.buffer.slice(this.contentLength);
|
|
102
|
-
this.contentLength = -1;
|
|
103
|
-
|
|
104
|
-
if (message.length > 0) {
|
|
105
|
-
this.send(message);
|
|
106
|
-
}
|
|
107
|
-
continue; // there may be more complete messages to process
|
|
108
|
-
}
|
|
109
|
-
} else {
|
|
110
|
-
let idx = this.buffer.indexOf(DebugAdapterSessionImpl.CONTENT_LENGTH);
|
|
111
|
-
if (idx > 0) {
|
|
112
|
-
// log unrecognized output
|
|
113
|
-
const output = this.buffer.slice(0, idx);
|
|
114
|
-
console.log(output.toString('utf-8'));
|
|
115
|
-
|
|
116
|
-
this.buffer = this.buffer.slice(idx);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
idx = this.buffer.indexOf(DebugAdapterSessionImpl.TWO_CRLF);
|
|
120
|
-
if (idx !== -1) {
|
|
121
|
-
const header = this.buffer.toString('utf8', 0, idx);
|
|
122
|
-
const lines = header.split('\r\n');
|
|
123
|
-
for (let i = 0; i < lines.length; i++) {
|
|
124
|
-
const pair = lines[i].split(/: +/);
|
|
125
|
-
if (pair[0] === DebugAdapterSessionImpl.CONTENT_LENGTH) {
|
|
126
|
-
this.contentLength = +pair[1];
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
this.buffer = this.buffer.slice(idx + DebugAdapterSessionImpl.TWO_CRLF.length);
|
|
130
|
-
continue;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
break;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
88
|
protected send(message: string): void {
|
|
138
89
|
if (this.channel) {
|
|
139
90
|
this.channel.send(message);
|
|
@@ -141,7 +92,7 @@ export class DebugAdapterSessionImpl implements DebugAdapterSession {
|
|
|
141
92
|
}
|
|
142
93
|
|
|
143
94
|
protected write(message: string): void {
|
|
144
|
-
this.communicationProvider.
|
|
95
|
+
this.communicationProvider.send(message);
|
|
145
96
|
}
|
|
146
97
|
|
|
147
98
|
async stop(): Promise<void> {
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
DebugAdapterContribution,
|
|
31
31
|
DebugAdapterSessionFactory,
|
|
32
32
|
DebugAdapterFactory
|
|
33
|
-
} from '
|
|
33
|
+
} from './debug-model';
|
|
34
34
|
import { DebugServiceImpl } from './debug-service-impl';
|
|
35
35
|
import { DebugAdapterContributionRegistry } from './debug-adapter-contribution-registry';
|
|
36
36
|
import { DebugAdapterSessionManager } from './debug-adapter-session-manager';
|
|
@@ -22,12 +22,12 @@
|
|
|
22
22
|
// Some entities copied and modified from https://github.com/Microsoft/vscode/blob/master/src/vs/vscode.d.ts
|
|
23
23
|
// Some entities copied and modified from https://github.com/Microsoft/vscode/blob/master/src/vs/workbench/parts/debug/common/debug.ts
|
|
24
24
|
|
|
25
|
-
import * as stream from 'stream';
|
|
26
25
|
import { WebSocketChannel } from '@theia/core/lib/common/messaging/web-socket-channel';
|
|
27
|
-
import { DebugConfiguration } from '
|
|
26
|
+
import { DebugConfiguration } from '../common/debug-configuration';
|
|
28
27
|
import { IJSONSchema, IJSONSchemaSnippet } from '@theia/core/lib/common/json-schema';
|
|
29
28
|
import { Disposable } from '@theia/core/lib/common/disposable';
|
|
30
29
|
import { MaybePromise } from '@theia/core/lib/common/types';
|
|
30
|
+
import { Event } from '@theia/core/lib/common/event';
|
|
31
31
|
|
|
32
32
|
// FIXME: break down this file to debug adapter and debug adapter contribution (see Theia file naming conventions)
|
|
33
33
|
|
|
@@ -96,8 +96,10 @@ export type DebugAdapterExecutable = DebugAdapterSpawnExecutable | DebugAdapterF
|
|
|
96
96
|
* TODO: the better name is DebugStreamConnection + handling on error and close
|
|
97
97
|
*/
|
|
98
98
|
export interface CommunicationProvider extends Disposable {
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
onMessageReceived: Event<string>;
|
|
100
|
+
onError: Event<Error>;
|
|
101
|
+
onClose: Event<void>;
|
|
102
|
+
send(message: string): void;
|
|
101
103
|
}
|
|
102
104
|
|
|
103
105
|
/**
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (C) 2021 Red Hat, Inc. and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
import { Emitter, Event } from '@theia/core/lib/common/event';
|
|
18
|
+
import { CommunicationProvider } from './debug-model';
|
|
19
|
+
import * as theia from '@theia/plugin';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* A communication provider for using the inline implementation of a debug adapter.
|
|
23
|
+
*/
|
|
24
|
+
export class InlineCommunicationProvider implements CommunicationProvider {
|
|
25
|
+
private messageReceivedEmitter = new Emitter<string>();
|
|
26
|
+
onMessageReceived: Event<string> = this.messageReceivedEmitter.event;
|
|
27
|
+
onError: Event<Error> = Event.None;
|
|
28
|
+
private closeEmitter = new Emitter<void>();
|
|
29
|
+
onClose: Event<void> = this.closeEmitter.event;
|
|
30
|
+
|
|
31
|
+
constructor(private debugAdapter: theia.DebugAdapter) {
|
|
32
|
+
this.debugAdapter.onDidSendMessage(msg => {
|
|
33
|
+
this.messageReceivedEmitter.fire(JSON.stringify(msg));
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
send(message: string): void {
|
|
38
|
+
this.debugAdapter.handleMessage(JSON.parse(message));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
dispose(): void {
|
|
42
|
+
this.debugAdapter.dispose();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (C) 2021 Red Hat, Inc. and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
|
18
|
+
import { Emitter, Event } from '@theia/core/lib/common/event';
|
|
19
|
+
import * as stream from 'stream';
|
|
20
|
+
import { CommunicationProvider } from './debug-model';
|
|
21
|
+
|
|
22
|
+
export class StreamCommunicationProvider extends DisposableCollection implements CommunicationProvider {
|
|
23
|
+
private messageReceivedEmitter = new Emitter<string>();
|
|
24
|
+
onMessageReceived: Event<string> = this.messageReceivedEmitter.event;
|
|
25
|
+
private errorEmitter = new Emitter<Error>();
|
|
26
|
+
onError: Event<Error> = this.errorEmitter.event;
|
|
27
|
+
private closeEmitter = new Emitter<void>();
|
|
28
|
+
onClose: Event<void> = this.closeEmitter.event;
|
|
29
|
+
|
|
30
|
+
// these constants are for the message header, see: https://microsoft.github.io/debug-adapter-protocol/overview#header-part
|
|
31
|
+
private static TWO_CRLF = '\r\n\r\n';
|
|
32
|
+
private static CONTENT_LENGTH = 'Content-Length';
|
|
33
|
+
private contentLength: number = -1;
|
|
34
|
+
private buffer: Buffer = Buffer.alloc(0);
|
|
35
|
+
|
|
36
|
+
constructor(private fromAdapter: stream.Readable, private toAdapter: stream.Writable) {
|
|
37
|
+
super();
|
|
38
|
+
|
|
39
|
+
this.fromAdapter.on('data', (data: Buffer) => this.handleData(data));
|
|
40
|
+
this.fromAdapter.on('close', () => this.closeEmitter.fire()); // FIXME pass a proper exit code
|
|
41
|
+
this.fromAdapter.on('error', error => this.errorEmitter.fire(error));
|
|
42
|
+
this.toAdapter.on('error', error => this.errorEmitter.fire(error));
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
send(message: string): void {
|
|
46
|
+
const msg = `${StreamCommunicationProvider.CONTENT_LENGTH}: ${Buffer.byteLength(message, 'utf8')}${StreamCommunicationProvider.TWO_CRLF}${message}`;
|
|
47
|
+
|
|
48
|
+
this.toAdapter.write(msg, 'utf8');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
protected handleData(data: Buffer): void {
|
|
52
|
+
this.buffer = Buffer.concat([this.buffer, data]);
|
|
53
|
+
|
|
54
|
+
while (true) {
|
|
55
|
+
if (this.contentLength >= 0) {
|
|
56
|
+
if (this.buffer.length >= this.contentLength) {
|
|
57
|
+
const message = this.buffer.toString('utf8', 0, this.contentLength);
|
|
58
|
+
this.buffer = this.buffer.slice(this.contentLength);
|
|
59
|
+
this.contentLength = -1;
|
|
60
|
+
|
|
61
|
+
if (message.length > 0) {
|
|
62
|
+
this.messageReceivedEmitter.fire(message);
|
|
63
|
+
}
|
|
64
|
+
continue; // there may be more complete messages to process
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
let idx = this.buffer.indexOf(StreamCommunicationProvider.CONTENT_LENGTH);
|
|
68
|
+
if (idx > 0) {
|
|
69
|
+
// log unrecognized output
|
|
70
|
+
const output = this.buffer.slice(0, idx);
|
|
71
|
+
console.log(output.toString('utf-8'));
|
|
72
|
+
|
|
73
|
+
this.buffer = this.buffer.slice(idx);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
idx = this.buffer.indexOf(StreamCommunicationProvider.TWO_CRLF);
|
|
77
|
+
if (idx !== -1) {
|
|
78
|
+
const header = this.buffer.toString('utf8', 0, idx);
|
|
79
|
+
const lines = header.split('\r\n');
|
|
80
|
+
for (let i = 0; i < lines.length; i++) {
|
|
81
|
+
const pair = lines[i].split(/: +/);
|
|
82
|
+
if (pair[0] === StreamCommunicationProvider.CONTENT_LENGTH) {
|
|
83
|
+
this.contentLength = +pair[1];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
this.buffer = this.buffer.slice(idx + StreamCommunicationProvider.TWO_CRLF.length);
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import * as fs from '@theia/core/shared/fs-extra';
|
|
18
18
|
import * as path from 'path';
|
|
19
|
-
import { DebugAdapterExecutable, DebugAdapterContribution } from '
|
|
19
|
+
import { DebugAdapterExecutable, DebugAdapterContribution } from '../debug-model';
|
|
20
20
|
import { isWindows, isOSX } from '@theia/core/lib/common/os';
|
|
21
21
|
import { IJSONSchema, IJSONSchemaSnippet } from '@theia/core/lib/common/json-schema';
|
|
22
22
|
import { deepClone } from '@theia/core/lib/common/objects';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"debug-model.d.ts","sourceRoot":"","sources":["../../src/common/debug-model.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"debug-model.js","sourceRoot":"","sources":["../../src/common/debug-model.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;kFAckF;;;AAiBlF,kHAAkH;AAElH;;GAEG;AACU,QAAA,mBAAmB,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAYjE;;GAEG;AACU,QAAA,0BAA0B,GAAG,MAAM,CAAC,4BAA4B,CAAC,CAAC;AAmD/E;;GAEG;AACU,QAAA,mBAAmB,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAUjE;;GAEG;AACU,QAAA,wBAAwB,GAAG,MAAM,CAAC,0BAA0B,CAAC,CAAC"}
|