|
| 1 | +import path from "path"; |
| 2 | +import { Worker } from "worker_threads"; |
1 | 3 | import { Group } from "../dependencyManager/types";
|
2 |
| -import { removeIndexesFromSourceCode } from "../helper/file"; |
3 |
| -import DependencyTreeManager from "../dependencyManager/dependencyManager"; |
4 | 4 | import { File } from "./types";
|
5 |
| -import Parser from "tree-sitter"; |
6 |
| -import assert from "assert"; |
7 | 5 | import { getLanguagePlugin } from "../languagesPlugins";
|
8 | 6 | import { DepExport } from "../languagesPlugins/types";
|
| 7 | +import { removeIndexesFromSourceCode } from "../helper/file"; |
| 8 | +import assert from "assert"; |
| 9 | +import Parser from "tree-sitter"; |
| 10 | +import fs from "fs"; |
9 | 11 |
|
10 |
| -class SplitRunner { |
11 |
| - private dependencyTreeManager: DependencyTreeManager; |
12 |
| - private entrypointPath: string; |
| 12 | +export class SplitRunner { |
| 13 | + private index: number; |
13 | 14 | private group: Group;
|
| 15 | + private entrypointPath: string; |
14 | 16 | private files: File[];
|
15 | 17 |
|
16 |
| - constructor(dependencyTreeManager: DependencyTreeManager, group: Group) { |
17 |
| - this.dependencyTreeManager = dependencyTreeManager; |
18 |
| - this.entrypointPath = dependencyTreeManager.dependencyTree.path; |
| 18 | + constructor( |
| 19 | + index: number, |
| 20 | + group: Group, |
| 21 | + entrypointPath: string, |
| 22 | + files: File[], |
| 23 | + ) { |
| 24 | + this.index = index; |
| 25 | + this.entrypointPath = entrypointPath; |
19 | 26 | this.group = group;
|
20 |
| - this.files = dependencyTreeManager.getFiles(); |
| 27 | + this.files = files; |
21 | 28 | }
|
22 | 29 |
|
23 | 30 | #removeAnnotationFromOtherGroups() {
|
@@ -83,7 +90,7 @@ class SplitRunner {
|
83 | 90 | // We always want to keep the entrypoint file.
|
84 | 91 | // It will never be imported anywhere, so we add it now.
|
85 | 92 | const filesToKeep = new Set<string>();
|
86 |
| - filesToKeep.add(this.dependencyTreeManager.dependencyTree.path); |
| 93 | + filesToKeep.add(this.entrypointPath); |
87 | 94 |
|
88 | 95 | this.files.forEach((file) => {
|
89 | 96 | const languagePlugin = getLanguagePlugin(
|
@@ -191,41 +198,100 @@ class SplitRunner {
|
191 | 198 | }
|
192 | 199 |
|
193 | 200 | run() {
|
194 |
| - console.info("\n"); |
195 |
| - console.time("Splitting"); |
| 201 | + console.time(`Splitting-${this.index}`); |
196 | 202 |
|
197 |
| - console.time("remove annotation from other groups"); |
| 203 | + console.time(`remove annotation from other groups-${this.index}`); |
198 | 204 | this.#removeAnnotationFromOtherGroups();
|
199 |
| - console.timeEnd("remove annotation from other groups"); |
| 205 | + console.timeEnd(`remove annotation from other groups-${this.index}`); |
200 | 206 |
|
201 |
| - console.time("Get export map"); |
| 207 | + console.time(`Get export map-${this.index}`); |
202 | 208 | const exportMap = this.#getExportMap();
|
203 |
| - console.timeEnd("Get export map"); |
| 209 | + console.timeEnd(`Get export map-${this.index}`); |
204 | 210 |
|
205 |
| - console.time("Remove invalid imports and usages"); |
| 211 | + console.time(`Remove invalid imports and usages-${this.index}`); |
206 | 212 | this.#removeInvalidImportsAndUsages(exportMap);
|
207 |
| - console.timeEnd("Remove invalid imports and usages"); |
| 213 | + console.timeEnd(`Remove invalid imports and usages-${this.index}`); |
208 | 214 |
|
209 |
| - console.time("Remove unused imports"); |
| 215 | + console.time(`Remove unused imports-${this.index}`); |
210 | 216 | this.#removeUnusedImports();
|
211 |
| - console.timeEnd("Remove unused imports"); |
| 217 | + console.timeEnd(`Remove unused imports-${this.index}`); |
212 | 218 |
|
213 |
| - console.time("Remove unused files"); |
| 219 | + console.time(`Remove unused files-${this.index}`); |
214 | 220 | this.#removeUnusedFiles();
|
215 |
| - console.timeEnd("Remove unused files"); |
| 221 | + console.timeEnd(`Remove unused files-${this.index}`); |
216 | 222 |
|
217 |
| - console.time("Remove unused exports"); |
| 223 | + console.time(`Remove unused exports-${this.index}`); |
218 | 224 | this.#removeUnusedExports(exportMap);
|
219 |
| - console.timeEnd("Remove unused exports"); |
| 225 | + console.timeEnd(`Remove unused exports-${this.index}`); |
220 | 226 |
|
221 |
| - console.time("Remove errors"); |
| 227 | + console.time(`Remove errors-${this.index}`); |
222 | 228 | this.#removeErrors();
|
223 |
| - console.timeEnd("Remove errors"); |
| 229 | + console.timeEnd(`Remove errors-${this.index}`); |
224 | 230 |
|
225 |
| - console.timeEnd("Splitting"); |
| 231 | + console.timeEnd(`Splitting-${this.index}`); |
226 | 232 |
|
227 |
| - return this.files; |
| 233 | + return { index: this.index, group: this.group, files: this.files }; |
228 | 234 | }
|
229 | 235 | }
|
230 | 236 |
|
231 |
| -export default SplitRunner; |
| 237 | +export function runWithWorker( |
| 238 | + index: number, |
| 239 | + group: Group, |
| 240 | + entryPointPath: string, |
| 241 | + files: File[], |
| 242 | +) { |
| 243 | + const worker = new Worker(path.resolve(__dirname, "worker"), { |
| 244 | + workerData: { |
| 245 | + index, |
| 246 | + group, |
| 247 | + entryPointPath, |
| 248 | + files, |
| 249 | + }, |
| 250 | + }); |
| 251 | + |
| 252 | + return new Promise<{ index: number; group: Group; files: File[] }>( |
| 253 | + (resolve, reject) => { |
| 254 | + worker.on( |
| 255 | + "message", |
| 256 | + (split: { index: number; group: Group; files: File[] }) => { |
| 257 | + resolve(split); |
| 258 | + }, |
| 259 | + ); |
| 260 | + |
| 261 | + worker.on("error", reject); |
| 262 | + worker.on("exit", (code) => { |
| 263 | + if (code !== 0) { |
| 264 | + reject(new Error(`Worker stopped with exit code ${code}`)); |
| 265 | + } |
| 266 | + }); |
| 267 | + }, |
| 268 | + ); |
| 269 | +} |
| 270 | + |
| 271 | +export function writeSplitsToDisk( |
| 272 | + outputDir: string, |
| 273 | + entrypointPath: string, |
| 274 | + splits: { index: number; group: Group; files: File[] }[], |
| 275 | +) { |
| 276 | + const targetDir = path.dirname(entrypointPath); |
| 277 | + const groupMap: Record<number, Group> = {}; |
| 278 | + |
| 279 | + splits.forEach((split) => { |
| 280 | + const annotationDirectory = path.join(outputDir, split.index.toString()); |
| 281 | + |
| 282 | + split.files.forEach((file) => { |
| 283 | + const relativeFileNamePath = path.relative(targetDir, file.path); |
| 284 | + const destinationPath = path.join( |
| 285 | + annotationDirectory, |
| 286 | + relativeFileNamePath, |
| 287 | + ); |
| 288 | + fs.mkdirSync(path.dirname(destinationPath), { recursive: true }); |
| 289 | + fs.writeFileSync(destinationPath, file.sourceCode, "utf8"); |
| 290 | + }); |
| 291 | + |
| 292 | + groupMap[split.index] = split.group; |
| 293 | + }); |
| 294 | + |
| 295 | + const annotationFilePath = path.join(outputDir, "annotations.json"); |
| 296 | + fs.writeFileSync(annotationFilePath, JSON.stringify(groupMap, null, 2)); |
| 297 | +} |
0 commit comments