Skip to content

Commit 04bf047

Browse files
committed
Formatting with diagnosis
1 parent 1e4d41f commit 04bf047

File tree

1 file changed

+47
-21
lines changed

1 file changed

+47
-21
lines changed

server/src/testserver.ts

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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
1717
let 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');
1919
let bsbLogPartialPath = 'bsb.log';
2020
let resExt = '.res';
2121
let resiExt = '.resi';
@@ -53,15 +53,13 @@ type formattingResult = {
5353
error: string,
5454
};
5555
let 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+
105103
let 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

202200
let 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

Comments
 (0)