From 0131b59abb5ea79dc8afc15b8d33a07c6774b931 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Mon, 11 Nov 2024 19:43:51 +0100 Subject: [PATCH] run from appropriate bins also on the LS client --- client/src/commands/code_analysis.ts | 9 ++-- client/src/commands/dump_debug.ts | 12 ++++- client/src/utils.ts | 80 ++++++++++++++++++++-------- 3 files changed, 75 insertions(+), 26 deletions(-) diff --git a/client/src/commands/code_analysis.ts b/client/src/commands/code_analysis.ts index 322844d33..7a8c1f7eb 100644 --- a/client/src/commands/code_analysis.ts +++ b/client/src/commands/code_analysis.ts @@ -14,7 +14,7 @@ import { OutputChannel, StatusBarItem, } from "vscode"; -import { analysisProdPath, getAnalysisBinaryPath } from "../utils"; +import { findProjectRootOfFileInDir, getBinaryPath } from "../utils"; export let statusBarItem = { setToStopText: (codeAnalysisRunningStatusBarItem: StatusBarItem) => { @@ -208,9 +208,12 @@ export const runCodeAnalysisWithReanalyze = ( let currentDocument = window.activeTextEditor.document; let cwd = targetDir ?? path.dirname(currentDocument.uri.fsPath); - let binaryPath = getAnalysisBinaryPath(); + let projectRootPath: string | null = findProjectRootOfFileInDir( + currentDocument.uri.fsPath + ); + let binaryPath = getBinaryPath("rescript-tools.exe", projectRootPath); if (binaryPath === null) { - window.showErrorMessage("Binary executable not found.", analysisProdPath); + window.showErrorMessage("Binary executable not found."); return; } diff --git a/client/src/commands/dump_debug.ts b/client/src/commands/dump_debug.ts index ff1e3cbd0..168d87a22 100644 --- a/client/src/commands/dump_debug.ts +++ b/client/src/commands/dump_debug.ts @@ -7,7 +7,11 @@ import { ViewColumn, window, } from "vscode"; -import { createFileInTempDir, getAnalysisBinaryPath } from "../utils"; +import { + createFileInTempDir, + findProjectRootOfFileInDir, + getBinaryPath, +} from "../utils"; import * as path from "path"; // Maps to Cli.ml @@ -132,7 +136,11 @@ export const dumpDebug = async ( const { line: endLine, character: endChar } = editor.selection.end; const filePath = editor.document.uri.fsPath; - const binaryPath = getAnalysisBinaryPath(); + let projectRootPath: string | null = findProjectRootOfFileInDir(filePath); + const binaryPath = getBinaryPath( + "rescript-editor-analysis.exe", + projectRootPath + ); if (binaryPath === null) { window.showErrorMessage("Binary executable not found."); return; diff --git a/client/src/utils.ts b/client/src/utils.ts index 0c6ba3ea7..4857045e4 100644 --- a/client/src/utils.ts +++ b/client/src/utils.ts @@ -1,31 +1,50 @@ import * as path from "path"; import * as fs from "fs"; import * as os from "os"; +import { DocumentUri } from "vscode-languageclient"; + +/* + * Much of the code in here is duplicated from the server code. + * At some point we should move the functionality powered by this + * to the server itself. + */ + +type binaryName = "rescript-editor-analysis.exe" | "rescript-tools.exe"; const platformDir = process.arch === "arm64" ? process.platform + process.arch : process.platform; -const analysisDevPath = path.join( - path.dirname(__dirname), - "..", - "analysis", - "rescript-editor-analysis.exe" -); - -export const analysisProdPath = path.join( - path.dirname(__dirname), - "..", - "server", - "analysis_binaries", - platformDir, - "rescript-editor-analysis.exe" -); - -export const getAnalysisBinaryPath = (): string | null => { - if (fs.existsSync(analysisDevPath)) { - return analysisDevPath; - } else if (fs.existsSync(analysisProdPath)) { - return analysisProdPath; +const getLegacyBinaryDevPath = (b: binaryName) => + path.join(path.dirname(__dirname), "..", "analysis", b); + +export const getLegacyBinaryProdPath = (b: binaryName) => + path.join( + path.dirname(__dirname), + "..", + "server", + "analysis_binaries", + platformDir, + b + ); + +export const getBinaryPath = ( + binaryName: "rescript-editor-analysis.exe" | "rescript-tools.exe", + projectRootPath: string +): string | null => { + const binaryFromCompilerPackage = path.join( + projectRootPath, + "node_modules", + "rescript", + platformDir, + binaryName + ); + + if (fs.existsSync(binaryFromCompilerPackage)) { + return binaryFromCompilerPackage; + } else if (fs.existsSync(getLegacyBinaryDevPath(binaryName))) { + return getLegacyBinaryDevPath(binaryName); + } else if (fs.existsSync(getLegacyBinaryProdPath(binaryName))) { + return getLegacyBinaryProdPath(binaryName); } else { return null; } @@ -39,3 +58,22 @@ export const createFileInTempDir = (prefix = "", extension = "") => { tempFileId = tempFileId + 1; return path.join(os.tmpdir(), tempFileName); }; + +export let findProjectRootOfFileInDir = ( + source: DocumentUri +): null | DocumentUri => { + let dir = path.dirname(source); + if ( + fs.existsSync(path.join(dir, "rescript.json")) || + fs.existsSync(path.join(dir, "bsconfig.json")) + ) { + return dir; + } else { + if (dir === source) { + // reached top + return null; + } else { + return findProjectRootOfFileInDir(dir); + } + } +};