monaco-languageclient 10.6.0 → 11.0.0-next.0
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/CHANGELOG.md +19 -4
- package/LICENSE +0 -0
- package/README.md +63 -63
- package/lib/common/commonTypes.d.ts +1 -1
- package/lib/common/commonTypes.d.ts.map +1 -1
- package/lib/common/utils.d.ts.map +1 -1
- package/lib/common/utils.js +2 -2
- package/lib/common/utils.js.map +1 -1
- package/lib/debugger/index.d.ts +1 -1
- package/lib/debugger/index.d.ts.map +1 -1
- package/lib/debugger/index.js +2 -4
- package/lib/debugger/index.js.map +1 -1
- package/lib/editorApp/config.d.ts +11 -11
- package/lib/editorApp/config.d.ts.map +1 -1
- package/lib/editorApp/config.js +0 -1
- package/lib/editorApp/config.js.map +1 -1
- package/lib/editorApp/editorApp.d.ts +5 -5
- package/lib/editorApp/editorApp.d.ts.map +1 -1
- package/lib/editorApp/editorApp.js +21 -23
- package/lib/editorApp/editorApp.js.map +1 -1
- package/lib/fs/definitions.d.ts.map +1 -1
- package/lib/fs/endpoints/defaultEndpoint.d.ts.map +1 -1
- package/lib/fs/endpoints/defaultEndpoint.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/vscode/apiWrapper.d.ts +2 -2
- package/lib/vscode/apiWrapper.d.ts.map +1 -1
- package/lib/vscode/apiWrapper.js +19 -22
- package/lib/vscode/apiWrapper.js.map +1 -1
- package/lib/vscode/config.d.ts +4 -4
- package/lib/vscode/config.d.ts.map +1 -1
- package/lib/vscode/config.js +0 -1
- package/lib/vscode/config.js.map +1 -1
- package/lib/vscode/locales.d.ts +1 -1
- package/lib/vscode/locales.d.ts.map +1 -1
- package/lib/vscode/locales.js +35 -18
- package/lib/vscode/locales.js.map +1 -1
- package/lib/vscode/utils.d.ts +3 -3
- package/lib/vscode/utils.d.ts.map +1 -1
- package/lib/vscode/utils.js +3 -10
- package/lib/vscode/utils.js.map +1 -1
- package/lib/vscode/viewsService.d.ts.map +1 -1
- package/lib/vscode/viewsService.js +13 -7
- package/lib/vscode/viewsService.js.map +1 -1
- package/lib/worker/index.d.ts +1 -1
- package/lib/worker/index.d.ts.map +1 -1
- package/lib/worker/index.js.map +1 -1
- package/lib/wrapper/lcconfig.d.ts +2 -2
- package/lib/wrapper/lcconfig.d.ts.map +1 -1
- package/lib/wrapper/lcmanager.d.ts.map +1 -1
- package/lib/wrapper/lcmanager.js.map +1 -1
- package/lib/wrapper/lcwrapper.d.ts +1 -1
- package/lib/wrapper/lcwrapper.d.ts.map +1 -1
- package/lib/wrapper/lcwrapper.js +17 -16
- package/lib/wrapper/lcwrapper.js.map +1 -1
- package/package.json +70 -96
- package/src/common/commonTypes.ts +35 -30
- package/src/common/index.ts +0 -1
- package/src/common/utils.ts +45 -45
- package/src/debugger/index.ts +130 -133
- package/src/editorApp/config.ts +33 -33
- package/src/editorApp/editorApp.ts +382 -370
- package/src/editorApp/index.ts +0 -0
- package/src/fs/definitions.ts +72 -75
- package/src/fs/endpoints/defaultEndpoint.ts +50 -41
- package/src/fs/index.ts +0 -0
- package/src/index.ts +18 -18
- package/src/vscode/apiWrapper.ts +302 -296
- package/src/vscode/config.ts +30 -30
- package/src/vscode/index.ts +0 -0
- package/src/vscode/locales.ts +127 -110
- package/src/vscode/utils.ts +20 -26
- package/src/vscode/viewsService.ts +44 -37
- package/src/worker/index.ts +38 -45
- package/src/wrapper/index.ts +0 -0
- package/src/wrapper/lcconfig.ts +16 -16
- package/src/wrapper/lcmanager.ts +68 -69
- package/src/wrapper/lcwrapper.ts +256 -249
package/src/wrapper/lcwrapper.ts
CHANGED
|
@@ -7,281 +7,288 @@ import { LogLevel } from '@codingame/monaco-vscode-api';
|
|
|
7
7
|
import { ConsoleLogger, type ILogger } from '@codingame/monaco-vscode-log-service-override';
|
|
8
8
|
import { MonacoLanguageClient, MonacoLanguageClientWithProposedFeatures } from 'monaco-languageclient';
|
|
9
9
|
import { createUrl, type WorkerConfigOptionsDirect, type WorkerConfigOptionsParams } from 'monaco-languageclient/common';
|
|
10
|
-
import { CloseAction, ErrorAction, MessageTransports, State } from 'vscode-languageclient/browser
|
|
11
|
-
import { BrowserMessageReader, BrowserMessageWriter } from 'vscode-languageserver-protocol/browser
|
|
10
|
+
import { CloseAction, ErrorAction, MessageTransports, State } from 'vscode-languageclient/browser';
|
|
11
|
+
import { BrowserMessageReader, BrowserMessageWriter } from 'vscode-languageserver-protocol/browser';
|
|
12
12
|
import { toSocket, WebSocketMessageReader, WebSocketMessageWriter } from 'vscode-ws-jsonrpc';
|
|
13
13
|
import type { LanguageClientConfig, LanguageClientRestartOptions } from './lcconfig.js';
|
|
14
14
|
|
|
15
15
|
export interface LanguageClientError {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
message: string;
|
|
17
|
+
error: Error | string;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export class LanguageClientWrapper {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
21
|
+
private languageClient?: MonacoLanguageClient | MonacoLanguageClientWithProposedFeatures;
|
|
22
|
+
private languageClientConfig: LanguageClientConfig;
|
|
23
|
+
private worker?: Worker;
|
|
24
|
+
private port?: MessagePort;
|
|
25
|
+
private languageId: string;
|
|
26
|
+
private logger: ILogger | undefined;
|
|
27
|
+
|
|
28
|
+
constructor(config: LanguageClientConfig) {
|
|
29
|
+
this.languageClientConfig = config;
|
|
30
|
+
this.languageId = this.languageClientConfig.languageId;
|
|
31
|
+
this.logger = new ConsoleLogger(this.languageClientConfig.logLevel ?? LogLevel.Off);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
haveLanguageClient(): boolean {
|
|
35
|
+
return this.languageClient !== undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
getLanguageClient(): MonacoLanguageClient | undefined {
|
|
39
|
+
return this.languageClient;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
getWorker(): Worker | undefined {
|
|
43
|
+
return this.worker;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
isStarted(): boolean {
|
|
47
|
+
return this.languageClient?.isRunning() ?? false;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async start(): Promise<void> {
|
|
51
|
+
if (this.languageClient?.isRunning() ?? false) {
|
|
52
|
+
this.logger?.info('startLanguageClientConnection: monaco-languageclient already running!');
|
|
53
|
+
return Promise.resolve();
|
|
37
54
|
}
|
|
38
55
|
|
|
39
|
-
|
|
40
|
-
|
|
56
|
+
return new Promise<void>((resolve, reject) => {
|
|
57
|
+
const conConfig = this.languageClientConfig.connection;
|
|
58
|
+
const conOptions = conConfig.options;
|
|
59
|
+
|
|
60
|
+
if (conOptions.$type === 'WebSocketDirect' || conOptions.$type === 'WebSocketParams' || conOptions.$type === 'WebSocketUrl') {
|
|
61
|
+
const webSocket = conOptions.$type === 'WebSocketDirect' ? conOptions.webSocket : new WebSocket(createUrl(conOptions));
|
|
62
|
+
return this.initMessageTransportWebSocket(webSocket, resolve, reject);
|
|
63
|
+
} else {
|
|
64
|
+
// init of worker and start of languageclient can be handled directly, because worker available already
|
|
65
|
+
return this.initMessageTransportWorker(conOptions, resolve, reject);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Restart the languageclient with options to control worker handling
|
|
72
|
+
*
|
|
73
|
+
* @param updatedWorker Set a new worker here that should be used. keepWorker has no effect then, as we want to dispose of the prior workers
|
|
74
|
+
* @param disposeWorker Set to false if worker should not be disposed
|
|
75
|
+
*/
|
|
76
|
+
async restart(updatedWorker?: Worker, forceWorkerDispose?: boolean): Promise<void> {
|
|
77
|
+
await this.dispose(forceWorkerDispose);
|
|
78
|
+
|
|
79
|
+
this.worker = updatedWorker;
|
|
80
|
+
this.logger?.info('Re-Starting monaco-languageclient');
|
|
81
|
+
return this.start();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
protected async initMessageTransportWebSocket(webSocket: WebSocket, resolve: () => void, reject: (reason?: unknown) => void) {
|
|
85
|
+
let messageTransports = this.languageClientConfig.connection.messageTransports;
|
|
86
|
+
if (messageTransports === undefined) {
|
|
87
|
+
const iWebSocket = toSocket(webSocket);
|
|
88
|
+
messageTransports = {
|
|
89
|
+
reader: new WebSocketMessageReader(iWebSocket),
|
|
90
|
+
writer: new WebSocketMessageWriter(iWebSocket)
|
|
91
|
+
};
|
|
41
92
|
}
|
|
42
93
|
|
|
43
|
-
|
|
44
|
-
|
|
94
|
+
// if websocket is already open, then start the languageclient directly
|
|
95
|
+
if (webSocket.readyState === WebSocket.OPEN) {
|
|
96
|
+
await this.performLanguageClientStart(messageTransports, resolve, reject);
|
|
45
97
|
}
|
|
46
98
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
99
|
+
// otherwise start on open
|
|
100
|
+
webSocket.onopen = async () => {
|
|
101
|
+
await this.performLanguageClientStart(messageTransports, resolve, reject);
|
|
102
|
+
};
|
|
103
|
+
webSocket.onerror = (ev: Event) => {
|
|
104
|
+
const languageClientError: LanguageClientError = {
|
|
105
|
+
message: `languageClientWrapper (${this.languageId}): Websocket connection failed.`,
|
|
106
|
+
error: (ev as ErrorEvent).error ?? 'No error was provided.'
|
|
107
|
+
};
|
|
108
|
+
reject(languageClientError);
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
protected async initMessageTransportWorker(
|
|
113
|
+
lccOptions: WorkerConfigOptionsDirect | WorkerConfigOptionsParams,
|
|
114
|
+
resolve: () => void,
|
|
115
|
+
reject: (reason?: unknown) => void
|
|
116
|
+
) {
|
|
117
|
+
if (this.worker === undefined) {
|
|
118
|
+
if (lccOptions.$type === 'WorkerConfig') {
|
|
119
|
+
const workerConfig = lccOptions as WorkerConfigOptionsParams;
|
|
120
|
+
this.worker = new Worker(workerConfig.url.href, {
|
|
121
|
+
type: workerConfig.type,
|
|
122
|
+
name: workerConfig.workerName
|
|
68
123
|
});
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Restart the languageclient with options to control worker handling
|
|
73
|
-
*
|
|
74
|
-
* @param updatedWorker Set a new worker here that should be used. keepWorker has no effect then, as we want to dispose of the prior workers
|
|
75
|
-
* @param disposeWorker Set to false if worker should not be disposed
|
|
76
|
-
*/
|
|
77
|
-
async restart(updatedWorker?: Worker, forceWorkerDispose?: boolean): Promise<void> {
|
|
78
|
-
await this.dispose(forceWorkerDispose);
|
|
79
|
-
|
|
80
|
-
this.worker = updatedWorker;
|
|
81
|
-
this.logger?.info('Re-Starting monaco-languageclient');
|
|
82
|
-
return this.start();
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
protected async initMessageTransportWebSocket(webSocket: WebSocket, resolve: () => void, reject: (reason?: unknown) => void) {
|
|
86
|
-
|
|
87
|
-
let messageTransports = this.languageClientConfig.connection.messageTransports;
|
|
88
|
-
if (messageTransports === undefined) {
|
|
89
|
-
const iWebSocket = toSocket(webSocket);
|
|
90
|
-
messageTransports = {
|
|
91
|
-
reader: new WebSocketMessageReader(iWebSocket),
|
|
92
|
-
writer: new WebSocketMessageWriter(iWebSocket)
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// if websocket is already open, then start the languageclient directly
|
|
97
|
-
if (webSocket.readyState === WebSocket.OPEN) {
|
|
98
|
-
await this.performLanguageClientStart(messageTransports, resolve, reject);
|
|
99
|
-
}
|
|
100
124
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
message: `languageClientWrapper (${this.languageId}): Websocket connection failed.`,
|
|
108
|
-
error: (ev as ErrorEvent).error ?? 'No error was provided.'
|
|
109
|
-
};
|
|
110
|
-
reject(languageClientError);
|
|
125
|
+
this.worker.onerror = (ev) => {
|
|
126
|
+
const languageClientError: LanguageClientError = {
|
|
127
|
+
message: `languageClientWrapper (${this.languageId}): Illegal worker configuration detected.`,
|
|
128
|
+
error: ev.error ?? 'No error was provided.'
|
|
129
|
+
};
|
|
130
|
+
reject(languageClientError);
|
|
111
131
|
};
|
|
132
|
+
} else {
|
|
133
|
+
const workerDirectConfig = lccOptions as WorkerConfigOptionsDirect;
|
|
134
|
+
this.worker = workerDirectConfig.worker;
|
|
135
|
+
}
|
|
136
|
+
if (lccOptions.messagePort !== undefined) {
|
|
137
|
+
this.port = lccOptions.messagePort;
|
|
138
|
+
}
|
|
112
139
|
}
|
|
113
140
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
if (lccOptions.messagePort !== undefined) {
|
|
135
|
-
this.port = lccOptions.messagePort;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const portOrWorker = this.port ? this.port : this.worker;
|
|
140
|
-
let messageTransports = this.languageClientConfig.connection.messageTransports;
|
|
141
|
-
if (messageTransports === undefined) {
|
|
142
|
-
messageTransports = {
|
|
143
|
-
reader: new BrowserMessageReader(portOrWorker),
|
|
144
|
-
writer: new BrowserMessageWriter(portOrWorker)
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
await this.performLanguageClientStart(messageTransports, resolve, reject);
|
|
141
|
+
const portOrWorker = this.port ?? this.worker;
|
|
142
|
+
let messageTransports = this.languageClientConfig.connection.messageTransports;
|
|
143
|
+
messageTransports ??= {
|
|
144
|
+
reader: new BrowserMessageReader(portOrWorker),
|
|
145
|
+
writer: new BrowserMessageWriter(portOrWorker)
|
|
146
|
+
};
|
|
147
|
+
await this.performLanguageClientStart(messageTransports, resolve, reject);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
protected async performLanguageClientStart(
|
|
151
|
+
messageTransports: MessageTransports,
|
|
152
|
+
resolve: () => void,
|
|
153
|
+
reject: (reason?: unknown) => void
|
|
154
|
+
) {
|
|
155
|
+
let starting = true;
|
|
156
|
+
// do not perform another start attempt if already running
|
|
157
|
+
if (this.languageClient?.isRunning() ?? false) {
|
|
158
|
+
this.logger?.info('performLanguageClientStart: monaco-languageclient already running!');
|
|
159
|
+
resolve();
|
|
149
160
|
}
|
|
150
161
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
// disable the default error handler...
|
|
164
|
-
errorHandler: {
|
|
165
|
-
error: (e: Error) => {
|
|
166
|
-
if (starting) {
|
|
167
|
-
reject(`Error occurred in language client: ${e}`);
|
|
168
|
-
return { action: ErrorAction.Shutdown };
|
|
169
|
-
} else {
|
|
170
|
-
return { action: ErrorAction.Continue };
|
|
171
|
-
}
|
|
172
|
-
},
|
|
173
|
-
closed: () => ({ action: CloseAction.DoNotRestart })
|
|
174
|
-
},
|
|
175
|
-
// ...but allowm to override all options
|
|
176
|
-
...this.languageClientConfig.clientOptions,
|
|
177
|
-
},
|
|
178
|
-
messageTransports
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
const conOptions = this.languageClientConfig.connection.options;
|
|
182
|
-
this.initRestartConfiguration(messageTransports, this.languageClientConfig.restartOptions);
|
|
183
|
-
|
|
184
|
-
const isWebSocket = conOptions.$type === 'WebSocketParams' || conOptions.$type === 'WebSocketUrl' || conOptions.$type === 'WebSocketDirect';
|
|
185
|
-
|
|
186
|
-
messageTransports.reader.onClose(async () => {
|
|
187
|
-
await this.languageClient?.stop();
|
|
188
|
-
|
|
189
|
-
if (isWebSocket && conOptions.stopOptions !== undefined) {
|
|
190
|
-
const stopOptions = conOptions.stopOptions;
|
|
191
|
-
stopOptions.onCall(this.getLanguageClient());
|
|
192
|
-
if (stopOptions.reportStatus !== undefined) {
|
|
193
|
-
this.logger?.info(this.reportStatus().join('\n'));
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
try {
|
|
199
|
-
this.languageClient = this.languageClientConfig.useClientWithProposedFeatures === true ? new MonacoLanguageClientWithProposedFeatures(mlcConfig) : new MonacoLanguageClient(mlcConfig);
|
|
200
|
-
if (this.languageClientConfig.registerFeatures !== undefined) {
|
|
201
|
-
this.languageClient.registerFeatures(this.languageClientConfig.registerFeatures);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
await this.languageClient.start();
|
|
205
|
-
|
|
206
|
-
if (isWebSocket && conOptions.startOptions !== undefined) {
|
|
207
|
-
const startOptions = conOptions.startOptions;
|
|
208
|
-
startOptions.onCall(this.getLanguageClient());
|
|
209
|
-
if (startOptions.reportStatus !== undefined) {
|
|
210
|
-
this.logger?.info(this.reportStatus().join('\n'));
|
|
211
|
-
}
|
|
162
|
+
const mlcConfig = {
|
|
163
|
+
id: this.languageClientConfig.languageId,
|
|
164
|
+
name: 'Monaco Wrapper Language Client',
|
|
165
|
+
clientOptions: {
|
|
166
|
+
// disable the default error handler...
|
|
167
|
+
errorHandler: {
|
|
168
|
+
error: (e: Error) => {
|
|
169
|
+
if (starting) {
|
|
170
|
+
reject(`Error occurred in language client: ${e}`);
|
|
171
|
+
return { action: ErrorAction.Shutdown };
|
|
172
|
+
} else {
|
|
173
|
+
return { action: ErrorAction.Continue };
|
|
212
174
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
175
|
+
},
|
|
176
|
+
closed: () => ({ action: CloseAction.DoNotRestart })
|
|
177
|
+
},
|
|
178
|
+
// ...but allowm to override all options
|
|
179
|
+
...this.languageClientConfig.clientOptions
|
|
180
|
+
},
|
|
181
|
+
messageTransports
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const conOptions = this.languageClientConfig.connection.options;
|
|
185
|
+
this.initRestartConfiguration(messageTransports, this.languageClientConfig.restartOptions);
|
|
186
|
+
|
|
187
|
+
const isWebSocket =
|
|
188
|
+
conOptions.$type === 'WebSocketParams' || conOptions.$type === 'WebSocketUrl' || conOptions.$type === 'WebSocketDirect';
|
|
189
|
+
|
|
190
|
+
messageTransports.reader.onClose(async () => {
|
|
191
|
+
await this.languageClient?.stop();
|
|
192
|
+
|
|
193
|
+
if (isWebSocket && conOptions.stopOptions !== undefined) {
|
|
194
|
+
const stopOptions = conOptions.stopOptions;
|
|
195
|
+
stopOptions.onCall(this.getLanguageClient());
|
|
196
|
+
if (stopOptions.reportStatus !== undefined) {
|
|
197
|
+
this.logger?.info(this.reportStatus().join('\n'));
|
|
219
198
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
} finally {
|
|
240
|
-
retry++;
|
|
241
|
-
if (retry > (restartOptions.retries) && !this.isStarted()) {
|
|
242
|
-
this.logger?.info(`Disabling Language Client. Failed to start clangd after ${restartOptions.retries} retries`);
|
|
243
|
-
} else {
|
|
244
|
-
setTimeout(async () => {
|
|
245
|
-
await this.restart(this.worker, restartOptions.keepWorker);
|
|
246
|
-
}, restartOptions.timeout);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
};
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
try {
|
|
203
|
+
this.languageClient =
|
|
204
|
+
this.languageClientConfig.useClientWithProposedFeatures === true
|
|
205
|
+
? new MonacoLanguageClientWithProposedFeatures(mlcConfig)
|
|
206
|
+
: new MonacoLanguageClient(mlcConfig);
|
|
207
|
+
if (this.languageClientConfig.registerFeatures !== undefined) {
|
|
208
|
+
this.languageClient.registerFeatures(this.languageClientConfig.registerFeatures);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
await this.languageClient.start();
|
|
212
|
+
|
|
213
|
+
if (isWebSocket && conOptions.startOptions !== undefined) {
|
|
214
|
+
const startOptions = conOptions.startOptions;
|
|
215
|
+
startOptions.onCall(this.getLanguageClient());
|
|
216
|
+
if (startOptions.reportStatus !== undefined) {
|
|
217
|
+
this.logger?.info(this.reportStatus().join('\n'));
|
|
251
218
|
}
|
|
219
|
+
}
|
|
220
|
+
} catch (e: unknown) {
|
|
221
|
+
const languageClientError: LanguageClientError = {
|
|
222
|
+
message: `languageClientWrapper (${this.languageId}): Start was unsuccessful.`,
|
|
223
|
+
error: Object.hasOwn(e ?? {}, 'cause') ? (e as Error) : 'No error was provided.'
|
|
224
|
+
};
|
|
225
|
+
reject(languageClientError);
|
|
252
226
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
if (
|
|
275
|
-
|
|
227
|
+
this.logger?.info(`languageClientWrapper (${this.languageId}): Started successfully.`);
|
|
228
|
+
resolve();
|
|
229
|
+
starting = false;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
protected initRestartConfiguration(messageTransports: MessageTransports, restartOptions?: LanguageClientRestartOptions) {
|
|
233
|
+
if (restartOptions !== undefined) {
|
|
234
|
+
let retry = 0;
|
|
235
|
+
|
|
236
|
+
const readerOnError = messageTransports.reader.onError(() => restartLC);
|
|
237
|
+
const readerOnClose = messageTransports.reader.onClose(() => restartLC);
|
|
238
|
+
|
|
239
|
+
const restartLC = async () => {
|
|
240
|
+
if (this.isStarted()) {
|
|
241
|
+
try {
|
|
242
|
+
readerOnError.dispose();
|
|
243
|
+
readerOnClose.dispose();
|
|
244
|
+
|
|
245
|
+
await this.restart(this.worker, restartOptions.keepWorker);
|
|
246
|
+
} finally {
|
|
247
|
+
retry++;
|
|
248
|
+
if (retry > restartOptions.retries && !this.isStarted()) {
|
|
249
|
+
this.logger?.info(`Disabling Language Client. Failed to start clangd after ${restartOptions.retries} retries`);
|
|
250
|
+
} else {
|
|
251
|
+
setTimeout(async () => {
|
|
252
|
+
await this.restart(this.worker, restartOptions.keepWorker);
|
|
253
|
+
}, restartOptions.timeout);
|
|
276
254
|
}
|
|
255
|
+
}
|
|
277
256
|
}
|
|
257
|
+
};
|
|
278
258
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
protected disposeWorker() {
|
|
262
|
+
this.worker?.terminate();
|
|
263
|
+
this.worker = undefined;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
async dispose(forceWorkerDispose?: boolean): Promise<void> {
|
|
267
|
+
try {
|
|
268
|
+
if (this.isStarted()) {
|
|
269
|
+
await this.languageClient?.dispose();
|
|
270
|
+
this.languageClient = undefined;
|
|
271
|
+
this.logger?.info('monaco-languageclient was successfully disposed.');
|
|
272
|
+
}
|
|
273
|
+
} catch (e) {
|
|
274
|
+
const languageClientError: LanguageClientError = {
|
|
275
|
+
message: `languageClientWrapper (${this.languageId}): Disposing the monaco-languageclient resulted in error.`,
|
|
276
|
+
error: Object.hasOwn(e ?? {}, 'cause') ? (e as Error) : 'No error was provided.'
|
|
277
|
+
};
|
|
278
|
+
return Promise.reject(languageClientError);
|
|
279
|
+
} finally {
|
|
280
|
+
// always terminate the worker if desired
|
|
281
|
+
if (this.languageClientConfig.disposeWorker === true || forceWorkerDispose === true) {
|
|
282
|
+
this.disposeWorker();
|
|
283
|
+
}
|
|
286
284
|
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
reportStatus() {
|
|
288
|
+
const status: string[] = [];
|
|
289
|
+
const languageClient = this.getLanguageClient();
|
|
290
|
+
status.push('LanguageClientWrapper status:');
|
|
291
|
+
status.push(`LanguageClient: ${languageClient?.name ?? 'Language Client'} is in a '${State[languageClient?.state ?? 1]}' state`);
|
|
292
|
+
return status;
|
|
293
|
+
}
|
|
287
294
|
}
|