tsc-ts 0.0.5 → 0.0.6

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 (171) hide show
  1. package/README.md +1 -1
  2. package/dist/api/compiler/ast.d.ts +10 -9
  3. package/dist/api/compiler/ast.js +22 -16
  4. package/dist/api/compiler/binder-utilities.js +2 -1
  5. package/dist/api/compiler/binder.js +9 -8
  6. package/dist/api/compiler/checker-calls.js +3 -2
  7. package/dist/api/compiler/checker-declaration-order.js +2 -1
  8. package/dist/api/compiler/checker-declarations.js +14 -14
  9. package/dist/api/compiler/checker-declared-types.d.ts +1 -1
  10. package/dist/api/compiler/checker-declared-types.js +12 -11
  11. package/dist/api/compiler/checker-decorators.js +3 -3
  12. package/dist/api/compiler/checker-deprecation.js +17 -18
  13. package/dist/api/compiler/checker-destructuring.d.ts +1 -1
  14. package/dist/api/compiler/checker-destructuring.js +3 -3
  15. package/dist/api/compiler/checker-elaboration.js +8 -7
  16. package/dist/api/compiler/checker-emit-resolver.d.ts +1 -1
  17. package/dist/api/compiler/checker-emit-resolver.js +5 -4
  18. package/dist/api/compiler/checker-grammar.js +18 -4
  19. package/dist/api/compiler/checker-heritage.d.ts +1 -1
  20. package/dist/api/compiler/checker-heritage.js +14 -13
  21. package/dist/api/compiler/checker-inference.d.ts +1 -1
  22. package/dist/api/compiler/checker-inference.js +9 -9
  23. package/dist/api/compiler/checker-javascript.d.ts +1 -1
  24. package/dist/api/compiler/checker-javascript.js +5 -4
  25. package/dist/api/compiler/checker-jsx.d.ts +1 -1
  26. package/dist/api/compiler/checker-jsx.js +4 -4
  27. package/dist/api/compiler/checker-literals.js +2 -2
  28. package/dist/api/compiler/checker-members.d.ts +5 -3
  29. package/dist/api/compiler/checker-members.js +75 -53
  30. package/dist/api/compiler/checker-modules.d.ts +1 -1
  31. package/dist/api/compiler/checker-modules.js +13 -13
  32. package/dist/api/compiler/checker-object-literals.d.ts +1 -1
  33. package/dist/api/compiler/checker-object-literals.js +11 -7
  34. package/dist/api/compiler/checker-overloads.d.ts +1 -1
  35. package/dist/api/compiler/checker-overloads.js +4 -3
  36. package/dist/api/compiler/checker-property-access.d.ts +1 -1
  37. package/dist/api/compiler/checker-property-access.js +2 -2
  38. package/dist/api/compiler/checker-services.js +2 -2
  39. package/dist/api/compiler/checker-signatures.d.ts +1 -1
  40. package/dist/api/compiler/checker-signatures.js +9 -8
  41. package/dist/api/compiler/checker-symbol-types.d.ts +2 -18
  42. package/dist/api/compiler/checker-symbol-types.js +22 -952
  43. package/dist/api/compiler/checker-symbols.d.ts +2 -2
  44. package/dist/api/compiler/checker-symbols.js +29 -27
  45. package/dist/api/compiler/checker-type-factory.d.ts +2 -2
  46. package/dist/api/compiler/checker-type-factory.js +57 -16
  47. package/dist/api/compiler/checker-type-nodes.d.ts +1 -1
  48. package/dist/api/compiler/checker-type-nodes.js +2 -2
  49. package/dist/api/compiler/checker-type-operators.d.ts +1 -1
  50. package/dist/api/compiler/checker-type-operators.js +5 -5
  51. package/dist/api/compiler/checker-types.d.ts +73 -7
  52. package/dist/api/compiler/checker-types.js +220 -43
  53. package/dist/api/compiler/checker-unused.d.ts +1 -1
  54. package/dist/api/compiler/checker-unused.js +3 -3
  55. package/dist/api/compiler/checker.d.ts +29 -8
  56. package/dist/api/compiler/checker.js +29 -9
  57. package/dist/api/compiler/diagnostics.d.ts +2 -8
  58. package/dist/api/compiler/diagnostics.js +4 -40
  59. package/dist/api/compiler/file-include.d.ts +35 -8
  60. package/dist/api/compiler/file-include.js +81 -18
  61. package/dist/api/compiler/file-loader.d.ts +33 -4
  62. package/dist/api/compiler/file-loader.js +90 -24
  63. package/dist/api/compiler/instantiation.d.ts +1 -1
  64. package/dist/api/compiler/instantiation.js +86 -50
  65. package/dist/api/compiler/link-tables.d.ts +69 -0
  66. package/dist/api/compiler/link-tables.js +236 -0
  67. package/dist/api/compiler/name-resolver.js +3 -3
  68. package/dist/api/compiler/node-builder-names.d.ts +1 -1
  69. package/dist/api/compiler/node-builder-names.js +12 -12
  70. package/dist/api/compiler/node-builder-pseudo.d.ts +1 -1
  71. package/dist/api/compiler/node-builder-pseudo.js +2 -1
  72. package/dist/api/compiler/node-builder.d.ts +1 -1
  73. package/dist/api/compiler/node-builder.js +16 -16
  74. package/dist/api/compiler/parallel-parse.d.ts +2 -0
  75. package/dist/api/compiler/parallel-parse.js +4 -0
  76. package/dist/api/compiler/parser.d.ts +33 -16
  77. package/dist/api/compiler/parser.js +95 -76
  78. package/dist/api/compiler/printer/emit-context.d.ts +5 -2
  79. package/dist/api/compiler/printer/emit-context.js +19 -13
  80. package/dist/api/compiler/program-checker.js +3 -0
  81. package/dist/api/compiler/program.js +9 -1
  82. package/dist/api/compiler/relations.d.ts +1 -1
  83. package/dist/api/compiler/relations.js +10 -10
  84. package/dist/api/compiler/symbol-accessibility.d.ts +1 -1
  85. package/dist/api/compiler/symbol-accessibility.js +123 -26
  86. package/dist/api/compiler/symbol.d.ts +45 -3
  87. package/dist/api/compiler/symbol.js +121 -10
  88. package/dist/api/compiler/transformers/alias-references.d.ts +1 -1
  89. package/dist/api/compiler/transformers/alias-references.js +2 -1
  90. package/dist/api/compiler/transformers/declarations-diagnostics.js +2 -1
  91. package/dist/api/compiler/transformers/declarations-pseudo.js +4 -2
  92. package/dist/api/compiler/transformers/declarations-syntactic.d.ts +1 -1
  93. package/dist/api/compiler/transformers/declarations-syntactic.js +9 -9
  94. package/dist/api/compiler/transformers/declarations-tracker.d.ts +1 -1
  95. package/dist/api/compiler/transformers/declarations-tracker.js +3 -2
  96. package/dist/api/compiler/transformers/declarations.js +6 -5
  97. package/dist/api/compiler/transformers/reference-resolver.d.ts +2 -1
  98. package/dist/api/compiler/transformers/reference-resolver.js +26 -24
  99. package/dist/api/compiler/transformers/subtree-facts.d.ts +1 -0
  100. package/dist/api/compiler/transformers/subtree-facts.js +7 -5
  101. package/dist/api/compiler/transformers/syntax-facts.d.ts +1 -0
  102. package/dist/api/compiler/transformers/syntax-facts.js +9 -5
  103. package/dist/api/compiler/transformers/type-serialization.js +12 -12
  104. package/package.json +9 -9
  105. package/src/compiler/ast.ts +27 -19
  106. package/src/compiler/binder-utilities.ts +2 -2
  107. package/src/compiler/binder.ts +15 -11
  108. package/src/compiler/checker-calls.ts +3 -3
  109. package/src/compiler/checker-declaration-order.ts +2 -2
  110. package/src/compiler/checker-declarations.ts +21 -14
  111. package/src/compiler/checker-declared-types.ts +12 -12
  112. package/src/compiler/checker-decorators.ts +3 -3
  113. package/src/compiler/checker-deprecation.ts +17 -21
  114. package/src/compiler/checker-destructuring.ts +3 -3
  115. package/src/compiler/checker-elaboration.ts +8 -8
  116. package/src/compiler/checker-emit-resolver.ts +5 -5
  117. package/src/compiler/checker-grammar.ts +17 -5
  118. package/src/compiler/checker-heritage.ts +21 -14
  119. package/src/compiler/checker-inference.ts +17 -9
  120. package/src/compiler/checker-javascript.ts +5 -5
  121. package/src/compiler/checker-jsx.ts +12 -8
  122. package/src/compiler/checker-literals.ts +2 -2
  123. package/src/compiler/checker-members.ts +91 -47
  124. package/src/compiler/checker-modules.ts +23 -13
  125. package/src/compiler/checker-object-literals.ts +22 -6
  126. package/src/compiler/checker-overloads.ts +6 -6
  127. package/src/compiler/checker-property-access.ts +2 -2
  128. package/src/compiler/checker-services.ts +2 -2
  129. package/src/compiler/checker-signatures.ts +9 -9
  130. package/src/compiler/checker-symbol-types.ts +20 -940
  131. package/src/compiler/checker-symbols.ts +42 -35
  132. package/src/compiler/checker-type-factory.ts +53 -16
  133. package/src/compiler/checker-type-nodes.ts +2 -2
  134. package/src/compiler/checker-type-operators.ts +13 -5
  135. package/src/compiler/checker-types.ts +223 -43
  136. package/src/compiler/checker-unused.ts +3 -3
  137. package/src/compiler/checker.ts +31 -9
  138. package/src/compiler/diagnostics.ts +5 -44
  139. package/src/compiler/file-include.ts +85 -17
  140. package/src/compiler/file-loader.ts +104 -35
  141. package/src/compiler/incremental.ts +39 -5
  142. package/src/compiler/instantiation.ts +99 -55
  143. package/src/compiler/link-tables.ts +245 -0
  144. package/src/compiler/name-resolver.ts +3 -3
  145. package/src/compiler/node-builder-names.ts +21 -19
  146. package/src/compiler/node-builder-pseudo.ts +2 -2
  147. package/src/compiler/node-builder.ts +24 -16
  148. package/src/compiler/parallel-check.ts +11 -8
  149. package/src/compiler/parallel-parse.ts +5 -0
  150. package/src/compiler/parse-thread.ts +0 -4
  151. package/src/compiler/parser.ts +120 -70
  152. package/src/compiler/printer/emit-context.ts +20 -15
  153. package/src/compiler/program-checker.ts +2 -0
  154. package/src/compiler/program.ts +8 -1
  155. package/src/compiler/relations.ts +10 -10
  156. package/src/compiler/symbol-accessibility.ts +120 -25
  157. package/src/compiler/symbol.ts +127 -9
  158. package/src/compiler/transformers/alias-references.ts +2 -2
  159. package/src/compiler/transformers/declarations-diagnostics.ts +2 -1
  160. package/src/compiler/transformers/declarations-pseudo.ts +7 -4
  161. package/src/compiler/transformers/declarations-syntactic.ts +17 -9
  162. package/src/compiler/transformers/declarations-tracker.ts +3 -3
  163. package/src/compiler/transformers/declarations.ts +6 -6
  164. package/src/compiler/transformers/reference-resolver.ts +37 -25
  165. package/src/compiler/transformers/subtree-facts.ts +13 -5
  166. package/src/compiler/transformers/syntax-facts.ts +10 -5
  167. package/src/compiler/transformers/type-serialization.ts +12 -12
  168. package/src/compiler/tsc-build.ts +17 -13
  169. package/src/compiler/tsc-cli.ts +9 -6
  170. package/src/compiler/tsc-compile.ts +16 -7
  171. package/src/compiler/tsc-watch.ts +94 -26
@@ -388,23 +388,6 @@ export class TypeAlias {
388
388
  }
389
389
  }
390
390
 
391
- /** One entry of a `TypeListCache`: the parts of its key, its value, and the next entry with the same hash. */
392
- class TypeListEntry<V> {
393
- readonly types: readonly Type[];
394
- readonly alias: TypeAlias | undefined;
395
- readonly tag: number;
396
- value: V;
397
- next: TypeListEntry<V> | undefined;
398
-
399
- constructor(types: readonly Type[], alias: TypeAlias | undefined, tag: number, value: V) {
400
- this.types = types;
401
- this.alias = alias;
402
- this.tag = tag;
403
- this.value = value;
404
- this.next = undefined;
405
- }
406
- }
407
-
408
391
  function sameTypeListParts(a: readonly Type[], b: readonly Type[]): boolean {
409
392
  if (a.length !== b.length) return false;
410
393
  for (let i = 0; i < a.length; i++) if (a[i]! !== b[i]!) return false;
@@ -421,34 +404,149 @@ function sameAliasParts(a: TypeAlias | undefined, b: TypeAlias | undefined): boo
421
404
  * aliasKey(alias)` plus a suffix spelled, without building them. A lookup takes a number hashing the
422
405
  * parts (`typeListHash`); entries keep their parts, so a match is exact and keys sharing a hash chain.
423
406
  * Like tsgo's hashed type list keys. A list must not change after it keys an entry.
407
+ *
408
+ * Entries are numbered in the order they are added: `heads` maps a hash to its first entry, and the
409
+ * lists and values of the entries are kept in arrays by number. Aliases, tags and the chains of
410
+ * entries that share a hash get arrays once an entry needs them.
424
411
  */
425
412
  export class TypeListCache<V> {
426
- private readonly entries = new Map<number, TypeListEntry<V>>();
413
+ private heads: Map<number, number>;
414
+ private lists: (readonly Type[])[];
415
+ private values: V[];
416
+ private aliases: (TypeAlias | undefined)[] | undefined;
417
+ private tags: number[] | undefined;
418
+ /** The next entry with the same hash, or -1. */
419
+ private nexts: number[] | undefined;
420
+
421
+ constructor() {
422
+ this.heads = new Map<number, number>();
423
+ this.lists = [];
424
+ this.values = [];
425
+ this.aliases = undefined;
426
+ this.tags = undefined;
427
+ this.nexts = undefined;
428
+ }
427
429
 
428
430
  get(hash: number, types: readonly Type[], alias: TypeAlias | undefined, tag: number): V | undefined {
429
- for (let e = this.entries.get(hash); e !== undefined; e = e.next)
430
- if (e.tag === tag && sameTypeListParts(e.types, types) && sameAliasParts(e.alias, alias)) return e.value;
431
- return undefined;
431
+ const entry = this.find(hash, types, alias, tag);
432
+ return entry >= 0 ? this.values[entry] : undefined;
432
433
  }
433
434
 
434
435
  set(hash: number, types: readonly Type[], alias: TypeAlias | undefined, tag: number, value: V): void {
435
- const head = this.entries.get(hash);
436
+ const head = this.heads.get(hash);
437
+ if (head !== undefined) {
438
+ const entry = this.findFrom(head, types, alias, tag);
439
+ if (entry >= 0) {
440
+ this.values[entry] = value;
441
+ return;
442
+ }
443
+ }
444
+ const entry = this.lists.length;
445
+ this.lists.push(types);
446
+ this.values.push(value);
447
+ const aliases = this.aliases;
448
+ if (aliases !== undefined) aliases.push(alias);
449
+ else if (alias !== undefined) {
450
+ const created: (TypeAlias | undefined)[] = [];
451
+ for (let i = 0; i < entry; i++) created.push(undefined);
452
+ created.push(alias);
453
+ this.aliases = created;
454
+ }
455
+ const tags = this.tags;
456
+ if (tags !== undefined) tags.push(tag);
457
+ else if (tag !== 0) {
458
+ const created: number[] = [];
459
+ for (let i = 0; i < entry; i++) created.push(0);
460
+ created.push(tag);
461
+ this.tags = created;
462
+ }
463
+ let nexts = this.nexts;
464
+ if (nexts !== undefined) nexts.push(-1);
436
465
  if (head === undefined) {
437
- this.entries.set(hash, new TypeListEntry(types, alias, tag, value));
466
+ this.heads.set(hash, entry);
438
467
  return;
439
468
  }
440
- for (let e: TypeListEntry<V> | undefined = head; e !== undefined; e = e.next)
441
- if (e.tag === tag && sameTypeListParts(e.types, types) && sameAliasParts(e.alias, alias)) {
442
- e.value = value;
443
- return;
444
- }
445
- const entry = new TypeListEntry(types, alias, tag, value);
446
- entry.next = head.next;
447
- head.next = entry;
469
+ // A second entry with this hash: chain it after the first.
470
+ if (nexts === undefined) {
471
+ nexts = [];
472
+ for (let i = 0; i <= entry; i++) nexts.push(-1);
473
+ this.nexts = nexts;
474
+ }
475
+ nexts[entry] = nexts[head]!;
476
+ nexts[head] = entry;
448
477
  }
449
478
 
450
479
  clear(): void {
451
- this.entries.clear();
480
+ this.heads = new Map<number, number>();
481
+ this.lists = [];
482
+ this.values = [];
483
+ this.aliases = undefined;
484
+ this.tags = undefined;
485
+ this.nexts = undefined;
486
+ }
487
+
488
+ /** The number of the entry with these parts, or -1. */
489
+ private find(hash: number, types: readonly Type[], alias: TypeAlias | undefined, tag: number): number {
490
+ const head = this.heads.get(hash);
491
+ return head !== undefined ? this.findFrom(head, types, alias, tag) : -1;
492
+ }
493
+
494
+ private findFrom(head: number, types: readonly Type[], alias: TypeAlias | undefined, tag: number): number {
495
+ const tags = this.tags;
496
+ const aliases = this.aliases;
497
+ const nexts = this.nexts;
498
+ for (let entry = head; entry >= 0; entry = nexts !== undefined ? nexts[entry]! : -1)
499
+ if (
500
+ (tags !== undefined ? tags[entry]! : 0) === tag &&
501
+ sameTypeListParts(this.lists[entry]!, types) &&
502
+ sameAliasParts(aliases !== undefined ? aliases[entry] : undefined, alias)
503
+ )
504
+ return entry;
505
+ return -1;
506
+ }
507
+ }
508
+
509
+ /**
510
+ * One list for each sequence of types that a checker keeps (`Checker.typeLists`): references and
511
+ * instantiation caches hold the same type arguments in many places, mostly lists of one or two types,
512
+ * and share one list for them. A list must not change once it is in the table.
513
+ */
514
+ export class TypeListTable {
515
+ private readonly heads = new Map<number, number>();
516
+ private readonly lists: Type[][] = [];
517
+ /** The next list with the same hash, or -1, once two lists share one. */
518
+ private nexts: number[] | undefined = undefined;
519
+
520
+ /**
521
+ * The list in the table with the types of `types`, in order, or `types` itself, which joins the
522
+ * table. `hash` is `typeListHash(types, undefined, 0)`.
523
+ */
524
+ intern(hash: number, types: Type[]): Type[] {
525
+ if (types.length === 0) return types;
526
+ const head = this.heads.get(hash);
527
+ const nexts = this.nexts;
528
+ if (head !== undefined)
529
+ for (let entry = head; entry >= 0; entry = nexts !== undefined ? nexts[entry]! : -1) {
530
+ const list = this.lists[entry]!;
531
+ if (sameTypeListParts(list, types)) return list;
532
+ }
533
+ const entry = this.lists.length;
534
+ this.lists.push(types);
535
+ if (nexts !== undefined) nexts.push(-1);
536
+ if (head === undefined) {
537
+ this.heads.set(hash, entry);
538
+ return types;
539
+ }
540
+ // A second list with this hash: chain it after the first.
541
+ let chain = nexts;
542
+ if (chain === undefined) {
543
+ chain = [];
544
+ for (let i = 0; i <= entry; i++) chain.push(-1);
545
+ this.nexts = chain;
546
+ }
547
+ chain[entry] = chain[head]!;
548
+ chain[head] = entry;
549
+ return types;
452
550
  }
453
551
  }
454
552
 
@@ -505,7 +603,7 @@ export class TypeExtra implements ProgramLifetime {
505
603
  origin: Type | undefined;
506
604
  keyPropertyName: string;
507
605
  constituentMap: Map<Type, Type> | undefined;
508
- constituentSet: Set<Type> | undefined;
606
+ constituentIds: Int32Array | undefined;
509
607
  membershipTests: number;
510
608
  // IntersectionType
511
609
  uniqueLiteralFilledInstantiation: Type | undefined;
@@ -519,7 +617,7 @@ export class TypeExtra implements ProgramLifetime {
519
617
  this.origin = undefined;
520
618
  this.keyPropertyName = '';
521
619
  this.constituentMap = undefined;
522
- this.constituentSet = undefined;
620
+ this.constituentIds = undefined;
523
621
  this.membershipTests = 0;
524
622
  this.uniqueLiteralFilledInstantiation = undefined;
525
623
  }
@@ -1105,21 +1203,48 @@ export class EvolvingArrayType extends ObjectType {
1105
1203
  }
1106
1204
  }
1107
1205
 
1108
- export class UnionOrIntersectionType extends StructuredType {
1206
+ /**
1207
+ * A union or intersection. Few have their members resolved or their properties cached, so those
1208
+ * live in `membersOf` (`UnionOrIntersectionMembers`), which is created when they are first written.
1209
+ */
1210
+ export class UnionOrIntersectionType extends Type {
1109
1211
  readonly types: Type[];
1110
- propertyCache: SymbolTable | undefined;
1111
- propertyCacheWithoutFunctionPropertyAugment: SymbolTable | undefined;
1112
- resolvedProperties: Symbol[] | undefined;
1212
+ membersOf: UnionOrIntersectionMembers | undefined;
1113
1213
 
1114
1214
  constructor(flags: TypeFlags, objectFlags: ObjectFlags, id: number, types: Type[]) {
1115
1215
  super(flags, objectFlags, id, undefined);
1116
1216
  this.types = types;
1217
+ this.membersOf = undefined;
1218
+ }
1219
+ }
1220
+
1221
+ /**
1222
+ * The resolved members of a union or intersection (`membersHolder`) and the caches of its
1223
+ * properties, created on first use.
1224
+ */
1225
+ export class UnionOrIntersectionMembers extends StructuredType {
1226
+ propertyCache: SymbolTable | undefined;
1227
+ propertyCacheWithoutFunctionPropertyAugment: SymbolTable | undefined;
1228
+ resolvedProperties: Symbol[] | undefined;
1229
+
1230
+ constructor(flags: TypeFlags, id: number) {
1231
+ super(flags, ObjectFlags.None, id, undefined);
1117
1232
  this.propertyCache = undefined;
1118
1233
  this.propertyCacheWithoutFunctionPropertyAugment = undefined;
1119
1234
  this.resolvedProperties = undefined;
1120
1235
  }
1121
1236
  }
1122
1237
 
1238
+ /** The members holder of a union or intersection, created if it has none yet. */
1239
+ export function unionOrIntersectionMembers(t: UnionOrIntersectionType): UnionOrIntersectionMembers {
1240
+ let members = t.membersOf;
1241
+ if (members === undefined) {
1242
+ members = new UnionOrIntersectionMembers(t.flags, t.id);
1243
+ t.membersOf = members;
1244
+ }
1245
+ return members;
1246
+ }
1247
+
1123
1248
  /** A union; all of its own fields are rarely set and live in `extra`. */
1124
1249
  export class UnionType extends UnionOrIntersectionType {
1125
1250
  constructor(objectFlags: ObjectFlags, id: number, types: Type[]) {
@@ -1173,14 +1298,18 @@ export class UnionType extends UnionOrIntersectionType {
1173
1298
  if (map !== undefined || this.extra !== undefined) typeExtra(this).constituentMap = map;
1174
1299
  }
1175
1300
 
1176
- /** The constituents of a large union, for membership tests; created on the second test. */
1177
- get constituentSet(): Set<Type> | undefined {
1301
+ /**
1302
+ * A hash table of the ids of a large union's constituents, for membership tests; created on the
1303
+ * second test (`constituentTable`). About eight bytes a constituent, where a set of them took
1304
+ * about five times that.
1305
+ */
1306
+ get constituentIds(): Int32Array | undefined {
1178
1307
  const extra = this.extra;
1179
- return extra !== undefined ? extra.constituentSet : undefined;
1308
+ return extra !== undefined ? extra.constituentIds : undefined;
1180
1309
  }
1181
1310
 
1182
- set constituentSet(set: Set<Type> | undefined) {
1183
- if (set !== undefined || this.extra !== undefined) typeExtra(this).constituentSet = set;
1311
+ set constituentIds(ids: Int32Array | undefined) {
1312
+ if (ids !== undefined || this.extra !== undefined) typeExtra(this).constituentIds = ids;
1184
1313
  }
1185
1314
 
1186
1315
  get membershipTests(): number {
@@ -1694,6 +1823,45 @@ export class ArrayTypeMapper extends TypeMapper {
1694
1823
  mapsThisOnly(): boolean {
1695
1824
  return this.sources.length === 1 && isThisTypeParameter(this.sources[0]!);
1696
1825
  }
1826
+
1827
+ /** The number of targets, one per source. */
1828
+ targetCount(): number {
1829
+ return this.targets.length;
1830
+ }
1831
+
1832
+ /** The target of the source at `index`. */
1833
+ targetAt(index: number): Type {
1834
+ return this.targets[index]!;
1835
+ }
1836
+ }
1837
+
1838
+ /**
1839
+ * The mapper of a type reference's members: its type arguments, then the reference itself for the
1840
+ * last source, the class or interface's `this` type. `targets` holds the type arguments only, so the
1841
+ * reference's own list serves without a copy that adds the reference.
1842
+ */
1843
+ export class ThisArgumentTypeMapper extends ArrayTypeMapper {
1844
+ readonly thisTarget: Type;
1845
+
1846
+ constructor(sources: Type[], typeArguments: Type[], thisTarget: Type) {
1847
+ super(sources, typeArguments);
1848
+ this.thisTarget = thisTarget;
1849
+ }
1850
+
1851
+ map(type: Type): Type {
1852
+ const sources = this.sources;
1853
+ const last = sources.length - 1;
1854
+ for (let i = 0; i < last; i++) if (type === sources[i]!) return this.targets[i]!;
1855
+ return type === sources[last]! ? this.thisTarget : type;
1856
+ }
1857
+
1858
+ targetCount(): number {
1859
+ return this.targets.length + 1;
1860
+ }
1861
+
1862
+ targetAt(index: number): Type {
1863
+ return index < this.targets.length ? this.targets[index]! : this.thisTarget;
1864
+ }
1697
1865
  }
1698
1866
 
1699
1867
  /**
@@ -1771,6 +1939,18 @@ export function newTypeMapper(sources: Type[], targets: Type[]): TypeMapper {
1771
1939
  : new ArrayTypeMapper(sources, targets);
1772
1940
  }
1773
1941
 
1942
+ /** `newTypeMapper(sources, [...typeArguments, thisTarget])`, without building that list where it can. */
1943
+ export function newThisArgumentTypeMapper(sources: Type[], typeArguments: Type[], thisTarget: Type): TypeMapper {
1944
+ if (sources.length === 1) return new SimpleTypeMapper(sources[0]!, thisTarget);
1945
+ if (sources.length >= indexedTypeMapperThreshold) {
1946
+ const targets: Type[] = [];
1947
+ for (const t of typeArguments) targets.push(t);
1948
+ targets.push(thisTarget);
1949
+ return new IndexedArrayTypeMapper(sources, targets);
1950
+ }
1951
+ return new ThisArgumentTypeMapper(sources, typeArguments, thisTarget);
1952
+ }
1953
+
1774
1954
  export function mergeTypeMappers(m1: TypeMapper | undefined, m2: TypeMapper): TypeMapper {
1775
1955
  return m1 !== undefined ? new MergedTypeMapper(m1, m2) : m2;
1776
1956
  }
@@ -49,7 +49,6 @@ import {
49
49
  } from './binder-utilities.js';
50
50
  import { type Checker, createDiagnosticForNode } from './checker.js';
51
51
  import { Diagnostic, DiagnosticCategory, Diagnostics } from './diagnostics.js';
52
- import { CheckFlags, type Symbol, SymbolFlags, getSymbolId } from './symbol.js';
53
52
  import { SyntaxKind } from './syntax-kind.js';
54
53
  import { getMergedSymbol, getSymbolOfDeclaration } from './checker-symbols.js';
55
54
  import { getResolvedSymbol } from './checker-expressions.js';
@@ -61,6 +60,7 @@ import type { Type } from './checker-types.js';
61
60
  import { getLiteralTypeFromPropertyName } from './checker-type-operators.js';
62
61
  import { getPropertyOfType } from './checker-members.js';
63
62
  import { getPropertyNameFromType, isTypeUsableAsPropertyName } from './checker-utilities.js';
63
+ import { CheckFlags, getDeclarations, getSymbolId, type Symbol, SymbolFlags } from './symbol.js';
64
64
 
65
65
  // ---- References
66
66
 
@@ -438,7 +438,7 @@ function checkUnusedLocalsAndParameters(c: Checker, node: Node): void {
438
438
  (local.flags & SymbolFlags.ModuleExports) !== 0
439
439
  )
440
440
  continue;
441
- for (const declaration of local.declarations) {
441
+ for (const declaration of getDeclarations(local)) {
442
442
  switch (declaration.kind) {
443
443
  case SyntaxKind.VariableDeclaration:
444
444
  case SyntaxKind.Parameter:
@@ -634,7 +634,7 @@ function isUnreferencedTypeParameter(c: Checker, typeParameter: Node): boolean {
634
634
  }
635
635
 
636
636
  function allDeclarationsInSameSourceFile(symbol: Symbol): boolean {
637
- const declarations = symbol.declarations;
637
+ const declarations = getDeclarations(symbol);
638
638
  if (declarations.length <= 1) return true;
639
639
  const file = getSourceFileOfNode(declarations[0]!);
640
640
  for (let i = 1; i < declarations.length; i++) if (getSourceFileOfNode(declarations[i]!) !== file) return false;
@@ -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 { IntLinkTable, LinkTable, SparseLinkTable } from './link-tables.js';
36
+ import { CompactSymbolLinkTable, IntLinkTable, LinkTable, 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 {
@@ -66,6 +66,7 @@ import {
66
66
  emptyTypes,
67
67
  VarianceFlags,
68
68
  TypeListCache,
69
+ TypeListTable,
69
70
  type ConditionalType,
70
71
  type InterfaceType,
71
72
  type TypeChecking,
@@ -107,7 +108,6 @@ import type { FlowNode, FlowReduceLabel } from './flow.js';
107
108
  import { JsxState } from './checker-jsx.js';
108
109
  import type { DeferredIterationError, IterationTypes } from './checker-iteration.js';
109
110
  import type { SpreadIndices } from './checker-contextual.js';
110
- import type { SlotSiblingProperties } from './checker-symbol-types.js';
111
111
  import { SourceFileMetadata, getEmitModuleFormatOfFile } from './program-utilities.js';
112
112
  import type { GrammarChecker } from './checker-grammar.js';
113
113
  import type { ResolvedModule } from './module-resolution-types.js';
@@ -264,6 +264,23 @@ function stableSort(list: Diagnostic[]): void {
264
264
  /** Maximum depth of nested `typeToString` calls before diagnostics are discarded. */
265
265
  export const maxSerializationLevel = 2;
266
266
 
267
+ /**
268
+ * File positions per symbol id in `ExternalModuleContainerIndex.keys`. Symbol ids are int32, so the
269
+ * keys stay exact.
270
+ */
271
+ export const fileIndexScale = 2 ** 21;
272
+
273
+ /** The modules that export each symbol, built once from every module's exports. */
274
+ export class ExternalModuleContainerIndex {
275
+ complete = false;
276
+ /**
277
+ * One key per symbol and module that exports it, ascending: the id of the symbol the export
278
+ * resolves to times `fileIndexScale`, plus the module's file position in `Checker.files`. The
279
+ * keys of one symbol are contiguous and in program order.
280
+ */
281
+ keys: number[] = [];
282
+ }
283
+
267
284
  /** The checker's caches for symbol accessibility. */
268
285
  export class SymbolAccessibilityCaches {
269
286
  /** Accessible chains by symbol id, then by `chainCacheKey`. */
@@ -274,6 +291,8 @@ export class SymbolAccessibilityCaches {
274
291
  readonly containersByFile = new Map<number, Map<number, Symbol[]>>();
275
292
  /** All modules that export a symbol, by symbol id. */
276
293
  readonly containers = new Map<number, Symbol[]>();
294
+ /** The modules each symbol is exported from, built on the first search of all modules. */
295
+ externalModuleContainers: ExternalModuleContainerIndex | undefined = undefined;
277
296
  /** The name tables of named class expressions, by node id. */
278
297
  readonly classExpressionNames = new Map<number, SymbolTable>();
279
298
  /** Computed declaration visibility by node id (see isDeclarationVisible), 0 if not computed. */
@@ -360,7 +379,7 @@ export class Checker implements TypeChecking {
360
379
  /** Bits of SymbolFlags for the meanings in which a symbol was referenced. */
361
380
  readonly symbolReferenceKinds = new IntLinkTable();
362
381
  /** The resolved symbol of an identifier, entity name or call. */
363
- readonly resolvedSymbols = new SparseLinkTable<Symbol>();
382
+ readonly resolvedSymbols = new CompactSymbolLinkTable();
364
383
  /** The resolved type of a type node or expression. */
365
384
  readonly resolvedTypes = new SparseLinkTable<Type>();
366
385
  /** The resolved signature of a call-like node or a signature declaration. */
@@ -398,10 +417,6 @@ export class Checker implements TypeChecking {
398
417
  readonly unresolvedSymbols = new Map<string, Symbol>();
399
418
  /** Widening's optional `undefined` properties by the id of the property each is created from. */
400
419
  readonly undefinedProperties = new Map<number, Symbol>();
401
- /** By file and name, the property that widening's optional `undefined` properties are created from. */
402
- readonly firstSiblingProperties = new Map<SourceFile, Map<string, Node>>();
403
- /** By tsgo checker, the first sibling properties of its files (firstSiblingProperty). */
404
- readonly slotSiblingProperties = new Map<number, SlotSiblingProperties>();
405
420
 
406
421
  // Interning tables.
407
422
  readonly stringLiteralTypes = new Map<string, LiteralType>();
@@ -421,6 +436,8 @@ export class Checker implements TypeChecking {
421
436
  readonly templateLiteralTypes = new Map<string, Type>();
422
437
  /** Instantiations of template literal types: the instantiated types, tagged with the template's id. */
423
438
  readonly templateLiteralInstantiations = new TypeListCache<Type>();
439
+ /** The type argument lists that references and instantiations keep, one of each (`TypeListTable`). */
440
+ readonly typeLists = new TypeListTable();
424
441
  readonly stringMappingTypes = new Map<string, Type>();
425
442
  readonly substitutionTypes = new Map<string, Type>();
426
443
  readonly subtypeReductionCache = new TypeListCache<Type[]>();
@@ -558,6 +575,13 @@ export class Checker implements TypeChecking {
558
575
  */
559
576
  readonly freeMapperCaches: Map<number, Type>[] = [];
560
577
  freeMapperCacheCount = 0;
578
+ /** Empty lists for type arguments that are compared with cached instantiations before any is kept. */
579
+ readonly freeTypeLists: Type[][] = [];
580
+ /**
581
+ * 1 by type id for the anonymous and mapped types whose declaration has no outer type parameters
582
+ * to instantiate (`getObjectTypeInstantiation`).
583
+ */
584
+ readonly withoutOuterTypeParameters = new IntLinkTable();
561
585
  conditionalConstraintDepth = 0;
562
586
 
563
587
  readonly suggestionResolver: SuggestionNameResolver;
@@ -1051,8 +1075,6 @@ export function disposeChecker(c: Checker): void {
1051
1075
  c.symbolAccessibilityCaches = undefined;
1052
1076
  c.unresolvedSymbols.clear();
1053
1077
  c.undefinedProperties.clear();
1054
- c.firstSiblingProperties.clear();
1055
- c.slotSiblingProperties.clear();
1056
1078
  c.stringLiteralTypes.clear();
1057
1079
  c.numberLiteralTypes.clear();
1058
1080
  c.bigintLiteralTypes.clear();
@@ -2,7 +2,7 @@
2
2
  * Diagnostics: message lookup and localization, the `Diagnostic` type, and tsc's plain and
3
3
  * pretty diagnostic output.
4
4
  */
5
- import { CharacterCodes, isDigit, isUnicodeWhiteSpace, utf8Length } from './character-codes.js';
5
+ import { isDigit, isUnicodeWhiteSpace, utf8Length } from './character-codes.js';
6
6
  import { Locale, translations } from './diagnostic-locales.js';
7
7
  import { Diagnostics, messageCodes, messageFlags, messageKeys, messageTexts } from './diagnostic-messages.js';
8
8
  import { getPathComponentsRelativeTo, getPathFromPathComponents, isRootedDiskPath, pathIsAbsolute } from './path.js';
@@ -146,15 +146,15 @@ function toWellFormed(text: string): string {
146
146
  /**
147
147
  * Where this thread computes the line starts and UTF-8 offsets of files that may be shared with other
148
148
  * threads (`useThreadTextCaches`): a copy of each such file, by file, that computes them in place.
149
- * Files leave the parser with line starts, except declaration files, and without UTF-8 offsets.
149
+ * Files leave the parser without line starts and UTF-8 offsets, except JSON files, which have line
150
+ * starts.
150
151
  */
151
152
  let threadCopies: Map<DiagnosticFile, DiagnosticFile> | undefined = undefined;
152
153
 
153
154
  /**
154
155
  * Makes this thread compute the caches of files that do not have them yet in copies of its own: the
155
- * files may be published (immutable) and shared with other threads. Declaration files leave the
156
- * parser without them (`Parser.parseSourceFile`): they make up most of the text of a typical program,
157
- * and are rarely checked or pointed into by a diagnostic.
156
+ * files may be published (immutable) and shared with other threads. Files leave the parser without
157
+ * them (`Parser.parseSourceFile`): most files are never pointed into by a diagnostic.
158
158
  */
159
159
  export function useThreadTextCaches(): void {
160
160
  if (threadCopies === undefined) threadCopies = new Map<DiagnosticFile, DiagnosticFile>();
@@ -174,15 +174,6 @@ function threadCopyOf(file: DiagnosticFile): DiagnosticFile | undefined {
174
174
  return copy;
175
175
  }
176
176
 
177
- /** The position of the first code unit at or after `pos` that is a CR or below, or not ASCII; or `end`. */
178
- function skipPlainASCII(units: Uint16Array, pos: number, end: number): number {
179
- for (let i = pos | 0; i < end; i = (i + 1) | 0) {
180
- const c = units[i] | 0;
181
- if (c <= CharacterCodes.carriageReturn || c >= 0x80) return i;
182
- }
183
- return end;
184
- }
185
-
186
177
  /** The text of a file diagnostics point into. */
187
178
  export class DiagnosticFile {
188
179
  readonly fileName: string;
@@ -206,36 +197,6 @@ export class DiagnosticFile {
206
197
  if (this.lineStarts.length === 0) this.lineStarts = computeLineStarts(this.text);
207
198
  }
208
199
 
209
- /**
210
- * Like `computeCaches`, from the text's UTF-16 code units `units[0, text.length)`, so the text
211
- * itself is neither searched nor copied.
212
- */
213
- computeCachesFromUnits(units: Uint16Array): void {
214
- const text = this.text;
215
- // ASCII texts are searched faster than walked.
216
- if (this.lineStarts.length !== 0 || Buffer.byteLength(text, 'utf8') === text.length) {
217
- this.computeCaches();
218
- return;
219
- }
220
- const length = text.length | 0;
221
- const lineStarts: number[] = [0];
222
- // Visit only the code units that may break a line; `skipPlainASCII` runs over the rest without
223
- // calls, so native builds keep its loop on registers. A CR followed by an LF leaves the line start
224
- // to the LF.
225
- for (let i = skipPlainASCII(units, 0, length); i < length; i = skipPlainASCII(units, (i + 1) | 0, length)) {
226
- const ch = units[i] | 0;
227
- if (
228
- ch === CharacterCodes.lineFeed ||
229
- (ch === CharacterCodes.carriageReturn &&
230
- (i + 1 >= length || (units[(i + 1) | 0] | 0) !== CharacterCodes.lineFeed)) ||
231
- ch === CharacterCodes.lineSeparator ||
232
- ch === CharacterCodes.paragraphSeparator
233
- )
234
- lineStarts.push(i + 1);
235
- }
236
- this.lineStarts = lineStarts;
237
- }
238
-
239
200
  /** Start offsets of each line, split at CR, LF, CRLF, LS and PS. */
240
201
  getLineStarts(): readonly number[] {
241
202
  if (this.lineStarts.length === 0) {