@@ -5,6 +5,7 @@ import * as rpc from "vscode-jsonrpc/node";
55import * as path from "path" ;
66import semver from "semver" ;
77import fs from "fs" ;
8+ import fsAsync from "fs/promises" ;
89import {
910 DidChangeWatchedFilesNotification ,
1011 DidOpenTextDocumentNotification ,
@@ -1260,6 +1261,93 @@ 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 = JSON . parse ( packageJsonContent ) ;
1277+ serverVersion = packageJson . version ;
1278+ } catch ( e ) {
1279+ // If we can't read the version, that's okay - we'll just omit it
1280+ serverVersion = undefined ;
1281+ }
1282+
1283+ const projects = Array . from ( projectsFiles . entries ( ) ) . map (
1284+ ( [ projectRootPath , pf ] ) => ( {
1285+ projectRootPath,
1286+ openFiles : Array . from ( pf . openFiles ) ,
1287+ filesWithDiagnostics : Array . from ( pf . filesWithDiagnostics ) ,
1288+ filesDiagnostics : pf . filesDiagnostics ,
1289+ rescriptVersion : pf . rescriptVersion ,
1290+ bscBinaryLocation : pf . bscBinaryLocation ,
1291+ editorAnalysisLocation : pf . editorAnalysisLocation ,
1292+ namespaceName : pf . namespaceName ,
1293+ hasPromptedToStartBuild : pf . hasPromptedToStartBuild ,
1294+ bsbWatcherByEditor :
1295+ pf . bsbWatcherByEditor != null
1296+ ? { pid : pf . bsbWatcherByEditor . pid ?? null }
1297+ : null ,
1298+ } ) ,
1299+ ) ;
1300+
1301+ const state = {
1302+ lspServerVersion : serverVersion ,
1303+ config : config . extensionConfiguration ,
1304+ projects,
1305+ workspaceFolders : Array . from ( workspaceFolders ) ,
1306+ runtimePathCache : utils . getRuntimePathCacheSnapshot ( ) ,
1307+ } ;
1308+
1309+ // Format JSON with pretty-printing (2-space indent) on the server side
1310+ // This ensures consistent formatting and handles any Maps/Sets that might
1311+ // have been converted to plain objects/arrays above
1312+ const formattedJson = JSON . stringify ( state , null , 2 ) ;
1313+
1314+ // Write the file to disk on the server side
1315+ const outputFile = utils . createFileInTempDir ( "_server_state.json" ) ;
1316+ fs . writeFileSync ( outputFile , formattedJson , { encoding : "utf-8" } ) ;
1317+
1318+ // Request the client to open the document
1319+ const fileUri = utils . pathToURI ( outputFile ) ;
1320+ const showDocumentRequest : p . RequestMessage = {
1321+ jsonrpc : c . jsonrpcVersion ,
1322+ id : serverSentRequestIdCounter ++ ,
1323+ method : "window/showDocument" ,
1324+ params : {
1325+ uri : fileUri ,
1326+ external : false ,
1327+ takeFocus : true ,
1328+ } ,
1329+ } ;
1330+ send ( showDocumentRequest ) ;
1331+
1332+ let response : p . ResponseMessage = {
1333+ jsonrpc : c . jsonrpcVersion ,
1334+ id : msg . id ,
1335+ result : { uri : fileUri } ,
1336+ } ;
1337+ return response ;
1338+ } catch ( e ) {
1339+ let response : p . ResponseMessage = {
1340+ jsonrpc : c . jsonrpcVersion ,
1341+ id : msg . id ,
1342+ error : {
1343+ code : p . ErrorCodes . InternalError ,
1344+ message : `Failed to dump server state: ${ String ( e ) } ` ,
1345+ } ,
1346+ } ;
1347+ return response ;
1348+ }
1349+ }
1350+
12631351async function onMessage ( msg : p . Message ) {
12641352 if ( p . Message . isNotification ( msg ) ) {
12651353 // notification message, aka the client ends it and doesn't want a reply
@@ -1458,6 +1546,9 @@ async function onMessage(msg: p.Message) {
14581546 retriggerCharacters : [ "=" , "," ] ,
14591547 }
14601548 : undefined ,
1549+ executeCommandProvider : {
1550+ commands : [ "rescript/dumpServerState" ] ,
1551+ } ,
14611552 } ,
14621553 } ;
14631554 let response : p . ResponseMessage = {
@@ -1555,47 +1646,18 @@ async function onMessage(msg: p.Message) {
15551646 if ( extName === c . resExt ) {
15561647 send ( await signatureHelp ( msg ) ) ;
15571648 }
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 ) {
1649+ } else if ( msg . method === p . ExecuteCommandRequest . method ) {
1650+ // Standard LSP executeCommand - supports editor-agnostic command execution
1651+ const params = msg . params as p . ExecuteCommandParams ;
1652+ if ( params . command === "rescript/dumpServerState" ) {
1653+ send ( await dumpServerState ( msg ) ) ;
1654+ } else {
15931655 let response : p . ResponseMessage = {
15941656 jsonrpc : c . jsonrpcVersion ,
15951657 id : msg . id ,
15961658 error : {
1597- code : p . ErrorCodes . InternalError ,
1598- message : `Failed to dump server state : ${ String ( e ) } ` ,
1659+ code : p . ErrorCodes . InvalidRequest ,
1660+ message : `Unknown command : ${ params . command } ` ,
15991661 } ,
16001662 } ;
16011663 send ( response ) ;
0 commit comments