src/vs/base/parts/ipc/node/ipc.cp.ts

284 LOC · 99 covered · 185 uncovered · 10 ranges · 58 concepts · 1 introducers · 32 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the filesrc/vs/platform/files/common/diskFileSystemProvider.ts · 256 LOCcommon/diskFileSystemPro…src/vs/platform/files/node/diskFileSystemProvider.ts · 898 LOCnode/diskFileSystemProvi…src/vs/platform/files/node/watcher/baseWatcher.ts · 275 LOCwatcher/baseWatcher.tssrc/vs/platform/files/node/watcher/nodejs/nodejsClient.ts · 26 LOCnodejs/nodejsClient.tssrc/vs/platform/files/node/watcher/nodejs/nodejsWatcher.ts · 178 LOCnodejs/nodejsWatcher.tssrc/vs/platform/files/node/watcher/nodejs/nodejsWatcherLib.ts · 637 LOCnodejs/nodejsWatcherLib.…src/vs/platform/files/node/watcher/watcherClient.ts · 47 LOCwatcher/watcherClient.tscolorThemeData.ts ×16 · 64 introduced LOCcolorThemeData.ts ×16tokenClassificationRegistry.ts ×1 · 3 introduced LOCtokenClassificationRegis…tokenClassificationRegistry.ts ×2 · 7 introduced LOCtokenClassificationRegis…tokenStyleResolving.test|title=Themes - TokenStyleResolving language|occurrence=1 · 0 introduced LOCtokenStyleResolving.test…colorThemeData.ts ×1 · 2 introduced LOCcolorThemeData.ts ×1colorThemeData.ts ×12 · 57 introduced LOCcolorThemeData.ts ×12tokenClassificationRegistry.ts ×2 · 6 introduced LOCtokenClassificationRegis…colorThemeData.ts ×5 · 21 introduced LOCcolorThemeData.ts ×5colorThemeData.ts ×1 · 6 introduced LOCcolorThemeData.ts ×1colorThemeData.ts ×33 · 242 introduced LOCcolorThemeData.ts ×33colorThemeData.ts ×2 · 5 introduced LOCcolorThemeData.ts ×2tokenStyleResolving.test|title=Themes - TokenStyleResolving resolveScopes - match most specific|occurrence=1 · 0 introduced LOCtokenStyleResolving.test…colorThemeData.ts ×5 · 33 introduced LOCcolorThemeData.ts ×5colorThemeData.ts ×1 · 4 introduced LOCcolorThemeData.ts ×1tokenClassificationRegistry.ts ×1 · 16 introduced LOCtokenClassificationRegis…colorThemeData.ts ×1 · 1 introduced LOCcolorThemeData.ts ×1colorThemeData.ts ×13 · 114 introduced LOCcolorThemeData.ts ×13colorThemeData.ts ×1 · 1 introduced LOCcolorThemeData.ts ×1colorThemeData.ts ×4 · 15 introduced LOCcolorThemeData.ts ×4colorThemeData.ts ×57 · 483 introduced LOCcolorThemeData.ts ×57agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache hit returns immediately without re-downloading|occurrence=1 · 0 introduced LOCagentSdkDownloader.test|…diskFileSystemProvider.ts ×11 · 79 introduced LOCdiskFileSystemProvider.t…agentSdkDownloader.ts ×3 · 28 introduced LOCagentSdkDownloader.ts ×3diskFileSystemProvider.ts ×20 · 260 introduced LOCdiskFileSystemProvider.t…agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×2 · 20 introduced LOCagentSdkDownloader.ts ×2stateService.ts ×2 · 7 introduced LOCstateService.ts ×2stateService.ts ×1 · 2 introduced LOCstateService.ts ×1stateService.ts ×2 · 14 introduced LOCstateService.ts ×2stateService.ts ×1 · 2 introduced LOCstateService.ts ×1diskFileSystemProvider.ts ×9 · 73 introduced LOCdiskFileSystemProvider.t…agentSdkDownloader.ts ×1 · 6 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×2 · 8 introduced LOCagentSdkDownloader.ts ×2agentSdkDownloader.ts ×1 · 5 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×2 · 8 introduced LOCagentSdkDownloader.ts ×2agentSdkDownloader.ts ×5 · 10 introduced LOCagentSdkDownloader.ts ×5agentSdkDownloader.ts ×1 · 3 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×3 · 5 introduced LOCagentSdkDownloader.ts ×3agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: true when product config populated and host has a target|occurrence=1 · 0 introduced LOCagentSdkDownloader.test|…agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×2 · 3 introduced LOCagentSdkDownloader.ts ×2agentSdkDownloader.ts ×1 · 8 introduced LOCagentSdkDownloader.ts ×1diskFileSystemProvider.ts ×28 · 135 introduced LOCdiskFileSystemProvider.t…diskFileSystemProvider.ts ×3 · 12 introduced LOCdiskFileSystemProvider.t…io.ts ×12 · 175 introduced LOCio.ts ×12agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×2 · 5 introduced LOCagentSdkDownloader.ts ×2diskFileSystemProvider.ts ×17 · 105 introduced LOCdiskFileSystemProvider.t…diskFileSystemProvider.ts ×1 · 21 introduced LOCdiskFileSystemProvider.t…stateService.ts ×1 · 2 introduced LOCstateService.ts ×1stateService.ts ×16 · 141 introduced LOCstateService.ts ×16diskFileSystemProvider.ts ×2 · 3 introduced LOCdiskFileSystemProvider.t…diskFileSystemProvider.ts ×10 · 34 introduced LOCdiskFileSystemProvider.t…diskFileSystemProvider.ts ×15 · 104 introduced LOCdiskFileSystemProvider.t…diskFileSystemProvider.ts ×21 · 577 introduced LOCdiskFileSystemProvider.t…agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: false when no env override and no product config|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: false when no env override and no product config|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: true when env override set|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: true when env override set|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: true when product config populated and host has a target|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: true when product config populated and host has a target|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache dir includes sdkTarget so Universal launches stay separate|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache dir includes sdkTarget so Universal launches stay separate|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache hit returns immediately without re-downloading|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache hit returns immediately without re-downloading|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache miss → downloads, extracts, writes sentinel|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache miss → downloads, extracts, writes sentinel|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cancel before download completes cleans up scratch dir|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cancel before download completes cleans up scratch dir|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: concurrent calls in same process share one download|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: concurrent calls in same process share one download|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: dev override returns the path unchanged|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: dev override returns the path unchanged|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: missing product config and no env override throws actionable error|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: missing product config and no env override throws actionable error|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: rename-loser path returns existing cache when winner already published|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: rename-loser path returns existing cache when winner already published|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: reports monotonic download progress ending at totalBytes|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: reports monotonic download progress ending at totalBytes|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: substitutes {sdkTarget} into urlTemplate|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: substitutes {sdkTarget} into urlTemplate|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: urlTemplate with unknown placeholder throws config error|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: urlTemplate with unknown placeholder throws config error|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=resolveSdkTarget appends -musl on musl Linux iff the package has separate musl SKUs|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=resolveSdkTarget appends -musl on musl Linux iff the package has separate musl SKUs|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=resolveSdkTarget returns <platform>-<arch> for supported (platform, arch)|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=resolveSdkTarget returns <platform>-<arch> for supported (platform, arch)|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=resolveSdkTarget returns undefined for unsupported (platform, arch)|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=resolveSdkTarget returns undefined for unsupported (platform, arch)|occurrence=1agentSdkDownloader.test|…checksumService.test|title=Checksum Service checksum|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/checksum/test/node/checksumService.test|title=Checksum Service checksum|occurrence=1checksumService.test|tit…state.test|title=StateService Basics (delayed strategy)|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/state/test/node/state.test|title=StateService Basics (delayed strategy)|occurrence=1state.test|title=StateSe…state.test|title=StateService Basics (immediate strategy)|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/state/test/node/state.test|title=StateService Basics (immediate strategy)|occurrence=1state.test|title=StateSe…state.test|title=StateService Closed before init|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/state/test/node/state.test|title=StateService Closed before init|occurrence=1state.test|title=StateSe…state.test|title=StateService Multiple ops (Immediate Strategy)|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/state/test/node/state.test|title=StateService Multiple ops (Immediate Strategy)|occurrence=1state.test|title=StateSe…state.test|title=StateService Multiple ops are buffered and applied|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/state/test/node/state.test|title=StateService Multiple ops are buffered and applied|occurrence=1state.test|title=StateSe…state.test|title=StateService Used after close|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/state/test/node/state.test|title=StateService Used after close|occurrence=1state.test|title=StateSe…state.test|title=StateService Used before init|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/state/test/node/state.test|title=StateService Used before init|occurrence=1state.test|title=StateSe…tokenStyleResolving.test|title=Themes - TokenStyleResolving color defaults|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/services/themes/test/node/tokenStyleResolving.test|title=Themes - TokenStyleResolving color defaults|occurrence=1tokenStyleResolving.test…tokenStyleResolving.test|title=Themes - TokenStyleResolving language - scope resolving|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/services/themes/test/node/tokenStyleResolving.test|title=Themes - TokenStyleResolving language - scope resolving|occurrence=1tokenStyleResolving.test…tokenStyleResolving.test|title=Themes - TokenStyleResolving language|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/services/themes/test/node/tokenStyleResolving.test|title=Themes - TokenStyleResolving language|occurrence=1tokenStyleResolving.test…tokenStyleResolving.test|title=Themes - TokenStyleResolving resolveScopes - match most specific|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/services/themes/test/node/tokenStyleResolving.test|title=Themes - TokenStyleResolving resolveScopes - match most specific|occurrence=1tokenStyleResolving.test…tokenStyleResolving.test|title=Themes - TokenStyleResolving resolveScopes|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/services/themes/test/node/tokenStyleResolving.test|title=Themes - TokenStyleResolving resolveScopes|occurrence=1tokenStyleResolving.test…tokenStyleResolving.test|title=Themes - TokenStyleResolving rule matching|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/services/themes/test/node/tokenStyleResolving.test|title=Themes - TokenStyleResolving rule matching|occurrence=1tokenStyleResolving.test…tokenStyleResolving.test|title=Themes - TokenStyleResolving super type|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/services/themes/test/node/tokenStyleResolving.test|title=Themes - TokenStyleResolving super type|occurrence=1tokenStyleResolving.test…Focused file · src/vs/base/parts/ipc/node/ipc.cp.ts · 284 LOCnode/ipc.cp.ts

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- diskFileSystemProvider.ts ×21
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 { ChildProcess, fork, ForkOptions } from 'child_process';
7 > import { createCancelablePromise, Delayer } from '../../../common/async.js';
8 > import { VSBuffer } from '../../../common/buffer.js';
9 > import { CancellationToken } from '../../../common/cancellation.js';
10 > import { isRemoteConsoleLog, log } from '../../../common/console.js';
11 > import * as errors from '../../../common/errors.js';
12 > import { Emitter, Event } from '../../../common/event.js';
13 > import { dispose, IDisposable, toDisposable } from '../../../common/lifecycle.js';
14 > import { deepClone } from '../../../common/objects.js';
15 > import { createQueuedSender } from '../../../node/processes.js';
16 > import { removeDangerousEnvVariables } from '../../../common/processes.js';
17 > import { ChannelClient as IPCClient, ChannelServer as IPCServer, IChannel, IChannelClient } from '../common/ipc.js';
18 >
19 > /**
20 > * This implementation doesn't perform well since it uses base64 encoding for buffers.
21 > * We should move all implementations to use named ipc.net, so we stop depending on cp.fork.
22 > */
23 >
24 > export class Server<TContext extends string> extends IPCServer<TContext> {
25 > constructor(ctx: TContext) {
26 super({
27 send: r => {
28 try {
29 process.send?.((<Buffer>r.buffer).toString('base64'));
30 } catch (e) { /* not much to do */ }
31 },
32 onMessage: Event.fromNodeEventEmitter(process, 'message', msg => VSBuffer.wrap(Buffer.from(msg, 'base64')))
33 }, ctx);
34
35 process.once('disconnect', () => this.dispose());
36 }
38 >
39 > export interface IIPCOptions {
40 >
41 > /**
42 > * A descriptive name for the server this connection is to. Used in logging.
43 > */
44 > serverName: string;
45 >
46 > /**
47 > * Time in millies before killing the ipc process. The next request after killing will start it again.
48 > */
49 > timeout?: number;
50 >
51 > /**
52 > * Arguments to the module to execute.
53 > */
54 > args?: string[];
55 >
56 > /**
57 > * Environment key-value pairs to be passed to the process that gets spawned for the ipc.
58 > */
59 > env?: any;
60 >
61 > /**
62 > * Allows to assign a debug port for debugging the application executed.
63 > */
64 > debug?: number;
65 >
66 > /**
67 > * Allows to assign a debug port for debugging the application and breaking it on the first line.
68 > */
69 > debugBrk?: number;
70 >
71 > /**
72 > * If set, starts the fork with empty execArgv. If not set, execArgv from the parent process are inherited,
73 > * except --inspect= and --inspect-brk= which are filtered as they would result in a port conflict.
74 > */
75 > freshExecArgv?: boolean;
76 >
77 > /**
78 > * Enables our createQueuedSender helper for this Client. Uses a queue when the internal Node.js queue is
79 > * full of messages - see notes on that method.
80 > */
81 > useQueue?: boolean;
82 > }
83 >
84 > export class Client implements IChannelClient, IDisposable {
85 >
86 > private disposeDelayer: Delayer<void> | undefined;
87 > private activeRequests = new Set<IDisposable>();
88 > private child: ChildProcess | null;
89 > private _client: IPCClient | null;
90 > private channels = new Map<string, IChannel>();
91 >
92 > private readonly _onDidProcessExit = new Emitter<{ code: number; signal: string }>();
93 > readonly onDidProcessExit = this._onDidProcessExit.event;
94 >
95 > constructor(private modulePath: string, private options: IIPCOptions) {
96 const timeout = options.timeout || 60000;
97 this.disposeDelayer = new Delayer<void>(timeout);
98 this.child = null;
99 this._client = null;
100 }
102 > getChannel<T extends IChannel>(channelName: string): T {
103 const that = this;
104
105 // eslint-disable-next-line local/code-no-dangerous-type-assertions
106 return {
107 call<T>(command: string, arg?: any, cancellationToken?: CancellationToken): Promise<T> {
108 return that.requestPromise<T>(channelName, command, arg, cancellationToken);
109 },
110 listen(event: string, arg?: any) {
111 return that.requestEvent(channelName, event, arg);
112 }
113 } as T;
114 }
116 > protected requestPromise<T>(channelName: string, name: string, arg?: any, cancellationToken = CancellationToken.None): Promise<T> {
117 if (!this.disposeDelayer) {
118 return Promise.reject(new Error('disposed'));
119 }
120
121 if (cancellationToken.isCancellationRequested) {
122 return Promise.reject(errors.canceled());
123 }
124
125 this.disposeDelayer.cancel();
126
127 const channel = this.getCachedChannel(channelName);
128 const result = createCancelablePromise(token => channel.call<T>(name, arg, token));
129 const cancellationTokenListener = cancellationToken.onCancellationRequested(() => result.cancel());
130
131 const disposable = toDisposable(() => result.cancel());
132 this.activeRequests.add(disposable);
133
134 result.finally(() => {
135 cancellationTokenListener.dispose();
136 this.activeRequests.delete(disposable);
137
138 if (this.activeRequests.size === 0 && this.disposeDelayer) {
139 this.disposeDelayer.trigger(() => this.disposeClient());
140 }
141 });
142
143 return result;
144 }
146 > protected requestEvent<T>(channelName: string, name: string, arg?: any): Event<T> {
147 if (!this.disposeDelayer) {
148 return Event.None;
149 }
150
151 this.disposeDelayer.cancel();
152
153 let listener: IDisposable;
154 const emitter = new Emitter<any>({
155 onWillAddFirstListener: () => {
156 const channel = this.getCachedChannel(channelName);
157 const event: Event<T> = channel.listen(name, arg);
158
159 listener = event(emitter.fire, emitter);
160 this.activeRequests.add(listener);
161 },
162 onDidRemoveLastListener: () => {
163 this.activeRequests.delete(listener);
164 listener.dispose();
165
166 if (this.activeRequests.size === 0 && this.disposeDelayer) {
167 this.disposeDelayer.trigger(() => this.disposeClient());
168 }
169 }
170 });
171
172 return emitter.event;
173 }
175 > private get client(): IPCClient {
176 if (!this._client) {
177 const args = this.options.args || [];
178 const forkOpts: ForkOptions = Object.create(null);
179
180 forkOpts.env = { ...deepClone(process.env), 'VSCODE_PARENT_PID': String(process.pid) };
181
182 if (this.options.env) {
183 forkOpts.env = { ...forkOpts.env, ...this.options.env };
184 }
185
186 if (this.options.freshExecArgv) {
187 forkOpts.execArgv = [];
188 }
189
190 if (typeof this.options.debug === 'number') {
191 forkOpts.execArgv = ['--nolazy', '--inspect=' + this.options.debug];
192 }
193
194 if (typeof this.options.debugBrk === 'number') {
195 forkOpts.execArgv = ['--nolazy', '--inspect-brk=' + this.options.debugBrk];
196 }
197
198 if (forkOpts.execArgv === undefined) {
199 forkOpts.execArgv = process.execArgv // if not set, the forked process inherits the execArgv of the parent process
200 .filter(a => !/^--inspect(-brk)?=/.test(a)) // --inspect and --inspect-brk can not be inherited as the port would conflict
201 .filter(a => !a.startsWith('--vscode-')); // --vscode-* arguments are unsupported by node.js and thus need to remove
202 }
203
204 removeDangerousEnvVariables(forkOpts.env);
205
206 this.child = fork(this.modulePath, args, forkOpts);
207
208 const onMessageEmitter = new Emitter<VSBuffer>();
209 const onRawMessage = Event.fromNodeEventEmitter(this.child, 'message', msg => msg);
210
211 const rawMessageDisposable = onRawMessage(msg => {
212
213 // Handle remote console logs specially
214 if (isRemoteConsoleLog(msg)) {
215 log(msg, `IPC Library: ${this.options.serverName}`);
216 return;
217 }
218
219 // Anything else goes to the outside
220 onMessageEmitter.fire(VSBuffer.wrap(Buffer.from(msg, 'base64')));
221 });
222
223 const sender = this.options.useQueue ? createQueuedSender(this.child) : this.child;
224 const send = (r: VSBuffer) => this.child?.connected && sender.send((<Buffer>r.buffer).toString('base64'));
225 const onMessage = onMessageEmitter.event;
226 const protocol = { send, onMessage };
227
228 this._client = new IPCClient(protocol);
229
230 const onExit = () => this.disposeClient();
231 process.once('exit', onExit);
232
233 this.child.on('error', err => console.warn('IPC "' + this.options.serverName + '" errored with ' + err));
234
235 this.child.on('exit', (code: any, signal: any) => {
236 process.removeListener('exit' as 'loaded', onExit); // https://github.com/electron/electron/issues/21475
237 rawMessageDisposable.dispose();
238
239 this.activeRequests.forEach(r => dispose(r));
240 this.activeRequests.clear();
241
242 if (code !== 0 && signal !== 'SIGTERM') {
243 console.warn('IPC "' + this.options.serverName + '" crashed with exit code ' + code + ' and signal ' + signal);
244 }
245
246 this.disposeDelayer?.cancel();
247 this.disposeClient();
248 this._onDidProcessExit.fire({ code, signal });
249 });
250 }
251
252 return this._client;
253 }
255 > private getCachedChannel(name: string): IChannel {
256 let channel = this.channels.get(name);
257
258 if (!channel) {
259 channel = this.client.getChannel(name);
260 this.channels.set(name, channel);
261 }
262
263 return channel;
264 }
266 > private disposeClient() {
267 if (this._client) {
268 if (this.child) {
269 this.child.kill();
270 this.child = null;
271 }
272 this._client = null;
273 this.channels.clear();
274 }
275 }
277 > dispose() {
278 this._onDidProcessExit.dispose();
279 this.disposeDelayer?.cancel();
280 this.disposeDelayer = undefined;
281 this.disposeClient();
282 this.activeRequests.clear();
283 }