tsc-ts 0.0.7 → 0.0.9

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.
Files changed (39) hide show
  1. package/README.md +1 -1
  2. package/dist/api/compiler/checker-declaration-order.js +3 -2
  3. package/dist/api/compiler/checker-declared-types.js +6 -3
  4. package/dist/api/compiler/checker-deprecation.js +14 -13
  5. package/dist/api/compiler/checker-destructuring.js +3 -2
  6. package/dist/api/compiler/checker-members.js +6 -2
  7. package/dist/api/compiler/checker-source-file.d.ts +12 -0
  8. package/dist/api/compiler/checker-source-file.js +35 -0
  9. package/dist/api/compiler/checker-symbol-types.js +5 -5
  10. package/dist/api/compiler/checker-symbols.js +5 -2
  11. package/dist/api/compiler/checker.d.ts +6 -1
  12. package/dist/api/compiler/checker.js +9 -1
  13. package/dist/api/compiler/file-loader.d.ts +2 -2
  14. package/dist/api/compiler/file-loader.js +43 -23
  15. package/dist/api/compiler/link-tables.d.ts +7 -0
  16. package/dist/api/compiler/link-tables.js +22 -0
  17. package/dist/api/compiler/parser.d.ts +7 -0
  18. package/dist/api/compiler/parser.js +55 -32
  19. package/dist/api/compiler/program-checker.d.ts +18 -0
  20. package/dist/api/compiler/program-checker.js +35 -2
  21. package/dist/api/library/diagnostics.d.ts +10 -0
  22. package/dist/api/library/diagnostics.js +20 -0
  23. package/package.json +9 -9
  24. package/src/compiler/checker-declaration-order.ts +3 -2
  25. package/src/compiler/checker-declared-types.ts +6 -3
  26. package/src/compiler/checker-deprecation.ts +13 -11
  27. package/src/compiler/checker-destructuring.ts +11 -2
  28. package/src/compiler/checker-members.ts +6 -2
  29. package/src/compiler/checker-source-file.ts +34 -0
  30. package/src/compiler/checker-symbol-types.ts +14 -4
  31. package/src/compiler/checker-symbols.ts +6 -2
  32. package/src/compiler/checker.ts +8 -1
  33. package/src/compiler/file-loader.ts +49 -24
  34. package/src/compiler/link-tables.ts +32 -0
  35. package/src/compiler/parallel-check.ts +199 -20
  36. package/src/compiler/parser.ts +55 -32
  37. package/src/compiler/program-checker.ts +36 -2
  38. package/src/compiler/thread-entry.ts +16 -1
  39. package/src/library/diagnostics.ts +23 -0
@@ -33,7 +33,7 @@ import type { DeferredCollisionCheck } from './checker-generated-code.js';
33
33
  import type { EmitHelperFileLinks } from './checker-emit-helpers.js';
34
34
  import { sideOf } from './side-state.js';
35
35
  import type { Node, PatternAmbientModule, SourceFile } from './ast.js';
36
- import { CompactSymbolLinkTable, IntLinkTable, LinkTable, SparseLinkTable } from './link-tables.js';
36
+ import { CompactSymbolLinkTable, IntLinkTable, LinkTable, PagedIdSet, SparseLinkTable } from './link-tables.js';
37
37
  import { getErrorRangeForNode, getSourceFileOfNode } from './binder-utilities.js';
38
38
  import { Diagnostic, type DiagnosticMessage, Diagnostics, compareDiagnostics } from './diagnostics.js';
39
39
  import {
@@ -402,6 +402,11 @@ export class Checker implements TypeChecking {
402
402
  readonly resolvedSignatures = new SparseLinkTable<Signature>();
403
403
  /** Merged symbols, indexed by the id of the symbol merged into them. */
404
404
  readonly mergedSymbols: Map<number, Symbol>;
405
+ /**
406
+ * The ids that `mergedSymbols` has, or had: most symbols are merged into none, and `getMergedSymbol`
407
+ * finds that here without probing the map.
408
+ */
409
+ readonly mergedSymbolIds = new PagedIdSet();
405
410
  /** Globals merged from the default libraries, shared with other checkers. */
406
411
  libGlobals: LibGlobals | undefined;
407
412
  /** The program's globals and module augmentations as another checker merged them, shared with it. */
@@ -746,6 +751,7 @@ export class Checker implements TypeChecking {
746
751
  this.globals = libs.copyGlobals();
747
752
  this.mergedSymbols = libs.copyMergedSymbols();
748
753
  }
754
+ for (const id of this.mergedSymbols.keys()) this.mergedSymbolIds.add(id);
749
755
  this.globalThisSymbol = this.newSymbol(SymbolFlags.Module, 'globalThis');
750
756
  this.globalThisSymbol.checkFlags = CheckFlags.Readonly;
751
757
  this.globalThisSymbol.exports = this.globals;
@@ -1087,6 +1093,7 @@ export function disposeChecker(c: Checker): void {
1087
1093
  c.mergedSymbols.clear();
1088
1094
  c.globals.clear();
1089
1095
  }
1096
+ c.mergedSymbolIds.clear();
1090
1097
  c.sharedSymbolCopies.clear();
1091
1098
  c.memberPositionsInLists.clear();
1092
1099
  c.memberNamesOfLists.clear();
@@ -216,7 +216,7 @@ export class LoadedFile {
216
216
  readonly references: LoadedReference[],
217
217
  readonly resolutionsInFile: ModeAwareCache<ResolvedModule> | undefined,
218
218
  readonly typeResolutionsInFile: ModeAwareCache<ResolvedTypeReferenceDirective> | undefined,
219
- readonly processingDiagnostics: ProcessingDiagnostic[],
219
+ readonly processingDiagnostics: readonly ProcessingDiagnostic[],
220
220
  readonly importHelpersImportSpecifier: StringLiteral | undefined,
221
221
  readonly jsxRuntimeImport: JsxRuntimeImport | undefined,
222
222
  ) {}
@@ -230,19 +230,28 @@ class SubTasksAhead {
230
230
  ) {}
231
231
  }
232
232
 
233
+ /** Read in place of a task's lists it has not created. */
234
+ const noParseTasks: readonly ParseTask[] = [];
235
+ const noTraces: readonly MessageWithArgs[] = [];
236
+ const noProcessingDiagnostics: readonly ProcessingDiagnostic[] = [];
237
+
238
+ /**
239
+ * A file to load. Its lists are created on first use: most tasks never get sub-tasks, traces or processing
240
+ * diagnostics, and large programs create hundreds of thousands of tasks.
241
+ */
233
242
  class ParseTask {
234
243
  path = '';
235
244
  file: SourceFile | undefined = undefined;
236
245
  redirectedParseTask: ParseTask | undefined = undefined;
237
- subTasks: ParseTask[] = [];
246
+ subTasks: ParseTask[] | undefined = undefined;
238
247
  loaded = false;
239
248
  startedSubTasks = false;
240
249
  metadata: SourceFileMetadata = libFileMetadata;
241
250
  resolutionsInFile: ModeAwareCache<ResolvedModule> | undefined = undefined;
242
- readonly resolutionsTrace: MessageWithArgs[] = [];
251
+ resolutionsTrace: MessageWithArgs[] | undefined = undefined;
243
252
  typeResolutionsInFile: ModeAwareCache<ResolvedTypeReferenceDirective> | undefined = undefined;
244
- readonly typeResolutionsTrace: MessageWithArgs[] = [];
245
- readonly processingDiagnostics: ProcessingDiagnostic[] = [];
253
+ typeResolutionsTrace: MessageWithArgs[] | undefined = undefined;
254
+ processingDiagnostics: ProcessingDiagnostic[] | undefined = undefined;
246
255
  importHelpersImportSpecifier: StringLiteral | undefined = undefined;
247
256
  jsxRuntimeImport: JsxRuntimeImport | undefined = undefined;
248
257
  /** The task of the same file name that was loaded instead of this one. */
@@ -267,10 +276,24 @@ class ParseTask {
267
276
  elideOnDepth: boolean,
268
277
  packageId: PackageId | undefined,
269
278
  ): void {
270
- this.subTasks.push(
279
+ (this.subTasks ??= []).push(
271
280
  new ParseTask(normalizePath(fileName), libFile, reason, false, increaseDepth, elideOnDepth, packageId),
272
281
  );
273
282
  }
283
+
284
+ addProcessingDiagnostic(diagnostic: ProcessingDiagnostic): void {
285
+ (this.processingDiagnostics ??= []).push(diagnostic);
286
+ }
287
+
288
+ /** Where module resolution traces go under `--traceResolution`; undefined without it. */
289
+ moduleTraces(trace: boolean): MessageWithArgs[] | undefined {
290
+ return trace ? (this.resolutionsTrace ??= []) : undefined;
291
+ }
292
+
293
+ /** Where type reference resolution traces go under `--traceResolution`; undefined without it. */
294
+ typeTraces(trace: boolean): MessageWithArgs[] | undefined {
295
+ return trace ? (this.typeResolutionsTrace ??= []) : undefined;
296
+ }
274
297
  }
275
298
 
276
299
  /** The tasks of one path, by file name casing. */
@@ -742,7 +765,7 @@ export class FileLoader {
742
765
  return undefined;
743
766
  }
744
767
  const references: LoadedReference[] = [];
745
- for (const sub of task.subTasks) {
768
+ for (const sub of task.subTasks ?? noParseTasks) {
746
769
  references.push(
747
770
  new LoadedReference(
748
771
  sub.normalizedFilePath,
@@ -769,7 +792,7 @@ export class FileLoader {
769
792
  references,
770
793
  task.resolutionsInFile,
771
794
  task.typeResolutionsInFile,
772
- task.processingDiagnostics,
795
+ task.processingDiagnostics ?? noProcessingDiagnostics,
773
796
  task.importHelpersImportSpecifier,
774
797
  task.jsxRuntimeImport,
775
798
  );
@@ -857,7 +880,7 @@ export class FileLoader {
857
880
  return;
858
881
  }
859
882
  const task = new ParseTask(absolute, undefined, reason, false, false, false, undefined);
860
- task.processingDiagnostics.push(
883
+ task.addProcessingDiagnostic(
861
884
  ProcessingDiagnostic.explainingFileInclude('', reason, resolved.message, resolved.args),
862
885
  );
863
886
  this.rootTasks.push(task);
@@ -1031,7 +1054,7 @@ export class FileLoader {
1031
1054
  }
1032
1055
  if (!taskByFileName.startedSubTasks && loadSubTasks) {
1033
1056
  taskByFileName.startedSubTasks = true;
1034
- this.start(taskByFileName.subTasks, data.lowestDepth);
1057
+ if (taskByFileName.subTasks !== undefined) this.start(taskByFileName.subTasks, data.lowestDepth);
1035
1058
  }
1036
1059
  }
1037
1060
  }
@@ -1073,7 +1096,7 @@ export class FileLoader {
1073
1096
  if (hasExtension(task.normalizedFilePath) && this.options.allowNonTsExtensions !== true) {
1074
1097
  const canonicalFileName = getCanonicalFileName(task.normalizedFilePath, fs.useCaseSensitiveFileNames);
1075
1098
  if (!this.isSupportedExtension(canonicalFileName)) {
1076
- task.processingDiagnostics.push(
1099
+ task.addProcessingDiagnostic(
1077
1100
  hasJSFileExtension(canonicalFileName)
1078
1101
  ? ProcessingDiagnostic.explainingFileInclude(
1079
1102
  '',
@@ -1122,7 +1145,7 @@ export class FileLoader {
1122
1145
  const reason = FileIncludeReason.reference(FileIncludeKind.LibReferenceDirective, task.path, i, undefined);
1123
1146
  const name = getLibFileName(file.libReferenceDirectives[i].fileName);
1124
1147
  if (name === '') {
1125
- task.processingDiagnostics.push(ProcessingDiagnostic.unknownReference(reason));
1148
+ task.addProcessingDiagnostic(ProcessingDiagnostic.unknownReference(reason));
1126
1149
  continue;
1127
1150
  }
1128
1151
  const libFile = this.pathForLibFile(name);
@@ -1140,7 +1163,7 @@ export class FileLoader {
1140
1163
  this.subTasksAhead.delete(task.normalizedFilePath);
1141
1164
  task.subTasks = ahead.subTasks;
1142
1165
  } else task.subTasks = this.subTasksOf(loaded);
1143
- for (const diagnostic of loaded.processingDiagnostics) task.processingDiagnostics.push(diagnostic.copy());
1166
+ for (const diagnostic of loaded.processingDiagnostics) task.addProcessingDiagnostic(diagnostic.copy());
1144
1167
  task.resolutionsInFile = loaded.resolutionsInFile;
1145
1168
  task.typeResolutionsInFile = loaded.typeResolutionsInFile;
1146
1169
  task.importHelpersImportSpecifier = loaded.importHelpersImportSpecifier;
@@ -1190,7 +1213,7 @@ export class FileLoader {
1190
1213
  reason,
1191
1214
  );
1192
1215
  if (typeof resolved !== 'string') {
1193
- task.processingDiagnostics.push(
1216
+ task.addProcessingDiagnostic(
1194
1217
  ProcessingDiagnostic.explainingFileInclude('', reason, resolved.message, resolved.args),
1195
1218
  );
1196
1219
  return;
@@ -1216,7 +1239,7 @@ export class FileLoader {
1216
1239
  containingFile,
1217
1240
  mode,
1218
1241
  redirect?.resolved,
1219
- task.typeResolutionsTrace,
1242
+ task.typeTraces(this.options.traceResolution === true),
1220
1243
  );
1221
1244
  resolutions.set(modeAwareKey(reference.fileName, mode), resolved);
1222
1245
  const reason = FileIncludeReason.reference(FileIncludeKind.TypeReferenceDirective, task.path, i, undefined);
@@ -1230,7 +1253,7 @@ export class FileLoader {
1230
1253
  resolved.packageId,
1231
1254
  );
1232
1255
  } else {
1233
- task.processingDiagnostics.push(ProcessingDiagnostic.unknownReference(reason));
1256
+ task.addProcessingDiagnostic(ProcessingDiagnostic.unknownReference(reason));
1234
1257
  }
1235
1258
  }
1236
1259
  task.typeResolutionsInFile = resolutions;
@@ -1247,7 +1270,7 @@ export class FileLoader {
1247
1270
  task.normalizedFilePath,
1248
1271
  ModuleKind.None,
1249
1272
  undefined,
1250
- task.typeResolutionsTrace,
1273
+ task.typeTraces(this.options.traceResolution === true),
1251
1274
  );
1252
1275
  resolutions.set(modeAwareKey(name, ModuleKind.None), resolved);
1253
1276
  if (resolved.resolvedFileName !== '') {
@@ -1260,7 +1283,7 @@ export class FileLoader {
1260
1283
  resolved.packageId,
1261
1284
  );
1262
1285
  } else {
1263
- task.processingDiagnostics.push(
1286
+ task.addProcessingDiagnostic(
1264
1287
  ProcessingDiagnostic.explainingFileInclude(
1265
1288
  '',
1266
1289
  FileIncludeReason.automaticTypeDirective(name, undefined),
@@ -1308,7 +1331,7 @@ export class FileLoader {
1308
1331
  containingFile,
1309
1332
  mode,
1310
1333
  redirect?.resolved,
1311
- task.resolutionsTrace,
1334
+ task.moduleTraces(this.options.traceResolution === true),
1312
1335
  );
1313
1336
  resolutions.set(modeAwareKey(moduleName, mode), resolved);
1314
1337
  const resolvedFileName = resolved.resolvedFileName;
@@ -1412,8 +1435,8 @@ export class FileLoader {
1412
1435
  }
1413
1436
  }
1414
1437
 
1415
- for (const trace of task.typeResolutionsTrace) host.trace(trace);
1416
- for (const trace of task.resolutionsTrace) host.trace(trace);
1438
+ for (const trace of task.typeResolutionsTrace ?? noTraces) host.trace(trace);
1439
+ for (const trace of task.resolutionsTrace ?? noTraces) host.trace(trace);
1417
1440
 
1418
1441
  const file = task.file;
1419
1442
  const packageId = data.packageId;
@@ -1440,7 +1463,7 @@ export class FileLoader {
1440
1463
  if (file !== undefined) packageIdToSourceFile.set(key, file);
1441
1464
  }
1442
1465
 
1443
- if (task.subTasks.length > 0) collectFiles(task.subTasks);
1466
+ if (task.subTasks !== undefined && task.subTasks.length > 0) collectFiles(task.subTasks);
1444
1467
 
1445
1468
  const redirected = task.redirectedParseTask;
1446
1469
  if (redirected !== undefined) {
@@ -1449,11 +1472,13 @@ export class FileLoader {
1449
1472
  }
1450
1473
  if (task.isForAutomaticTypeDirective) {
1451
1474
  typeResolutionsInFile.set(task.path, task.typeResolutionsInFile);
1452
- for (const diagnostic of task.processingDiagnostics) includeProcessor.addProcessingDiagnostic(diagnostic);
1475
+ for (const diagnostic of task.processingDiagnostics ?? noProcessingDiagnostics)
1476
+ includeProcessor.addProcessingDiagnostic(diagnostic);
1453
1477
  continue;
1454
1478
  }
1455
1479
  const path = task.path;
1456
- for (const diagnostic of task.processingDiagnostics) includeProcessor.addProcessingDiagnostic(diagnostic);
1480
+ for (const diagnostic of task.processingDiagnostics ?? noProcessingDiagnostics)
1481
+ includeProcessor.addProcessingDiagnostic(diagnostic);
1457
1482
  if (file === undefined) {
1458
1483
  missingFiles.push(task.normalizedFilePath);
1459
1484
  continue;
@@ -169,6 +169,38 @@ export class ClusteredIntLinkTable {
169
169
  }
170
170
  }
171
171
 
172
+ /** Ids in pages of `IdSetPaging.Ids` ids, one bit each; a page is created by the first id added to it. */
173
+ export class PagedIdSet {
174
+ readonly pages: (Int32Array | undefined)[] = [];
175
+
176
+ has(id: number): boolean {
177
+ const page = this.pages[id >> IdSetPaging.Bits];
178
+ return page !== undefined && (page[(id >> 5) & IdSetPaging.WordMask]! & (1 << (id & 31))) !== 0;
179
+ }
180
+
181
+ add(id: number): void {
182
+ const index = id >> IdSetPaging.Bits;
183
+ let page = this.pages[index];
184
+ if (page === undefined) {
185
+ while (this.pages.length <= index) this.pages.push(undefined);
186
+ page = new Int32Array(IdSetPaging.Words);
187
+ this.pages[index] = page;
188
+ }
189
+ page[(id >> 5) & IdSetPaging.WordMask] |= 1 << (id & 31);
190
+ }
191
+
192
+ clear(): void {
193
+ this.pages.length = 0;
194
+ }
195
+ }
196
+
197
+ /** `PagedIdSet` pages: 8192 ids in 256 words. */
198
+ const enum IdSetPaging {
199
+ Bits = 13,
200
+ Words = 1 << (Bits - 5),
201
+ WordMask = Words - 1,
202
+ }
203
+
172
204
  /** The number of set bits of a 32-bit value. */
173
205
  function bitCount(x: number): number {
174
206
  x = x - ((x >>> 1) & 0x55555555);