Skip to content

Commit f28cf45

Browse files
committed
fix problem tab accidentally being cleared due to syntax error diagnostics publishing not accounting for existing compiler errors for current file
1 parent 38d58f9 commit f28cf45

File tree

2 files changed

+32
-11
lines changed

2 files changed

+32
-11
lines changed

server/src/server.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { assert } from "console";
2020
import { fileURLToPath } from "url";
2121
import { ChildProcess } from "child_process";
2222
import { WorkspaceEdit } from "vscode-languageserver";
23+
import { filesDiagnostics } from "./utils";
2324

2425
interface extensionConfiguration {
2526
askToStartBuild: boolean;
@@ -41,6 +42,8 @@ let projectsFiles: Map<
4142
{
4243
openFiles: Set<string>;
4344
filesWithDiagnostics: Set<string>;
45+
filesDiagnostics: filesDiagnostics;
46+
4447
bsbWatcherByEditor: null | ChildProcess;
4548

4649
// This keeps track of whether we've prompted the user to start a build
@@ -79,8 +82,20 @@ let openCompiledFileRequest = new v.RequestType<
7982
void
8083
>("rescript-vscode.open_compiled");
8184

85+
let getDiagnosticsForFile = (fileUri: string): p.Diagnostic[] => {
86+
let diagnostics: p.Diagnostic[] | null = null;
87+
88+
projectsFiles.forEach((projectFile, _projectRootPath) => {
89+
if (diagnostics == null && projectFile.filesDiagnostics[fileUri] != null) {
90+
diagnostics = projectFile.filesDiagnostics[fileUri].slice();
91+
}
92+
});
93+
94+
return diagnostics ?? [];
95+
};
8296
let sendUpdatedDiagnostics = () => {
83-
projectsFiles.forEach(({ filesWithDiagnostics }, projectRootPath) => {
97+
projectsFiles.forEach((projectFile, projectRootPath) => {
98+
let { filesWithDiagnostics } = projectFile;
8499
let content = fs.readFileSync(
85100
path.join(projectRootPath, c.compilerLogPartialPath),
86101
{ encoding: "utf-8" }
@@ -91,6 +106,7 @@ let sendUpdatedDiagnostics = () => {
91106
codeActions,
92107
} = utils.parseCompilerLogOutput(content);
93108

109+
projectFile.filesDiagnostics = filesAndErrors;
94110
codeActionsFromDiagnostics = codeActions;
95111

96112
// diff
@@ -188,6 +204,7 @@ let openedFile = (fileUri: string, fileContent: string) => {
188204
projectRootState = {
189205
openFiles: new Set(),
190206
filesWithDiagnostics: new Set(),
207+
filesDiagnostics: {},
191208
bsbWatcherByEditor: null,
192209
hasPromptedToStartBuild: /(\/|\\)node_modules(\/|\\)/.test(
193210
projectRootPath
@@ -608,17 +625,21 @@ let updateDiagnosticSyntax = (fileUri: string, fileContent: string) => {
608625
let tmpname = utils.createFileInTempDir(extension);
609626
fs.writeFileSync(tmpname, fileContent, { encoding: "utf-8" });
610627

611-
let items: p.Diagnostic[] | [] = utils.runAnalysisAfterSanityCheck(filePath, [
612-
"diagnosticSyntax",
613-
tmpname,
614-
]);
628+
// We need to account for any existing diagnostics from the compiler for this
629+
// file. If we don't we might accidentally clear the current file's compiler
630+
// diagnostics if there's no syntax diagostics to send. This is because
631+
// publishing an empty diagnostics array is equivalent to saying "clear all
632+
// errors".
633+
let compilerDiagnosticsForFile = getDiagnosticsForFile(fileUri);
634+
let syntaxDiagnosticsForFile: p.Diagnostic[] =
635+
utils.runAnalysisAfterSanityCheck(filePath, ["diagnosticSyntax", tmpname]);
615636

616637
let notification: p.NotificationMessage = {
617638
jsonrpc: c.jsonrpcVersion,
618639
method: "textDocument/publishDiagnostics",
619640
params: {
620641
uri: fileUri,
621-
diagnostics: items,
642+
diagnostics: [...syntaxDiagnosticsForFile, ...compilerDiagnosticsForFile],
622643
},
623644
};
624645

server/src/utils.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ let parseFileAndRange = (fileAndRange: string) => {
474474
};
475475

476476
// main parsing logic
477-
type filesDiagnostics = {
477+
export type filesDiagnostics = {
478478
[key: string]: p.Diagnostic[];
479479
};
480480
type parsedCompilerLogResult = {
@@ -589,7 +589,7 @@ export let parseCompilerLogOutput = (
589589
code: undefined,
590590
severity: t.DiagnosticSeverity.Error,
591591
tag: undefined,
592-
content: [lines[i], lines[i+1]],
592+
content: [lines[i], lines[i + 1]],
593593
});
594594
i++;
595595
} else if (/^ +([0-9]+| +|\.) (|)/.test(line)) {
@@ -603,9 +603,9 @@ export let parseCompilerLogOutput = (
603603
// 10 ┆
604604
} else if (line.startsWith(" ")) {
605605
// part of the actual diagnostics message
606-
parsedDiagnostics[parsedDiagnostics.length - 1].content.push(
607-
line.slice(2)
608-
);
606+
parsedDiagnostics[parsedDiagnostics.length - 1].content.push(
607+
line.slice(2)
608+
);
609609
} else if (line.trim() != "") {
610610
// We'll assume that everything else is also part of the diagnostics too.
611611
// Most of these should have been indented 2 spaces; sadly, some of them

0 commit comments

Comments
 (0)