Skip to content

Commit a21c7d8

Browse files
authored
Merge pull request #1161 from nojaf/refactor-dump
Refactor dump command
2 parents 441959d + 17721fe commit a21c7d8

File tree

4 files changed

+111
-78
lines changed

4 files changed

+111
-78
lines changed

client/src/commands.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ 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";
1312
export { pasteAsRescriptJson } from "./commands/paste_as_rescript_json";
1413
export { pasteAsRescriptJsx } from "./commands/paste_as_rescript_jsx";
1514

client/src/commands/dump_server_state.ts

Lines changed: 0 additions & 38 deletions
This file was deleted.

client/src/extension.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
WorkspaceEdit,
1414
CodeActionKind,
1515
Diagnostic,
16+
ViewColumn,
1617
} from "vscode";
1718
import { ThemeColor } from "vscode";
1819

@@ -373,8 +374,30 @@ export function activate(context: ExtensionContext) {
373374
customCommands.dumpDebug(context, debugDumpStatusBarItem);
374375
});
375376

376-
commands.registerCommand("rescript-vscode.dump-server-state", () => {
377-
customCommands.dumpServerState(client, context, debugDumpStatusBarItem);
377+
commands.registerCommand("rescript-vscode.dump-server-state", async () => {
378+
try {
379+
const result = (await client.sendRequest("workspace/executeCommand", {
380+
command: "rescript/dumpServerState",
381+
})) as { content: string };
382+
383+
// Create an unsaved document with the server state content
384+
const document = await workspace.openTextDocument({
385+
content: result.content,
386+
language: "json",
387+
});
388+
389+
// Show the document in the editor
390+
await window.showTextDocument(document, {
391+
viewColumn: ViewColumn.Beside,
392+
preview: false,
393+
});
394+
} catch (e) {
395+
outputChannel.appendLine(`Failed to dump server state: ${String(e)}`);
396+
window.showErrorMessage(
397+
"Failed to dump server state. See 'Output' tab, 'ReScript Language Server' channel for details.",
398+
);
399+
outputChannel.show();
400+
}
378401
});
379402

380403
commands.registerCommand("rescript-vscode.showProblems", async () => {

server/src/server.ts

Lines changed: 86 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as rpc from "vscode-jsonrpc/node";
55
import * as path from "path";
66
import semver from "semver";
77
import fs from "fs";
8+
import fsAsync from "fs/promises";
89
import {
910
DidChangeWatchedFilesNotification,
1011
DidOpenTextDocumentNotification,
@@ -1260,6 +1261,80 @@ function openCompiledFile(msg: p.RequestMessage): p.Message {
12601261
return response;
12611262
}
12621263

1264+
async function dumpServerState(
1265+
msg: p.RequestMessage,
1266+
): Promise<p.ResponseMessage> {
1267+
// Custom debug endpoint: dump current server state (config + projectsFiles)
1268+
try {
1269+
// Read the server version from package.json
1270+
let serverVersion: string | undefined;
1271+
try {
1272+
const packageJsonPath = path.join(__dirname, "..", "package.json");
1273+
const packageJsonContent = await fsAsync.readFile(packageJsonPath, {
1274+
encoding: "utf-8",
1275+
});
1276+
const packageJson: { version?: unknown } = JSON.parse(packageJsonContent);
1277+
serverVersion =
1278+
typeof packageJson.version === "string"
1279+
? packageJson.version
1280+
: undefined;
1281+
} catch (e) {
1282+
// If we can't read the version, that's okay - we'll just omit it
1283+
serverVersion = undefined;
1284+
}
1285+
1286+
const projects = Array.from(projectsFiles.entries()).map(
1287+
([projectRootPath, pf]) => ({
1288+
projectRootPath,
1289+
openFiles: Array.from(pf.openFiles),
1290+
filesWithDiagnostics: Array.from(pf.filesWithDiagnostics),
1291+
filesDiagnostics: pf.filesDiagnostics,
1292+
rescriptVersion: pf.rescriptVersion,
1293+
bscBinaryLocation: pf.bscBinaryLocation,
1294+
editorAnalysisLocation: pf.editorAnalysisLocation,
1295+
namespaceName: pf.namespaceName,
1296+
hasPromptedToStartBuild: pf.hasPromptedToStartBuild,
1297+
bsbWatcherByEditor:
1298+
pf.bsbWatcherByEditor != null
1299+
? { pid: pf.bsbWatcherByEditor.pid ?? null }
1300+
: null,
1301+
}),
1302+
);
1303+
1304+
const state = {
1305+
lspServerVersion: serverVersion,
1306+
config: config.extensionConfiguration,
1307+
projects,
1308+
workspaceFolders: Array.from(workspaceFolders),
1309+
runtimePathCache: utils.getRuntimePathCacheSnapshot(),
1310+
};
1311+
1312+
// Format JSON with pretty-printing (2-space indent) on the server side
1313+
// This ensures consistent formatting and handles any Maps/Sets that might
1314+
// have been converted to plain objects/arrays above
1315+
const formattedJson = JSON.stringify(state, null, 2);
1316+
1317+
// Return the content so the client can create an unsaved document
1318+
// This avoids creating temporary files that would never be cleaned up
1319+
let response: p.ResponseMessage = {
1320+
jsonrpc: c.jsonrpcVersion,
1321+
id: msg.id,
1322+
result: { content: formattedJson },
1323+
};
1324+
return response;
1325+
} catch (e) {
1326+
let response: p.ResponseMessage = {
1327+
jsonrpc: c.jsonrpcVersion,
1328+
id: msg.id,
1329+
error: {
1330+
code: p.ErrorCodes.InternalError,
1331+
message: `Failed to dump server state: ${String(e)}`,
1332+
},
1333+
};
1334+
return response;
1335+
}
1336+
}
1337+
12631338
async function onMessage(msg: p.Message) {
12641339
if (p.Message.isNotification(msg)) {
12651340
// notification message, aka the client ends it and doesn't want a reply
@@ -1458,6 +1533,9 @@ async function onMessage(msg: p.Message) {
14581533
retriggerCharacters: ["=", ","],
14591534
}
14601535
: undefined,
1536+
executeCommandProvider: {
1537+
commands: ["rescript/dumpServerState"],
1538+
},
14611539
},
14621540
};
14631541
let response: p.ResponseMessage = {
@@ -1555,47 +1633,18 @@ async function onMessage(msg: p.Message) {
15551633
if (extName === c.resExt) {
15561634
send(await signatureHelp(msg));
15571635
}
1558-
} else if (msg.method === "rescript/dumpServerState") {
1559-
// Custom debug endpoint: dump current server state (config + projectsFiles)
1560-
try {
1561-
const projects = Array.from(projectsFiles.entries()).map(
1562-
([projectRootPath, pf]) => ({
1563-
projectRootPath,
1564-
openFiles: Array.from(pf.openFiles),
1565-
filesWithDiagnostics: Array.from(pf.filesWithDiagnostics),
1566-
filesDiagnostics: pf.filesDiagnostics,
1567-
rescriptVersion: pf.rescriptVersion,
1568-
bscBinaryLocation: pf.bscBinaryLocation,
1569-
editorAnalysisLocation: pf.editorAnalysisLocation,
1570-
namespaceName: pf.namespaceName,
1571-
hasPromptedToStartBuild: pf.hasPromptedToStartBuild,
1572-
bsbWatcherByEditor:
1573-
pf.bsbWatcherByEditor != null
1574-
? { pid: pf.bsbWatcherByEditor.pid ?? null }
1575-
: null,
1576-
}),
1577-
);
1578-
1579-
const result = {
1580-
config: config.extensionConfiguration,
1581-
projects,
1582-
workspaceFolders: Array.from(workspaceFolders),
1583-
runtimePathCache: utils.getRuntimePathCacheSnapshot(),
1584-
};
1585-
1586-
let response: p.ResponseMessage = {
1587-
jsonrpc: c.jsonrpcVersion,
1588-
id: msg.id,
1589-
result,
1590-
};
1591-
send(response);
1592-
} catch (e) {
1636+
} else if (msg.method === p.ExecuteCommandRequest.method) {
1637+
// Standard LSP executeCommand - supports editor-agnostic command execution
1638+
const params = msg.params as p.ExecuteCommandParams;
1639+
if (params.command === "rescript/dumpServerState") {
1640+
send(await dumpServerState(msg));
1641+
} else {
15931642
let response: p.ResponseMessage = {
15941643
jsonrpc: c.jsonrpcVersion,
15951644
id: msg.id,
15961645
error: {
1597-
code: p.ErrorCodes.InternalError,
1598-
message: `Failed to dump server state: ${String(e)}`,
1646+
code: p.ErrorCodes.InvalidRequest,
1647+
message: `Unknown command: ${params.command}`,
15991648
},
16001649
};
16011650
send(response);

0 commit comments

Comments
 (0)