@@ -20,6 +20,7 @@ import { assert } from "console";
20
20
import { fileURLToPath } from "url" ;
21
21
import { ChildProcess } from "child_process" ;
22
22
import { WorkspaceEdit } from "vscode-languageserver" ;
23
+ import { filesDiagnostics } from "./utils" ;
23
24
24
25
interface extensionConfiguration {
25
26
askToStartBuild : boolean ;
@@ -41,6 +42,8 @@ let projectsFiles: Map<
41
42
{
42
43
openFiles : Set < string > ;
43
44
filesWithDiagnostics : Set < string > ;
45
+ filesDiagnostics : filesDiagnostics ;
46
+
44
47
bsbWatcherByEditor : null | ChildProcess ;
45
48
46
49
// This keeps track of whether we've prompted the user to start a build
@@ -79,8 +82,20 @@ let openCompiledFileRequest = new v.RequestType<
79
82
void
80
83
> ( "rescript-vscode.open_compiled" ) ;
81
84
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
+ } ;
82
96
let sendUpdatedDiagnostics = ( ) => {
83
- projectsFiles . forEach ( ( { filesWithDiagnostics } , projectRootPath ) => {
97
+ projectsFiles . forEach ( ( projectFile , projectRootPath ) => {
98
+ let { filesWithDiagnostics } = projectFile ;
84
99
let content = fs . readFileSync (
85
100
path . join ( projectRootPath , c . compilerLogPartialPath ) ,
86
101
{ encoding : "utf-8" }
@@ -91,6 +106,7 @@ let sendUpdatedDiagnostics = () => {
91
106
codeActions,
92
107
} = utils . parseCompilerLogOutput ( content ) ;
93
108
109
+ projectFile . filesDiagnostics = filesAndErrors ;
94
110
codeActionsFromDiagnostics = codeActions ;
95
111
96
112
// diff
@@ -188,6 +204,7 @@ let openedFile = (fileUri: string, fileContent: string) => {
188
204
projectRootState = {
189
205
openFiles : new Set ( ) ,
190
206
filesWithDiagnostics : new Set ( ) ,
207
+ filesDiagnostics : { } ,
191
208
bsbWatcherByEditor : null ,
192
209
hasPromptedToStartBuild : / ( \/ | \\ ) n o d e _ m o d u l e s ( \/ | \\ ) / . test (
193
210
projectRootPath
@@ -608,17 +625,21 @@ let updateDiagnosticSyntax = (fileUri: string, fileContent: string) => {
608
625
let tmpname = utils . createFileInTempDir ( extension ) ;
609
626
fs . writeFileSync ( tmpname , fileContent , { encoding : "utf-8" } ) ;
610
627
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 ] ) ;
615
636
616
637
let notification : p . NotificationMessage = {
617
638
jsonrpc : c . jsonrpcVersion ,
618
639
method : "textDocument/publishDiagnostics" ,
619
640
params : {
620
641
uri : fileUri ,
621
- diagnostics : items ,
642
+ diagnostics : [ ... syntaxDiagnosticsForFile , ... compilerDiagnosticsForFile ] ,
622
643
} ,
623
644
} ;
624
645
0 commit comments