Skip to content

Commit 7b777cb

Browse files
committed
rework starting and restarting language clients
1 parent 8155463 commit 7b777cb

File tree

2 files changed

+109
-83
lines changed

2 files changed

+109
-83
lines changed

package.json

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -501,19 +501,19 @@
501501
"devDependencies": {
502502
"@types/glob": "^7.1.3",
503503
"@types/mocha": "^8.2.2",
504-
"@types/node": "^15.3.0",
504+
"@types/node": "^15.12.2",
505505
"@types/vscode": "^1.56.0",
506-
"@typescript-eslint/eslint-plugin": "^4.23.0",
507-
"@typescript-eslint/parser": "^4.23.0",
508-
"eslint": "^7.26.0",
506+
"@typescript-eslint/eslint-plugin": "^4.26.1",
507+
"@typescript-eslint/parser": "^4.26.1",
508+
"eslint": "^7.28.0",
509509
"glob": "^7.1.7",
510-
"mocha": "^8.4.0",
511-
"ts-loader": "^9.1.2",
512-
"typescript": "^4.2.4",
513-
"vsce": "^1.88.0",
510+
"mocha": "^9.0.0",
511+
"ts-loader": "^9.2.3",
512+
"typescript": "^4.3.2",
513+
"vsce": "^1.93.0",
514514
"vscode-debugadapter-testsupport": "^1.47.0",
515515
"vscode-test": "^1.5.2",
516-
"webpack": "^5.37.0",
517-
"webpack-cli": "^4.7.0"
516+
"webpack": "^5.38.1",
517+
"webpack-cli": "^4.7.2"
518518
}
519519
}

vscode-client/extension.ts

Lines changed: 99 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,33 @@ function getPythonCommand(folder: vscode.WorkspaceFolder | undefined): string |
4343
let clientsMutex = new Mutex();
4444
let clients: Map<string, LanguageClient> = new Map();
4545

46-
async function pythonExcetionDidChangeExecutionDetails(uri: vscode.Uri | undefined) {
47-
if (uri && clients.has(uri.toString())) {
48-
await clientsMutex.dispatch(async () => {
49-
let client = clients.get(uri.toString());
50-
clients.delete(uri.toString());
51-
await client?.stop();
52-
});
46+
async function updateLoadedDocumentClients(uri?: vscode.Uri | undefined) {
47+
// if (uri && clients.has(uri.toString())) {
48+
// await clientsMutex.dispatch(async () => {
49+
// let client = clients.get(uri.toString());
50+
// clients.delete(uri.toString());
51+
// await client?.stop();
52+
// });
53+
54+
// await getLanguageClientForResource(uri);
55+
// }
56+
57+
OUTPUT_CHANNEL.appendLine("initialze/restart all needed language clients.");
58+
await clientsMutex.dispatch(async () => {
59+
for (let client of clients.values()) {
60+
await client.stop().catch((_) => {});
61+
}
62+
clients.clear();
63+
});
5364

54-
await getLanguageClientForResource(uri);
65+
for (let document of vscode.workspace.textDocuments) {
66+
try {
67+
await getLanguageClientForDocument(document).catch((_) => {});
68+
} catch {
69+
// do nothing
70+
}
5571
}
72+
await updateEditorContext().catch((_) => {});
5673
}
5774

5875
let _sortedWorkspaceFolders: string[] | undefined;
@@ -96,7 +113,7 @@ async function getLanguageClientForDocument(document: vscode.TextDocument): Prom
96113
}
97114

98115
async function getLanguageClientForResource(resource: string | vscode.Uri): Promise<LanguageClient | undefined> {
99-
let client = await clientsMutex.dispatch(async () => {
116+
var client = await clientsMutex.dispatch(async () => {
100117
let uri = resource instanceof vscode.Uri ? resource : vscode.Uri.parse(resource);
101118
let workspaceFolder = vscode.workspace.getWorkspaceFolder(uri);
102119

@@ -108,58 +125,78 @@ async function getLanguageClientForResource(resource: string | vscode.Uri): Prom
108125

109126
var result = clients.get(workspaceFolder.uri.toString());
110127

111-
if (!result) {
112-
let config = vscode.workspace.getConfiguration(CONFIG_SECTION, uri);
128+
if (result) return result;
113129

114-
let mode = config.get<string>("languageServer.mode", "stdio");
130+
let config = vscode.workspace.getConfiguration(CONFIG_SECTION, uri);
115131

116-
const serverOptions: ServerOptions =
117-
mode === "tcp" ? getServerOptionsTCP(workspaceFolder) : getServerOptionsStdIo(workspaceFolder);
118-
let name = `RobotCode Language Server mode=${mode} for workspace folder "${workspaceFolder.name}"`;
132+
let mode = config.get<string>("languageServer.mode", "stdio");
119133

120-
let outputChannel = mode === "stdio" ? vscode.window.createOutputChannel(name) : undefined;
134+
const serverOptions: ServerOptions =
135+
mode === "tcp" ? getServerOptionsTCP(workspaceFolder) : getServerOptionsStdIo(workspaceFolder);
136+
let name = `RobotCode Language Server mode=${mode} for folder "${workspaceFolder.name}"`;
121137

122-
let clientOptions: LanguageClientOptions = {
123-
documentSelector: [
124-
{ scheme: "file", language: "robotframework", pattern: `${workspaceFolder.uri.fsPath}/**/*` },
125-
],
126-
synchronize: {
127-
configurationSection: [CONFIG_SECTION, "python"],
128-
},
129-
initializationOptions: {
130-
storageUri: extensionContext?.storageUri?.toString(),
131-
globalStorageUri: extensionContext?.globalStorageUri?.toString(),
132-
},
133-
diagnosticCollectionName: "robotcode",
134-
workspaceFolder: workspaceFolder,
135-
outputChannel: outputChannel,
136-
markdown: {
137-
isTrusted: true,
138-
},
139-
progressOnInitialization: true,
140-
};
138+
let outputChannel = mode === "stdio" ? vscode.window.createOutputChannel(name) : undefined;
139+
140+
let clientOptions: LanguageClientOptions = {
141+
documentSelector: [
142+
{ scheme: "file", language: "robotframework", pattern: `${workspaceFolder.uri.fsPath}/**/*` },
143+
],
144+
synchronize: {
145+
configurationSection: [CONFIG_SECTION, "python"],
146+
},
147+
initializationOptions: {
148+
storageUri: extensionContext?.storageUri?.toString(),
149+
globalStorageUri: extensionContext?.globalStorageUri?.toString(),
150+
},
151+
diagnosticCollectionName: "robotcode",
152+
workspaceFolder: workspaceFolder,
153+
outputChannel: outputChannel,
154+
markdown: {
155+
isTrusted: true,
156+
},
157+
progressOnInitialization: true,
158+
initializationFailedHandler: (error) => {
159+
return false;
160+
},
161+
};
162+
163+
OUTPUT_CHANNEL.appendLine(`create Language client: ${name}`);
164+
result = new LanguageClient(name, serverOptions, clientOptions);
165+
166+
OUTPUT_CHANNEL.appendLine(`trying to start Language client: ${name}`);
167+
result.start();
168+
169+
result = await result.onReady().then(
170+
(_) => {
171+
OUTPUT_CHANNEL.appendLine(`client ${client?.clientOptions.workspaceFolder?.uri ?? "unknown"} ready.`);
172+
return result;
173+
},
174+
(reason) => {
175+
OUTPUT_CHANNEL.appendLine(
176+
`client ${client?.clientOptions.workspaceFolder?.uri ?? "unknown"} error: ${reason}`
177+
);
178+
vscode.window.showErrorMessage(reason.message ?? "Unknown error.");
179+
return undefined;
180+
}
181+
);
182+
183+
if (result) clients.set(workspaceFolder.uri.toString(), result);
141184

142-
OUTPUT_CHANNEL.appendLine(`start Language client: ${name}`);
143-
result = new LanguageClient(name, serverOptions, clientOptions);
144-
clients.set(workspaceFolder.uri.toString(), result);
145-
}
146185
return result;
147186
});
148187

149188
if (client) {
150-
if (client.needsStart()) {
151-
client.start();
152-
}
189+
// be sure client is correctly initialized
153190

154191
var counter = 0;
155-
while (!client.initializeResult && counter < 10_000) {
156-
await sleep(100);
157-
counter++;
192+
try {
193+
while (!client.initializeResult && counter < 1000) {
194+
await sleep(10);
195+
counter++;
196+
}
197+
} catch {
198+
return undefined;
158199
}
159-
160-
await client.onReady().catch((reason) => {
161-
OUTPUT_CHANNEL.appendLine("puhhh: " + reason);
162-
});
163200
}
164201

165202
return client;
@@ -236,27 +273,21 @@ class RobotCodeDebugConfigurationProvider implements vscode.DebugConfigurationPr
236273

237274
if (!debugConfiguration.python) debugConfiguration.python = getPythonCommand(folder);
238275

239-
if (!debugConfiguration.robotPythonPath) debugConfiguration.robotPythonPath = [];
240-
debugConfiguration.robotPythonPath = config
241-
.get<Array<string>>("robot.pythonPath", [])
242-
.concat(debugConfiguration.robotPythonPath);
243-
244-
if (!debugConfiguration.args) debugConfiguration.args = [];
245-
debugConfiguration.args = config.get<Array<string>>("robot.args", []).concat(debugConfiguration.args);
276+
debugConfiguration.robotPythonPath = [
277+
...config.get<Array<string>>("robot.pythonPath", []),
278+
...(debugConfiguration.robotPythonPath ?? []),
279+
];
246280

247-
if (!debugConfiguration.variables) debugConfiguration.variables = {};
248-
debugConfiguration.variables = Object.assign(
249-
{},
250-
config.get<Object>("robot.variables", {}),
251-
debugConfiguration.variables
252-
);
281+
debugConfiguration.args = [...config.get<Array<string>>("robot.args", []), ...(debugConfiguration.args ?? [])];
253282

254-
if (!debugConfiguration.env) debugConfiguration.env = {};
255-
debugConfiguration.env = Object.assign({}, config.get<Object>("robot.env", {}), debugConfiguration.env);
283+
debugConfiguration.variables = {
284+
...config.get<Object>("robot.variables", {}),
285+
...(debugConfiguration.variables ?? {}),
286+
};
256287

257-
if (debugConfiguration.attachPython == undefined) debugConfiguration.attachPython = false;
288+
debugConfiguration.env = { ...config.get<Object>("robot.env", {}), ...(debugConfiguration.env ?? {}) };
258289

259-
if (debugConfiguration.noDebug) {
290+
if (!debugConfiguration.attachPython || debugConfiguration.noDebug) {
260291
debugConfiguration.attachPython = false;
261292
}
262293

@@ -502,7 +533,7 @@ export async function activateAsync(context: vscode.ExtensionContext) {
502533
OUTPUT_CHANNEL.appendLine("Python Extension is active");
503534

504535
context.subscriptions.push(
505-
pythonExtension.exports.settings.onDidChangeExecutionDetails(pythonExcetionDidChangeExecutionDetails),
536+
pythonExtension.exports.settings.onDidChangeExecutionDetails(updateLoadedDocumentClients),
506537
vscode.commands.registerCommand("robotcode.runSuite", async (resource) => {
507538
return await debugSuiteOrTestcase(resource ?? vscode.window.activeTextEditor?.document.uri, undefined, {
508539
noDebug: true,
@@ -629,7 +660,6 @@ export async function activateAsync(context: vscode.ExtensionContext) {
629660

630661
vscode.workspace.onDidChangeConfiguration((event) => {
631662
for (let s of [
632-
//"python.pythonPath",
633663
"robotcode.python",
634664
"robotcode.languageServer.mode",
635665
"robotcode.languageServer.tcpPort",
@@ -694,11 +724,7 @@ export async function activateAsync(context: vscode.ExtensionContext) {
694724
})
695725
);
696726

697-
for (let document of vscode.workspace.textDocuments) {
698-
getLanguageClientForDocument(document);
699-
}
700-
701-
updateEditorContext();
727+
await updateLoadedDocumentClients();
702728
}
703729

704730
function displayProgress(promise: Promise<any>) {

0 commit comments

Comments
 (0)