Skip to content

Commit b20cbf8

Browse files
authored
Merge pull request #1130 from nojaf/dump-lsp-server
Add command to dump LSP server state
2 parents 9faaa30 + 3807930 commit b20cbf8

File tree

6 files changed

+93
-1
lines changed

6 files changed

+93
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525

2626
- Find `@rescript/runtime` for Rewatch compiler-args call. https://github.com/rescript-lang/rescript-vscode/pull/1125
2727
- Use `prepareRename` command (when a new enough ReScript version is used) to speed up the `rename` command. https://github.com/rescript-lang/rescript-vscode/pull/1124
28-
- Use `compiler-info.json` to find the `@rescript/runtime` and `bsc.exe` if available.
28+
- Use `compiler-info.json` to find the `@rescript/runtime` and `bsc.exe` if available. https://github.com/rescript-lang/rescript-vscode/pull/1129
29+
- Add `Dump LSP Server State` command to client. https://github.com/rescript-lang/rescript-vscode/pull/1130
2930

3031
## 1.64.0
3132

client/src/commands.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export { createInterface } from "./commands/create_interface";
99
export { openCompiled } from "./commands/open_compiled";
1010
export { switchImplIntf } from "./commands/switch_impl_intf";
1111
export { dumpDebug, dumpDebugRetrigger } from "./commands/dump_debug";
12+
export { dumpServerState } from "./commands/dump_server_state";
1213

1314
export const codeAnalysisWithReanalyze = (
1415
targetDir: string | null,
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import {
2+
ExtensionContext,
3+
StatusBarItem,
4+
Uri,
5+
ViewColumn,
6+
window,
7+
} from "vscode";
8+
import { LanguageClient } from "vscode-languageclient/node";
9+
import * as fs from "fs";
10+
import { createFileInTempDir } from "../utils";
11+
12+
export async function dumpServerState(
13+
client: LanguageClient,
14+
_context?: ExtensionContext,
15+
_statusBarItem?: StatusBarItem,
16+
) {
17+
try {
18+
const result = await client.sendRequest("rescript/dumpServerState");
19+
const outputFile = createFileInTempDir("server_state", ".json");
20+
21+
// Pretty-print JSON with stable ordering where possible
22+
const replacer = (_key: string, value: any) => {
23+
if (value instanceof Map) return Object.fromEntries(value);
24+
if (value instanceof Set) return Array.from(value);
25+
return value;
26+
};
27+
28+
const json = JSON.stringify(result, replacer, 2);
29+
fs.writeFileSync(outputFile, json, { encoding: "utf-8" });
30+
31+
await window.showTextDocument(Uri.parse(outputFile), {
32+
viewColumn: ViewColumn.Beside,
33+
preview: false,
34+
});
35+
} catch (e) {
36+
window.showErrorMessage(`Failed to dump server state: ${String(e)}`);
37+
}
38+
}

client/src/extension.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,10 @@ export function activate(context: ExtensionContext) {
371371
customCommands.dumpDebug(context, debugDumpStatusBarItem);
372372
});
373373

374+
commands.registerCommand("rescript-vscode.dump-server-state", () => {
375+
customCommands.dumpServerState(client, context, debugDumpStatusBarItem);
376+
});
377+
374378
commands.registerCommand("rescript-vscode.showProblems", async () => {
375379
try {
376380
await commands.executeCommand("workbench.actions.view.problems");

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@
8888
{
8989
"command": "rescript-vscode.debug-dump-start",
9090
"title": "DEBUG ReScript: Dump analysis info"
91+
},
92+
{
93+
"command": "rescript-vscode.dump-server-state",
94+
"title": "DEBUG ReScript: Dump LSP Server State"
9195
}
9296
],
9397
"keybindings": [

server/src/server.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,6 +1485,50 @@ async function onMessage(msg: p.Message) {
14851485
if (extName === c.resExt) {
14861486
send(await signatureHelp(msg));
14871487
}
1488+
} else if (msg.method === "rescript/dumpServerState") {
1489+
// Custom debug endpoint: dump current server state (config + projectsFiles)
1490+
try {
1491+
const projects = Array.from(projectsFiles.entries()).map(
1492+
([projectRootPath, pf]) => ({
1493+
projectRootPath,
1494+
openFiles: Array.from(pf.openFiles),
1495+
filesWithDiagnostics: Array.from(pf.filesWithDiagnostics),
1496+
filesDiagnostics: pf.filesDiagnostics,
1497+
rescriptVersion: pf.rescriptVersion,
1498+
bscBinaryLocation: pf.bscBinaryLocation,
1499+
editorAnalysisLocation: pf.editorAnalysisLocation,
1500+
namespaceName: pf.namespaceName,
1501+
hasPromptedToStartBuild: pf.hasPromptedToStartBuild,
1502+
bsbWatcherByEditor:
1503+
pf.bsbWatcherByEditor != null
1504+
? { pid: pf.bsbWatcherByEditor.pid ?? null }
1505+
: null,
1506+
}),
1507+
);
1508+
1509+
const result = {
1510+
config: config.extensionConfiguration,
1511+
projects,
1512+
workspaceFolders: Array.from(workspaceFolders),
1513+
};
1514+
1515+
let response: p.ResponseMessage = {
1516+
jsonrpc: c.jsonrpcVersion,
1517+
id: msg.id,
1518+
result,
1519+
};
1520+
send(response);
1521+
} catch (e) {
1522+
let response: p.ResponseMessage = {
1523+
jsonrpc: c.jsonrpcVersion,
1524+
id: msg.id,
1525+
error: {
1526+
code: p.ErrorCodes.InternalError,
1527+
message: `Failed to dump server state: ${String(e)}`,
1528+
},
1529+
};
1530+
send(response);
1531+
}
14881532
} else {
14891533
let response: p.ResponseMessage = {
14901534
jsonrpc: c.jsonrpcVersion,

0 commit comments

Comments
 (0)