parseCompilerLogOutput uses os.EOL, causing stale diagnostics on Windows and doesn't handle the new "Error in <project>:" header

Aperta Adatta ai principianti
#1,185 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
78/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Tranquilla
Stack tecnologico
node.js, vscode

Direzione di ricerca

Inizia individuando parseCompilerLogOutput() ed esamina come suddivide il contenuto del log del compilatore e come gestisce le righe non riconosciute. Verifica il parser con log del compilatore relativi a compilazioni riuscite e con diagnostica, usando terminatori di riga in stile Windows e LF. Il lavoro è completato quando le build riuscite cancellano la diagnostica obsoleta, la nuova diagnostica sostituisce quella precedente e l’header Error in : non produce più un avviso di analisi non necessario.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Summary

I found two related issues in the compiler log parser while debugging another Windows issue in the language server.

The primary issue is that parseCompilerLogOutput() splits the compiler log using os.EOL.

On Windows, the ReScript compiler writes .compiler.log using LF (\n) line endings, while os.EOL is \r\n. As a result, the parser treats the entire file as a single line.

This was likely difficult to notice because the parser behaves correctly on Unix-like systems. The compiler emits LF (\n) line endings on every platform, which matches os.EOL on Linux and macOS. The mismatch only occurs on Windows, where os.EOL is \r\n.

This prevents it from detecting #Done(...) after successful builds, so previously reported compiler diagnostics are not cleared until another compilation produces updated diagnostics.

After fixing the line splitting locally, I also noticed another parser issue: the current compiler output contains lines such as

Error in <project>:

These lines are currently treated as parse errors even though the actual diagnostic immediately follows and is parsed correctly.


Environment

  • OS: Windows 10 x64
  • VS Code extension: v1.73.11 (Pre-release)
  • Language Server: v1.72.0
  • ReScript: 12.3.0
  • Node: 24.18.0

Investigation

The problem is inside parseCompilerLogOutput().

Current code:

const lines = content.split(os.EOL);

I added logging of the raw compiler log.

When the project builds successfully, .compiler.log contains:

#Start(1784551270096)
#Done(1784551270250)

The file itself is correct. A ReScript maintainer previously stated that the compiler intentionally emits LF (\n) line endings on every platform, and this still appears to be the case in ReScript 12.3.0 based on my testing.

However, because it uses LF line endings, split(os.EOL) produces a single string on Windows instead of separate lines.

After replacing it with

const lines = content.split(/\r\n|\n|\r/);

(or equivalently split(/\r\n|[\n\r]/))

the parser correctly detects #Start(...) and #Done(...).

After this change:

  • diagnostics are cleared correctly after successful builds;
  • old diagnostics no longer remain visible;
  • new diagnostics replace previous ones correctly.

Additional parser issue

After fixing the line splitting, another parser issue became visible.

Unlike the line-ending issue above, this issue appears to be platform-independent. I only noticed it after fixing the Windows-specific line splitting issue.

Current compiler output starts with:

Error in shopify-admin-extension:

  Syntax error!
  C:\...

The parser reports the header as a parse error because Error in <project>: is not handled anywhere in parseCompilerLogOutput().

As a result, the language server displays the warning:

There are more compiler warning/errors that we could not parse.

even though the actual diagnostic is parsed correctly. The only unrecognized line is the project header.

It seems sufficient to simply ignore it:

} else if (line.startsWith("Error in ")) {
  // Project header emitted by the compiler.
}

The actual diagnostic immediately follows, so no information is lost.


Why os.EOL is not appropriate here

os.EOL describes the native newline sequence of the operating system.

It does not describe the line endings used by an arbitrary file.

This is also consistent with ReScript itself. In a discussion on the ReScript forum, a maintainer stated that the compiler intentionally emits LF (\n) line endings on every platform, including Windows:

"The ReScript printer currently always emits \n newlines."

The discussion is from 2021, but this behavior appears to be unchanged based on testing with ReScript 12.3.0, the VS Code extension 1.73.11 (pre-release), and the language server 1.72.0.

For parsing file contents, splitting on all standard newline sequences is generally recommended:

content.split(/\r\n|\n|\r/)

This correctly handles:

  • Windows (CRLF)
  • Unix/Linux/macOS (LF)
  • legacy CR files

without depending on the platform where the parser is running or the line endings used by the file.

References:


I verified locally that changing the line splitting fixes the stale diagnostics issue, and handling the Error in <project>: header removes the unnecessary "There are more compiler warning/errors that we could not parse." warning.

Lingua principale
ReScript
Stelle
354
Fork
63
Merge medio
11h 29m
PR unite (30g)
1

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di rescript-lang/rescript-vscode

Tutte le issue di rescript-lang/rescript-vscode

Issue simili

Altre issue su DevTools

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.