@@ -15,7 +15,7 @@ import { Range } from 'vscode-languageserver-textdocument';
1515// See https://microsoft.github.io/language-server-protocol/specification Abstract Message
1616// version is fixed to 2.0
1717let jsonrpcVersion = '2.0' ;
18- let bscPartialPath = path . join ( 'node_modules' , '.bin ' , 'bsc' ) ;
18+ let bscPartialPath = path . join ( 'node_modules' , 'bs-platform ' , process . platform , 'bsc.exe ' ) ;
1919let bsbLogPartialPath = 'bsb.log' ;
2020let resExt = '.res' ;
2121let resiExt = '.resi' ;
@@ -53,15 +53,13 @@ type formattingResult = {
5353 error : string ,
5454} ;
5555let formatUsingValidBscPath = ( code : string , bscPath : p . DocumentUri , isInterface : boolean ) : formattingResult => {
56- // TODO: what if there's space in the path?
57- let result ;
5856 // library cleans up after itself. No need to manually remove temp file
5957 let tmpobj = tmp . fileSync ( ) ;
6058 let extension = isInterface ? resiExt : resExt ;
6159 let fileToFormat = tmpobj . name + extension ;
6260 fs . writeFileSync ( fileToFormat , code , { encoding : 'utf-8' } ) ;
6361 try {
64- result = childProcess . execSync ( ` ${ bscPath } -fmt ${ fileToFormat } ` )
62+ let result = childProcess . execFileSync ( bscPath , [ '-color' , 'never' , '-format' , fileToFormat ] , { stdio : 'pipe' } )
6563 return {
6664 kind : 'success' ,
6765 result : result . toString ( ) ,
@@ -101,7 +99,7 @@ let parseBsbOutputLocation = (location: string): Range => {
10199 }
102100 }
103101}
104- type diagnosis = { range : Range , diagnosis : string }
102+
105103let parseBsbLogOutput = ( content : string ) => {
106104 /* example bsb.log file content:
107105
@@ -173,7 +171,7 @@ FAILED: src/test.cmj src/test.cmi
173171 }
174172
175173 // map of file path to list of diagnosis
176- let ret : { [ key : string ] : diagnosis [ ] } = { }
174+ let ret : { [ key : string ] : t . Diagnostic [ ] } = { }
177175 res . forEach ( diagnosisLines => {
178176 let [ fileAndLocation , ...diagnosisMessage ] = diagnosisLines
179177 let lastSpace = fileAndLocation . lastIndexOf ( ' ' )
@@ -192,15 +190,14 @@ FAILED: src/test.cmj src/test.cmi
192190 . trim ( ) ;
193191 ret [ file ] . push ( {
194192 range : parseBsbOutputLocation ( location ) ,
195- diagnosis : cleanedUpDiagnosis ,
193+ message : cleanedUpDiagnosis ,
196194 } )
197195 } )
198196
199197 return ret
200198}
201199
202200let startWatchingBsbOutputFile = ( root : p . DocumentUri , process : NodeJS . Process ) => {
203- // console.log(root);
204201 // TOOD: setTimeout instead
205202 let id = setInterval ( ( ) => {
206203 let openFiles = Object . keys ( stupidFileContentCache ) ;
@@ -214,7 +211,7 @@ let startWatchingBsbOutputFile = (root: p.DocumentUri, process: NodeJS.Process)
214211 }
215212 } ) ;
216213
217- let files : { [ key : string ] : diagnosis [ ] } = { }
214+ let files : { [ key : string ] : t . Diagnostic [ ] } = { }
218215
219216 let res = Array . from ( bsbLogDirs )
220217 . forEach ( bsbLogDir => {
@@ -233,13 +230,7 @@ let startWatchingBsbOutputFile = (root: p.DocumentUri, process: NodeJS.Process)
233230 uri : file ,
234231 // there's a new optional version param from https://github.com/microsoft/language-server-protocol/issues/201
235232 // not using it for now, sigh
236- diagnostics :
237- files [ file ] . map ( ( { range, diagnosis } ) => {
238- return {
239- range : range ,
240- message : diagnosis ,
241- }
242- } ) ,
233+ diagnostics : files [ file ] ,
243234 }
244235 let notification : m . NotificationMessage = {
245236 jsonrpc : jsonrpcVersion ,
@@ -313,7 +304,7 @@ process.on('message', (a: (m.RequestMessage | m.NotificationMessage)) => {
313304 // TODO: handle single file
314305 console . log ( "not handling single file" )
315306 } else {
316- diagnosisTimer = startWatchingBsbOutputFile ( root , process )
307+ // diagnosisTimer = startWatchingBsbOutputFile(root, process)
317308 }
318309 // send the list of things we support
319310 let result : p . InitializeResult = {
@@ -415,16 +406,51 @@ process.on('message', (a: (m.RequestMessage | m.NotificationMessage)) => {
415406 result : result ,
416407 } ;
417408 process . send ! ( response ) ;
409+
410+ let params2 : p . PublishDiagnosticsParams = {
411+ uri : params . textDocument . uri ,
412+ // there's a new optional version param from https://github.com/microsoft/language-server-protocol/issues/201
413+ // not using it for now, sigh
414+ diagnostics : [ ] ,
415+ }
416+ let notification : m . NotificationMessage = {
417+ jsonrpc : jsonrpcVersion ,
418+ method : 'textDocument/publishDiagnostics' ,
419+ params : params2 ,
420+ } ;
421+ process . send ! ( notification ) ;
418422 } else {
419423 let response : m . ResponseMessage = {
420424 jsonrpc : jsonrpcVersion ,
421425 id : aa . id ,
422- error : {
423- code : m . ErrorCodes . ParseError ,
424- message : formattedResult . error ,
425- }
426+ result : [ ] ,
427+ // technically a formatting failure should return the error but
428+ // since this is LSP... the idiom seems to be to silently return
429+ // nothing (to avoid an alert window each time on bad formatting)
430+ // while sending a diangosis about the error afterward
431+
432+ // error: {
433+ // code: m.ErrorCodes.ParseError,
434+ // message: formattedResult.error,
435+ // }
426436 } ;
427437 process . send ! ( response ) ;
438+
439+ let filesAndErrors = parseBsbLogOutput ( formattedResult . error )
440+ Object . keys ( filesAndErrors ) . forEach ( file => {
441+ let params2 : p . PublishDiagnosticsParams = {
442+ uri : params . textDocument . uri ,
443+ // there's a new optional version param from https://github.com/microsoft/language-server-protocol/issues/201
444+ // not using it for now, sigh
445+ diagnostics : filesAndErrors [ file ] ,
446+ }
447+ let notification : m . NotificationMessage = {
448+ jsonrpc : jsonrpcVersion ,
449+ method : 'textDocument/publishDiagnostics' ,
450+ params : params2 ,
451+ } ;
452+ process . send ! ( notification ) ;
453+ } )
428454 }
429455 }
430456 }
0 commit comments