@@ -20,12 +20,14 @@ let bscPartialPath = path.join('node_modules', '.bin', 'bsc')
2020// https://microsoft.github.io/language-server-protocol/specification#initialize
2121// According to the spec, there could be requests before the 'initialize' request. Link in comment tells how to handle them.
2222let initialized = false ;
23+ // https://microsoft.github.io/language-server-protocol/specification#exit
24+ let shutdownRequestAlreadyReceived = false ;
2325
2426// congrats. A simple UI problem is now a distributed system problem
2527let stupidFileContentCache : { [ key : string ] : string } = {
2628}
2729
28- let findDirOfFileNearFile = ( fileToFind : p . DocumentUri , source : p . DocumentUri , ) => {
30+ let findDirOfFileNearFile = ( fileToFind : p . DocumentUri , source : p . DocumentUri ) => {
2931 let dir = path . dirname ( source )
3032 if ( fs . existsSync ( path . join ( dir , fileToFind ) ) ) {
3133 return dir
@@ -68,13 +70,26 @@ let formatUsingValidBscPath = (code: string, bscPath: p.DocumentUri, isInterface
6870 }
6971}
7072
73+ // let startWatchingBsbOutputFile = () => {
74+ // fs.watch()
75+ // }
76+ // let stopWatchingBsbOutputFile = () => {
77+ // fs.unwatchFile()
78+ // }
79+
7180process . on ( 'message' , ( a : ( m . RequestMessage | m . NotificationMessage ) ) => {
7281 if ( ( a as m . RequestMessage ) . id == null ) {
82+ // this is a notification message, aka client sent and forgot
7383 let aa = ( a as m . NotificationMessage )
7484 if ( ! initialized && aa . method !== 'exit' ) {
7585 // From spec: "Notifications should be dropped, except for the exit notification. This will allow the exit of a server without an initialize request"
7686 } else if ( aa . method === 'exit' ) {
77- // nothing to do for now
87+ // The server should exit with success code 0 if the shutdown request has been received before; otherwise with error code 1
88+ if ( shutdownRequestAlreadyReceived ) {
89+ process . exit ( 0 )
90+ } else {
91+ process . exit ( 1 )
92+ }
7893 } else if ( aa . method === DidOpenTextDocumentNotification . method ) {
7994 let params = ( aa . params as p . DidOpenTextDocumentParams ) ;
8095 stupidFileContentCache [ params . textDocument . uri ] = params . textDocument . text ;
@@ -92,6 +107,7 @@ process.on('message', (a: (m.RequestMessage | m.NotificationMessage)) => {
92107 delete stupidFileContentCache [ params . textDocument . uri ] ;
93108 }
94109 } else {
110+ // this is a request message, aka client sent request, waits for our reply
95111 let aa = ( a as m . RequestMessage )
96112 if ( ! initialized && aa . method !== 'initialize' ) {
97113 let response : m . ResponseMessage = {
@@ -128,6 +144,27 @@ process.on('message', (a: (m.RequestMessage | m.NotificationMessage)) => {
128144 result : null ,
129145 } ;
130146 ( < any > process ) . send ( response ) ;
147+ } else if ( aa . method === 'shutdown' ) {
148+ // https://microsoft.github.io/language-server-protocol/specification#shutdown
149+ if ( shutdownRequestAlreadyReceived ) {
150+ let response : m . ResponseMessage = {
151+ jsonrpc : jsonrpcVersion ,
152+ id : aa . id ,
153+ error : {
154+ code : m . ErrorCodes . InvalidRequest ,
155+ message : `Language server already received the shutdown request`
156+ }
157+ } ;
158+ ( < any > process ) . send ( response ) ;
159+ } else {
160+ shutdownRequestAlreadyReceived = true
161+ let response : m . ResponseMessage = {
162+ jsonrpc : jsonrpcVersion ,
163+ id : aa . id ,
164+ result : null ,
165+ } ;
166+ ( < any > process ) . send ( response ) ;
167+ }
131168 } else if ( aa . method === p . DocumentFormattingRequest . method ) {
132169 let params = ( aa . params as p . DocumentFormattingParams )
133170 let filePath = params . textDocument . uri . replace ( 'file:' , '' )
0 commit comments