@@ -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,22 @@ let openCompiledFileRequest = new v.RequestType<
79
82
void
80
83
> ( "rescript-vscode.open_compiled" ) ;
81
84
85
+ let getCurrentCompilerDiagnosticsForFile = (
86
+ fileUri : string
87
+ ) : p . Diagnostic [ ] => {
88
+ let diagnostics : p . Diagnostic [ ] | null = null ;
89
+
90
+ projectsFiles . forEach ( ( projectFile , _projectRootPath ) => {
91
+ if ( diagnostics == null && projectFile . filesDiagnostics [ fileUri ] != null ) {
92
+ diagnostics = projectFile . filesDiagnostics [ fileUri ] . slice ( ) ;
93
+ }
94
+ } ) ;
95
+
96
+ return diagnostics ?? [ ] ;
97
+ } ;
82
98
let sendUpdatedDiagnostics = ( ) => {
83
- projectsFiles . forEach ( ( { filesWithDiagnostics } , projectRootPath ) => {
99
+ projectsFiles . forEach ( ( projectFile , projectRootPath ) => {
100
+ let { filesWithDiagnostics } = projectFile ;
84
101
let content = fs . readFileSync (
85
102
path . join ( projectRootPath , c . compilerLogPartialPath ) ,
86
103
{ encoding : "utf-8" }
@@ -91,6 +108,7 @@ let sendUpdatedDiagnostics = () => {
91
108
codeActions,
92
109
} = utils . parseCompilerLogOutput ( content ) ;
93
110
111
+ projectFile . filesDiagnostics = filesAndErrors ;
94
112
codeActionsFromDiagnostics = codeActions ;
95
113
96
114
// diff
@@ -188,6 +206,7 @@ let openedFile = (fileUri: string, fileContent: string) => {
188
206
projectRootState = {
189
207
openFiles : new Set ( ) ,
190
208
filesWithDiagnostics : new Set ( ) ,
209
+ filesDiagnostics : { } ,
191
210
bsbWatcherByEditor : null ,
192
211
hasPromptedToStartBuild : / ( \/ | \\ ) n o d e _ m o d u l e s ( \/ | \\ ) / . test (
193
212
projectRootPath
@@ -608,17 +627,22 @@ let updateDiagnosticSyntax = (fileUri: string, fileContent: string) => {
608
627
let tmpname = utils . createFileInTempDir ( extension ) ;
609
628
fs . writeFileSync ( tmpname , fileContent , { encoding : "utf-8" } ) ;
610
629
611
- let items : p . Diagnostic [ ] | [ ] = utils . runAnalysisAfterSanityCheck ( filePath , [
612
- "diagnosticSyntax" ,
613
- tmpname ,
614
- ] ) ;
630
+ // We need to account for any existing diagnostics from the compiler for this
631
+ // file. If we don't we might accidentally clear the current file's compiler
632
+ // diagnostics if there's no syntax diagostics to send. This is because
633
+ // publishing an empty diagnostics array is equivalent to saying "clear all
634
+ // errors".
635
+ let compilerDiagnosticsForFile =
636
+ getCurrentCompilerDiagnosticsForFile ( fileUri ) ;
637
+ let syntaxDiagnosticsForFile : p . Diagnostic [ ] =
638
+ utils . runAnalysisAfterSanityCheck ( filePath , [ "diagnosticSyntax" , tmpname ] ) ;
615
639
616
640
let notification : p . NotificationMessage = {
617
641
jsonrpc : c . jsonrpcVersion ,
618
642
method : "textDocument/publishDiagnostics" ,
619
643
params : {
620
644
uri : fileUri ,
621
- diagnostics : items ,
645
+ diagnostics : [ ... syntaxDiagnosticsForFile , ... compilerDiagnosticsForFile ] ,
622
646
} ,
623
647
} ;
624
648
0 commit comments