tsc-ts 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/api/compiler/ast.d.ts +2 -0
- package/dist/api/compiler/ast.js +3 -0
- package/dist/api/compiler/checker-calls.js +5 -1
- package/dist/api/compiler/checker-grammar.js +3 -2
- package/dist/api/compiler/checker-inference.js +8 -2
- package/dist/api/compiler/checker-members.js +8 -3
- package/dist/api/compiler/checker-source-file.d.ts +12 -0
- package/dist/api/compiler/checker-source-file.js +35 -0
- package/dist/api/compiler/checker-symbols.js +2 -1
- package/dist/api/compiler/checker-type-factory.js +8 -2
- package/dist/api/compiler/checker.d.ts +17 -1
- package/dist/api/compiler/checker.js +49 -1
- package/dist/api/compiler/compile-program.d.ts +26 -2
- package/dist/api/compiler/compile-program.js +100 -7
- package/dist/api/compiler/diagnostics.d.ts +22 -0
- package/dist/api/compiler/diagnostics.js +86 -4
- package/dist/api/compiler/file-loader.d.ts +13 -3
- package/dist/api/compiler/file-loader.js +106 -30
- package/dist/api/compiler/link-tables.d.ts +7 -0
- package/dist/api/compiler/link-tables.js +22 -0
- package/dist/api/compiler/parallel-parse.d.ts +3 -2
- package/dist/api/compiler/parallel-parse.js +17 -5
- package/dist/api/compiler/parser.js +15 -14
- package/dist/api/compiler/printer/emit-context.d.ts +2 -0
- package/dist/api/compiler/printer/emit-context.js +4 -0
- package/dist/api/compiler/printer/printer.d.ts +48 -2
- package/dist/api/compiler/printer/printer.js +238 -14
- package/dist/api/compiler/program-checker.d.ts +22 -0
- package/dist/api/compiler/program-checker.js +39 -2
- package/dist/api/compiler/program.d.ts +2 -6
- package/dist/api/compiler/program.js +5 -30
- package/dist/api/compiler/relations.js +10 -0
- package/dist/api/compiler/symbol.d.ts +1 -1
- package/dist/api/compiler/symbol.js +8 -10
- package/dist/api/library/diagnostics.d.ts +10 -0
- package/dist/api/library/diagnostics.js +20 -0
- package/package.json +9 -9
- package/src/compiler/ast.ts +3 -0
- package/src/compiler/checker-calls.ts +3 -1
- package/src/compiler/checker-grammar.ts +3 -2
- package/src/compiler/checker-inference.ts +7 -2
- package/src/compiler/checker-members.ts +9 -3
- package/src/compiler/checker-source-file.ts +34 -0
- package/src/compiler/checker-symbols.ts +2 -1
- package/src/compiler/checker-type-factory.ts +4 -2
- package/src/compiler/checker.ts +45 -1
- package/src/compiler/compile-program.ts +121 -7
- package/src/compiler/diagnostics.ts +84 -3
- package/src/compiler/file-loader.ts +106 -29
- package/src/compiler/incremental.ts +80 -13
- package/src/compiler/link-tables.ts +32 -0
- package/src/compiler/parallel-check.ts +326 -62
- package/src/compiler/parallel-emit.ts +320 -0
- package/src/compiler/parallel-parse.ts +16 -5
- package/src/compiler/parse-thread.ts +3 -0
- package/src/compiler/parser.ts +15 -16
- package/src/compiler/printer/emit-context.ts +5 -0
- package/src/compiler/printer/printer.ts +231 -16
- package/src/compiler/program-checker.ts +40 -2
- package/src/compiler/program.ts +5 -25
- package/src/compiler/relations.ts +7 -0
- package/src/compiler/symbol.ts +15 -10
- package/src/compiler/thread-entry.ts +61 -3
- package/src/compiler/tsc-build.ts +63 -9
- package/src/compiler/tsc-cli.ts +5 -0
- package/src/compiler/tsc-compile.ts +278 -3
- package/src/library/diagnostics.ts +23 -0
|
@@ -326,6 +326,11 @@ export class Diagnostic {
|
|
|
326
326
|
reportsDeprecated;
|
|
327
327
|
skippedOnNoEmit = false;
|
|
328
328
|
repopulateInfo = undefined;
|
|
329
|
+
/**
|
|
330
|
+
* What `formatDiagnostic` gives for this diagnostic in `formattedReports.format`, where the checker
|
|
331
|
+
* thread that found it formatted it (`packResult`); `''` otherwise.
|
|
332
|
+
*/
|
|
333
|
+
formatted = '';
|
|
329
334
|
constructor(file, pos, end, message, args = []) {
|
|
330
335
|
this.file = file;
|
|
331
336
|
this.pos = pos;
|
|
@@ -358,6 +363,7 @@ export class Diagnostic {
|
|
|
358
363
|
result.relatedInformation = this.relatedInformation;
|
|
359
364
|
result.skippedOnNoEmit = this.skippedOnNoEmit;
|
|
360
365
|
result.repopulateInfo = this.repopulateInfo;
|
|
366
|
+
result.formatted = this.formatted;
|
|
361
367
|
return result;
|
|
362
368
|
}
|
|
363
369
|
}
|
|
@@ -463,10 +469,12 @@ function compareRelatedInfo(a, b) {
|
|
|
463
469
|
export function compareDiagnostics(a, b) {
|
|
464
470
|
if (a === b)
|
|
465
471
|
return 0;
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
472
|
+
const c = compareCodePoints(fileNameOf(a), fileNameOf(b));
|
|
473
|
+
return c !== 0 ? c : compareDiagnosticsInFile(a, b);
|
|
474
|
+
}
|
|
475
|
+
/** `compareDiagnostics` of two diagnostics whose files have the same name. */
|
|
476
|
+
function compareDiagnosticsInFile(a, b) {
|
|
477
|
+
let c = a.pos - b.pos;
|
|
470
478
|
if (c !== 0)
|
|
471
479
|
return c;
|
|
472
480
|
c = a.end - b.end;
|
|
@@ -486,6 +494,66 @@ export function compareDiagnostics(a, b) {
|
|
|
486
494
|
return c;
|
|
487
495
|
return compareRelatedInfo(a.relatedInformation, b.relatedInformation);
|
|
488
496
|
}
|
|
497
|
+
/**
|
|
498
|
+
* `diagnostics` in the order of `compareDiagnostics`, equal ones in their order in `diagnostics`. File
|
|
499
|
+
* names are compared once per pair of files rather than once per pair of diagnostics: the distinct
|
|
500
|
+
* files are sorted by name, and each diagnostic sorts by its file's place in that order, then by the
|
|
501
|
+
* rest of `compareDiagnostics`. A program's diagnostics come a file at a time, so the files are found
|
|
502
|
+
* from the runs of one file.
|
|
503
|
+
*/
|
|
504
|
+
export function sortDiagnostics(diagnostics) {
|
|
505
|
+
const n = diagnostics.length;
|
|
506
|
+
if (n < 2)
|
|
507
|
+
return diagnostics.slice();
|
|
508
|
+
const fileIndices = new Map();
|
|
509
|
+
const files = [];
|
|
510
|
+
const fileOf = [];
|
|
511
|
+
let last = undefined;
|
|
512
|
+
let lastIndex = -1;
|
|
513
|
+
for (let i = 0; i < n; i++) {
|
|
514
|
+
const file = diagnostics[i].file;
|
|
515
|
+
if (lastIndex < 0 || file !== last) {
|
|
516
|
+
let k = fileIndices.get(file);
|
|
517
|
+
if (k === undefined) {
|
|
518
|
+
k = files.length;
|
|
519
|
+
fileIndices.set(file, k);
|
|
520
|
+
files.push(file);
|
|
521
|
+
}
|
|
522
|
+
last = file;
|
|
523
|
+
lastIndex = k;
|
|
524
|
+
}
|
|
525
|
+
fileOf.push(lastIndex);
|
|
526
|
+
}
|
|
527
|
+
// Files with the same name share a rank, as they compare equal.
|
|
528
|
+
const nameOf = (k) => {
|
|
529
|
+
const file = files[k];
|
|
530
|
+
return file === undefined ? '' : file.fileName;
|
|
531
|
+
};
|
|
532
|
+
const byName = [];
|
|
533
|
+
for (let k = 0; k < files.length; k++)
|
|
534
|
+
byName.push(k);
|
|
535
|
+
byName.sort((x, y) => compareCodePoints(nameOf(x), nameOf(y)));
|
|
536
|
+
const rank = [];
|
|
537
|
+
for (let k = 0; k < files.length; k++)
|
|
538
|
+
rank.push(0);
|
|
539
|
+
for (let k = 1; k < byName.length; k++)
|
|
540
|
+
rank[byName[k]] = rank[byName[k - 1]] + (nameOf(byName[k]) === nameOf(byName[k - 1]) ? 0 : 1);
|
|
541
|
+
const order = [];
|
|
542
|
+
for (let i = 0; i < n; i++)
|
|
543
|
+
order.push(i);
|
|
544
|
+
order.sort((x, y) => {
|
|
545
|
+
const c = rank[fileOf[x]] - rank[fileOf[y]];
|
|
546
|
+
if (c !== 0)
|
|
547
|
+
return c;
|
|
548
|
+
const a = diagnostics[x];
|
|
549
|
+
const b = diagnostics[y];
|
|
550
|
+
return a === b ? 0 : compareDiagnosticsInFile(a, b);
|
|
551
|
+
});
|
|
552
|
+
const sorted = [];
|
|
553
|
+
for (const i of order)
|
|
554
|
+
sorted.push(diagnostics[i]);
|
|
555
|
+
return sorted;
|
|
556
|
+
}
|
|
489
557
|
function equalChain(a, b) {
|
|
490
558
|
if (a.length !== b.length)
|
|
491
559
|
return false;
|
|
@@ -567,13 +635,27 @@ function formatDiagnosticIn(diagnostic, fileName, options) {
|
|
|
567
635
|
result += `${categoryName(diagnostic.category)} TS${diagnostic.code}: `;
|
|
568
636
|
return result + flattenDiagnosticMessage(diagnostic, options.newLine, options.locale) + options.newLine;
|
|
569
637
|
}
|
|
638
|
+
/**
|
|
639
|
+
* The plain format the main thread reports a compilation's diagnostics in (`DiagnosticReporter.plainFormat`),
|
|
640
|
+
* which its checker threads receive a copy of and format the diagnostics they send back in
|
|
641
|
+
* (`Diagnostic.formatted`). Unset where diagnostics are reported with color and context, or not at all.
|
|
642
|
+
*/
|
|
643
|
+
export class FormattedReports {
|
|
644
|
+
format = undefined;
|
|
645
|
+
}
|
|
646
|
+
export const formattedReports = new FormattedReports();
|
|
570
647
|
/** `formatDiagnostic` of each diagnostic. */
|
|
571
648
|
export function formatDiagnostics(diagnostics, options) {
|
|
572
649
|
let result = '';
|
|
650
|
+
const formatted = options === formattedReports.format;
|
|
573
651
|
// Sorted diagnostics come a file at a time: the relative name of the last file is kept.
|
|
574
652
|
let lastFile = undefined;
|
|
575
653
|
let lastName = '';
|
|
576
654
|
for (const diagnostic of diagnostics) {
|
|
655
|
+
if (formatted && diagnostic.formatted !== '') {
|
|
656
|
+
result += diagnostic.formatted;
|
|
657
|
+
continue;
|
|
658
|
+
}
|
|
577
659
|
const file = diagnostic.file;
|
|
578
660
|
if (file !== undefined && file !== lastFile) {
|
|
579
661
|
lastFile = file;
|
|
@@ -95,10 +95,10 @@ export declare class LoadedFile {
|
|
|
95
95
|
readonly references: LoadedReference[];
|
|
96
96
|
readonly resolutionsInFile: ModeAwareCache<ResolvedModule> | undefined;
|
|
97
97
|
readonly typeResolutionsInFile: ModeAwareCache<ResolvedTypeReferenceDirective> | undefined;
|
|
98
|
-
readonly processingDiagnostics: ProcessingDiagnostic[];
|
|
98
|
+
readonly processingDiagnostics: readonly ProcessingDiagnostic[];
|
|
99
99
|
readonly importHelpersImportSpecifier: StringLiteral | undefined;
|
|
100
100
|
readonly jsxRuntimeImport: JsxRuntimeImport | undefined;
|
|
101
|
-
constructor(file: SourceFile, isLibFile: boolean, metadata: SourceFileMetadata, references: LoadedReference[], resolutionsInFile: ModeAwareCache<ResolvedModule> | undefined, typeResolutionsInFile: ModeAwareCache<ResolvedTypeReferenceDirective> | undefined, processingDiagnostics: ProcessingDiagnostic[], importHelpersImportSpecifier: StringLiteral | undefined, jsxRuntimeImport: JsxRuntimeImport | undefined);
|
|
101
|
+
constructor(file: SourceFile, isLibFile: boolean, metadata: SourceFileMetadata, references: LoadedReference[], resolutionsInFile: ModeAwareCache<ResolvedModule> | undefined, typeResolutionsInFile: ModeAwareCache<ResolvedTypeReferenceDirective> | undefined, processingDiagnostics: readonly ProcessingDiagnostic[], importHelpersImportSpecifier: StringLiteral | undefined, jsxRuntimeImport: JsxRuntimeImport | undefined);
|
|
102
102
|
}
|
|
103
103
|
/** Referenced projects, and how their sources map to declaration outputs. */
|
|
104
104
|
export declare class ProjectReferenceMapper {
|
|
@@ -147,6 +147,11 @@ export declare class ProcessedFiles {
|
|
|
147
147
|
* threads (`preparedPackageJsonLookups`); `undefined` where they may miss some.
|
|
148
148
|
*/
|
|
149
149
|
readonly preparedPackageJsons: readonly PackageJsonLookup[] | undefined;
|
|
150
|
+
/**
|
|
151
|
+
* The files each file's imports and type reference directives added to the program, by index into
|
|
152
|
+
* `files`, without the file itself.
|
|
153
|
+
*/
|
|
154
|
+
readonly addedFiles: readonly (readonly number[])[];
|
|
150
155
|
constructor(resolver: Resolver,
|
|
151
156
|
/** Libraries first, sorted, then other files in load order. */
|
|
152
157
|
files: readonly SourceFile[], filesByPath: ReadonlyMap<string, SourceFile>, missingFiles: readonly string[], resolvedModules: ReadonlyMap<string, ModeAwareCache<ResolvedModule> | undefined>, typeResolutionsInFile: ReadonlyMap<string, ModeAwareCache<ResolvedTypeReferenceDirective> | undefined>, sourceFileMetadata: ReadonlyMap<string, SourceFileMetadata>, jsxRuntimeImports: ReadonlyMap<string, JsxRuntimeImport>, importHelpersImportSpecifiers: ReadonlyMap<string, StringLiteral>, libFiles: ReadonlyMap<string, LibFile>,
|
|
@@ -158,7 +163,12 @@ export declare class ProcessedFiles {
|
|
|
158
163
|
* The `package.json` lookups made resolving the files whose resolutions were taken from parse
|
|
159
164
|
* threads (`preparedPackageJsonLookups`); `undefined` where they may miss some.
|
|
160
165
|
*/
|
|
161
|
-
preparedPackageJsons: readonly PackageJsonLookup[] | undefined
|
|
166
|
+
preparedPackageJsons: readonly PackageJsonLookup[] | undefined,
|
|
167
|
+
/**
|
|
168
|
+
* The files each file's imports and type reference directives added to the program, by index into
|
|
169
|
+
* `files`, without the file itself.
|
|
170
|
+
*/
|
|
171
|
+
addedFiles: readonly (readonly number[])[]);
|
|
162
172
|
}
|
|
163
173
|
/** The files of `processed` with `file` in place of the file at its path, for `Program.updateFile`. */
|
|
164
174
|
export declare function withReplacedFile(processed: ProcessedFiles, file: SourceFile): ProcessedFiles;
|
|
@@ -165,6 +165,14 @@ class SubTasksAhead {
|
|
|
165
165
|
this.subTasks = subTasks;
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
|
+
/** Read in place of a task's lists it has not created. */
|
|
169
|
+
const noParseTasks = [];
|
|
170
|
+
const noTraces = [];
|
|
171
|
+
const noProcessingDiagnostics = [];
|
|
172
|
+
/**
|
|
173
|
+
* A file to load. Its lists are created on first use: most tasks never get sub-tasks, traces or processing
|
|
174
|
+
* diagnostics, and large programs create hundreds of thousands of tasks.
|
|
175
|
+
*/
|
|
168
176
|
class ParseTask {
|
|
169
177
|
normalizedFilePath;
|
|
170
178
|
libFile;
|
|
@@ -176,19 +184,21 @@ class ParseTask {
|
|
|
176
184
|
path = '';
|
|
177
185
|
file = undefined;
|
|
178
186
|
redirectedParseTask = undefined;
|
|
179
|
-
subTasks =
|
|
187
|
+
subTasks = undefined;
|
|
180
188
|
loaded = false;
|
|
181
189
|
startedSubTasks = false;
|
|
182
190
|
metadata = libFileMetadata;
|
|
183
191
|
resolutionsInFile = undefined;
|
|
184
|
-
resolutionsTrace =
|
|
192
|
+
resolutionsTrace = undefined;
|
|
185
193
|
typeResolutionsInFile = undefined;
|
|
186
|
-
typeResolutionsTrace =
|
|
187
|
-
processingDiagnostics =
|
|
194
|
+
typeResolutionsTrace = undefined;
|
|
195
|
+
processingDiagnostics = undefined;
|
|
188
196
|
importHelpersImportSpecifier = undefined;
|
|
189
197
|
jsxRuntimeImport = undefined;
|
|
190
198
|
/** The task of the same file name that was loaded instead of this one. */
|
|
191
199
|
loadedTask = undefined;
|
|
200
|
+
/** Whether an import or a type reference directive adds the file (`ProcessedFiles.addedFiles`). */
|
|
201
|
+
byImport;
|
|
192
202
|
constructor(normalizedFilePath, libFile, includeReason, isForAutomaticTypeDirective, increaseDepth,
|
|
193
203
|
/** A JavaScript file found in `node_modules`, loaded only within `maxNodeModuleJsDepth`. */
|
|
194
204
|
elideOnDepth, packageId) {
|
|
@@ -199,17 +209,37 @@ class ParseTask {
|
|
|
199
209
|
this.increaseDepth = increaseDepth;
|
|
200
210
|
this.elideOnDepth = elideOnDepth;
|
|
201
211
|
this.packageId = packageId;
|
|
212
|
+
const kind = includeReason !== undefined ? includeReason.kind : -1;
|
|
213
|
+
this.byImport = kind === 0 /* FileIncludeKind.Import */ || kind === 2 /* FileIncludeKind.TypeReferenceDirective */;
|
|
202
214
|
}
|
|
203
215
|
addSubTask(fileName, libFile, reason, increaseDepth, elideOnDepth, packageId) {
|
|
204
|
-
this.subTasks.push(new ParseTask(normalizePath(fileName), libFile, reason, false, increaseDepth, elideOnDepth, packageId));
|
|
216
|
+
(this.subTasks ??= []).push(new ParseTask(normalizePath(fileName), libFile, reason, false, increaseDepth, elideOnDepth, packageId));
|
|
217
|
+
}
|
|
218
|
+
addProcessingDiagnostic(diagnostic) {
|
|
219
|
+
(this.processingDiagnostics ??= []).push(diagnostic);
|
|
220
|
+
}
|
|
221
|
+
/** Where module resolution traces go under `--traceResolution`; undefined without it. */
|
|
222
|
+
moduleTraces(trace) {
|
|
223
|
+
return trace ? (this.resolutionsTrace ??= []) : undefined;
|
|
224
|
+
}
|
|
225
|
+
/** Where type reference resolution traces go under `--traceResolution`; undefined without it. */
|
|
226
|
+
typeTraces(trace) {
|
|
227
|
+
return trace ? (this.typeResolutionsTrace ??= []) : undefined;
|
|
205
228
|
}
|
|
206
229
|
}
|
|
230
|
+
const noData = [];
|
|
207
231
|
/** The tasks of one path, by file name casing. */
|
|
208
232
|
class ParseTaskData {
|
|
209
233
|
tasks = new Map();
|
|
210
234
|
lowestDepth = Number.MAX_SAFE_INTEGER;
|
|
211
235
|
startedSubTasks = false;
|
|
212
236
|
packageId = undefined;
|
|
237
|
+
/** The index of this path's file in the program's files, once collected; -1 for none. */
|
|
238
|
+
index = -1;
|
|
239
|
+
/** For a deduplicated package's path, the tasks of the copy kept (`collect`). */
|
|
240
|
+
keptCopy = undefined;
|
|
241
|
+
/** The paths the file's imports and type reference directives add, once collected. */
|
|
242
|
+
added = noData;
|
|
213
243
|
constructor(task) {
|
|
214
244
|
this.tasks.set(task.normalizedFilePath, task);
|
|
215
245
|
}
|
|
@@ -321,6 +351,7 @@ export class ProcessedFiles {
|
|
|
321
351
|
redirectFilesByPath;
|
|
322
352
|
projectReferenceMapper;
|
|
323
353
|
preparedPackageJsons;
|
|
354
|
+
addedFiles;
|
|
324
355
|
constructor(resolver,
|
|
325
356
|
/** Libraries first, sorted, then other files in load order. */
|
|
326
357
|
files, filesByPath, missingFiles, resolvedModules, typeResolutionsInFile, sourceFileMetadata, jsxRuntimeImports, importHelpersImportSpecifiers, libFiles,
|
|
@@ -332,7 +363,12 @@ export class ProcessedFiles {
|
|
|
332
363
|
* The `package.json` lookups made resolving the files whose resolutions were taken from parse
|
|
333
364
|
* threads (`preparedPackageJsonLookups`); `undefined` where they may miss some.
|
|
334
365
|
*/
|
|
335
|
-
preparedPackageJsons
|
|
366
|
+
preparedPackageJsons,
|
|
367
|
+
/**
|
|
368
|
+
* The files each file's imports and type reference directives added to the program, by index into
|
|
369
|
+
* `files`, without the file itself.
|
|
370
|
+
*/
|
|
371
|
+
addedFiles) {
|
|
336
372
|
this.resolver = resolver;
|
|
337
373
|
this.files = files;
|
|
338
374
|
this.filesByPath = filesByPath;
|
|
@@ -350,6 +386,7 @@ export class ProcessedFiles {
|
|
|
350
386
|
this.redirectFilesByPath = redirectFilesByPath;
|
|
351
387
|
this.projectReferenceMapper = projectReferenceMapper;
|
|
352
388
|
this.preparedPackageJsons = preparedPackageJsons;
|
|
389
|
+
this.addedFiles = addedFiles;
|
|
353
390
|
}
|
|
354
391
|
}
|
|
355
392
|
/** The files of `processed` with `file` in place of the file at its path, for `Program.updateFile`. */
|
|
@@ -358,7 +395,9 @@ export function withReplacedFile(processed, file) {
|
|
|
358
395
|
files[files.findIndex((f) => f.path === file.path)] = file;
|
|
359
396
|
const filesByPath = new Map(processed.filesByPath);
|
|
360
397
|
filesByPath.set(file.path, file);
|
|
361
|
-
return new ProcessedFiles(processed.resolver, files, filesByPath, processed.missingFiles, processed.resolvedModules, processed.typeResolutionsInFile, processed.sourceFileMetadata, processed.jsxRuntimeImports, processed.importHelpersImportSpecifiers, processed.libFiles, processed.sourceFilesFoundSearchingNodeModules, processed.includeProcessor.copy(file.path), processed.outputFileToProjectReferenceSource, processed.redirectTargets, processed.redirectFilesByPath, processed.projectReferenceMapper, processed.preparedPackageJsons
|
|
398
|
+
return new ProcessedFiles(processed.resolver, files, filesByPath, processed.missingFiles, processed.resolvedModules, processed.typeResolutionsInFile, processed.sourceFileMetadata, processed.jsxRuntimeImports, processed.importHelpersImportSpecifiers, processed.libFiles, processed.sourceFilesFoundSearchingNodeModules, processed.includeProcessor.copy(file.path), processed.outputFileToProjectReferenceSource, processed.redirectTargets, processed.redirectFilesByPath, processed.projectReferenceMapper, processed.preparedPackageJsons,
|
|
399
|
+
// The file has the same references (`canReplaceFile`), and keeps its index.
|
|
400
|
+
processed.addedFiles);
|
|
362
401
|
}
|
|
363
402
|
/** Whether `file` imports the `importHelpers` module (tslib) under `options`. */
|
|
364
403
|
export function needsImportHelpersImportSpecifier(file, options) {
|
|
@@ -640,7 +679,7 @@ export class FileLoader {
|
|
|
640
679
|
return undefined;
|
|
641
680
|
}
|
|
642
681
|
const references = [];
|
|
643
|
-
for (const sub of task.subTasks) {
|
|
682
|
+
for (const sub of task.subTasks ?? noParseTasks) {
|
|
644
683
|
references.push(new LoadedReference(sub.normalizedFilePath, sub.libFile !== undefined ? sub.libFile.name : '', sub.includeReason, sub.increaseDepth, sub.elideOnDepth, sub.packageId));
|
|
645
684
|
const subDepth = sub.increaseDepth ? depth + 1 : depth;
|
|
646
685
|
// `run` skips these.
|
|
@@ -655,7 +694,7 @@ export class FileLoader {
|
|
|
655
694
|
// Traces are reported in the program's order: such programs resolve on their own.
|
|
656
695
|
if (file === undefined || this.options.traceResolution === true)
|
|
657
696
|
return undefined;
|
|
658
|
-
return new LoadedFile(file, task.libFile !== undefined, task.metadata, references, task.resolutionsInFile, task.typeResolutionsInFile, task.processingDiagnostics, task.importHelpersImportSpecifier, task.jsxRuntimeImport);
|
|
697
|
+
return new LoadedFile(file, task.libFile !== undefined, task.metadata, references, task.resolutionsInFile, task.typeResolutionsInFile, task.processingDiagnostics ?? noProcessingDiagnostics, task.importHelpersImportSpecifier, task.jsxRuntimeImport);
|
|
659
698
|
}
|
|
660
699
|
// ---- Project references
|
|
661
700
|
loadProjectReferences() {
|
|
@@ -737,7 +776,7 @@ export class FileLoader {
|
|
|
737
776
|
return;
|
|
738
777
|
}
|
|
739
778
|
const task = new ParseTask(absolute, undefined, reason, false, false, false, undefined);
|
|
740
|
-
task.
|
|
779
|
+
task.addProcessingDiagnostic(ProcessingDiagnostic.explainingFileInclude('', reason, resolved.message, resolved.args));
|
|
741
780
|
this.rootTasks.push(task);
|
|
742
781
|
}
|
|
743
782
|
isSupportedExtension(canonicalFileName) {
|
|
@@ -888,7 +927,8 @@ export class FileLoader {
|
|
|
888
927
|
}
|
|
889
928
|
if (!taskByFileName.startedSubTasks && loadSubTasks) {
|
|
890
929
|
taskByFileName.startedSubTasks = true;
|
|
891
|
-
|
|
930
|
+
if (taskByFileName.subTasks !== undefined)
|
|
931
|
+
this.start(taskByFileName.subTasks, data.lowestDepth);
|
|
892
932
|
}
|
|
893
933
|
}
|
|
894
934
|
}
|
|
@@ -921,7 +961,7 @@ export class FileLoader {
|
|
|
921
961
|
if (hasExtension(task.normalizedFilePath) && this.options.allowNonTsExtensions !== true) {
|
|
922
962
|
const canonicalFileName = getCanonicalFileName(task.normalizedFilePath, fs.useCaseSensitiveFileNames);
|
|
923
963
|
if (!this.isSupportedExtension(canonicalFileName)) {
|
|
924
|
-
task.
|
|
964
|
+
task.addProcessingDiagnostic(hasJSFileExtension(canonicalFileName)
|
|
925
965
|
? ProcessingDiagnostic.explainingFileInclude('', task.includeReason, 1519 /* Diagnostics.File_0_is_a_JavaScript_file_Did_you_mean_to_enable_the_allowJs_option */, [task.normalizedFilePath])
|
|
926
966
|
: ProcessingDiagnostic.explainingFileInclude('', task.includeReason, 1230 /* Diagnostics.File_0_has_an_unsupported_extension_The_only_supported_extensions_are_1 */, [task.normalizedFilePath, this.supportedExtensionsList()]));
|
|
927
967
|
return;
|
|
@@ -955,7 +995,7 @@ export class FileLoader {
|
|
|
955
995
|
const reason = FileIncludeReason.reference(3 /* FileIncludeKind.LibReferenceDirective */, task.path, i, undefined);
|
|
956
996
|
const name = getLibFileName(file.libReferenceDirectives[i].fileName);
|
|
957
997
|
if (name === '') {
|
|
958
|
-
task.
|
|
998
|
+
task.addProcessingDiagnostic(ProcessingDiagnostic.unknownReference(reason));
|
|
959
999
|
continue;
|
|
960
1000
|
}
|
|
961
1001
|
const libFile = this.pathForLibFile(name);
|
|
@@ -975,7 +1015,7 @@ export class FileLoader {
|
|
|
975
1015
|
else
|
|
976
1016
|
task.subTasks = this.subTasksOf(loaded);
|
|
977
1017
|
for (const diagnostic of loaded.processingDiagnostics)
|
|
978
|
-
task.
|
|
1018
|
+
task.addProcessingDiagnostic(diagnostic.copy());
|
|
979
1019
|
task.resolutionsInFile = loaded.resolutionsInFile;
|
|
980
1020
|
task.typeResolutionsInFile = loaded.typeResolutionsInFile;
|
|
981
1021
|
task.importHelpersImportSpecifier = loaded.importHelpersImportSpecifier;
|
|
@@ -1002,7 +1042,7 @@ export class FileLoader {
|
|
|
1002
1042
|
const reason = FileIncludeReason.reference(1 /* FileIncludeKind.ReferenceFile */, this.toPath(containingFile), index, undefined);
|
|
1003
1043
|
const resolved = this.getSourceFileFromReference(normalizePath(referencedFileName), moduleName, containingFile, reason);
|
|
1004
1044
|
if (typeof resolved !== 'string') {
|
|
1005
|
-
task.
|
|
1045
|
+
task.addProcessingDiagnostic(ProcessingDiagnostic.explainingFileInclude('', reason, resolved.message, resolved.args));
|
|
1006
1046
|
return;
|
|
1007
1047
|
}
|
|
1008
1048
|
task.addSubTask(resolved, undefined, reason, false, false, undefined);
|
|
@@ -1020,14 +1060,14 @@ export class FileLoader {
|
|
|
1020
1060
|
const mode = reference.resolutionMode !== ModuleKind.None
|
|
1021
1061
|
? reference.resolutionMode
|
|
1022
1062
|
: getDefaultResolutionModeForFile(file.fileName, task.metadata, options);
|
|
1023
|
-
const resolved = this.resolver.resolveTypeReferenceDirective(reference.fileName, containingFile, mode, redirect?.resolved, task.
|
|
1063
|
+
const resolved = this.resolver.resolveTypeReferenceDirective(reference.fileName, containingFile, mode, redirect?.resolved, task.typeTraces(this.options.traceResolution === true));
|
|
1024
1064
|
resolutions.set(modeAwareKey(reference.fileName, mode), resolved);
|
|
1025
1065
|
const reason = FileIncludeReason.reference(2 /* FileIncludeKind.TypeReferenceDirective */, task.path, i, undefined);
|
|
1026
1066
|
if (resolved.resolvedFileName !== '') {
|
|
1027
1067
|
task.addSubTask(resolved.resolvedFileName, undefined, reason, resolved.isExternalLibraryImport, false, resolved.packageId);
|
|
1028
1068
|
}
|
|
1029
1069
|
else {
|
|
1030
|
-
task.
|
|
1070
|
+
task.addProcessingDiagnostic(ProcessingDiagnostic.unknownReference(reason));
|
|
1031
1071
|
}
|
|
1032
1072
|
}
|
|
1033
1073
|
task.typeResolutionsInFile = resolutions;
|
|
@@ -1039,13 +1079,13 @@ export class FileLoader {
|
|
|
1039
1079
|
const resolutions = new Map();
|
|
1040
1080
|
for (const name of names) {
|
|
1041
1081
|
// Resolved without a mode: CommonJS under node16/nodenext, `import` conditions under bundler.
|
|
1042
|
-
const resolved = this.resolver.resolveTypeReferenceDirective(name, task.normalizedFilePath, ModuleKind.None, undefined, task.
|
|
1082
|
+
const resolved = this.resolver.resolveTypeReferenceDirective(name, task.normalizedFilePath, ModuleKind.None, undefined, task.typeTraces(this.options.traceResolution === true));
|
|
1043
1083
|
resolutions.set(modeAwareKey(name, ModuleKind.None), resolved);
|
|
1044
1084
|
if (resolved.resolvedFileName !== '') {
|
|
1045
1085
|
task.addSubTask(resolved.resolvedFileName, undefined, FileIncludeReason.automaticTypeDirective(name, resolved.packageId), resolved.isExternalLibraryImport, false, resolved.packageId);
|
|
1046
1086
|
}
|
|
1047
1087
|
else {
|
|
1048
|
-
task.
|
|
1088
|
+
task.addProcessingDiagnostic(ProcessingDiagnostic.explainingFileInclude('', FileIncludeReason.automaticTypeDirective(name, undefined), 821 /* Diagnostics.Cannot_find_type_definition_file_for_0 */, [name]));
|
|
1049
1089
|
}
|
|
1050
1090
|
}
|
|
1051
1091
|
task.typeResolutionsInFile = resolutions;
|
|
@@ -1083,7 +1123,7 @@ export class FileLoader {
|
|
|
1083
1123
|
if (moduleName === '')
|
|
1084
1124
|
continue;
|
|
1085
1125
|
const mode = getModeForUsageLocation(file.fileName, task.metadata, entry, options);
|
|
1086
|
-
const resolved = this.resolver.resolveModuleName(moduleName, containingFile, mode, redirect?.resolved, task.
|
|
1126
|
+
const resolved = this.resolver.resolveModuleName(moduleName, containingFile, mode, redirect?.resolved, task.moduleTraces(this.options.traceResolution === true));
|
|
1087
1127
|
resolutions.set(modeAwareKey(moduleName, mode), resolved);
|
|
1088
1128
|
const resolvedFileName = resolved.resolvedFileName;
|
|
1089
1129
|
if (resolvedFileName === '')
|
|
@@ -1134,9 +1174,16 @@ export class FileLoader {
|
|
|
1134
1174
|
const packageIdToSourceFile = new Map();
|
|
1135
1175
|
const checkCasing = this.options.forceConsistentCasingInFileNames !== false;
|
|
1136
1176
|
const seen = new Map();
|
|
1137
|
-
|
|
1177
|
+
// The paths each file's imports and type reference directives add (the tasks of each path), for
|
|
1178
|
+
// `ProcessedFiles.addedFiles`: recorded while collecting visits them, as their files are only known
|
|
1179
|
+
// once every file is collected.
|
|
1180
|
+
const fileData = [];
|
|
1181
|
+
const libData = new Map();
|
|
1182
|
+
const packageIdToData = new Map();
|
|
1183
|
+
const collectFiles = (tasks, added) => {
|
|
1138
1184
|
for (let task of tasks) {
|
|
1139
1185
|
const includeReason = task.includeReason;
|
|
1186
|
+
const byImport = task.byImport;
|
|
1140
1187
|
// Automatic type directive tasks are an implementation detail, not a reason.
|
|
1141
1188
|
if (task.redirectedParseTask === undefined && !task.isForAutomaticTypeDirective) {
|
|
1142
1189
|
if (task.loadedTask !== undefined)
|
|
@@ -1145,6 +1192,8 @@ export class FileLoader {
|
|
|
1145
1192
|
addIncludeReason(includeProcessor, task, includeReason);
|
|
1146
1193
|
}
|
|
1147
1194
|
const data = this.taskDataByPath.get(task.path);
|
|
1195
|
+
if (added !== undefined && data !== undefined && byImport)
|
|
1196
|
+
added.push(data);
|
|
1148
1197
|
if (!task.loaded || data === undefined)
|
|
1149
1198
|
continue;
|
|
1150
1199
|
const checkedName = seen.get(data);
|
|
@@ -1169,9 +1218,9 @@ export class FileLoader {
|
|
|
1169
1218
|
tasksSeenByNameIgnoreCase.set(lowerCasePath, task);
|
|
1170
1219
|
}
|
|
1171
1220
|
}
|
|
1172
|
-
for (const trace of task.typeResolutionsTrace)
|
|
1221
|
+
for (const trace of task.typeResolutionsTrace ?? noTraces)
|
|
1173
1222
|
host.trace(trace);
|
|
1174
|
-
for (const trace of task.resolutionsTrace)
|
|
1223
|
+
for (const trace of task.resolutionsTrace ?? noTraces)
|
|
1175
1224
|
host.trace(trace);
|
|
1176
1225
|
const file = task.file;
|
|
1177
1226
|
const packageId = data.packageId;
|
|
@@ -1186,15 +1235,19 @@ export class FileLoader {
|
|
|
1186
1235
|
targets.push(task.normalizedFilePath);
|
|
1187
1236
|
redirectFilesByPath.set(task.path, new RedirectFile(files.length + redirectFilesByPath.size, task.normalizedFilePath, task.path, packageIdFile.path));
|
|
1188
1237
|
filesByPath.set(task.path, packageIdFile);
|
|
1238
|
+
data.keptCopy = packageIdToData.get(key);
|
|
1189
1239
|
if (data.lowestDepth > 0)
|
|
1190
1240
|
sourceFilesFoundSearchingNodeModules.add(task.path);
|
|
1191
1241
|
continue;
|
|
1192
1242
|
}
|
|
1193
|
-
if (file !== undefined)
|
|
1243
|
+
if (file !== undefined) {
|
|
1194
1244
|
packageIdToSourceFile.set(key, file);
|
|
1245
|
+
packageIdToData.set(key, data);
|
|
1246
|
+
}
|
|
1195
1247
|
}
|
|
1196
|
-
|
|
1197
|
-
|
|
1248
|
+
let own = undefined;
|
|
1249
|
+
if (task.subTasks !== undefined && task.subTasks.length > 0)
|
|
1250
|
+
collectFiles(task.subTasks, (own = []));
|
|
1198
1251
|
const redirected = task.redirectedParseTask;
|
|
1199
1252
|
if (redirected !== undefined) {
|
|
1200
1253
|
outputFileToProjectReferenceSource.set(redirected.path, task.normalizedFilePath);
|
|
@@ -1202,12 +1255,12 @@ export class FileLoader {
|
|
|
1202
1255
|
}
|
|
1203
1256
|
if (task.isForAutomaticTypeDirective) {
|
|
1204
1257
|
typeResolutionsInFile.set(task.path, task.typeResolutionsInFile);
|
|
1205
|
-
for (const diagnostic of task.processingDiagnostics)
|
|
1258
|
+
for (const diagnostic of task.processingDiagnostics ?? noProcessingDiagnostics)
|
|
1206
1259
|
includeProcessor.addProcessingDiagnostic(diagnostic);
|
|
1207
1260
|
continue;
|
|
1208
1261
|
}
|
|
1209
1262
|
const path = task.path;
|
|
1210
|
-
for (const diagnostic of task.processingDiagnostics)
|
|
1263
|
+
for (const diagnostic of task.processingDiagnostics ?? noProcessingDiagnostics)
|
|
1211
1264
|
includeProcessor.addProcessingDiagnostic(diagnostic);
|
|
1212
1265
|
if (file === undefined) {
|
|
1213
1266
|
missingFiles.push(task.normalizedFilePath);
|
|
@@ -1215,11 +1268,15 @@ export class FileLoader {
|
|
|
1215
1268
|
}
|
|
1216
1269
|
if (task.libFile !== undefined) {
|
|
1217
1270
|
libFiles.push(file);
|
|
1271
|
+
libData.set(file, data);
|
|
1218
1272
|
libFilesByPath.set(path, task.libFile);
|
|
1219
1273
|
}
|
|
1220
1274
|
else {
|
|
1221
1275
|
files.push(file);
|
|
1276
|
+
fileData.push(data);
|
|
1222
1277
|
}
|
|
1278
|
+
if (own !== undefined)
|
|
1279
|
+
data.added = own;
|
|
1223
1280
|
filesByPath.set(path, file);
|
|
1224
1281
|
resolvedModules.set(path, task.resolutionsInFile);
|
|
1225
1282
|
typeResolutionsInFile.set(path, task.typeResolutionsInFile);
|
|
@@ -1233,7 +1290,7 @@ export class FileLoader {
|
|
|
1233
1290
|
sourceFilesFoundSearchingNodeModules.add(path);
|
|
1234
1291
|
}
|
|
1235
1292
|
};
|
|
1236
|
-
collectFiles(this.rootTasks);
|
|
1293
|
+
collectFiles(this.rootTasks, undefined);
|
|
1237
1294
|
const priorities = new Map();
|
|
1238
1295
|
for (const file of libFiles)
|
|
1239
1296
|
priorities.set(file, this.libFilePriority(file));
|
|
@@ -1241,6 +1298,25 @@ export class FileLoader {
|
|
|
1241
1298
|
const allFiles = [...libFiles, ...files];
|
|
1242
1299
|
for (const redirect of redirectFilesByPath.values())
|
|
1243
1300
|
redirect.index += libFiles.length;
|
|
1301
|
+
// The files a file adds, without reading its resolutions again or looking up their paths.
|
|
1302
|
+
const dataOfFiles = [];
|
|
1303
|
+
for (const file of libFiles)
|
|
1304
|
+
dataOfFiles.push(libData.get(file));
|
|
1305
|
+
for (const data of fileData)
|
|
1306
|
+
dataOfFiles.push(data);
|
|
1307
|
+
for (let i = 0; i < dataOfFiles.length; i++)
|
|
1308
|
+
dataOfFiles[i].index = i;
|
|
1309
|
+
const addedFiles = [];
|
|
1310
|
+
for (let i = 0; i < dataOfFiles.length; i++) {
|
|
1311
|
+
const added = [];
|
|
1312
|
+
for (const data of dataOfFiles[i].added) {
|
|
1313
|
+
const kept = data.keptCopy;
|
|
1314
|
+
const k = kept !== undefined ? kept.index : data.index;
|
|
1315
|
+
if (k >= 0 && k !== i)
|
|
1316
|
+
added.push(k);
|
|
1317
|
+
}
|
|
1318
|
+
addedFiles.push(added);
|
|
1319
|
+
}
|
|
1244
1320
|
const keys = [...this.libResolutions.keys()].sort();
|
|
1245
1321
|
for (const key of keys) {
|
|
1246
1322
|
const resolution = this.libResolutions.get(key);
|
|
@@ -1252,7 +1328,7 @@ export class FileLoader {
|
|
|
1252
1328
|
for (const trace of resolution.trace)
|
|
1253
1329
|
host.trace(trace);
|
|
1254
1330
|
}
|
|
1255
|
-
return new ProcessedFiles(this.resolver, allFiles, filesByPath, missingFiles, resolvedModules, typeResolutionsInFile, sourceFileMetadata, jsxRuntimeImports, importHelpersImportSpecifiers, libFilesByPath, sourceFilesFoundSearchingNodeModules, includeProcessor, outputFileToProjectReferenceSource, redirectTargets, redirectFilesByPath, this.mapper, this.tookPreparedResolutions ? preparedPackageJsonLookups() : noPackageJsonLookups);
|
|
1331
|
+
return new ProcessedFiles(this.resolver, allFiles, filesByPath, missingFiles, resolvedModules, typeResolutionsInFile, sourceFileMetadata, jsxRuntimeImports, importHelpersImportSpecifiers, libFilesByPath, sourceFilesFoundSearchingNodeModules, includeProcessor, outputFileToProjectReferenceSource, redirectTargets, redirectFilesByPath, this.mapper, this.tookPreparedResolutions ? preparedPackageJsonLookups() : noPackageJsonLookups, addedFiles);
|
|
1256
1332
|
}
|
|
1257
1333
|
}
|
|
1258
1334
|
const noPackageJsonLookups = [];
|
|
@@ -58,6 +58,13 @@ export declare class ClusteredIntLinkTable {
|
|
|
58
58
|
set(id: number, value: number): void;
|
|
59
59
|
private pageOf;
|
|
60
60
|
}
|
|
61
|
+
/** Ids in pages of `IdSetPaging.Ids` ids, one bit each; a page is created by the first id added to it. */
|
|
62
|
+
export declare class PagedIdSet {
|
|
63
|
+
readonly pages: (Int32Array | undefined)[];
|
|
64
|
+
has(id: number): boolean;
|
|
65
|
+
add(id: number): void;
|
|
66
|
+
clear(): void;
|
|
67
|
+
}
|
|
61
68
|
/**
|
|
62
69
|
* A page of a `CompactSymbolLinkTable`: one bit per id of the page in eight 32-id words, the number
|
|
63
70
|
* of symbols stored before each word, and the symbols in id order. The words are fields, so a
|
|
@@ -146,6 +146,28 @@ export class ClusteredIntLinkTable {
|
|
|
146
146
|
return this.lastPage;
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
|
+
/** Ids in pages of `IdSetPaging.Ids` ids, one bit each; a page is created by the first id added to it. */
|
|
150
|
+
export class PagedIdSet {
|
|
151
|
+
pages = [];
|
|
152
|
+
has(id) {
|
|
153
|
+
const page = this.pages[id >> 13 /* IdSetPaging.Bits */];
|
|
154
|
+
return page !== undefined && (page[(id >> 5) & 255 /* IdSetPaging.WordMask */] & (1 << (id & 31))) !== 0;
|
|
155
|
+
}
|
|
156
|
+
add(id) {
|
|
157
|
+
const index = id >> 13 /* IdSetPaging.Bits */;
|
|
158
|
+
let page = this.pages[index];
|
|
159
|
+
if (page === undefined) {
|
|
160
|
+
while (this.pages.length <= index)
|
|
161
|
+
this.pages.push(undefined);
|
|
162
|
+
page = new Int32Array(256 /* IdSetPaging.Words */);
|
|
163
|
+
this.pages[index] = page;
|
|
164
|
+
}
|
|
165
|
+
page[(id >> 5) & 255 /* IdSetPaging.WordMask */] |= 1 << (id & 31);
|
|
166
|
+
}
|
|
167
|
+
clear() {
|
|
168
|
+
this.pages.length = 0;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
149
171
|
/** The number of set bits of a 32-bit value. */
|
|
150
172
|
function bitCount(x) {
|
|
151
173
|
x = x - ((x >>> 1) & 0x55555555);
|
|
@@ -128,7 +128,7 @@ export declare function fileSize(fileName: string): number;
|
|
|
128
128
|
* Then, for the same reason, large files, one per chunk: root files (TypeScript's 3 MB `checker.ts`,
|
|
129
129
|
* which in a chunk of root files kept one thread busy after the others were done) and the files the
|
|
130
130
|
* parse threads found (`csstype`'s 0.9 MB of declarations, found through React's). The other files go
|
|
131
|
-
* out in program order, in chunks of up to `maxChunk
|
|
131
|
+
* out in program order, in chunks of up to `maxChunk` files and about `maxChunkBytes` of text.
|
|
132
132
|
*/
|
|
133
133
|
export declare class ParseQueue {
|
|
134
134
|
private readonly libraries;
|
|
@@ -148,7 +148,8 @@ export declare class ParseQueue {
|
|
|
148
148
|
left(): number;
|
|
149
149
|
/**
|
|
150
150
|
* The next chunk for one of `threads` parse threads, or `undefined` when nothing is left. With
|
|
151
|
-
* `full`, other files only go out `maxChunk`
|
|
151
|
+
* `full`, other files only go out in full chunks, `maxChunk` files or `maxChunkBytes` of text, and stay
|
|
152
|
+
* queued until there are as many.
|
|
152
153
|
*/
|
|
153
154
|
next(threads: number, full?: boolean): LoadMessage | undefined;
|
|
154
155
|
}
|
|
@@ -187,6 +187,12 @@ export function fileSize(fileName) {
|
|
|
187
187
|
const maxChunk = 16;
|
|
188
188
|
/** Files from this size (bytes) on take a parse thread 25 ms or more, and go out ahead of others. */
|
|
189
189
|
const largeFile = 256 * 1024;
|
|
190
|
+
/**
|
|
191
|
+
* The most text (bytes) a chunk of other files holds, about one large file's: a chunk ends with the file
|
|
192
|
+
* that reaches it. Sixteen of tsc-ts's own compiler sources, 50-200 KB each, made one chunk that kept its
|
|
193
|
+
* thread busy for 30-45 ms after the others were done.
|
|
194
|
+
*/
|
|
195
|
+
const maxChunkBytes = largeFile;
|
|
190
196
|
/**
|
|
191
197
|
* The files to hand out to parse threads, each queued once. Library files go out first, one per
|
|
192
198
|
* chunk, also those found later through `/// <reference lib>`: a large one (`lib.dom.d.ts`) takes a
|
|
@@ -194,7 +200,7 @@ const largeFile = 256 * 1024;
|
|
|
194
200
|
* Then, for the same reason, large files, one per chunk: root files (TypeScript's 3 MB `checker.ts`,
|
|
195
201
|
* which in a chunk of root files kept one thread busy after the others were done) and the files the
|
|
196
202
|
* parse threads found (`csstype`'s 0.9 MB of declarations, found through React's). The other files go
|
|
197
|
-
* out in program order, in chunks of up to `maxChunk
|
|
203
|
+
* out in program order, in chunks of up to `maxChunk` files and about `maxChunkBytes` of text.
|
|
198
204
|
*/
|
|
199
205
|
export class ParseQueue {
|
|
200
206
|
libraries = new LoadJobs();
|
|
@@ -238,7 +244,8 @@ export class ParseQueue {
|
|
|
238
244
|
}
|
|
239
245
|
/**
|
|
240
246
|
* The next chunk for one of `threads` parse threads, or `undefined` when nothing is left. With
|
|
241
|
-
* `full`, other files only go out `maxChunk`
|
|
247
|
+
* `full`, other files only go out in full chunks, `maxChunk` files or `maxChunkBytes` of text, and stay
|
|
248
|
+
* queued until there are as many.
|
|
242
249
|
*/
|
|
243
250
|
next(threads, full = false) {
|
|
244
251
|
const libraries = this.libraries;
|
|
@@ -263,11 +270,16 @@ export class ParseQueue {
|
|
|
263
270
|
}
|
|
264
271
|
const queue = this.others;
|
|
265
272
|
const left = queue.names.length - this.head;
|
|
266
|
-
if (left <= 0
|
|
273
|
+
if (left <= 0)
|
|
267
274
|
return undefined;
|
|
268
|
-
const
|
|
275
|
+
const most = full ? maxChunk : Math.min(maxChunk, Math.max(1, Math.floor(left / threads)));
|
|
269
276
|
const start = this.head;
|
|
270
|
-
|
|
277
|
+
let end = start;
|
|
278
|
+
let bytes = 0;
|
|
279
|
+
while (end < queue.names.length && end - start < most && bytes < maxChunkBytes)
|
|
280
|
+
bytes += queue.sizes[end++];
|
|
281
|
+
if (full && end - start < maxChunk && bytes < maxChunkBytes)
|
|
282
|
+
return undefined;
|
|
271
283
|
this.head = end;
|
|
272
284
|
return {
|
|
273
285
|
stop: false,
|