@@ -21,6 +21,7 @@ import { fileURLToPath } from "url";
21
21
import { ChildProcess } from "child_process" ;
22
22
import { WorkspaceEdit } from "vscode-languageserver" ;
23
23
import { TextEdit } from "vscode-languageserver-types" ;
24
+ import { OnReadOpts } from "node:net" ;
24
25
25
26
// https://microsoft.github.io/language-server-protocol/specification#initialize
26
27
// According to the spec, there could be requests before the 'initialize' request. Link in comment tells how to handle them.
@@ -243,6 +244,111 @@ if (process.argv.includes("--stdio")) {
243
244
send = ( msg : m . Message ) => process . send ! ( msg ) ;
244
245
process . on ( "message" , onMessage ) ;
245
246
}
247
+
248
+ function hover ( msg : p . RequestMessage ) {
249
+ let params = msg . params as p . HoverParams ;
250
+ let filePath = fileURLToPath ( params . textDocument . uri ) ;
251
+ let response = utils . runAnalysisCommand (
252
+ filePath ,
253
+ [ "hover" , filePath , params . position . line , params . position . character ] ,
254
+ msg
255
+ ) ;
256
+ send ( response ) ;
257
+ }
258
+
259
+ function definition ( msg : p . RequestMessage ) {
260
+ // https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_definition
261
+ let params = msg . params as p . DefinitionParams ;
262
+ let filePath = fileURLToPath ( params . textDocument . uri ) ;
263
+ let response = utils . runAnalysisCommand (
264
+ filePath ,
265
+ [ "definition" , filePath , params . position . line , params . position . character ] ,
266
+ msg
267
+ ) ;
268
+ send ( response ) ;
269
+ }
270
+
271
+ function rename ( msg : p . RequestMessage ) {
272
+ // https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_rename
273
+ let params = msg . params as p . RenameParams ;
274
+ let filePath = fileURLToPath ( params . textDocument . uri ) ;
275
+ let locations : p . Location [ ] | null = utils . getReferencesForPosition (
276
+ filePath ,
277
+ params . position
278
+ ) ;
279
+ let result : WorkspaceEdit | null ;
280
+ if ( locations === null ) {
281
+ result = null ;
282
+ } else {
283
+ let changes : { [ uri : string ] : TextEdit [ ] } = { } ;
284
+ locations . forEach ( ( { uri, range } ) => {
285
+ let textEdit : TextEdit = { range, newText : params . newName } ;
286
+ if ( uri in changes ) {
287
+ changes [ uri ] . push ( textEdit ) ;
288
+ } else {
289
+ changes [ uri ] = [ textEdit ] ;
290
+ }
291
+ } ) ;
292
+ result = { changes } ;
293
+ }
294
+ let renameResponse : m . ResponseMessage = {
295
+ jsonrpc : c . jsonrpcVersion ,
296
+ id : msg . id ,
297
+ result,
298
+ } ;
299
+ send ( renameResponse ) ;
300
+ }
301
+
302
+ function references ( msg : p . RequestMessage ) {
303
+ // https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references
304
+ let params = msg . params as p . ReferenceParams ;
305
+ let filePath = fileURLToPath ( params . textDocument . uri ) ;
306
+ let result : typeof p . ReferencesRequest . type = utils . getReferencesForPosition (
307
+ filePath ,
308
+ params . position
309
+ ) ;
310
+ let definitionResponse : m . ResponseMessage = {
311
+ jsonrpc : c . jsonrpcVersion ,
312
+ id : msg . id ,
313
+ result,
314
+ // error: code and message set in case an exception happens during the definition request.
315
+ } ;
316
+ send ( definitionResponse ) ;
317
+ }
318
+
319
+ function documentSymbol ( msg : p . RequestMessage ) {
320
+ // https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_documentSymbol
321
+ let params = msg . params as p . DocumentSymbolParams ;
322
+ let filePath = fileURLToPath ( params . textDocument . uri ) ;
323
+ let response = utils . runAnalysisCommand (
324
+ filePath ,
325
+ [ "documentSymbol" , filePath ] ,
326
+ msg
327
+ ) ;
328
+ send ( response ) ;
329
+ }
330
+
331
+ function completion ( msg : p . RequestMessage ) {
332
+ let params = msg . params as p . ReferenceParams ;
333
+ let filePath = fileURLToPath ( params . textDocument . uri ) ;
334
+ let code = getOpenedFileContent ( params . textDocument . uri ) ;
335
+ let tmpname = utils . createFileInTempDir ( ) ;
336
+ fs . writeFileSync ( tmpname , code , { encoding : "utf-8" } ) ;
337
+ let response = utils . runAnalysisCommand (
338
+ filePath ,
339
+ [
340
+ "completion" ,
341
+ filePath ,
342
+ params . position . line ,
343
+ params . position . character ,
344
+ tmpname ,
345
+ ] ,
346
+ msg
347
+ ) ;
348
+ fs . unlink ( tmpname , ( ) => null ) ;
349
+ send ( response ) ;
350
+ }
351
+
246
352
function onMessage ( msg : m . Message ) {
247
353
if ( m . isNotificationMessage ( msg ) ) {
248
354
// notification message, aka the client ends it and doesn't want a reply
@@ -353,105 +459,17 @@ function onMessage(msg: m.Message) {
353
459
send ( response ) ;
354
460
}
355
461
} else if ( msg . method === p . HoverRequest . method ) {
356
- let params = msg . params as p . HoverParams ;
357
- let filePath = fileURLToPath ( params . textDocument . uri ) ;
358
- let response = utils . runAnalysisCommand (
359
- filePath ,
360
- [ "hover" , filePath , params . position . line , params . position . character ] ,
361
- msg
362
- ) ;
363
- send ( response ) ;
462
+ hover ( msg ) ;
364
463
} else if ( msg . method === p . DefinitionRequest . method ) {
365
- // https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_definition
366
- let params = msg . params as p . DefinitionParams ;
367
- let filePath = fileURLToPath ( params . textDocument . uri ) ;
368
- let response = utils . runAnalysisCommand (
369
- filePath ,
370
- [
371
- "definition" ,
372
- filePath ,
373
- params . position . line ,
374
- params . position . character ,
375
- ] ,
376
- msg
377
- ) ;
378
- send ( response ) ;
464
+ definition ( msg ) ;
379
465
} else if ( msg . method === p . RenameRequest . method ) {
380
- // https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_rename
381
- let params = msg . params as p . RenameParams ;
382
- let filePath = fileURLToPath ( params . textDocument . uri ) ;
383
- let locations : p . Location [ ] | null = utils . getReferencesForPosition (
384
- filePath ,
385
- params . position
386
- ) ;
387
- let result : WorkspaceEdit | null ;
388
- if ( locations === null ) {
389
- result = null ;
390
- } else {
391
- let changes : { [ uri : string ] : TextEdit [ ] } = { } ;
392
- locations . forEach ( ( { uri, range } ) => {
393
- let textEdit : TextEdit = { range, newText : params . newName } ;
394
- if ( uri in changes ) {
395
- changes [ uri ] . push ( textEdit ) ;
396
- } else {
397
- changes [ uri ] = [ textEdit ] ;
398
- }
399
- } ) ;
400
-
401
- result = { changes } ;
402
- }
403
-
404
- let renameResponse : m . ResponseMessage = {
405
- jsonrpc : c . jsonrpcVersion ,
406
- id : msg . id ,
407
- result,
408
- } ;
409
-
410
- send ( renameResponse ) ;
466
+ rename ( msg ) ;
411
467
} else if ( msg . method === p . ReferencesRequest . method ) {
412
- // https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references
413
- let params = msg . params as p . ReferenceParams ;
414
- let filePath = fileURLToPath ( params . textDocument . uri ) ;
415
- let result : typeof p . ReferencesRequest . type = utils . getReferencesForPosition (
416
- filePath ,
417
- params . position
418
- ) ;
419
- let definitionResponse : m . ResponseMessage = {
420
- jsonrpc : c . jsonrpcVersion ,
421
- id : msg . id ,
422
- result,
423
- // error: code and message set in case an exception happens during the definition request.
424
- } ;
425
- send ( definitionResponse ) ;
468
+ references ( msg ) ;
426
469
} else if ( msg . method === p . DocumentSymbolRequest . method ) {
427
- // https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_documentSymbol
428
- let params = msg . params as p . DocumentSymbolParams ;
429
- let filePath = fileURLToPath ( params . textDocument . uri ) ;
430
- let response = utils . runAnalysisCommand (
431
- filePath ,
432
- [ "documentSymbol" , filePath ] ,
433
- msg
434
- ) ;
435
- send ( response ) ;
470
+ documentSymbol ( msg ) ;
436
471
} else if ( msg . method === p . CompletionRequest . method ) {
437
- let params = msg . params as p . ReferenceParams ;
438
- let filePath = fileURLToPath ( params . textDocument . uri ) ;
439
- let code = getOpenedFileContent ( params . textDocument . uri ) ;
440
- let tmpname = utils . createFileInTempDir ( ) ;
441
- fs . writeFileSync ( tmpname , code , { encoding : "utf-8" } ) ;
442
- let response = utils . runAnalysisCommand (
443
- filePath ,
444
- [
445
- "completion" ,
446
- filePath ,
447
- params . position . line ,
448
- params . position . character ,
449
- tmpname ,
450
- ] ,
451
- msg
452
- ) ;
453
- fs . unlink ( tmpname , ( ) => null ) ;
454
- send ( response ) ;
472
+ completion ( msg ) ;
455
473
} else if ( msg . method === p . DocumentFormattingRequest . method ) {
456
474
// technically, a formatting failure should reply with the error. Sadly
457
475
// the LSP alert box for these error replies sucks (e.g. doesn't actually
0 commit comments