Skip to content

Commit be41c28

Browse files
committed
Use NormalizedPath and FileURI types
1 parent e864320 commit be41c28

File tree

8 files changed

+421
-193
lines changed

8 files changed

+421
-193
lines changed

client/src/utils.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,7 @@ export const createFileInTempDir = (prefix = "", extension = "") => {
5959
return path.join(os.tmpdir(), tempFileName);
6060
};
6161

62-
export let findProjectRootOfFileInDir = (
63-
source: DocumentUri,
64-
): null | DocumentUri => {
62+
export let findProjectRootOfFileInDir = (source: string): null | string => {
6563
let dir = path.dirname(source);
6664
if (
6765
fs.existsSync(path.join(dir, "rescript.json")) ||

server/src/bsc-args/rewatch.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ async function getRuntimePath(
2323

2424
export async function getRewatchBscArgs(
2525
send: (msg: p.Message) => void,
26-
bscBinaryLocation: string | null,
26+
bscBinaryLocation: utils.NormalizedPath | null,
2727
projectsFiles: Map<string, projectFiles>,
2828
entry: IncrementallyCompiledFileInfo,
2929
): Promise<RewatchCompilerArgs | null> {

server/src/codeActions.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// OCaml binary.
44
import * as p from "vscode-languageserver-protocol";
55
import * as utils from "./utils";
6-
import { fileURLToPath } from "url";
76

87
export type fileCodeActions = { range: p.Range; codeAction: p.CodeAction };
98

@@ -14,7 +13,7 @@ export type filesCodeActions = {
1413
interface findCodeActionsConfig {
1514
diagnostic: p.Diagnostic;
1615
diagnosticMessage: string[];
17-
file: string;
16+
file: utils.FileURI;
1817
range: p.Range;
1918
addFoundActionsHere: filesCodeActions;
2019
}
@@ -190,7 +189,7 @@ interface codeActionExtractorConfig {
190189
line: string;
191190
index: number;
192191
array: string[];
193-
file: string;
192+
file: utils.FileURI;
194193
range: p.Range;
195194
diagnostic: p.Diagnostic;
196195
codeActions: filesCodeActions;
@@ -631,7 +630,7 @@ let simpleAddMissingCases: codeActionExtractor = async ({
631630
.join("")
632631
.trim();
633632

634-
let filePath = fileURLToPath(file);
633+
let filePath = utils.uriToNormalizedPath(file as utils.FileURI);
635634

636635
let newSwitchCode = await utils.runAnalysisAfterSanityCheck(filePath, [
637636
"codemod",

server/src/incrementalCompilation.ts

Lines changed: 71 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import * as path from "path";
22
import fs from "fs";
33
import * as utils from "./utils";
4-
import { pathToFileURL } from "url";
54
import readline from "readline";
65
import { performance } from "perf_hooks";
76
import * as p from "vscode-languageserver-protocol";
@@ -14,7 +13,8 @@ import { fileCodeActions } from "./codeActions";
1413
import { projectsFiles } from "./projectFiles";
1514
import { getRewatchBscArgs, RewatchCompilerArgs } from "./bsc-args/rewatch";
1615
import { BsbCompilerArgs, getBsbBscArgs } from "./bsc-args/bsb";
17-
import { workspaceFolders } from "./server";
16+
import { getCurrentCompilerDiagnosticsForFile } from "./server";
17+
import { NormalizedPath } from "./utils";
1818

1919
export function debug() {
2020
return (
@@ -32,8 +32,8 @@ export type IncrementallyCompiledFileInfo = {
3232
file: {
3333
/** File type. */
3434
extension: ".res" | ".resi";
35-
/** Path to the source file. */
36-
sourceFilePath: string;
35+
/** Path to the source file (normalized). */
36+
sourceFilePath: NormalizedPath;
3737
/** Name of the source file. */
3838
sourceFileName: string;
3939
/** Module name of the source file. */
@@ -69,29 +69,29 @@ export type IncrementallyCompiledFileInfo = {
6969
killCompilationListeners: Array<() => void>;
7070
/** Project specific information. */
7171
project: {
72-
/** The root path of the project. */
73-
rootPath: string;
72+
/** The root path of the project (normalized to match projectsFiles keys). */
73+
rootPath: NormalizedPath;
7474
/** The root path of the workspace (if a monorepo) */
75-
workspaceRootPath: string;
75+
workspaceRootPath: NormalizedPath;
7676
/** Computed location of bsc. */
77-
bscBinaryLocation: string;
77+
bscBinaryLocation: NormalizedPath;
7878
/** The arguments needed for bsc, derived from the project configuration/build.ninja. */
7979
callArgs: Promise<Array<string> | null>;
8080
/** The location of the incremental folder for this project. */
81-
incrementalFolderPath: string;
81+
incrementalFolderPath: NormalizedPath;
8282
};
8383
/** Any code actions for this incremental file. */
8484
codeActions: Array<fileCodeActions>;
8585
};
8686

8787
const incrementallyCompiledFileInfo: Map<
88-
string,
88+
NormalizedPath,
8989
IncrementallyCompiledFileInfo
9090
> = new Map();
9191
const hasReportedFeatureFailedError: Set<string> = new Set();
92-
const originalTypeFileToFilePath: Map<string, string> = new Map();
92+
const originalTypeFileToFilePath: Map<string, NormalizedPath> = new Map();
9393

94-
export function incrementalCompilationFileChanged(changedPath: string) {
94+
export function incrementalCompilationFileChanged(changedPath: NormalizedPath) {
9595
const filePath = originalTypeFileToFilePath.get(changedPath);
9696
if (filePath != null) {
9797
const entry = incrementallyCompiledFileInfo.get(filePath);
@@ -116,7 +116,7 @@ export function incrementalCompilationFileChanged(changedPath: string) {
116116
}
117117

118118
export function removeIncrementalFileFolder(
119-
projectRootPath: string,
119+
projectRootPath: NormalizedPath,
120120
onAfterRemove?: () => void,
121121
) {
122122
fs.rm(
@@ -128,7 +128,7 @@ export function removeIncrementalFileFolder(
128128
);
129129
}
130130

131-
export function recreateIncrementalFileFolder(projectRootPath: string) {
131+
export function recreateIncrementalFileFolder(projectRootPath: NormalizedPath) {
132132
if (debug()) {
133133
console.log("Recreating incremental file folder");
134134
}
@@ -142,8 +142,8 @@ export function recreateIncrementalFileFolder(projectRootPath: string) {
142142
}
143143

144144
export function cleanUpIncrementalFiles(
145-
filePath: string,
146-
projectRootPath: string,
145+
filePath: NormalizedPath,
146+
projectRootPath: NormalizedPath,
147147
) {
148148
const ext = filePath.endsWith(".resi") ? ".resi" : ".res";
149149
const namespace = utils.getNamespaceNameFromConfigFile(projectRootPath);
@@ -242,7 +242,7 @@ function removeAnsiCodes(s: string): string {
242242
return s.replace(ansiEscape, "");
243243
}
244244
function triggerIncrementalCompilationOfFile(
245-
filePath: string,
245+
filePath: NormalizedPath,
246246
fileContent: string,
247247
send: send,
248248
onCompilationFinished?: () => void,
@@ -256,25 +256,31 @@ function triggerIncrementalCompilationOfFile(
256256
console.log("Did not find project root path for " + filePath);
257257
return;
258258
}
259-
const project = projectsFiles.get(projectRootPath);
259+
// projectRootPath is already normalized (NormalizedPath) from findProjectRootOfFile
260+
// Use getProjectFile to verify the project exists
261+
const project = utils.getProjectFile(projectRootPath);
260262
if (project == null) {
261263
if (debug()) console.log("Did not find open project for " + filePath);
262264
return;
263265
}
266+
// projectRootPath is already the correct normalized key format
267+
const actualProjectRootPath = projectRootPath;
264268

265269
// computeWorkspaceRootPathFromLockfile returns null if lockfile found (local package) or if no parent found
266-
const computedWorkspaceRoot =
267-
utils.computeWorkspaceRootPathFromLockfile(projectRootPath);
270+
const computedWorkspaceRoot = utils.computeWorkspaceRootPathFromLockfile(
271+
actualProjectRootPath,
272+
);
268273
// If null, it means either a lockfile was found (local package) or no parent project root exists
269-
// In both cases, we default to projectRootPath
270-
const workspaceRootPath = computedWorkspaceRoot ?? projectRootPath;
274+
// In both cases, we default to actualProjectRootPath
275+
const workspaceRootPath: NormalizedPath =
276+
computedWorkspaceRoot ?? actualProjectRootPath;
271277

272278
// Determine if lockfile was found for debug logging
273-
// If computedWorkspaceRoot is null and projectRootPath is not null, check if parent exists
279+
// If computedWorkspaceRoot is null and actualProjectRootPath is not null, check if parent exists
274280
const foundRewatchLockfileInProjectRoot =
275281
computedWorkspaceRoot == null &&
276-
projectRootPath != null &&
277-
utils.findProjectRootOfFile(projectRootPath, true) != null;
282+
actualProjectRootPath != null &&
283+
utils.findProjectRootOfFile(actualProjectRootPath, true) != null;
278284

279285
if (foundRewatchLockfileInProjectRoot && debug()) {
280286
console.log(
@@ -299,15 +305,15 @@ function triggerIncrementalCompilationOfFile(
299305
? `${moduleName}-${project.namespaceName}`
300306
: moduleName;
301307

302-
const incrementalFolderPath = path.join(
303-
projectRootPath,
308+
const incrementalFolderPath: NormalizedPath = path.join(
309+
actualProjectRootPath,
304310
INCREMENTAL_FILE_FOLDER_LOCATION,
305-
);
311+
) as NormalizedPath;
306312

307313
let originalTypeFileLocation = path.resolve(
308-
projectRootPath,
314+
actualProjectRootPath,
309315
c.compilerDirPartialPath,
310-
path.relative(projectRootPath, filePath),
316+
path.relative(actualProjectRootPath, filePath),
311317
);
312318

313319
const parsed = path.parse(originalTypeFileLocation);
@@ -326,8 +332,8 @@ function triggerIncrementalCompilationOfFile(
326332
incrementalFilePath: path.join(incrementalFolderPath, moduleName + ext),
327333
},
328334
project: {
329-
workspaceRootPath: workspaceRootPath ?? projectRootPath,
330-
rootPath: projectRootPath,
335+
workspaceRootPath,
336+
rootPath: actualProjectRootPath,
331337
callArgs: Promise.resolve([]),
332338
bscBinaryLocation,
333339
incrementalFolderPath,
@@ -373,7 +379,10 @@ function triggerIncrementalCompilationOfFile(
373379
};
374380
}
375381
}
376-
function verifyTriggerToken(filePath: string, triggerToken: number): boolean {
382+
function verifyTriggerToken(
383+
filePath: NormalizedPath,
384+
triggerToken: number,
385+
): boolean {
377386
return (
378387
incrementallyCompiledFileInfo.get(filePath)?.compilation?.triggerToken ===
379388
triggerToken
@@ -578,7 +587,8 @@ async function compileContents(
578587
const change = Object.values(ca.codeAction.edit.changes)[0];
579588

580589
ca.codeAction.edit.changes = {
581-
[pathToFileURL(entry.file.sourceFilePath).toString()]: change,
590+
[utils.pathToURI(entry.file.sourceFilePath) as utils.FileURI]:
591+
change,
582592
};
583593
}
584594
});
@@ -645,11 +655,34 @@ async function compileContents(
645655
}
646656
}
647657

658+
const fileUri = utils.pathToURI(
659+
entry.file.sourceFilePath,
660+
) as utils.FileURI;
661+
662+
// Update filesWithDiagnostics to track this file
663+
// entry.project.rootPath is guaranteed to match a key in projectsFiles
664+
// (see triggerIncrementalCompilationOfFile where the entry is created)
665+
const projectFile = projectsFiles.get(entry.project.rootPath);
666+
667+
if (projectFile != null) {
668+
// Get compiler diagnostics from main build (if any)
669+
const compilerDiagnosticsForFile =
670+
getCurrentCompilerDiagnosticsForFile(fileUri);
671+
const allDiagnostics = [...res, ...compilerDiagnosticsForFile];
672+
673+
if (allDiagnostics.length > 0) {
674+
projectFile.filesWithDiagnostics.add(fileUri as utils.FileURI);
675+
} else {
676+
// Only remove if there are no diagnostics at all
677+
projectFile.filesWithDiagnostics.delete(fileUri as utils.FileURI);
678+
}
679+
}
680+
648681
const notification: p.NotificationMessage = {
649682
jsonrpc: c.jsonrpcVersion,
650683
method: "textDocument/publishDiagnostics",
651684
params: {
652-
uri: pathToFileURL(entry.file.sourceFilePath),
685+
uri: fileUri,
653686
diagnostics: res,
654687
},
655688
};
@@ -667,7 +700,7 @@ async function compileContents(
667700
}
668701

669702
export function handleUpdateOpenedFile(
670-
filePath: string,
703+
filePath: utils.NormalizedPath,
671704
fileContent: string,
672705
send: send,
673706
onCompilationFinished?: () => void,
@@ -683,7 +716,7 @@ export function handleUpdateOpenedFile(
683716
);
684717
}
685718

686-
export function handleClosedFile(filePath: string) {
719+
export function handleClosedFile(filePath: NormalizedPath) {
687720
if (debug()) {
688721
console.log("Closed: " + filePath);
689722
}
@@ -695,7 +728,7 @@ export function handleClosedFile(filePath: string) {
695728
}
696729

697730
export function getCodeActionsFromIncrementalCompilation(
698-
filePath: string,
731+
filePath: NormalizedPath,
699732
): Array<fileCodeActions> | null {
700733
const entry = incrementallyCompiledFileInfo.get(filePath);
701734
if (entry != null) {

0 commit comments

Comments
 (0)