Skip to content

Commit d8eac38

Browse files
committed
refactor(vscode): some refactorings and code cleanup
1 parent b23331b commit d8eac38

File tree

5 files changed

+174
-108
lines changed

5 files changed

+174
-108
lines changed

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2012,11 +2012,11 @@
20122012
}
20132013
},
20142014
{
2015-
"name": "robot-get_document_imports",
2016-
"displayName": "Get Document Imports",
2015+
"name": "robot-get_file_imports",
2016+
"displayName": "List imported libraries, resources and variable files for a Robot Framework Document",
20172017
"toolReferenceName": "robotGetDocumentImports",
2018-
"modelDescription": "Retrieves a list of all imported libraries and resource files for a specific Robot Framework document. Returns the names and paths of all libraries imported in the specified Robot Framework file. Use this tool when you need to analyze the dependencies of a Robot Framework document or understand its library and resource usage. Limitations: Only works with Robot Framework files, may not detect dynamic imports or libraries loaded at runtime, and requires the specified file to be accessible from the workspace's Robot Framework configuration.",
2019-
"userDescription": "Gets a list of all imported libraries and resources for a specific Robot Framework document.",
2018+
"modelDescription": "Retrieves a list of all imported libraries, resources and variable files for a specific Robot Framework document. Returns the names and paths of all libraries imported in the specified Robot Framework file. Use this tool when you need to analyze the dependencies of a Robot Framework document or understand its library and resource usage. Limitations: Only works with Robot Framework files, may not detect dynamic imports or libraries loaded at runtime, and requires the specified file to be accessible from the workspace's Robot Framework configuration.",
2019+
"userDescription": "Gets a list of all imported libraries, resources and variable files for a specific Robot Framework document.",
20202020
"canBeReferencedInPrompt": true,
20212021
"tags": [
20222022
"robot",
@@ -2044,7 +2044,7 @@
20442044
"displayName": "Get Robot Framework Environment Informations",
20452045
"toolReferenceName": "robotGetEnvironmentInfo",
20462046
"modelDescription": "Retrieves detailed environment information for Robot Framework workspaces or files. Returns comprehensive details about the Python interpreter (version, executable path), installed Robot Framework version, RobotCode extension version, and optional tool versions (robocop, robotidy) if available. Use this tool when you need to diagnose environment issues, verify installations, check version compatibility, or troubleshoot Robot Framework setup problems. Limitations: Only provides information about the currently configured Python environment for the workspace, may not detect tools installed in different Python environments, requires proper workspace configuration to access environment details, and information accuracy depends on the current RobotCode language server connection.",
2047-
"userDescription": "Gets informations about the Robot Framework Environment.",
2047+
"userDescription": "Gets informations about the Robot Framework Environment .",
20482048
"canBeReferencedInPrompt": true,
20492049
"tags": [
20502050
"robot",

vscode-client/extension/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ export async function activateAsync(context: vscode.ExtensionContext): Promise<v
163163
new GetKeywordInfoTool(context, languageClientManger, outputChannel),
164164
),
165165
vscode.lm.registerTool(
166-
"robot-get_document_imports",
166+
"robot-get_file_imports",
167167
new GetDocumentImportsTool(context, languageClientManger, outputChannel),
168168
),
169169
vscode.lm.registerTool(

vscode-client/extension/languageclientsmanger.ts

Lines changed: 94 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ import { getAvailablePort } from "./net_utils";
2727
const LANGUAGE_SERVER_DEFAULT_TCP_PORT = 6610;
2828
const LANGUAGE_SERVER_DEFAULT_HOST = "127.0.0.1";
2929

30+
// Language Server Configuration Constants
31+
const CLIENT_DISPOSE_TIMEOUT = 5000;
32+
const CLIENT_SLEEP_DURATION = 500;
33+
const LANGUAGE_CLIENT_PREFIX = "$robotCode:";
34+
3035
export function toVsCodeRange(range: Range): vscode.Range {
3136
return new vscode.Range(
3237
new vscode.Position(range.start.line, range.start.character),
@@ -146,39 +151,52 @@ export class LanguageClientsManager {
146151
}
147152

148153
private _supportedLanguages?: string[];
154+
private _fileExtensions?: string[];
149155

150-
public get supportedLanguages(): string[] {
151-
if (this._supportedLanguages === undefined) {
152-
this._supportedLanguages = ["robotframework"];
153-
154-
vscode.extensions.all.forEach((extension) => {
155-
if (this._supportedLanguages !== undefined && extension.packageJSON !== undefined) {
156-
const ext = (extension.packageJSON as RobotCodeContributions)?.contributes?.robotCode?.languageIds;
156+
/**
157+
* Invalidate cached extension data when extensions change
158+
*/
159+
private invalidateExtensionCaches(): void {
160+
this._supportedLanguages = undefined;
161+
this._fileExtensions = undefined;
162+
}
157163

158-
if (ext !== undefined) {
159-
this._supportedLanguages.push(...ext);
160-
}
164+
/**
165+
* Helper method to collect extension contributions from all VS Code extensions
166+
*/
167+
private static collectExtensionContributions(
168+
propertyPath: "languageIds" | "fileExtensions",
169+
defaultValues: string[],
170+
): string[] {
171+
const result: string[] = [...defaultValues];
172+
173+
vscode.extensions.all.forEach((extension) => {
174+
if (extension.packageJSON) {
175+
const ext = (extension.packageJSON as RobotCodeContributions)?.contributes?.robotCode?.[propertyPath];
176+
if (ext !== undefined) {
177+
result.push(...ext);
161178
}
162-
});
179+
}
180+
});
181+
182+
return result;
183+
}
184+
185+
public get supportedLanguages(): string[] {
186+
if (this._supportedLanguages === undefined) {
187+
this._supportedLanguages = LanguageClientsManager.collectExtensionContributions("languageIds", [
188+
"robotframework",
189+
]);
163190
}
164191
return this._supportedLanguages;
165192
}
166193

167-
private _fileExtensions?: string[];
168-
169194
public get fileExtensions(): string[] {
170195
if (this._fileExtensions === undefined) {
171-
this._fileExtensions = ["robot", "resource"];
172-
173-
vscode.extensions.all.forEach((extension) => {
174-
if (this._fileExtensions !== undefined && extension.packageJSON !== undefined) {
175-
const ext = (extension.packageJSON as RobotCodeContributions)?.contributes?.robotCode?.fileExtensions;
176-
177-
if (ext !== undefined) {
178-
this._fileExtensions.push(...ext);
179-
}
180-
}
181-
});
196+
this._fileExtensions = LanguageClientsManager.collectExtensionContributions("fileExtensions", [
197+
"robot",
198+
"resource",
199+
]);
182200
}
183201
return this._fileExtensions;
184202
}
@@ -195,8 +213,15 @@ export class LanguageClientsManager {
195213
fileWatcher1.onDidDelete((uri) => this.restart(vscode.workspace.getWorkspaceFolder(uri)?.uri));
196214
fileWatcher1.onDidChange((uri) => this.restart(vscode.workspace.getWorkspaceFolder(uri)?.uri));
197215

216+
// Listen for extension changes to invalidate caches
217+
const extensionChangeListener = vscode.extensions.onDidChange(() => {
218+
this.logger.debug("Extensions changed, invalidating caches");
219+
this.invalidateExtensionCaches();
220+
});
221+
198222
this._disposables = vscode.Disposable.from(
199223
fileWatcher1,
224+
extensionChangeListener,
200225

201226
this.pythonManager.onActivePythonEnvironmentChanged(async (event) => {
202227
if (event.resource !== undefined) {
@@ -228,16 +253,37 @@ export class LanguageClientsManager {
228253
);
229254
}
230255

256+
private readonly logger = {
257+
info: (message: string) => this.outputChannel.appendLine(`[INFO] ${message}`),
258+
warn: (message: string) => this.outputChannel.appendLine(`[WARN] ${message}`),
259+
error: (message: string) => this.outputChannel.appendLine(`[ERROR] ${message}`),
260+
debug: (message: string) => this.outputChannel.appendLine(`[DEBUG] ${message}`),
261+
};
262+
231263
public async clearCaches(uri?: vscode.Uri): Promise<void> {
264+
this.logger.info("Clearing language server caches...");
265+
232266
if (uri !== undefined) {
233267
const client = await this.getLanguageClientForResource(uri);
234268
if (client) {
235-
await client.sendRequest("robot/cache/clear");
269+
try {
270+
await client.sendRequest("robot/cache/clear");
271+
this.logger.info(`Cache cleared for ${uri.toString()}`);
272+
} catch (error) {
273+
this.logger.error(`Failed to clear cache for ${uri.toString()}: ${error}`);
274+
}
236275
}
237276
} else {
238-
for (const client of this.clients.values()) {
239-
await client.sendRequest("robot/cache/clear");
240-
}
277+
const clearPromises = Array.from(this.clients.values()).map(async (client) => {
278+
try {
279+
await client.sendRequest("robot/cache/clear");
280+
} catch (error) {
281+
this.logger.error(`Failed to clear cache for client: ${error}`);
282+
}
283+
});
284+
285+
await Promise.allSettled(clearPromises);
286+
this.logger.info("Cache clearing completed for all clients");
241287
}
242288
}
243289

@@ -248,9 +294,9 @@ export class LanguageClientsManager {
248294
this.clients.clear();
249295

250296
for (const client of clients) {
251-
promises.push(client.dispose(5000));
297+
promises.push(client.dispose(CLIENT_DISPOSE_TIMEOUT));
252298
}
253-
await sleep(500);
299+
await sleep(CLIENT_SLEEP_DURATION);
254300

255301
return Promise.all(promises).then(
256302
(r) => {
@@ -266,7 +312,7 @@ export class LanguageClientsManager {
266312
dispose(): void {
267313
this.stopAllClients().then(
268314
(_) => undefined,
269-
(_) => undefined,
315+
(error) => this.logger.error(`Error during dispose: ${error}`),
270316
);
271317
this._disposables.dispose();
272318
}
@@ -554,16 +600,15 @@ export class LanguageClientsManager {
554600

555601
const clientOptions: LanguageClientOptions = {
556602
documentSelector:
557-
// TODO: use SUPPORTED_LANGUAGES here
558603
vscode.workspace.workspaceFolders?.length === 1
559-
? [
560-
{ scheme: "file", language: "robotframework" },
561-
{ scheme: "untitled", language: "robotframework" },
562-
]
563-
: [
564-
{ scheme: "file", language: "robotframework", pattern: `${workspaceFolder.uri.fsPath}/**/*` },
565-
{ scheme: "untitled", language: "robotframework", pattern: `${workspaceFolder.uri.fsPath}/**/*` },
566-
],
604+
? this.supportedLanguages.flatMap((lang) => [
605+
{ scheme: "file", language: lang },
606+
{ scheme: "untitled", language: lang },
607+
])
608+
: this.supportedLanguages.flatMap((lang) => [
609+
{ scheme: "file", language: lang, pattern: `${workspaceFolder.uri.fsPath}/**/*` },
610+
{ scheme: "untitled", language: lang, pattern: `${workspaceFolder.uri.fsPath}/**/*` },
611+
]),
567612
synchronize: {
568613
configurationSection: [CONFIG_SECTION],
569614
},
@@ -656,7 +701,12 @@ export class LanguageClientsManager {
656701
};
657702

658703
this.outputChannel.appendLine(`create Language client: ${name}`);
659-
result = new LanguageClient(`$robotCode:${workspaceFolder.uri.toString()}`, name, serverOptions, clientOptions);
704+
result = new LanguageClient(
705+
`${LANGUAGE_CLIENT_PREFIX}${workspaceFolder.uri.toString()}`,
706+
name,
707+
serverOptions,
708+
clientOptions,
709+
);
660710

661711
this.outputChannel.appendLine(`trying to start Language client: ${name}`);
662712

@@ -736,12 +786,12 @@ export class LanguageClientsManager {
736786
this.clients.delete(workspaceFolder.uri.toString());
737787

738788
if (client) {
739-
await client.dispose(5000);
740-
await sleep(500);
789+
await client.dispose(CLIENT_DISPOSE_TIMEOUT);
790+
await sleep(CLIENT_SLEEP_DURATION);
741791
}
742792
} else {
743793
if (await this.stopAllClients()) {
744-
await sleep(500);
794+
await sleep(CLIENT_SLEEP_DURATION);
745795
}
746796
}
747797
});

vscode-client/extension/lmTools.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export class GetLibraryInfoTool implements vscode.LanguageModelTool<GetLibraryIn
7878
}
7979

8080
return {
81-
invocationMessage: "Retrieving Robot Framework Library details",
81+
invocationMessage: `Retrieving Robot Framework Library details for library: '${options.input.libraryName}'`,
8282
};
8383
}
8484
}
@@ -130,7 +130,7 @@ export class GetKeywordInfoTool implements vscode.LanguageModelTool<GetKeywordIn
130130
}
131131

132132
async prepareInvocation?(
133-
options: vscode.LanguageModelToolInvocationPrepareOptions<GetLibraryInfoToolParamters>,
133+
options: vscode.LanguageModelToolInvocationPrepareOptions<GetKeywordInfoToolParamters>,
134134
_token: vscode.CancellationToken,
135135
): Promise<vscode.PreparedToolInvocation> {
136136
const workspaceFolder = resolveWorkspaceFolder(options.input.resourcePath);
@@ -141,7 +141,7 @@ export class GetKeywordInfoTool implements vscode.LanguageModelTool<GetKeywordIn
141141
}
142142

143143
return {
144-
invocationMessage: "Retrieving Robot Framework Keyword details",
144+
invocationMessage: `Retrieving Robot Framework Keyword details for keyword: '${options.input.keywordName}' from library: '${options.input.libraryName}'`,
145145
};
146146
}
147147
}
@@ -183,7 +183,7 @@ export class GetDocumentImportsTool implements vscode.LanguageModelTool<GetDocum
183183
}
184184

185185
return {
186-
invocationMessage: "Retrieving Robot Framework Document Imports",
186+
invocationMessage: `Retrieving Robot Framework Document Imports for '${options.input.resourcePath}'`,
187187
};
188188
}
189189
}

0 commit comments

Comments
 (0)