@theia/plugin-ext 1.33.0-next.2 → 1.33.0-next.24
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/common/index.js +2 -0
- package/lib/common/index.js.map +1 -1
- package/lib/common/plugin-api-rpc-model.d.ts +78 -0
- package/lib/common/plugin-api-rpc-model.d.ts.map +1 -1
- package/lib/common/plugin-api-rpc-model.js +17 -1
- package/lib/common/plugin-api-rpc-model.js.map +1 -1
- package/lib/common/plugin-api-rpc.d.ts +20 -7
- package/lib/common/plugin-api-rpc.d.ts.map +1 -1
- package/lib/common/plugin-api-rpc.js +0 -2
- package/lib/common/plugin-api-rpc.js.map +1 -1
- package/lib/common/plugin-protocol.d.ts +4 -4
- package/lib/common/plugin-protocol.d.ts.map +1 -1
- package/lib/common/proxy-handler.d.ts +66 -0
- package/lib/common/proxy-handler.d.ts.map +1 -0
- package/lib/common/proxy-handler.js +98 -0
- package/lib/common/proxy-handler.js.map +1 -0
- package/lib/common/reference-map.d.ts +8 -0
- package/lib/common/reference-map.d.ts.map +1 -0
- package/lib/common/reference-map.js +40 -0
- package/lib/common/reference-map.js.map +1 -0
- package/lib/common/rpc-protocol.d.ts +25 -51
- package/lib/common/rpc-protocol.d.ts.map +1 -1
- package/lib/common/rpc-protocol.js +126 -323
- package/lib/common/rpc-protocol.js.map +1 -1
- package/lib/hosted/browser/hosted-plugin-watcher.d.ts +1 -1
- package/lib/hosted/browser/hosted-plugin-watcher.d.ts.map +1 -1
- package/lib/hosted/browser/hosted-plugin-watcher.js.map +1 -1
- package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
- package/lib/hosted/browser/hosted-plugin.js +13 -8
- package/lib/hosted/browser/hosted-plugin.js.map +1 -1
- package/lib/hosted/browser/plugin-worker.d.ts.map +1 -1
- package/lib/hosted/browser/plugin-worker.js +14 -9
- package/lib/hosted/browser/plugin-worker.js.map +1 -1
- package/lib/hosted/browser/worker/worker-main.d.ts +1 -1
- package/lib/hosted/browser/worker/worker-main.d.ts.map +1 -1
- package/lib/hosted/browser/worker/worker-main.js +23 -22
- package/lib/hosted/browser/worker/worker-main.js.map +1 -1
- package/lib/hosted/node/hosted-plugin-process.d.ts +5 -4
- package/lib/hosted/node/hosted-plugin-process.d.ts.map +1 -1
- package/lib/hosted/node/hosted-plugin-process.js +20 -13
- package/lib/hosted/node/hosted-plugin-process.js.map +1 -1
- package/lib/hosted/node/hosted-plugin-protocol.d.ts +22 -0
- package/lib/hosted/node/hosted-plugin-protocol.d.ts.map +1 -0
- package/lib/hosted/node/hosted-plugin-protocol.js +37 -0
- package/lib/hosted/node/hosted-plugin-protocol.js.map +1 -0
- package/lib/hosted/node/hosted-plugin.d.ts +1 -1
- package/lib/hosted/node/hosted-plugin.d.ts.map +1 -1
- package/lib/hosted/node/hosted-plugin.js.map +1 -1
- package/lib/hosted/node/plugin-host.d.ts +1 -1
- package/lib/hosted/node/plugin-host.d.ts.map +1 -1
- package/lib/hosted/node/plugin-host.js +10 -21
- package/lib/hosted/node/plugin-host.js.map +1 -1
- package/lib/hosted/node/plugin-service.d.ts +1 -1
- package/lib/hosted/node/plugin-service.d.ts.map +1 -1
- package/lib/hosted/node/plugin-service.js.map +1 -1
- package/lib/main/browser/custom-editors/custom-editors-main.d.ts.map +1 -1
- package/lib/main/browser/custom-editors/custom-editors-main.js +2 -2
- package/lib/main/browser/custom-editors/custom-editors-main.js.map +1 -1
- package/lib/main/browser/file-system-main-impl.d.ts +1 -0
- package/lib/main/browser/file-system-main-impl.d.ts.map +1 -1
- package/lib/main/browser/file-system-main-impl.js +9 -2
- package/lib/main/browser/file-system-main-impl.js.map +1 -1
- package/lib/main/browser/languages-main.d.ts +1 -0
- package/lib/main/browser/languages-main.d.ts.map +1 -1
- package/lib/main/browser/languages-main.js +10 -0
- package/lib/main/browser/languages-main.js.map +1 -1
- package/lib/main/browser/main-context.d.ts.map +1 -1
- package/lib/main/browser/main-context.js +0 -3
- package/lib/main/browser/main-context.js.map +1 -1
- package/lib/main/browser/tasks-main.d.ts.map +1 -1
- package/lib/main/browser/tasks-main.js +13 -9
- package/lib/main/browser/tasks-main.js.map +1 -1
- package/lib/main/browser/terminal-main.d.ts +1 -1
- package/lib/main/browser/terminal-main.d.ts.map +1 -1
- package/lib/main/browser/terminal-main.js +2 -2
- package/lib/main/browser/terminal-main.js.map +1 -1
- package/lib/main/browser/webview/webview.d.ts +1 -0
- package/lib/main/browser/webview/webview.d.ts.map +1 -1
- package/lib/main/browser/webview/webview.js.map +1 -1
- package/lib/main/browser/webviews-main.d.ts.map +1 -1
- package/lib/main/browser/webviews-main.js +6 -6
- package/lib/main/browser/webviews-main.js.map +1 -1
- package/lib/plugin/debug/debug-ext.d.ts +2 -1
- package/lib/plugin/debug/debug-ext.d.ts.map +1 -1
- package/lib/plugin/debug/debug-ext.js +10 -1
- package/lib/plugin/debug/debug-ext.js.map +1 -1
- package/lib/plugin/debug/plugin-debug-adapter-session.d.ts +6 -5
- package/lib/plugin/debug/plugin-debug-adapter-session.d.ts.map +1 -1
- package/lib/plugin/debug/plugin-debug-adapter-session.js +18 -4
- package/lib/plugin/debug/plugin-debug-adapter-session.js.map +1 -1
- package/lib/plugin/file-system-ext-impl.d.ts +2 -0
- package/lib/plugin/file-system-ext-impl.d.ts.map +1 -1
- package/lib/plugin/file-system-ext-impl.js +22 -5
- package/lib/plugin/file-system-ext-impl.js.map +1 -1
- package/lib/plugin/languages/inline-completion.d.ts +21 -0
- package/lib/plugin/languages/inline-completion.d.ts.map +1 -0
- package/lib/plugin/languages/inline-completion.js +94 -0
- package/lib/plugin/languages/inline-completion.js.map +1 -0
- package/lib/plugin/languages.d.ts +5 -2
- package/lib/plugin/languages.d.ts.map +1 -1
- package/lib/plugin/languages.js +16 -1
- package/lib/plugin/languages.js.map +1 -1
- package/lib/plugin/plugin-context.d.ts.map +1 -1
- package/lib/plugin/plugin-context.js +107 -3
- package/lib/plugin/plugin-context.js.map +1 -1
- package/lib/plugin/theming.d.ts.map +1 -1
- package/lib/plugin/theming.js +3 -0
- package/lib/plugin/theming.js.map +1 -1
- package/lib/plugin/type-converters.d.ts.map +1 -1
- package/lib/plugin/type-converters.js +6 -14
- package/lib/plugin/type-converters.js.map +1 -1
- package/lib/plugin/type-converters.spec.js +5 -4
- package/lib/plugin/type-converters.spec.js.map +1 -1
- package/lib/plugin/types-impl.d.ts +149 -9
- package/lib/plugin/types-impl.d.ts.map +1 -1
- package/lib/plugin/types-impl.js +205 -32
- package/lib/plugin/types-impl.js.map +1 -1
- package/package.json +25 -25
- package/src/common/index.ts +4 -0
- package/src/common/plugin-api-rpc-model.ts +96 -0
- package/src/common/plugin-api-rpc.ts +25 -7
- package/src/common/plugin-protocol.ts +4 -4
- package/src/common/proxy-handler.ts +126 -0
- package/src/common/reference-map.ts +38 -0
- package/src/common/rpc-protocol.ts +128 -401
- package/src/hosted/browser/hosted-plugin-watcher.ts +4 -3
- package/src/hosted/browser/hosted-plugin.ts +17 -8
- package/src/hosted/browser/plugin-worker.ts +16 -10
- package/src/hosted/browser/worker/worker-main.ts +25 -26
- package/src/hosted/node/hosted-plugin-process.ts +25 -16
- package/src/hosted/node/hosted-plugin-protocol.ts +49 -0
- package/src/hosted/node/hosted-plugin.ts +1 -1
- package/src/hosted/node/plugin-host.ts +11 -22
- package/src/hosted/node/plugin-service.ts +1 -1
- package/src/main/browser/custom-editors/custom-editors-main.ts +2 -1
- package/src/main/browser/file-system-main-impl.ts +12 -3
- package/src/main/browser/languages-main.ts +18 -1
- package/src/main/browser/main-context.ts +0 -4
- package/src/main/browser/tasks-main.ts +13 -9
- package/src/main/browser/terminal-main.ts +2 -2
- package/src/main/browser/webview/pre/main.js +8 -1
- package/src/main/browser/webview/webview.ts +1 -0
- package/src/main/browser/webviews-main.ts +6 -3
- package/src/plugin/debug/debug-ext.ts +11 -2
- package/src/plugin/debug/plugin-debug-adapter-session.ts +17 -9
- package/src/plugin/file-system-ext-impl.ts +21 -5
- package/src/plugin/languages/inline-completion.ts +126 -0
- package/src/plugin/languages.ts +30 -3
- package/src/plugin/plugin-context.ts +142 -4
- package/src/plugin/theming.ts +3 -0
- package/src/plugin/type-converters.spec.ts +5 -4
- package/src/plugin/type-converters.ts +10 -12
- package/src/plugin/types-impl.ts +253 -27
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
//
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
|
+
import { BasicChannel } from '@theia/core/lib/common/message-rpc/channel';
|
|
17
|
+
import { Uint8ArrayReadBuffer, Uint8ArrayWriteBuffer } from '@theia/core/lib/common/message-rpc/uint8-array-message-buffer';
|
|
16
18
|
import { injectable } from '@theia/core/shared/inversify';
|
|
17
|
-
import { Emitter } from '@theia/core/lib/common/event';
|
|
18
19
|
import { RPCProtocol, RPCProtocolImpl } from '../../common/rpc-protocol';
|
|
19
20
|
|
|
20
21
|
@injectable()
|
|
@@ -25,22 +26,27 @@ export class PluginWorker {
|
|
|
25
26
|
public readonly rpc: RPCProtocol;
|
|
26
27
|
|
|
27
28
|
constructor() {
|
|
28
|
-
const emitter = new Emitter<string>();
|
|
29
|
-
|
|
30
29
|
this.worker = new Worker(new URL('./worker/worker-main',
|
|
31
30
|
// @ts-expect-error (TS1343)
|
|
32
31
|
// We compile to CommonJS but `import.meta` is still available in the browser
|
|
33
32
|
import.meta.url));
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
const channel = new BasicChannel(() => {
|
|
35
|
+
const writer = new Uint8ArrayWriteBuffer();
|
|
36
|
+
writer.onCommit(buffer => {
|
|
37
|
+
this.worker.postMessage(buffer);
|
|
38
|
+
});
|
|
39
|
+
return writer;
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
this.rpc = new RPCProtocolImpl(channel);
|
|
37
43
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
this.worker.postMessage(m);
|
|
42
|
-
}
|
|
44
|
+
// eslint-disable-next-line arrow-body-style
|
|
45
|
+
this.worker.onmessage = buffer => channel.onMessageEmitter.fire(() => {
|
|
46
|
+
return new Uint8ArrayReadBuffer(buffer.data);
|
|
43
47
|
});
|
|
48
|
+
|
|
49
|
+
this.worker.onerror = e => channel.onErrorEmitter.fire(e);
|
|
44
50
|
}
|
|
45
51
|
|
|
46
52
|
}
|
|
@@ -13,28 +13,29 @@
|
|
|
13
13
|
//
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
|
-
|
|
17
|
-
import
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import { MAIN_RPC_CONTEXT, Plugin, emptyPlugin, TerminalServiceExt } from '../../../common/plugin-api-rpc';
|
|
21
|
-
import { createAPIFactory } from '../../../plugin/plugin-context';
|
|
22
|
-
import { getPluginId, PluginMetadata } from '../../../common/plugin-protocol';
|
|
16
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
17
|
+
import 'reflect-metadata';
|
|
18
|
+
import { BasicChannel } from '@theia/core/lib/common/message-rpc/channel';
|
|
19
|
+
import { Uint8ArrayReadBuffer, Uint8ArrayWriteBuffer } from '@theia/core/lib/common/message-rpc/uint8-array-message-buffer';
|
|
23
20
|
import * as theia from '@theia/plugin';
|
|
24
|
-
import {
|
|
21
|
+
import { emptyPlugin, MAIN_RPC_CONTEXT, Plugin, TerminalServiceExt } from '../../../common/plugin-api-rpc';
|
|
25
22
|
import { ExtPluginApi } from '../../../common/plugin-ext-api-contribution';
|
|
26
|
-
import {
|
|
23
|
+
import { getPluginId, PluginMetadata } from '../../../common/plugin-protocol';
|
|
24
|
+
import { RPCProtocolImpl } from '../../../common/rpc-protocol';
|
|
25
|
+
import { ClipboardExt } from '../../../plugin/clipboard-ext';
|
|
27
26
|
import { EditorsAndDocumentsExtImpl } from '../../../plugin/editors-and-documents';
|
|
28
|
-
import { WorkspaceExtImpl } from '../../../plugin/workspace';
|
|
29
27
|
import { MessageRegistryExt } from '../../../plugin/message-registry';
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
28
|
+
import { createAPIFactory } from '../../../plugin/plugin-context';
|
|
29
|
+
import { PluginManagerExtImpl } from '../../../plugin/plugin-manager';
|
|
32
30
|
import { KeyValueStorageProxy } from '../../../plugin/plugin-storage';
|
|
31
|
+
import { PreferenceRegistryExtImpl } from '../../../plugin/preference-registry';
|
|
32
|
+
import { SecretsExtImpl } from '../../../plugin/secrets-ext';
|
|
33
|
+
import { TerminalServiceExtImpl } from '../../../plugin/terminal-ext';
|
|
33
34
|
import { WebviewsExtImpl } from '../../../plugin/webviews';
|
|
35
|
+
import { WorkspaceExtImpl } from '../../../plugin/workspace';
|
|
36
|
+
import { createDebugExtStub } from './debug-stub';
|
|
34
37
|
import { loadManifest } from './plugin-manifest-loader';
|
|
35
|
-
import {
|
|
36
|
-
import { reviver } from '../../../plugin/types-impl';
|
|
37
|
-
import { SecretsExtImpl } from '../../../plugin/secrets-ext';
|
|
38
|
+
import { WorkerEnvExtImpl } from './worker-env-ext';
|
|
38
39
|
|
|
39
40
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
40
41
|
const ctx = self as any;
|
|
@@ -42,22 +43,20 @@ const ctx = self as any;
|
|
|
42
43
|
const pluginsApiImpl = new Map<string, typeof theia>();
|
|
43
44
|
const pluginsModulesNames = new Map<string, Plugin>();
|
|
44
45
|
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
reviver: reviver
|
|
46
|
+
const channel = new BasicChannel(() => {
|
|
47
|
+
const writeBuffer = new Uint8ArrayWriteBuffer();
|
|
48
|
+
writeBuffer.onCommit(buffer => {
|
|
49
|
+
ctx.postMessage(buffer);
|
|
50
|
+
});
|
|
51
|
+
return writeBuffer;
|
|
54
52
|
});
|
|
55
|
-
|
|
56
53
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
57
54
|
addEventListener('message', (message: any) => {
|
|
58
|
-
|
|
55
|
+
channel.onMessageEmitter.fire(() => new Uint8ArrayReadBuffer(message.data));
|
|
59
56
|
});
|
|
60
57
|
|
|
58
|
+
const rpc = new RPCProtocolImpl(channel);
|
|
59
|
+
|
|
61
60
|
const scripts = new Set<string>();
|
|
62
61
|
|
|
63
62
|
function initialize(contextPath: string, pluginMetadata: PluginMetadata): void {
|
|
@@ -14,16 +14,18 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
import
|
|
18
|
-
import {
|
|
19
|
-
import { ILogger, ConnectionErrorHandler, ContributionProvider, MessageService } from '@theia/core/lib/common';
|
|
17
|
+
import { ConnectionErrorHandler, ContributionProvider, ILogger, MessageService } from '@theia/core/lib/common';
|
|
18
|
+
import { Deferred } from '@theia/core/lib/common/promise-util';
|
|
20
19
|
import { createIpcEnv } from '@theia/core/lib/node/messaging/ipc-protocol';
|
|
21
|
-
import {
|
|
22
|
-
import
|
|
20
|
+
import { inject, injectable, named } from '@theia/core/shared/inversify';
|
|
21
|
+
import * as cp from 'child_process';
|
|
23
22
|
import { HostedPluginCliContribution } from './hosted-plugin-cli-contribution';
|
|
24
|
-
import * as psTree from 'ps-tree';
|
|
25
|
-
import { Deferred } from '@theia/core/lib/common/promise-util';
|
|
26
23
|
import { HostedPluginLocalizationService } from './hosted-plugin-localization-service';
|
|
24
|
+
import { ProcessTerminatedMessage, ProcessTerminateMessage } from './hosted-plugin-protocol';
|
|
25
|
+
import { BinaryMessagePipe } from '@theia/core/lib/node/messaging/binary-message-pipe';
|
|
26
|
+
import { DeployedPlugin, HostedPluginClient, PluginHostEnvironmentVariable, PluginIdentifiers, PLUGIN_HOST_BACKEND, ServerPluginRunner } from '../../common/plugin-protocol';
|
|
27
|
+
import psTree = require('ps-tree');
|
|
28
|
+
import { Duplex } from 'stream';
|
|
27
29
|
|
|
28
30
|
export interface IPCConnectionOptions {
|
|
29
31
|
readonly serverName: string;
|
|
@@ -60,6 +62,7 @@ export class HostedPluginProcess implements ServerPluginRunner {
|
|
|
60
62
|
protected readonly localizationService: HostedPluginLocalizationService;
|
|
61
63
|
|
|
62
64
|
private childProcess: cp.ChildProcess | undefined;
|
|
65
|
+
private messagePipe?: BinaryMessagePipe;
|
|
63
66
|
private client: HostedPluginClient;
|
|
64
67
|
|
|
65
68
|
private terminatingPluginServer = false;
|
|
@@ -82,14 +85,14 @@ export class HostedPluginProcess implements ServerPluginRunner {
|
|
|
82
85
|
}
|
|
83
86
|
|
|
84
87
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
85
|
-
public acceptMessage(pluginHostId: string, message:
|
|
88
|
+
public acceptMessage(pluginHostId: string, message: Uint8Array): boolean {
|
|
86
89
|
return pluginHostId === 'main';
|
|
87
90
|
}
|
|
88
91
|
|
|
89
92
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
90
|
-
public onMessage(pluginHostId: string,
|
|
91
|
-
if (this.
|
|
92
|
-
this.
|
|
93
|
+
public onMessage(pluginHostId: string, message: Uint8Array): void {
|
|
94
|
+
if (this.messagePipe) {
|
|
95
|
+
this.messagePipe.send(message);
|
|
93
96
|
}
|
|
94
97
|
}
|
|
95
98
|
|
|
@@ -106,12 +109,12 @@ export class HostedPluginProcess implements ServerPluginRunner {
|
|
|
106
109
|
const waitForTerminated = new Deferred<void>();
|
|
107
110
|
cp.on('message', message => {
|
|
108
111
|
const msg = JSON.parse(message as string);
|
|
109
|
-
if (
|
|
112
|
+
if (ProcessTerminatedMessage.is(msg)) {
|
|
110
113
|
waitForTerminated.resolve();
|
|
111
114
|
}
|
|
112
115
|
});
|
|
113
116
|
const stopTimeout = this.cli.pluginHostStopTimeout;
|
|
114
|
-
cp.send(JSON.stringify({ type:
|
|
117
|
+
cp.send(JSON.stringify({ type: ProcessTerminateMessage.TYPE, stopTimeout }));
|
|
115
118
|
|
|
116
119
|
const terminateTimeout = this.cli.pluginHostTerminateTimeout;
|
|
117
120
|
if (terminateTimeout) {
|
|
@@ -156,9 +159,11 @@ export class HostedPluginProcess implements ServerPluginRunner {
|
|
|
156
159
|
logger: this.logger,
|
|
157
160
|
args: []
|
|
158
161
|
});
|
|
159
|
-
|
|
162
|
+
|
|
163
|
+
this.messagePipe = new BinaryMessagePipe(this.childProcess.stdio[4] as Duplex);
|
|
164
|
+
this.messagePipe.onMessage(buffer => {
|
|
160
165
|
if (this.client) {
|
|
161
|
-
this.client.postMessage(PLUGIN_HOST_BACKEND,
|
|
166
|
+
this.client.postMessage(PLUGIN_HOST_BACKEND, buffer);
|
|
162
167
|
}
|
|
163
168
|
});
|
|
164
169
|
}
|
|
@@ -184,7 +189,11 @@ export class HostedPluginProcess implements ServerPluginRunner {
|
|
|
184
189
|
silent: true,
|
|
185
190
|
env: env,
|
|
186
191
|
execArgv: [],
|
|
187
|
-
|
|
192
|
+
// 5th element MUST be 'overlapped' for it to work properly on Windows.
|
|
193
|
+
// 'overlapped' works just like 'pipe' on non-Windows platforms.
|
|
194
|
+
// See: https://nodejs.org/docs/latest-v14.x/api/child_process.html#child_process_options_stdio
|
|
195
|
+
// Note: For some reason `@types/node` does not know about 'overlapped'.
|
|
196
|
+
stdio: ['pipe', 'pipe', 'pipe', 'ipc', 'overlapped' as 'pipe']
|
|
188
197
|
};
|
|
189
198
|
const inspectArgPrefix = `--${options.serverName}-inspect`;
|
|
190
199
|
const inspectArg = process.argv.find(v => v.startsWith(inspectArgPrefix));
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2022 STMicroelectronics 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
|
+
// Custom message protocol between `HostedPluginProcess` and its `PluginHost` child process.
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Sent to initiate termination of the counterpart process.
|
|
21
|
+
*/
|
|
22
|
+
export interface ProcessTerminateMessage {
|
|
23
|
+
type: typeof ProcessTerminateMessage.TYPE,
|
|
24
|
+
stopTimeout?: number
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export namespace ProcessTerminateMessage {
|
|
28
|
+
export const TYPE = 0;
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
|
+
export function is(object: any): object is ProcessTerminateMessage {
|
|
31
|
+
return typeof object === 'object' && object.type === TYPE;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Sent to inform the counter part process that the process termination has been completed.
|
|
37
|
+
*/
|
|
38
|
+
export interface ProcessTerminatedMessage {
|
|
39
|
+
type: typeof ProcessTerminateMessage.TYPE,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export namespace ProcessTerminatedMessage {
|
|
43
|
+
export const TYPE = 1;
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
|
+
export function is(object: any): object is ProcessTerminateMessage {
|
|
46
|
+
return typeof object === 'object' && object.type === TYPE;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
@@ -71,7 +71,7 @@ export class HostedPluginSupport {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
onMessage(pluginHostId: string, message:
|
|
74
|
+
onMessage(pluginHostId: string, message: Uint8Array): void {
|
|
75
75
|
// need to perform routing
|
|
76
76
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
77
77
|
if (this.pluginRunners.length > 0) {
|
|
@@ -13,11 +13,12 @@
|
|
|
13
13
|
//
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
|
-
|
|
17
|
-
import
|
|
18
|
-
import {
|
|
16
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
17
|
+
import 'reflect-metadata';
|
|
18
|
+
import { ConnectionClosedError, RPCProtocolImpl } from '../../common/rpc-protocol';
|
|
19
|
+
import { ProcessTerminatedMessage, ProcessTerminateMessage } from './hosted-plugin-protocol';
|
|
19
20
|
import { PluginHostRPC } from './plugin-host-rpc';
|
|
20
|
-
import {
|
|
21
|
+
import { IPCChannel } from '@theia/core/lib/node';
|
|
21
22
|
|
|
22
23
|
console.log('PLUGIN_HOST(' + process.pid + ') starting instance');
|
|
23
24
|
|
|
@@ -74,18 +75,8 @@ process.on('rejectionHandled', (promise: Promise<any>) => {
|
|
|
74
75
|
});
|
|
75
76
|
|
|
76
77
|
let terminating = false;
|
|
77
|
-
const
|
|
78
|
-
const rpc = new RPCProtocolImpl(
|
|
79
|
-
onMessage: emitter.event,
|
|
80
|
-
send: (m: string) => {
|
|
81
|
-
if (process.send && !terminating) {
|
|
82
|
-
process.send(m);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
reviver: reviver
|
|
88
|
-
});
|
|
78
|
+
const channel = new IPCChannel();
|
|
79
|
+
const rpc = new RPCProtocolImpl(channel);
|
|
89
80
|
|
|
90
81
|
process.on('message', async (message: string) => {
|
|
91
82
|
if (terminating) {
|
|
@@ -93,10 +84,9 @@ process.on('message', async (message: string) => {
|
|
|
93
84
|
}
|
|
94
85
|
try {
|
|
95
86
|
const msg = JSON.parse(message);
|
|
96
|
-
if (
|
|
87
|
+
if (ProcessTerminateMessage.is(msg)) {
|
|
97
88
|
terminating = true;
|
|
98
|
-
|
|
99
|
-
if ('stopTimeout' in msg && typeof msg.stopTimeout === 'number' && msg.stopTimeout) {
|
|
89
|
+
if (msg.stopTimeout) {
|
|
100
90
|
await Promise.race([
|
|
101
91
|
pluginHostRPC.terminate(),
|
|
102
92
|
new Promise(resolve => setTimeout(resolve, msg.stopTimeout))
|
|
@@ -106,10 +96,9 @@ process.on('message', async (message: string) => {
|
|
|
106
96
|
}
|
|
107
97
|
rpc.dispose();
|
|
108
98
|
if (process.send) {
|
|
109
|
-
process.send(JSON.stringify({ type:
|
|
99
|
+
process.send(JSON.stringify({ type: ProcessTerminatedMessage.TYPE }));
|
|
110
100
|
}
|
|
111
|
-
|
|
112
|
-
emitter.fire(message);
|
|
101
|
+
|
|
113
102
|
}
|
|
114
103
|
} catch (e) {
|
|
115
104
|
console.error(e);
|
|
@@ -164,7 +164,7 @@ export class HostedPluginServerImpl implements HostedPluginServer {
|
|
|
164
164
|
return Promise.all(plugins.map(plugin => this.localizationService.localizePlugin(plugin)));
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
onMessage(pluginHostId: string, message:
|
|
167
|
+
onMessage(pluginHostId: string, message: Uint8Array): Promise<void> {
|
|
168
168
|
this.hostedPlugin.onMessage(pluginHostId, message);
|
|
169
169
|
return Promise.resolve();
|
|
170
170
|
}
|
|
@@ -223,11 +223,12 @@ export class CustomEditorsMainImpl implements CustomEditorsMain, Disposable {
|
|
|
223
223
|
const view = await this.widgetManager.getOrCreateWidget<CustomEditorWidget>(CustomEditorWidget.FACTORY_ID, <WebviewWidgetIdentifier>{ id: panelId });
|
|
224
224
|
this.webviewsMain.hookWebview(view);
|
|
225
225
|
view.title.label = title;
|
|
226
|
-
const { enableFindWidget, retainContextWhenHidden, enableScripts, localResourceRoots, ...contentOptions } = options;
|
|
226
|
+
const { enableFindWidget, retainContextWhenHidden, enableScripts, enableForms, localResourceRoots, ...contentOptions } = options;
|
|
227
227
|
view.viewColumn = ViewColumn.One; // behaviour might be overridden later using widgetOpenerOptions (if available)
|
|
228
228
|
view.options = { enableFindWidget, retainContextWhenHidden };
|
|
229
229
|
view.setContentOptions({
|
|
230
230
|
allowScripts: enableScripts,
|
|
231
|
+
allowForms: enableForms,
|
|
231
232
|
localResourceRoots: localResourceRoots && localResourceRoots.map(root => root.toString()),
|
|
232
233
|
...contentOptions,
|
|
233
234
|
...view.contentOptions
|
|
@@ -27,7 +27,7 @@ import { URI } from '@theia/core/shared/vscode-uri';
|
|
|
27
27
|
import { interfaces } from '@theia/core/shared/inversify';
|
|
28
28
|
import CoreURI from '@theia/core/lib/common/uri';
|
|
29
29
|
import { BinaryBuffer } from '@theia/core/lib/common/buffer';
|
|
30
|
-
import { Disposable } from '@theia/core/lib/common/disposable';
|
|
30
|
+
import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable';
|
|
31
31
|
import { Event, Emitter } from '@theia/core/lib/common/event';
|
|
32
32
|
import { MAIN_RPC_CONTEXT, FileSystemMain, FileSystemExt, IFileChangeDto } from '../../common/plugin-api-rpc';
|
|
33
33
|
import { RPCProtocol } from '../../common/rpc-protocol';
|
|
@@ -46,15 +46,24 @@ export class FileSystemMainImpl implements FileSystemMain, Disposable {
|
|
|
46
46
|
private readonly _proxy: FileSystemExt;
|
|
47
47
|
private readonly _fileProvider = new Map<number, RemoteFileSystemProvider>();
|
|
48
48
|
private readonly _fileService: FileService;
|
|
49
|
+
private readonly _disposables = new DisposableCollection();
|
|
49
50
|
|
|
50
51
|
constructor(rpc: RPCProtocol, container: interfaces.Container) {
|
|
51
52
|
this._proxy = rpc.getProxy(MAIN_RPC_CONTEXT.FILE_SYSTEM_EXT);
|
|
52
53
|
this._fileService = container.get(FileService);
|
|
54
|
+
|
|
55
|
+
for (const { scheme, capabilities } of this._fileService.listCapabilities()) {
|
|
56
|
+
this._proxy.$acceptProviderInfos(scheme, capabilities);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
this._disposables.push(this._fileService.onDidChangeFileSystemProviderRegistrations(e => this._proxy.$acceptProviderInfos(e.scheme, e.provider?.capabilities)));
|
|
60
|
+
this._disposables.push(this._fileService.onDidChangeFileSystemProviderCapabilities(e => this._proxy.$acceptProviderInfos(e.scheme, e.provider.capabilities)));
|
|
61
|
+
this._disposables.push(Disposable.create(() => this._fileProvider.forEach(value => value.dispose())));
|
|
62
|
+
this._disposables.push(Disposable.create(() => this._fileProvider.clear()));
|
|
53
63
|
}
|
|
54
64
|
|
|
55
65
|
dispose(): void {
|
|
56
|
-
this.
|
|
57
|
-
this._fileProvider.clear();
|
|
66
|
+
this._disposables.dispose();
|
|
58
67
|
}
|
|
59
68
|
|
|
60
69
|
$registerFileSystemProvider(handle: number, scheme: string, capabilities: FileSystemProviderCapabilities): void {
|
|
@@ -34,7 +34,8 @@ import {
|
|
|
34
34
|
WorkspaceTextEditDto,
|
|
35
35
|
PluginInfo,
|
|
36
36
|
LanguageStatus as LanguageStatusDTO,
|
|
37
|
-
InlayHintDto
|
|
37
|
+
InlayHintDto,
|
|
38
|
+
IdentifiableInlineCompletions
|
|
38
39
|
} from '../../common/plugin-api-rpc';
|
|
39
40
|
import { injectable, inject } from '@theia/core/shared/inversify';
|
|
40
41
|
import {
|
|
@@ -868,6 +869,22 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
|
|
|
868
869
|
}
|
|
869
870
|
}
|
|
870
871
|
|
|
872
|
+
$registerInlineCompletionsSupport(handle: number, selector: SerializedDocumentFilter[]): void {
|
|
873
|
+
const languageSelector = this.toLanguageSelector(selector);
|
|
874
|
+
const provider: monaco.languages.InlineCompletionsProvider<IdentifiableInlineCompletions> = {
|
|
875
|
+
provideInlineCompletions: async (
|
|
876
|
+
model: monaco.editor.ITextModel,
|
|
877
|
+
position: monaco.Position,
|
|
878
|
+
context: monaco.languages.InlineCompletionContext,
|
|
879
|
+
token: CancellationToken
|
|
880
|
+
): Promise<IdentifiableInlineCompletions | undefined> => this.proxy.$provideInlineCompletions(handle, model.uri, position, context, token),
|
|
881
|
+
freeInlineCompletions: (completions: IdentifiableInlineCompletions): void => {
|
|
882
|
+
this.proxy.$freeInlineCompletionsList(handle, completions.pid);
|
|
883
|
+
}
|
|
884
|
+
};
|
|
885
|
+
this.register(handle, (monaco.languages.registerInlineCompletionsProvider as RegistrationFunction<monaco.languages.InlineCompletionsProvider>)(languageSelector, provider));
|
|
886
|
+
}
|
|
887
|
+
|
|
871
888
|
$registerQuickFixProvider(
|
|
872
889
|
handle: number,
|
|
873
890
|
pluginInfo: PluginInfo,
|
|
@@ -56,7 +56,6 @@ import { CustomEditorsMainImpl } from './custom-editors/custom-editors-main';
|
|
|
56
56
|
import { SecretsMainImpl } from './secrets-main';
|
|
57
57
|
import { WebviewViewsMainImpl } from './webview-views/webview-views-main';
|
|
58
58
|
import { MonacoLanguages } from '@theia/monaco/lib/browser/monaco-languages';
|
|
59
|
-
import { NotificationExtImpl } from '../../plugin/notification';
|
|
60
59
|
import { UntitledResourceResolver } from '@theia/core/lib/common/resource';
|
|
61
60
|
import { ThemeService } from '@theia/core/lib/browser/theming';
|
|
62
61
|
|
|
@@ -110,9 +109,6 @@ export function setUpPluginApi(rpc: RPCProtocol, container: interfaces.Container
|
|
|
110
109
|
const notificationMain = new NotificationMainImpl(rpc, container);
|
|
111
110
|
rpc.set(PLUGIN_RPC_CONTEXT.NOTIFICATION_MAIN, notificationMain);
|
|
112
111
|
|
|
113
|
-
const notificationExt = new NotificationExtImpl(rpc);
|
|
114
|
-
rpc.set(MAIN_RPC_CONTEXT.NOTIFICATION_EXT, notificationExt);
|
|
115
|
-
|
|
116
112
|
const terminalMain = new TerminalServiceMainImpl(rpc, container);
|
|
117
113
|
rpc.set(PLUGIN_RPC_CONTEXT.TERMINAL_MAIN, terminalMain);
|
|
118
114
|
|
|
@@ -26,7 +26,7 @@ import { RPCProtocol } from '../../common/rpc-protocol';
|
|
|
26
26
|
import { Disposable, DisposableCollection } from '@theia/core/lib/common';
|
|
27
27
|
import { TaskProviderRegistry, TaskResolverRegistry, TaskProvider, TaskResolver } from '@theia/task/lib/browser/task-contribution';
|
|
28
28
|
import { interfaces } from '@theia/core/shared/inversify';
|
|
29
|
-
import { TaskInfo, TaskExitedEvent, TaskConfiguration,
|
|
29
|
+
import { TaskInfo, TaskExitedEvent, TaskConfiguration, TaskOutputPresentation, RevealKind, PanelKind } from '@theia/task/lib/common/task-protocol';
|
|
30
30
|
import { TaskWatcher } from '@theia/task/lib/common/task-watcher';
|
|
31
31
|
import { TaskService } from '@theia/task/lib/browser/task-service';
|
|
32
32
|
import { TaskDefinitionRegistry } from '@theia/task/lib/browser';
|
|
@@ -207,8 +207,11 @@ export class TasksMainImpl implements TasksMain, Disposable {
|
|
|
207
207
|
if (presentation) {
|
|
208
208
|
partialConfig.presentation = this.convertTaskPresentation(presentation);
|
|
209
209
|
}
|
|
210
|
-
if (group
|
|
211
|
-
partialConfig.group =
|
|
210
|
+
if (group) {
|
|
211
|
+
partialConfig.group = {
|
|
212
|
+
kind: group.kind,
|
|
213
|
+
isDefault: group.isDefault
|
|
214
|
+
};
|
|
212
215
|
}
|
|
213
216
|
return {
|
|
214
217
|
...common,
|
|
@@ -225,12 +228,13 @@ export class TasksMainImpl implements TasksMain, Disposable {
|
|
|
225
228
|
if (presentation) {
|
|
226
229
|
partialDto.presentation = this.convertTaskPresentation(presentation);
|
|
227
230
|
}
|
|
228
|
-
if (group) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
231
|
+
if (group === 'build' || group === 'test') {
|
|
232
|
+
partialDto.group = {
|
|
233
|
+
kind: group,
|
|
234
|
+
isDefault: false
|
|
235
|
+
};
|
|
236
|
+
} else if (typeof group === 'object') {
|
|
237
|
+
partialDto.group = group;
|
|
234
238
|
}
|
|
235
239
|
return {
|
|
236
240
|
...common,
|
|
@@ -260,11 +260,11 @@ export class TerminalServiceMainImpl implements TerminalServiceMain, TerminalLin
|
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
-
async provideLinks(line: string, terminal: TerminalWidget,
|
|
263
|
+
async provideLinks(line: string, terminal: TerminalWidget, cancellationToken?: CancellationToken | undefined): Promise<TerminalLink[]> {
|
|
264
264
|
if (this.terminalLinkProviders.length < 1) {
|
|
265
265
|
return [];
|
|
266
266
|
}
|
|
267
|
-
const links = await this.extProxy.$provideTerminalLinks(line, terminal.id,
|
|
267
|
+
const links = await this.extProxy.$provideTerminalLinks(line, terminal.id, cancellationToken ?? CancellationToken.None);
|
|
268
268
|
return links.map(link => ({ ...link, handle: () => this.extProxy.$handleTerminalLink(link) }));
|
|
269
269
|
}
|
|
270
270
|
|
|
@@ -479,7 +479,14 @@
|
|
|
479
479
|
const newFrame = document.createElement('iframe');
|
|
480
480
|
newFrame.setAttribute('id', 'pending-frame');
|
|
481
481
|
newFrame.setAttribute('frameborder', '0');
|
|
482
|
-
|
|
482
|
+
const sandboxOptions = ['allow-same-origin'];
|
|
483
|
+
if (options.allowScripts) {
|
|
484
|
+
sandboxOptions.push('allow-scripts', 'allow-downloads');
|
|
485
|
+
}
|
|
486
|
+
if (options.allowForms ?? options.allowScripts) {
|
|
487
|
+
sandboxOptions.push('allow-forms');
|
|
488
|
+
}
|
|
489
|
+
newFrame.setAttribute('sandbox', sandboxOptions.join(' '));
|
|
483
490
|
if (host.fakeLoad) {
|
|
484
491
|
// We should just be able to use srcdoc, but I wasn't
|
|
485
492
|
// seeing the service worker applying properly.
|
|
@@ -73,6 +73,7 @@ export const enum WebviewMessageChannels {
|
|
|
73
73
|
|
|
74
74
|
export interface WebviewContentOptions {
|
|
75
75
|
readonly allowScripts?: boolean;
|
|
76
|
+
readonly allowForms?: boolean;
|
|
76
77
|
readonly localResourceRoots?: ReadonlyArray<string>;
|
|
77
78
|
readonly portMapping?: ReadonlyArray<WebviewPortMapping>;
|
|
78
79
|
readonly enableCommandUris?: boolean;
|
|
@@ -67,10 +67,11 @@ export class WebviewsMainImpl implements WebviewsMain, Disposable {
|
|
|
67
67
|
this.hookWebview(view);
|
|
68
68
|
view.viewType = viewType;
|
|
69
69
|
view.title.label = title;
|
|
70
|
-
const { enableFindWidget, retainContextWhenHidden, enableScripts, localResourceRoots, ...contentOptions } = options;
|
|
70
|
+
const { enableFindWidget, retainContextWhenHidden, enableScripts, enableForms, localResourceRoots, ...contentOptions } = options;
|
|
71
71
|
view.options = { enableFindWidget, retainContextWhenHidden };
|
|
72
72
|
view.setContentOptions({
|
|
73
73
|
allowScripts: enableScripts,
|
|
74
|
+
allowForms: enableForms,
|
|
74
75
|
localResourceRoots: localResourceRoots && localResourceRoots.map(root => root.toString()),
|
|
75
76
|
...contentOptions
|
|
76
77
|
});
|
|
@@ -171,9 +172,10 @@ export class WebviewsMainImpl implements WebviewsMain, Disposable {
|
|
|
171
172
|
|
|
172
173
|
async $setOptions(handle: string, options: WebviewOptions): Promise<void> {
|
|
173
174
|
const webview = await this.getWebview(handle);
|
|
174
|
-
const { enableScripts, localResourceRoots, ...contentOptions } = options;
|
|
175
|
+
const { enableScripts, enableForms, localResourceRoots, ...contentOptions } = options;
|
|
175
176
|
webview.setContentOptions({
|
|
176
177
|
allowScripts: enableScripts,
|
|
178
|
+
allowForms: enableForms,
|
|
177
179
|
localResourceRoots: localResourceRoots && localResourceRoots.map(root => root.toString()),
|
|
178
180
|
...contentOptions
|
|
179
181
|
});
|
|
@@ -210,10 +212,11 @@ export class WebviewsMainImpl implements WebviewsMain, Disposable {
|
|
|
210
212
|
}
|
|
211
213
|
|
|
212
214
|
const options = widget.options;
|
|
213
|
-
const { allowScripts, localResourceRoots, ...contentOptions } = widget.contentOptions;
|
|
215
|
+
const { allowScripts, allowForms, localResourceRoots, ...contentOptions } = widget.contentOptions;
|
|
214
216
|
this.updateViewState(widget);
|
|
215
217
|
await this.proxy.$deserializeWebviewPanel(handle, widget.viewType, title, state, widget.viewState, {
|
|
216
218
|
enableScripts: allowScripts,
|
|
219
|
+
enableForms: allowForms,
|
|
217
220
|
localResourceRoots: localResourceRoots && localResourceRoots.map(root => URI.parse(root)),
|
|
218
221
|
...contentOptions,
|
|
219
222
|
...options
|
|
@@ -32,6 +32,7 @@ import { DebugAdapter } from '@theia/debug/lib/common/debug-model';
|
|
|
32
32
|
import { PluginDebugAdapterCreator } from './plugin-debug-adapter-creator';
|
|
33
33
|
import { NodeDebugAdapterCreator } from '../node/debug/plugin-node-debug-adapter-creator';
|
|
34
34
|
import { DebugProtocol } from '@vscode/debugprotocol';
|
|
35
|
+
import { DebugConfiguration } from '@theia/debug/lib/common/debug-configuration';
|
|
35
36
|
|
|
36
37
|
interface ConfigurationProviderRecord {
|
|
37
38
|
handle: number;
|
|
@@ -171,7 +172,13 @@ export class DebugExtImpl implements DebugExt {
|
|
|
171
172
|
}
|
|
172
173
|
|
|
173
174
|
startDebugging(folder: theia.WorkspaceFolder | undefined, nameOrConfiguration: string | theia.DebugConfiguration, options: theia.DebugSessionOptions): PromiseLike<boolean> {
|
|
174
|
-
return this.proxy.$startDebugging(folder, nameOrConfiguration,
|
|
175
|
+
return this.proxy.$startDebugging(folder, nameOrConfiguration, {
|
|
176
|
+
parentSessionId: options.parentSession?.id,
|
|
177
|
+
compact: options.compact,
|
|
178
|
+
consoleMode: options.consoleMode,
|
|
179
|
+
lifecycleManagedByParent: options.lifecycleManagedByParent,
|
|
180
|
+
noDebug: options.noDebug
|
|
181
|
+
});
|
|
175
182
|
}
|
|
176
183
|
|
|
177
184
|
stopDebugging(session?: theia.DebugSession): PromiseLike<void> {
|
|
@@ -313,13 +320,15 @@ export class DebugExtImpl implements DebugExt {
|
|
|
313
320
|
return undefined;
|
|
314
321
|
}
|
|
315
322
|
|
|
316
|
-
async $createDebugSession(debugConfiguration:
|
|
323
|
+
async $createDebugSession(debugConfiguration: DebugConfiguration, workspaceFolderUri: string | undefined): Promise<string> {
|
|
317
324
|
const sessionId = uuid.v4();
|
|
318
325
|
|
|
326
|
+
const parentSession = debugConfiguration.parentSessionId ? this.sessions.get(debugConfiguration.parentSessionId) : undefined;
|
|
319
327
|
const theiaSession: theia.DebugSession = {
|
|
320
328
|
id: sessionId,
|
|
321
329
|
type: debugConfiguration.type,
|
|
322
330
|
name: debugConfiguration.name,
|
|
331
|
+
parentSession: parentSession,
|
|
323
332
|
workspaceFolder: this.toWorkspaceFolder(workspaceFolderUri),
|
|
324
333
|
configuration: debugConfiguration,
|
|
325
334
|
customRequest: async (command: string, args?: any) => {
|