Skip to content

Commit e2d5e90

Browse files
author
Benjamin Pasero
committed
debt - move extension debug IPC channel closer to interface
1 parent bc797a3 commit e2d5e90

2 files changed

Lines changed: 110 additions & 100 deletions

File tree

src/vs/code/electron-main/app.ts

Lines changed: 1 addition & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -68,20 +68,18 @@ import { statSync } from 'fs';
6868
import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsIpc';
6969
import { IDiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsService';
7070
import { ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/extensionHostDebugIpc';
71+
import { ElectronExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/electron-main/extensionHostDebugIpc';
7172
import { IElectronMainService, ElectronMainService } from 'vs/platform/electron/electron-main/electronMainService';
7273
import { ISharedProcessMainService, SharedProcessMainService } from 'vs/platform/ipc/electron-main/sharedProcessMainService';
7374
import { IDialogMainService, DialogMainService } from 'vs/platform/dialogs/electron-main/dialogs';
7475
import { withNullAsUndefined } from 'vs/base/common/types';
75-
import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv';
7676
import { coalesce } from 'vs/base/common/arrays';
7777
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
7878
import { StorageKeysSyncRegistryChannel } from 'vs/platform/userDataSync/common/userDataSyncIpc';
7979
import { INativeEnvironmentService } from 'vs/platform/environment/node/environmentService';
8080
import { mnemonicButtonLabel, getPathLabel } from 'vs/base/common/labels';
8181
import { WebviewMainService } from 'vs/platform/webview/electron-main/webviewMainService';
8282
import { IWebviewManagerService } from 'vs/platform/webview/common/webviewManagerService';
83-
import { createServer, AddressInfo } from 'net';
84-
import { IOpenExtensionWindowResult } from 'vs/platform/debug/common/extensionHostDebug';
8583
import { IFileService } from 'vs/platform/files/common/files';
8684
import { stripComments } from 'vs/base/common/json';
8785
import { generateUuid } from 'vs/base/common/uuid';
@@ -867,100 +865,3 @@ export class CodeApplication extends Disposable {
867865
});
868866
}
869867
}
870-
871-
class ElectronExtensionHostDebugBroadcastChannel<TContext> extends ExtensionHostDebugBroadcastChannel<TContext> {
872-
873-
constructor(private windowsMainService: IWindowsMainService) {
874-
super();
875-
}
876-
877-
call(ctx: TContext, command: string, arg?: any): Promise<any> {
878-
if (command === 'openExtensionDevelopmentHostWindow') {
879-
return this.openExtensionDevelopmentHostWindow(arg[0], arg[1], arg[2]);
880-
} else {
881-
return super.call(ctx, command, arg);
882-
}
883-
}
884-
885-
private async openExtensionDevelopmentHostWindow(args: string[], env: IProcessEnvironment, debugRenderer: boolean): Promise<IOpenExtensionWindowResult> {
886-
const pargs = parseArgs(args, OPTIONS);
887-
const extDevPaths = pargs.extensionDevelopmentPath;
888-
if (!extDevPaths) {
889-
return {};
890-
}
891-
892-
const [codeWindow] = this.windowsMainService.openExtensionDevelopmentHostWindow(extDevPaths, {
893-
context: OpenContext.API,
894-
cli: pargs,
895-
userEnv: Object.keys(env).length > 0 ? env : undefined
896-
});
897-
898-
if (!debugRenderer) {
899-
return {};
900-
}
901-
902-
const debug = codeWindow.win.webContents.debugger;
903-
904-
let listeners = debug.isAttached() ? Infinity : 0;
905-
const server = createServer(listener => {
906-
if (listeners++ === 0) {
907-
debug.attach();
908-
}
909-
910-
let closed = false;
911-
const writeMessage = (message: object) => {
912-
if (!closed) { // in case sendCommand promises settle after closed
913-
listener.write(JSON.stringify(message) + '\0'); // null-delimited, CDP-compatible
914-
}
915-
};
916-
917-
const onMessage = (_event: Event, method: string, params: unknown, sessionId?: string) =>
918-
writeMessage(({ method, params, sessionId }));
919-
920-
codeWindow.win.on('close', () => {
921-
debug.removeListener('message', onMessage);
922-
listener.end();
923-
closed = true;
924-
});
925-
926-
debug.addListener('message', onMessage);
927-
928-
let buf = Buffer.alloc(0);
929-
listener.on('data', data => {
930-
buf = Buffer.concat([buf, data]);
931-
for (let delimiter = buf.indexOf(0); delimiter !== -1; delimiter = buf.indexOf(0)) {
932-
let data: { id: number; sessionId: string; params: {} };
933-
try {
934-
const contents = buf.slice(0, delimiter).toString('utf8');
935-
buf = buf.slice(delimiter + 1);
936-
data = JSON.parse(contents);
937-
} catch (e) {
938-
console.error('error reading cdp line', e);
939-
}
940-
941-
// depends on a new API for which electron.d.ts has not been updated:
942-
// @ts-ignore
943-
debug.sendCommand(data.method, data.params, data.sessionId)
944-
.then((result: object) => writeMessage({ id: data.id, sessionId: data.sessionId, result }))
945-
.catch((error: Error) => writeMessage({ id: data.id, sessionId: data.sessionId, error: { code: 0, message: error.message } }));
946-
}
947-
});
948-
949-
listener.on('error', err => {
950-
console.error('error on cdp pipe:', err);
951-
});
952-
953-
listener.on('close', () => {
954-
closed = true;
955-
if (--listeners === 0) {
956-
debug.detach();
957-
}
958-
});
959-
});
960-
961-
await new Promise(r => server.listen(0, r));
962-
codeWindow.win.on('close', () => server.close());
963-
964-
return { rendererDebugPort: (server.address() as AddressInfo).port };
965-
}
966-
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { IOpenExtensionWindowResult } from 'vs/platform/debug/common/extensionHostDebug';
7+
import { IProcessEnvironment } from 'vs/base/common/platform';
8+
import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv';
9+
import { createServer, AddressInfo } from 'net';
10+
import { ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/extensionHostDebugIpc';
11+
import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows';
12+
import { OpenContext } from 'vs/platform/windows/node/window';
13+
14+
export class ElectronExtensionHostDebugBroadcastChannel<TContext> extends ExtensionHostDebugBroadcastChannel<TContext> {
15+
16+
constructor(private windowsMainService: IWindowsMainService) {
17+
super();
18+
}
19+
20+
call(ctx: TContext, command: string, arg?: any): Promise<any> {
21+
if (command === 'openExtensionDevelopmentHostWindow') {
22+
return this.openExtensionDevelopmentHostWindow(arg[0], arg[1], arg[2]);
23+
} else {
24+
return super.call(ctx, command, arg);
25+
}
26+
}
27+
28+
private async openExtensionDevelopmentHostWindow(args: string[], env: IProcessEnvironment, debugRenderer: boolean): Promise<IOpenExtensionWindowResult> {
29+
const pargs = parseArgs(args, OPTIONS);
30+
const extDevPaths = pargs.extensionDevelopmentPath;
31+
if (!extDevPaths) {
32+
return {};
33+
}
34+
35+
const [codeWindow] = this.windowsMainService.openExtensionDevelopmentHostWindow(extDevPaths, {
36+
context: OpenContext.API,
37+
cli: pargs,
38+
userEnv: Object.keys(env).length > 0 ? env : undefined
39+
});
40+
41+
if (!debugRenderer) {
42+
return {};
43+
}
44+
45+
const debug = codeWindow.win.webContents.debugger;
46+
47+
let listeners = debug.isAttached() ? Infinity : 0;
48+
const server = createServer(listener => {
49+
if (listeners++ === 0) {
50+
debug.attach();
51+
}
52+
53+
let closed = false;
54+
const writeMessage = (message: object) => {
55+
if (!closed) { // in case sendCommand promises settle after closed
56+
listener.write(JSON.stringify(message) + '\0'); // null-delimited, CDP-compatible
57+
}
58+
};
59+
60+
const onMessage = (_event: Event, method: string, params: unknown, sessionId?: string) =>
61+
writeMessage(({ method, params, sessionId }));
62+
63+
codeWindow.win.on('close', () => {
64+
debug.removeListener('message', onMessage);
65+
listener.end();
66+
closed = true;
67+
});
68+
69+
debug.addListener('message', onMessage);
70+
71+
let buf = Buffer.alloc(0);
72+
listener.on('data', data => {
73+
buf = Buffer.concat([buf, data]);
74+
for (let delimiter = buf.indexOf(0); delimiter !== -1; delimiter = buf.indexOf(0)) {
75+
let data: { id: number; sessionId: string; params: {} };
76+
try {
77+
const contents = buf.slice(0, delimiter).toString('utf8');
78+
buf = buf.slice(delimiter + 1);
79+
data = JSON.parse(contents);
80+
} catch (e) {
81+
console.error('error reading cdp line', e);
82+
}
83+
84+
// depends on a new API for which electron.d.ts has not been updated:
85+
// @ts-ignore
86+
debug.sendCommand(data.method, data.params, data.sessionId)
87+
.then((result: object) => writeMessage({ id: data.id, sessionId: data.sessionId, result }))
88+
.catch((error: Error) => writeMessage({ id: data.id, sessionId: data.sessionId, error: { code: 0, message: error.message } }));
89+
}
90+
});
91+
92+
listener.on('error', err => {
93+
console.error('error on cdp pipe:', err);
94+
});
95+
96+
listener.on('close', () => {
97+
closed = true;
98+
if (--listeners === 0) {
99+
debug.detach();
100+
}
101+
});
102+
});
103+
104+
await new Promise(r => server.listen(0, r));
105+
codeWindow.win.on('close', () => server.close());
106+
107+
return { rendererDebugPort: (server.address() as AddressInfo).port };
108+
}
109+
}

0 commit comments

Comments
 (0)