Skip to content

Commit 9cb7481

Browse files
committed
Replace chokidar
1 parent a960dfa commit 9cb7481

File tree

2 files changed

+61
-78
lines changed

2 files changed

+61
-78
lines changed

server/src/incrementalCompilation.ts

Lines changed: 19 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import * as cp from "node:child_process";
99
import semver from "semver";
1010
import config, { send } from "./config";
1111
import * as c from "./constants";
12-
import * as chokidar from "chokidar";
1312
import { fileCodeActions } from "./codeActions";
1413
import { projectsFiles } from "./projectFiles";
1514

@@ -92,38 +91,29 @@ const incrementallyCompiledFileInfo: Map<
9291
const hasReportedFeatureFailedError: Set<string> = new Set();
9392
const originalTypeFileToFilePath: Map<string, string> = new Map();
9493

95-
let incrementalFilesWatcher = chokidar
96-
.watch([], {
97-
awaitWriteFinish: {
98-
stabilityThreshold: 1,
99-
},
100-
})
101-
.on("all", (e, changedPath) => {
102-
if (e !== "change" && e !== "unlink") return;
103-
const filePath = originalTypeFileToFilePath.get(changedPath);
104-
if (filePath != null) {
105-
const entry = incrementallyCompiledFileInfo.get(filePath);
106-
if (entry != null) {
94+
export function incrementalCompilationFileChanged(changedPath: string) {
95+
const filePath = originalTypeFileToFilePath.get(changedPath);
96+
if (filePath != null) {
97+
const entry = incrementallyCompiledFileInfo.get(filePath);
98+
if (entry != null) {
99+
if (debug()) {
100+
console.log("[watcher] Cleaning up incremental files for " + filePath);
101+
}
102+
if (entry.compilation != null) {
107103
if (debug()) {
108-
console.log(
109-
"[watcher] Cleaning up incremental files for " + filePath
110-
);
111-
}
112-
if (entry.compilation != null) {
113-
if (debug()) {
114-
console.log("[watcher] Was compiling, killing");
115-
}
116-
clearTimeout(entry.compilation.timeout);
117-
entry.killCompilationListeners.forEach((cb) => cb());
118-
entry.compilation = null;
104+
console.log("[watcher] Was compiling, killing");
119105
}
120-
cleanUpIncrementalFiles(
121-
entry.file.sourceFilePath,
122-
entry.project.rootPath
123-
);
106+
clearTimeout(entry.compilation.timeout);
107+
entry.killCompilationListeners.forEach((cb) => cb());
108+
entry.compilation = null;
124109
}
110+
cleanUpIncrementalFiles(
111+
entry.file.sourceFilePath,
112+
entry.project.rootPath
113+
);
125114
}
126-
});
115+
}
116+
}
127117

128118
export function removeIncrementalFileFolder(
129119
projectRootPath: string,
@@ -465,10 +455,6 @@ function triggerIncrementalCompilationOfFile(
465455
incrementalFileCacheEntry.project.callArgs = figureOutBscArgs(
466456
incrementalFileCacheEntry
467457
);
468-
// Set up watcher for relevant cmt/cmti
469-
incrementalFilesWatcher.add([
470-
incrementalFileCacheEntry.file.originalTypeFileLocation,
471-
]);
472458
originalTypeFileToFilePath.set(
473459
incrementalFileCacheEntry.file.originalTypeFileLocation,
474460
incrementalFileCacheEntry.file.sourceFilePath
@@ -781,7 +767,6 @@ export function handleClosedFile(filePath: string) {
781767
cleanUpIncrementalFiles(filePath, entry.project.rootPath);
782768
incrementallyCompiledFileInfo.delete(filePath);
783769
originalTypeFileToFilePath.delete(entry.file.originalTypeFileLocation);
784-
incrementalFilesWatcher.unwatch([entry.file.originalTypeFileLocation]);
785770
}
786771

787772
export function getCodeActionsFromIncrementalCompilation(

server/src/server.ts

Lines changed: 42 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import * as v from "vscode-languageserver";
44
import * as rpc from "vscode-jsonrpc/node";
55
import * as path from "path";
66
import fs from "fs";
7-
// TODO: check DidChangeWatchedFilesNotification.
87
import {
8+
DidChangeWatchedFilesNotification,
99
DidOpenTextDocumentNotification,
1010
DidChangeTextDocumentNotification,
1111
DidCloseTextDocumentNotification,
@@ -14,6 +14,7 @@ import {
1414
InlayHintParams,
1515
CodeLensParams,
1616
SignatureHelpParams,
17+
InitializedNotification,
1718
} from "vscode-languageserver-protocol";
1819
import * as lookup from "./lookup";
1920
import * as utils from "./utils";
@@ -27,6 +28,10 @@ import * as ic from "./incrementalCompilation";
2728
import config, { extensionConfiguration } from "./config";
2829
import { projectsFiles } from "./projectFiles";
2930

31+
// Absolute paths to all the workspace folders
32+
// Configured during the initialize request
33+
const workspaceFolders = new Set<string>();
34+
3035
// This holds client capabilities specific to our extension, and not necessarily
3136
// related to the LS protocol. It's for enabling/disabling features that might
3237
// work in one client, like VSCode, but perhaps not in others, like vim.
@@ -209,21 +214,18 @@ let deleteProjectConfigCache = async (rootPath: string) => {
209214
}
210215
};
211216

212-
let compilerLogsWatcher = chokidar
213-
.watch([], {
214-
awaitWriteFinish: {
215-
stabilityThreshold: 1,
216-
},
217-
})
218-
.on("all", async (_e, changedPath) => {
219-
if (changedPath.includes("build.ninja")) {
217+
async function onWorkspaceDidChangeWatchedFiles(
218+
params: p.DidChangeWatchedFilesParams
219+
) {
220+
await Promise.all(params.changes.map(async (change) => {
221+
if (change.uri.includes("build.ninja")) {
220222
if (config.extensionConfiguration.cache?.projectConfig?.enable === true) {
221-
let projectRoot = utils.findProjectRootOfFile(changedPath);
223+
let projectRoot = utils.findProjectRootOfFile(change.uri);
222224
if (projectRoot != null) {
223225
await syncProjectConfigCache(projectRoot);
224226
}
225227
}
226-
} else {
228+
} else if (change.uri.includes("compiler.log")) {
227229
try {
228230
await sendUpdatedDiagnostics();
229231
sendCompilationFinishedMessage();
@@ -236,13 +238,11 @@ let compilerLogsWatcher = chokidar
236238
} catch {
237239
console.log("Error while sending updated diagnostics");
238240
}
241+
} else {
242+
ic.incrementalCompilationFileChanged(fileURLToPath(change.uri));
239243
}
240-
});
241-
242-
let stopWatchingCompilerLog = () => {
243-
// TODO: cleanup of compilerLogs?
244-
compilerLogsWatcher.close();
245-
};
244+
}));
245+
}
246246

247247
type clientSentBuildAction = {
248248
title: string;
@@ -280,13 +280,7 @@ let openedFile = async (fileUri: string, fileContent: string) => {
280280
: false,
281281
};
282282
projectsFiles.set(projectRootPath, projectRootState);
283-
compilerLogsWatcher.add(
284-
path.join(projectRootPath, c.compilerLogPartialPath)
285-
);
286283
if (config.extensionConfiguration.cache?.projectConfig?.enable === true) {
287-
compilerLogsWatcher.add(
288-
path.join(projectRootPath, c.buildNinjaPartialPath)
289-
);
290284
await syncProjectConfigCache(projectRootPath);
291285
}
292286
}
@@ -364,12 +358,6 @@ let closedFile = async (fileUri: string) => {
364358
root.openFiles.delete(filePath);
365359
// clear diagnostics too if no open files open in said project
366360
if (root.openFiles.size === 0) {
367-
compilerLogsWatcher.unwatch(
368-
path.join(projectRootPath, c.compilerLogPartialPath)
369-
);
370-
compilerLogsWatcher.unwatch(
371-
path.join(projectRootPath, c.buildNinjaPartialPath)
372-
);
373361
await deleteProjectConfigCache(projectRootPath);
374362
deleteProjectDiagnostics(projectRootPath);
375363
if (root.bsbWatcherByEditor !== null) {
@@ -1051,7 +1039,7 @@ async function onMessage(msg: p.Message) {
10511039
} else {
10521040
process.exit(1);
10531041
}
1054-
} else if (msg.method === "initialized") {
1042+
} else if (msg.method === InitializedNotification.method) {
10551043
/*
10561044
The initialized notification is sent from the client to the server after the client received the result of the initialize request
10571045
but before the client is sending any other request or notification to the server.
@@ -1060,27 +1048,32 @@ async function onMessage(msg: p.Message) {
10601048
We use this to register the file watchers for the project.
10611049
The client can watch files for us and send us events via the `workspace/didChangeWatchedFiles`
10621050
*/
1063-
const watchers =
1064-
Array.from(projectsFiles.keys()).flatMap(projectRootPath => [
1051+
const watchers = Array.from(workspaceFolders).flatMap(
1052+
(projectRootPath) => [
10651053
{
10661054
globPattern: path.join(projectRootPath, c.compilerLogPartialPath),
1067-
kind: p.WatchKind.Change | p.WatchKind.Create,
1055+
kind: p.WatchKind.Change | p.WatchKind.Create | p.WatchKind.Delete,
10681056
},
10691057
{
10701058
globPattern: path.join(projectRootPath, c.buildNinjaPartialPath),
1071-
kind: p.WatchKind.Change | p.WatchKind.Create,
1059+
kind: p.WatchKind.Change | p.WatchKind.Create | p.WatchKind.Delete,
10721060
},
1073-
])
1074-
const registrationParams : p.RegistrationParams = {
1075-
registrations:[
10761061
{
1077-
id: "rescript_file_watcher",
1078-
method: p.DidChangeWatchedFilesNotification.method,
1079-
registerOptions: {
1080-
watchers
1081-
}
1062+
globPattern: `${path.join(projectRootPath, c.compilerDirPartialPath)}/**/*.{cmt,cmi}`,
1063+
kind: p.WatchKind.Change | p.WatchKind.Delete,
10821064
}
10831065
]
1066+
);
1067+
const registrationParams: p.RegistrationParams = {
1068+
registrations: [
1069+
{
1070+
id: "rescript_file_watcher",
1071+
method: DidChangeWatchedFilesNotification.method,
1072+
registerOptions: {
1073+
watchers,
1074+
},
1075+
},
1076+
],
10841077
};
10851078
const req: p.RequestMessage = {
10861079
jsonrpc: c.jsonrpcVersion,
@@ -1089,6 +1082,9 @@ async function onMessage(msg: p.Message) {
10891082
params: registrationParams,
10901083
};
10911084
send(req);
1085+
} else if (msg.method === DidChangeWatchedFilesNotification.method) {
1086+
const params = msg.params as p.DidChangeWatchedFilesParams;
1087+
await onWorkspaceDidChangeWatchedFiles(params);
10921088
} else if (msg.method === DidOpenTextDocumentNotification.method) {
10931089
let params = msg.params as p.DidOpenTextDocumentParams;
10941090
await openedFile(params.textDocument.uri, params.textDocument.text);
@@ -1134,6 +1130,10 @@ async function onMessage(msg: p.Message) {
11341130
} else if (msg.method === "initialize") {
11351131
// Save initial configuration, if present
11361132
let initParams = msg.params as InitializeParams;
1133+
for (const workspaceFolder of initParams.workspaceFolders || []) {
1134+
const workspaceRootPath = fileURLToPath(workspaceFolder.uri);
1135+
workspaceFolders.add(workspaceRootPath);
1136+
}
11371137
let initialConfiguration = initParams.initializationOptions
11381138
?.extensionConfiguration as extensionConfiguration | undefined;
11391139

@@ -1245,8 +1245,6 @@ async function onMessage(msg: p.Message) {
12451245
} else {
12461246
shutdownRequestAlreadyReceived = true;
12471247
// TODO: recheck logic around init/shutdown...
1248-
stopWatchingCompilerLog();
1249-
// TODO: delete bsb watchers
12501248

12511249
if (pullConfigurationPeriodically != null) {
12521250
clearInterval(pullConfigurationPeriodically);

0 commit comments

Comments
 (0)