From 02d32f852cbb589b1f7da3b99ee74aaf3b423614 Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 19 Sep 2025 14:35:37 +0200 Subject: [PATCH 1/2] Use compiler-info.json to find runtime and bsc --- server/src/bsc-args/rewatch.ts | 9 ++++----- server/src/constants.ts | 5 +++++ server/src/find-runtime.ts | 19 ++++++++++++++++--- server/src/incrementalCompilation.ts | 7 ++++++- server/src/utils.ts | 14 ++++++++++++++ 5 files changed, 45 insertions(+), 9 deletions(-) diff --git a/server/src/bsc-args/rewatch.ts b/server/src/bsc-args/rewatch.ts index 5e39c4ed6..c4ac3528d 100644 --- a/server/src/bsc-args/rewatch.ts +++ b/server/src/bsc-args/rewatch.ts @@ -57,6 +57,7 @@ async function getRuntimePath( export async function getRewatchBscArgs( send: (msg: p.Message) => void, + bscBinaryLocation: string | null, projectsFiles: Map, entry: IncrementallyCompiledFileInfo, ): Promise { @@ -124,12 +125,10 @@ export async function getRewatchBscArgs( "--compiler-args", entry.file.sourceFilePath, ]; - const bscExe = await utils.findBscExeBinary( - entry.project.workspaceRootPath, - ); + const env: NodeJS.ProcessEnv = {}; - if (bscExe != null) { - env["RESCRIPT_BSC_EXE"] = bscExe; + if (bscBinaryLocation != null) { + env["RESCRIPT_BSC_EXE"] = bscBinaryLocation; } // For ReScript >= 12.0.0-beta.11 we need to set RESCRIPT_RUNTIME diff --git a/server/src/constants.ts b/server/src/constants.ts index 1242c454d..28e213bff 100644 --- a/server/src/constants.ts +++ b/server/src/constants.ts @@ -33,6 +33,11 @@ export let rescriptJsonPartialPath = "rescript.json"; export let compilerDirPartialPath = path.join("lib", "bs"); export let compilerOcamlDirPartialPath = path.join("lib", "ocaml"); export let compilerLogPartialPath = path.join("lib", "bs", ".compiler.log"); +export let compilerInfoPartialPath = path.join( + "lib", + "bs", + "compiler-info.json", +); export let buildNinjaPartialPath = path.join("lib", "bs", "build.ninja"); export let rewatchLockPartialPath = path.join("lib", "rewatch.lock"); export let rescriptLockPartialPath = path.join("lib", "rescript.lock"); diff --git a/server/src/find-runtime.ts b/server/src/find-runtime.ts index 257c98e56..42512e044 100644 --- a/server/src/find-runtime.ts +++ b/server/src/find-runtime.ts @@ -1,5 +1,6 @@ -import { readdir, stat as statAsync } from "fs/promises"; +import { readdir, stat as statAsync, readFile } from "fs/promises"; import { join, resolve } from "path"; +import { compilerInfoPartialPath } from "./constants"; // Efficient parallel folder traversal to find node_modules directories async function findNodeModulesDirs( @@ -91,7 +92,19 @@ async function findRescriptRuntimeInAlternativeLayout( return results; } -async function findRuntimePath(project: string) { +async function findRuntimePath(project: string): Promise { + // Try a compiler-info.json file first + const compilerInfo = resolve(project, compilerInfoPartialPath); + try { + const contents = await readFile(compilerInfo, "utf8"); + const compileInfo: { runtime_path?: string } = JSON.parse(contents); + if (compileInfo && compileInfo.runtime_path) { + return [compileInfo.runtime_path]; + } + } catch { + // Ignore errors, fallback to node_modules search + } + // Find all node_modules directories using efficient traversal const node_modules = await findNodeModulesDirs(project); @@ -136,7 +149,7 @@ async function findRuntimePath(project: string) { return rescriptRuntimeDirs.map((runtime) => resolve(runtime)); } -function findRuntimeCached() { +function findRuntimeCached(): (project: string) => Promise { const cache = new Map(); return async (project: string) => { if (cache.has(project)) { diff --git a/server/src/incrementalCompilation.ts b/server/src/incrementalCompilation.ts index 849047e4c..50be4f526 100644 --- a/server/src/incrementalCompilation.ts +++ b/server/src/incrementalCompilation.ts @@ -185,7 +185,12 @@ export async function getBscArgs( ): Promise { return entry.buildSystem === "bsb" ? await getBsbBscArgs(entry) - : await getRewatchBscArgs(send, projectsFiles, entry); + : await getRewatchBscArgs( + send, + entry.project.bscBinaryLocation, + projectsFiles, + entry, + ); } function argCouples(argList: string[]): string[][] { diff --git a/server/src/utils.ts b/server/src/utils.ts index 9dd089799..12457d982 100644 --- a/server/src/utils.ts +++ b/server/src/utils.ts @@ -92,6 +92,20 @@ let findBinary = async ( return path.join(config.extensionConfiguration.platformPath, binary); } + if (projectRootPath !== null && binary === "bsc.exe") { + try { + const compilerInfo = path.resolve( + projectRootPath, + c.compilerInfoPartialPath, + ); + const contents = await fsAsync.readFile(compilerInfo, "utf8"); + const compileInfo = JSON.parse(contents); + if (compileInfo && compileInfo.runtime_path) { + return compileInfo.runtime_path; + } + } catch {} + } + const rescriptDir = lookup.findFilePathFromProjectRoot( projectRootPath, path.join("node_modules", "rescript"), From 891e9e399dca70b8d606b5328c9c05f8f122435d Mon Sep 17 00:00:00 2001 From: nojaf Date: Thu, 25 Sep 2025 09:07:36 +0200 Subject: [PATCH 2/2] Add changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea51bcd8a..4e3b1f5c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ - Find `@rescript/runtime` for Rewatch compiler-args call. https://github.com/rescript-lang/rescript-vscode/pull/1125 - Use `prepareRename` command (when a new enough ReScript version is used) to speed up the `rename` command. https://github.com/rescript-lang/rescript-vscode/pull/1124 +- Use `compiler-info.json` to find the `@rescript/runtime` and `bsc.exe` if available. ## 1.64.0