@theia/debug 1.18.0 → 1.21.0-next.12

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.
Files changed (168) hide show
  1. package/lib/browser/console/debug-console-contribution.d.ts +1 -0
  2. package/lib/browser/console/debug-console-contribution.d.ts.map +1 -1
  3. package/lib/browser/console/debug-console-contribution.js +8 -6
  4. package/lib/browser/console/debug-console-contribution.js.map +1 -1
  5. package/lib/browser/console/debug-console-session.d.ts +1 -1
  6. package/lib/browser/console/debug-console-session.js +2 -2
  7. package/lib/browser/console/debug-console-session.js.map +1 -1
  8. package/lib/browser/debug-configuration-manager.d.ts.map +1 -1
  9. package/lib/browser/debug-configuration-manager.js +8 -7
  10. package/lib/browser/debug-configuration-manager.js.map +1 -1
  11. package/lib/browser/debug-frontend-application-contribution.d.ts +5 -12
  12. package/lib/browser/debug-frontend-application-contribution.d.ts.map +1 -1
  13. package/lib/browser/debug-frontend-application-contribution.js +139 -112
  14. package/lib/browser/debug-frontend-application-contribution.js.map +1 -1
  15. package/lib/browser/debug-preferences.d.ts +1 -0
  16. package/lib/browser/debug-preferences.d.ts.map +1 -1
  17. package/lib/browser/debug-preferences.js +22 -6
  18. package/lib/browser/debug-preferences.js.map +1 -1
  19. package/lib/browser/debug-prefix-configuration.d.ts.map +1 -1
  20. package/lib/browser/debug-prefix-configuration.js +3 -3
  21. package/lib/browser/debug-prefix-configuration.js.map +1 -1
  22. package/lib/browser/debug-session-connection.d.ts +23 -18
  23. package/lib/browser/debug-session-connection.d.ts.map +1 -1
  24. package/lib/browser/debug-session-connection.js +86 -65
  25. package/lib/browser/debug-session-connection.js.map +1 -1
  26. package/lib/browser/debug-session-contribution.d.ts +1 -1
  27. package/lib/browser/debug-session-contribution.d.ts.map +1 -1
  28. package/lib/browser/debug-session-contribution.js +1 -1
  29. package/lib/browser/debug-session-contribution.js.map +1 -1
  30. package/lib/browser/debug-session-manager.d.ts +6 -14
  31. package/lib/browser/debug-session-manager.d.ts.map +1 -1
  32. package/lib/browser/debug-session-manager.js +41 -44
  33. package/lib/browser/debug-session-manager.js.map +1 -1
  34. package/lib/browser/debug-session.d.ts +9 -8
  35. package/lib/browser/debug-session.d.ts.map +1 -1
  36. package/lib/browser/debug-session.js +55 -58
  37. package/lib/browser/debug-session.js.map +1 -1
  38. package/lib/browser/model/debug-function-breakpoint.d.ts.map +1 -1
  39. package/lib/browser/model/debug-function-breakpoint.js +4 -3
  40. package/lib/browser/model/debug-function-breakpoint.js.map +1 -1
  41. package/lib/browser/preferences/launch-preferences.d.ts.map +1 -1
  42. package/lib/browser/preferences/launch-preferences.js +2 -1
  43. package/lib/browser/preferences/launch-preferences.js.map +1 -1
  44. package/lib/browser/view/debug-breakpoints-source.d.ts +0 -1
  45. package/lib/browser/view/debug-breakpoints-source.d.ts.map +1 -1
  46. package/lib/browser/view/debug-breakpoints-source.js +1 -7
  47. package/lib/browser/view/debug-breakpoints-source.js.map +1 -1
  48. package/lib/browser/view/debug-breakpoints-widget.d.ts.map +1 -1
  49. package/lib/browser/view/debug-breakpoints-widget.js +2 -1
  50. package/lib/browser/view/debug-breakpoints-widget.js.map +1 -1
  51. package/lib/browser/view/debug-configuration-widget.d.ts +1 -1
  52. package/lib/browser/view/debug-configuration-widget.d.ts.map +1 -1
  53. package/lib/browser/view/debug-configuration-widget.js +8 -8
  54. package/lib/browser/view/debug-configuration-widget.js.map +1 -1
  55. package/lib/browser/view/debug-session-widget.d.ts +2 -1
  56. package/lib/browser/view/debug-session-widget.d.ts.map +1 -1
  57. package/lib/browser/view/debug-session-widget.js +12 -6
  58. package/lib/browser/view/debug-session-widget.js.map +1 -1
  59. package/lib/browser/view/debug-stack-frames-source.d.ts +0 -1
  60. package/lib/browser/view/debug-stack-frames-source.d.ts.map +1 -1
  61. package/lib/browser/view/debug-stack-frames-source.js +2 -5
  62. package/lib/browser/view/debug-stack-frames-source.js.map +1 -1
  63. package/lib/browser/view/debug-stack-frames-widget.d.ts.map +1 -1
  64. package/lib/browser/view/debug-stack-frames-widget.js +2 -1
  65. package/lib/browser/view/debug-stack-frames-widget.js.map +1 -1
  66. package/lib/browser/view/debug-threads-source.d.ts +0 -1
  67. package/lib/browser/view/debug-threads-source.d.ts.map +1 -1
  68. package/lib/browser/view/debug-threads-source.js +1 -7
  69. package/lib/browser/view/debug-threads-source.js.map +1 -1
  70. package/lib/browser/view/debug-threads-widget.d.ts.map +1 -1
  71. package/lib/browser/view/debug-threads-widget.js +2 -1
  72. package/lib/browser/view/debug-threads-widget.js.map +1 -1
  73. package/lib/browser/view/debug-toolbar-widget.d.ts.map +1 -1
  74. package/lib/browser/view/debug-toolbar-widget.js +9 -8
  75. package/lib/browser/view/debug-toolbar-widget.js.map +1 -1
  76. package/lib/browser/view/debug-variables-source.d.ts +0 -1
  77. package/lib/browser/view/debug-variables-source.d.ts.map +1 -1
  78. package/lib/browser/view/debug-variables-source.js +2 -5
  79. package/lib/browser/view/debug-variables-source.js.map +1 -1
  80. package/lib/browser/view/debug-variables-widget.d.ts.map +1 -1
  81. package/lib/browser/view/debug-variables-widget.js +2 -1
  82. package/lib/browser/view/debug-variables-widget.js.map +1 -1
  83. package/lib/browser/view/debug-view-model.js +3 -3
  84. package/lib/browser/view/debug-view-model.js.map +1 -1
  85. package/lib/browser/view/debug-watch-source.d.ts +0 -1
  86. package/lib/browser/view/debug-watch-source.d.ts.map +1 -1
  87. package/lib/browser/view/debug-watch-source.js +2 -5
  88. package/lib/browser/view/debug-watch-source.js.map +1 -1
  89. package/lib/browser/view/debug-watch-widget.d.ts.map +1 -1
  90. package/lib/browser/view/debug-watch-widget.js +2 -1
  91. package/lib/browser/view/debug-watch-widget.js.map +1 -1
  92. package/lib/browser/view/debug-widget.d.ts.map +1 -1
  93. package/lib/browser/view/debug-widget.js +2 -1
  94. package/lib/browser/view/debug-widget.js.map +1 -1
  95. package/lib/common/debug-service.d.ts +10 -0
  96. package/lib/common/debug-service.d.ts.map +1 -1
  97. package/lib/node/debug-adapter-contribution-registry.d.ts +1 -1
  98. package/lib/node/debug-adapter-contribution-registry.d.ts.map +1 -1
  99. package/lib/node/debug-adapter-contribution-registry.js +1 -1
  100. package/lib/node/debug-adapter-contribution-registry.js.map +1 -1
  101. package/lib/node/debug-adapter-factory.d.ts +4 -4
  102. package/lib/node/debug-adapter-factory.d.ts.map +1 -1
  103. package/lib/node/debug-adapter-factory.js +10 -12
  104. package/lib/node/debug-adapter-factory.js.map +1 -1
  105. package/lib/node/debug-adapter-session-manager.d.ts +1 -1
  106. package/lib/node/debug-adapter-session-manager.d.ts.map +1 -1
  107. package/lib/node/debug-adapter-session-manager.js +1 -2
  108. package/lib/node/debug-adapter-session-manager.js.map +1 -1
  109. package/lib/node/debug-adapter-session.d.ts +7 -13
  110. package/lib/node/debug-adapter-session.d.ts.map +1 -1
  111. package/lib/node/debug-adapter-session.js +25 -68
  112. package/lib/node/debug-adapter-session.js.map +1 -1
  113. package/lib/node/debug-backend-module.js +1 -1
  114. package/lib/node/debug-backend-module.js.map +1 -1
  115. package/lib/{common → node}/debug-model.d.ts +37 -19
  116. package/lib/node/debug-model.d.ts.map +1 -0
  117. package/lib/{common → node}/debug-model.js +0 -0
  118. package/lib/node/debug-model.js.map +1 -0
  119. package/lib/node/inline-debug-adapter.d.ts +34 -0
  120. package/lib/node/inline-debug-adapter.d.ts.map +1 -0
  121. package/lib/node/inline-debug-adapter.js +45 -0
  122. package/lib/node/inline-debug-adapter.js.map +1 -0
  123. package/lib/node/stream-debug-adapter.d.ts +52 -0
  124. package/lib/node/stream-debug-adapter.d.ts.map +1 -0
  125. package/lib/node/stream-debug-adapter.js +113 -0
  126. package/lib/node/stream-debug-adapter.js.map +1 -0
  127. package/lib/node/vscode/vscode-debug-adapter-contribution.d.ts +1 -1
  128. package/lib/node/vscode/vscode-debug-adapter-contribution.d.ts.map +1 -1
  129. package/package.json +17 -17
  130. package/src/browser/console/debug-console-contribution.tsx +9 -6
  131. package/src/browser/console/debug-console-session.ts +2 -2
  132. package/src/browser/debug-configuration-manager.ts +10 -8
  133. package/src/browser/debug-frontend-application-contribution.ts +160 -125
  134. package/src/browser/debug-preferences.ts +23 -6
  135. package/src/browser/debug-prefix-configuration.ts +4 -4
  136. package/src/browser/debug-session-connection.ts +102 -76
  137. package/src/browser/debug-session-contribution.ts +3 -4
  138. package/src/browser/debug-session-manager.ts +45 -47
  139. package/src/browser/debug-session.tsx +54 -57
  140. package/src/browser/model/debug-function-breakpoint.tsx +4 -3
  141. package/src/browser/preferences/launch-preferences.ts +2 -1
  142. package/src/browser/view/debug-breakpoints-source.tsx +0 -6
  143. package/src/browser/view/debug-breakpoints-widget.ts +2 -1
  144. package/src/browser/view/debug-configuration-widget.tsx +8 -7
  145. package/src/browser/view/debug-session-widget.ts +12 -6
  146. package/src/browser/view/debug-stack-frames-source.tsx +0 -6
  147. package/src/browser/view/debug-stack-frames-widget.ts +2 -1
  148. package/src/browser/view/debug-threads-source.tsx +0 -6
  149. package/src/browser/view/debug-threads-widget.ts +2 -1
  150. package/src/browser/view/debug-toolbar-widget.tsx +13 -8
  151. package/src/browser/view/debug-variables-source.ts +0 -6
  152. package/src/browser/view/debug-variables-widget.ts +2 -1
  153. package/src/browser/view/debug-view-model.ts +3 -3
  154. package/src/browser/view/debug-watch-source.ts +0 -6
  155. package/src/browser/view/debug-watch-widget.ts +2 -1
  156. package/src/browser/view/debug-widget.ts +2 -1
  157. package/src/common/debug-service.ts +13 -0
  158. package/src/node/debug-adapter-contribution-registry.ts +1 -1
  159. package/src/node/debug-adapter-factory.ts +17 -17
  160. package/src/node/debug-adapter-session-manager.ts +1 -2
  161. package/src/node/debug-adapter-session.ts +32 -80
  162. package/src/node/debug-backend-module.ts +1 -1
  163. package/src/{common → node}/debug-model.ts +38 -18
  164. package/src/node/inline-debug-adapter.ts +47 -0
  165. package/src/node/stream-debug-adapter.ts +126 -0
  166. package/src/node/vscode/vscode-debug-adapter-contribution.ts +1 -1
  167. package/lib/common/debug-model.d.ts.map +0 -1
  168. package/lib/common/debug-model.js.map +0 -1
@@ -22,40 +22,33 @@
22
22
  // Some entities copied and modified from https://github.com/Microsoft/vscode-debugadapter-node/blob/master/adapter/src/protocol.ts
23
23
 
24
24
  import {
25
- CommunicationProvider,
26
- DebugAdapterSession,
27
- } from '../common/debug-model';
25
+ DebugAdapter,
26
+ DebugAdapterSession
27
+ } from './debug-model';
28
28
  import { DebugProtocol } from 'vscode-debugprotocol';
29
- import { IWebSocket } from '@theia/core/shared/vscode-ws-jsonrpc';
30
- import { DisposableCollection, Disposable } from '@theia/core/lib/common/disposable';
29
+ import { Channel } from '../common/debug-service';
31
30
 
32
31
  /**
33
32
  * [DebugAdapterSession](#DebugAdapterSession) implementation.
34
33
  */
35
34
  export class DebugAdapterSessionImpl implements DebugAdapterSession {
36
35
 
37
- private static TWO_CRLF = '\r\n\r\n';
38
- private static CONTENT_LENGTH = 'Content-Length';
39
-
40
- private readonly toDispose = new DisposableCollection();
41
- private channel: IWebSocket | undefined;
42
- private contentLength: number;
43
- private buffer: Buffer;
36
+ private channel: Channel | undefined;
37
+ private isClosed: boolean = false;
44
38
 
45
39
  constructor(
46
40
  readonly id: string,
47
- protected readonly communicationProvider: CommunicationProvider
41
+ protected readonly debugAdapter: DebugAdapter
48
42
  ) {
49
- this.contentLength = -1;
50
- this.buffer = Buffer.alloc(0);
51
- this.toDispose.pushAll([
52
- this.communicationProvider,
53
- Disposable.create(() => this.write(JSON.stringify({ seq: -1, type: 'request', command: 'disconnect' }))),
54
- Disposable.create(() => this.write(JSON.stringify({ seq: -1, type: 'request', command: 'terminate' })))
55
- ]);
43
+ this.debugAdapter.onMessageReceived((message: string) => this.send(message));
44
+ this.debugAdapter.onClose(() => this.onDebugAdapterExit());
45
+ this.debugAdapter.onError(error => this.onDebugAdapterError(error));
46
+
56
47
  }
57
48
 
58
- async start(channel: IWebSocket): Promise<void> {
49
+ async start(channel: Channel): Promise<void> {
50
+
51
+ console.debug(`starting debug adapter session '${this.id}'`);
59
52
  if (this.channel) {
60
53
  throw new Error('The session has already been started, id: ' + this.id);
61
54
  }
@@ -63,25 +56,19 @@ export class DebugAdapterSessionImpl implements DebugAdapterSession {
63
56
  this.channel.onMessage((message: string) => this.write(message));
64
57
  this.channel.onClose(() => this.channel = undefined);
65
58
 
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
59
  }
71
60
 
72
- protected onDebugAdapterExit(exitCode: number, signal: string | undefined): void {
73
- const event: DebugProtocol.ExitedEvent = {
74
- type: 'event',
75
- event: 'exited',
76
- seq: -1,
77
- body: {
78
- exitCode
79
- }
80
- };
81
- this.send(JSON.stringify(event));
61
+ protected onDebugAdapterExit(): void {
62
+ this.isClosed = true;
63
+ console.debug(`onDebugAdapterExit session: '${this.id}'`);
64
+ if (this.channel) {
65
+ this.channel.close();
66
+ this.channel = undefined;
67
+ }
82
68
  }
83
69
 
84
70
  protected onDebugAdapterError(error: Error): void {
71
+ console.debug(`error in debug adapter session: '${this.id}': ${JSON.stringify(error)}`);
85
72
  const event: DebugProtocol.Event = {
86
73
  type: 'event',
87
74
  event: 'error',
@@ -91,49 +78,6 @@ export class DebugAdapterSessionImpl implements DebugAdapterSession {
91
78
  this.send(JSON.stringify(event));
92
79
  }
93
80
 
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
81
  protected send(message: string): void {
138
82
  if (this.channel) {
139
83
  this.channel.send(message);
@@ -141,10 +85,18 @@ export class DebugAdapterSessionImpl implements DebugAdapterSession {
141
85
  }
142
86
 
143
87
  protected write(message: string): void {
144
- this.communicationProvider.input.write(`Content-Length: ${Buffer.byteLength(message, 'utf8')}\r\n\r\n${message}`, 'utf8');
88
+ if (!this.isClosed) {
89
+ this.debugAdapter.send(message);
90
+ }
145
91
  }
146
92
 
147
93
  async stop(): Promise<void> {
148
- this.toDispose.dispose();
94
+ console.debug(`stopping debug adapter session: '${this.id}'`);
95
+
96
+ if (!this.isClosed) {
97
+ await this.debugAdapter.stop();
98
+ }
99
+ this.channel?.close();
100
+ this.channel = undefined;
149
101
  }
150
102
  }
@@ -30,7 +30,7 @@ import {
30
30
  DebugAdapterContribution,
31
31
  DebugAdapterSessionFactory,
32
32
  DebugAdapterFactory
33
- } from '../common/debug-model';
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,11 @@
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
- import { WebSocketChannel } from '@theia/core/lib/common/messaging/web-socket-channel';
27
- import { DebugConfiguration } from './debug-configuration';
25
+ import { DebugConfiguration } from '../common/debug-configuration';
28
26
  import { IJSONSchema, IJSONSchemaSnippet } from '@theia/core/lib/common/json-schema';
29
- import { Disposable } from '@theia/core/lib/common/disposable';
30
27
  import { MaybePromise } from '@theia/core/lib/common/types';
28
+ import { Event } from '@theia/core/lib/common/event';
29
+ import { Channel } from '../common/debug-service';
31
30
 
32
31
  // FIXME: break down this file to debug adapter and debug adapter contribution (see Theia file naming conventions)
33
32
 
@@ -37,12 +36,14 @@ import { MaybePromise } from '@theia/core/lib/common/types';
37
36
  export const DebugAdapterSession = Symbol('DebugAdapterSession');
38
37
 
39
38
  /**
40
- * The debug adapter session.
39
+ * The debug adapter session. The debug adapter session manages the lifecycle of a
40
+ * debug session: the debug session should be discarded if and only if the debug adapter
41
+ * session is stopped.
41
42
  */
42
43
  export interface DebugAdapterSession {
43
44
  id: string;
44
45
  parentSession?: DebugAdapterSession;
45
- start(channel: WebSocketChannel): Promise<void>
46
+ start(channel: Channel): Promise<void>
46
47
  stop(): Promise<void>
47
48
  }
48
49
 
@@ -55,7 +56,7 @@ export const DebugAdapterSessionFactory = Symbol('DebugAdapterSessionFactory');
55
56
  * The [debug session](#DebugSession) factory.
56
57
  */
57
58
  export interface DebugAdapterSessionFactory {
58
- get(sessionId: string, communicationProvider: CommunicationProvider): DebugAdapterSession;
59
+ get(sessionId: string, debugAdapter: DebugAdapter): DebugAdapterSession;
59
60
  }
60
61
 
61
62
  /**
@@ -88,16 +89,35 @@ export interface DebugAdapterForkExecutable {
88
89
  export type DebugAdapterExecutable = DebugAdapterSpawnExecutable | DebugAdapterForkExecutable;
89
90
 
90
91
  /**
91
- * Provides some way we can communicate with the running debug adapter. In general there is
92
- * no obligation as of how to launch/initialize local or remote debug adapter
93
- * process/server, it can be done separately and it is not required that this interface covers the
94
- * procedure, however it is also not disallowed.
95
- *
96
- * TODO: the better name is DebugStreamConnection + handling on error and close
92
+ * Implementers stand for the various types of debug adapters the system can talk to.
93
+ * Creation of debug adapters is not covered in this interface, but handling communication
94
+ * and the end of life is.
97
95
  */
98
- export interface CommunicationProvider extends Disposable {
99
- output: stream.Readable;
100
- input: stream.Writable;
96
+
97
+ export interface DebugAdapter {
98
+ /**
99
+ * A DAP protocol message has been received from the debug adapter
100
+ */
101
+ onMessageReceived: Event<string>;
102
+ /**
103
+ * Send a DAP message to the debug adapter
104
+ * @param message the JSON-encoded DAP message
105
+ */
106
+ send(message: string): void;
107
+ /**
108
+ * An error has occured communicating with the debug adapter. This does not meant the debug adapter
109
+ * has terminated.
110
+ */
111
+ onError: Event<Error>;
112
+ /**
113
+ * The connection to the debug adapter has been lost. This signals the end of life for this
114
+ * debug adapter instance.
115
+ */
116
+ onClose: Event<void>;
117
+ /**
118
+ * Terminate the connection to the debug adapter.
119
+ */
120
+ stop(): Promise<void>;
101
121
  }
102
122
 
103
123
  /**
@@ -109,8 +129,8 @@ export const DebugAdapterFactory = Symbol('DebugAdapterFactory');
109
129
  * Factory to start debug adapter.
110
130
  */
111
131
  export interface DebugAdapterFactory {
112
- start(executable: DebugAdapterExecutable): CommunicationProvider;
113
- connect(debugServerPort: number): CommunicationProvider;
132
+ start(executable: DebugAdapterExecutable): DebugAdapter;
133
+ connect(debugServerPort: number): DebugAdapter;
114
134
  }
115
135
 
116
136
  /**
@@ -0,0 +1,47 @@
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 { DebugAdapter } from './debug-model';
19
+ import * as theia from '@theia/plugin';
20
+
21
+ /**
22
+ * A debug adapter for using the inline implementation from a plugin.
23
+ */
24
+ export class InlineDebugAdapter implements DebugAdapter {
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
+ async start(): Promise<void> {
38
+ }
39
+
40
+ send(message: string): void {
41
+ this.debugAdapter.handleMessage(JSON.parse(message));
42
+ }
43
+
44
+ async stop(): Promise<void> {
45
+ this.debugAdapter.dispose();
46
+ }
47
+ }
@@ -0,0 +1,126 @@
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 { ChildProcess } from 'child_process';
20
+ import * as stream from 'stream';
21
+ import * as net from 'net';
22
+ import { DebugAdapter } from './debug-model';
23
+
24
+ abstract class StreamDebugAdapter extends DisposableCollection {
25
+ private messageReceivedEmitter = new Emitter<string>();
26
+ onMessageReceived: Event<string> = this.messageReceivedEmitter.event;
27
+ private errorEmitter = new Emitter<Error>();
28
+ onError: Event<Error> = this.errorEmitter.event;
29
+ private closeEmitter = new Emitter<void>();
30
+ onClose: Event<void> = this.closeEmitter.event;
31
+
32
+ // these constants are for the message header, see: https://microsoft.github.io/debug-adapter-protocol/overview#header-part
33
+ private static TWO_CRLF = '\r\n\r\n';
34
+ private static CONTENT_LENGTH = 'Content-Length';
35
+ private contentLength: number = -1;
36
+ private buffer: Buffer = Buffer.alloc(0);
37
+
38
+ constructor(private fromAdapter: stream.Readable, private toAdapter: stream.Writable) {
39
+ super();
40
+
41
+ this.fromAdapter.on('data', (data: Buffer) => this.handleData(data));
42
+ this.fromAdapter.on('close', () => this.handleClosed()); // FIXME pass a proper exit code
43
+ this.fromAdapter.on('error', error => this.errorEmitter.fire(error));
44
+ this.toAdapter.on('error', error => this.errorEmitter.fire(error));
45
+ }
46
+
47
+ handleClosed(): void {
48
+ this.closeEmitter.fire();
49
+ }
50
+
51
+ send(message: string): void {
52
+ const msg = `${StreamDebugAdapter.CONTENT_LENGTH}: ${Buffer.byteLength(message, 'utf8')}${StreamDebugAdapter.TWO_CRLF}${message}`;
53
+
54
+ this.toAdapter.write(msg, 'utf8');
55
+ }
56
+
57
+ protected handleData(data: Buffer): void {
58
+ this.buffer = Buffer.concat([this.buffer, data]);
59
+
60
+ while (true) {
61
+ if (this.contentLength >= 0) {
62
+ if (this.buffer.length >= this.contentLength) {
63
+ const message = this.buffer.toString('utf8', 0, this.contentLength);
64
+ this.buffer = this.buffer.slice(this.contentLength);
65
+ this.contentLength = -1;
66
+
67
+ if (message.length > 0) {
68
+ this.messageReceivedEmitter.fire(message);
69
+ }
70
+ continue; // there may be more complete messages to process
71
+ }
72
+ } else {
73
+ let idx = this.buffer.indexOf(StreamDebugAdapter.CONTENT_LENGTH);
74
+ if (idx > 0) {
75
+ // log unrecognized output
76
+ const output = this.buffer.slice(0, idx);
77
+ console.log(output.toString('utf-8'));
78
+
79
+ this.buffer = this.buffer.slice(idx);
80
+ }
81
+
82
+ idx = this.buffer.indexOf(StreamDebugAdapter.TWO_CRLF);
83
+ if (idx !== -1) {
84
+ const header = this.buffer.toString('utf8', 0, idx);
85
+ const lines = header.split('\r\n');
86
+ for (let i = 0; i < lines.length; i++) {
87
+ const pair = lines[i].split(/: +/);
88
+ if (pair[0] === StreamDebugAdapter.CONTENT_LENGTH) {
89
+ this.contentLength = +pair[1];
90
+ }
91
+ }
92
+ this.buffer = this.buffer.slice(idx + StreamDebugAdapter.TWO_CRLF.length);
93
+ continue;
94
+ }
95
+ }
96
+ break;
97
+ }
98
+ }
99
+ }
100
+
101
+ export class ProcessDebugAdapter extends StreamDebugAdapter implements DebugAdapter {
102
+ protected readonly process: ChildProcess;
103
+ constructor(process: ChildProcess) {
104
+ super(process.stdout!, process.stdin!);
105
+ this.process = process;
106
+ }
107
+
108
+ async stop(): Promise<void> {
109
+ this.process.kill();
110
+ this.process.stdin?.end();
111
+ }
112
+ }
113
+
114
+ export class SocketDebugAdapter extends StreamDebugAdapter implements DebugAdapter {
115
+ private readonly socket: net.Socket;
116
+ constructor(socket: net.Socket) {
117
+ super(socket, socket);
118
+ this.socket = socket;
119
+ }
120
+
121
+ stop(): Promise<void> {
122
+ return new Promise<void>(resolve => {
123
+ this.socket.end(() => resolve());
124
+ });
125
+ }
126
+ }
@@ -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 '../../common/debug-model';
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"}