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
@@ -13,7 +13,6 @@ import {
13
13
  import { getSymbolNameForPrivateIdentifier } from './binder.js';
14
14
  import { getCombinedModifierFlags } from './binder-utilities.js';
15
15
  import { Diagnostic, type DiagnosticMessage, Diagnostics, messageElidedInCompatibilityPyramid } from './diagnostics.js';
16
- import { CheckFlags, type Symbol, SymbolFlags, getSymbolId } from './symbol.js';
17
16
  import { SyntaxKind } from './syntax-kind.js';
18
17
  import { isContextSensitive } from './checker-functions.js';
19
18
  import { type Checker, createDiagnosticForNode } from './checker.js';
@@ -224,6 +223,7 @@ import {
224
223
  isNumericLiteralName,
225
224
  maybeTypeOfKind,
226
225
  } from './checker-utilities.js';
226
+ import { CheckFlags, declarationCount, getDeclarations, getSymbolId, type Symbol, SymbolFlags } from './symbol.js';
227
227
 
228
228
  // ---- Results and caches
229
229
 
@@ -754,8 +754,8 @@ function isEnumTypeRelatedTo(c: Checker, source: Symbol, target: Symbol, reporte
754
754
  c.enumRelation.set(key, RelationComparisonResult.Failed);
755
755
  return false;
756
756
  }
757
- const sourceDecl = sourceProperty.declarations.find((d) => d.kind === SyntaxKind.EnumMember);
758
- const targetDecl = targetProperty.declarations.find((d) => d.kind === SyntaxKind.EnumMember);
757
+ const sourceDecl = getDeclarations(sourceProperty).find((d) => d.kind === SyntaxKind.EnumMember);
758
+ const targetDecl = getDeclarations(targetProperty).find((d) => d.kind === SyntaxKind.EnumMember);
759
759
  if (sourceDecl === undefined || targetDecl === undefined) continue;
760
760
  computeEnumMemberValues(c, sourceDecl.parent!);
761
761
  computeEnumMemberValues(c, targetDecl.parent!);
@@ -1375,8 +1375,8 @@ export class Relater extends TypeComparer {
1375
1375
  return true;
1376
1376
  }
1377
1377
  const objectLiteralDeclaration =
1378
- source.symbol !== undefined && source.symbol.declarations.length !== 0
1379
- ? source.symbol.declarations[0]!
1378
+ source.symbol !== undefined && declarationCount(source.symbol) !== 0
1379
+ ? source.symbol.declaration!
1380
1380
  : undefined;
1381
1381
  const valueDeclaration = prop.valueDeclaration;
1382
1382
  let suggestion: Symbol | undefined = undefined;
@@ -3037,9 +3037,9 @@ export class Relater extends TypeComparer {
3037
3037
  names[0],
3038
3038
  names[1],
3039
3039
  ]);
3040
- if (unmatchedProperty.declarations.length !== 0)
3040
+ if (declarationCount(unmatchedProperty) !== 0)
3041
3041
  this.relatedInfo.push(
3042
- createDiagnosticForNode(unmatchedProperty.declarations[0]!, Diagnostics.X_0_is_declared_here, [propName]),
3042
+ createDiagnosticForNode(unmatchedProperty.declaration!, Diagnostics.X_0_is_declared_here, [propName]),
3043
3043
  );
3044
3044
  } else if (this.tryElaborateArrayLikeErrors(source, target, false)) {
3045
3045
  const names = getTypeNamesForErrorDisplay(c, source, target);
@@ -3486,7 +3486,7 @@ export class Relater extends TypeComparer {
3486
3486
  if (
3487
3487
  (source.flags & TypeFlags.TypeParameter) !== 0 &&
3488
3488
  source.symbol !== undefined &&
3489
- source.symbol.declarations.length !== 0 &&
3489
+ declarationCount(source.symbol) !== 0 &&
3490
3490
  getConstraintOfType(c, source) === undefined
3491
3491
  ) {
3492
3492
  const syntheticParam = cloneTypeParameter(c, source);
@@ -3494,7 +3494,7 @@ export class Relater extends TypeComparer {
3494
3494
  if (hasNonCircularBaseConstraint(c, syntheticParam)) {
3495
3495
  this.relatedInfo.push(
3496
3496
  createDiagnosticForNode(
3497
- source.symbol.declarations[0]!,
3497
+ source.symbol.declaration!,
3498
3498
  Diagnostics.This_type_parameter_might_need_an_extends_0_constraint,
3499
3499
  [typeToString(c, target)],
3500
3500
  ),
@@ -4504,7 +4504,7 @@ import { getTypeAliasInstantiation } from './checker-type-nodes.js';
4504
4504
 
4505
4505
  export function getTypeParameterModifiers(tp: Type): ModifierFlags {
4506
4506
  let flags = 0;
4507
- if (tp.symbol !== undefined) for (const d of tp.symbol.declarations) flags |= getCombinedModifierFlags(d);
4507
+ if (tp.symbol !== undefined) for (const d of getDeclarations(tp.symbol)) flags |= getCombinedModifierFlags(d);
4508
4508
  return flags & (ModifierFlags.In | ModifierFlags.Out | ModifierFlags.Const);
4509
4509
  }
4510
4510
 
@@ -35,7 +35,7 @@ import {
35
35
  isGlobalSourceFile,
36
36
  isModuleExportsAccessExpression,
37
37
  } from './binder-utilities.js';
38
- import { type Checker, SymbolAccessibilityCaches } from './checker.js';
38
+ import { type Checker, ExternalModuleContainerIndex, SymbolAccessibilityCaches, fileIndexScale } from './checker.js';
39
39
  import { getEffectiveDeclarationFlags } from './checker-declarations.js';
40
40
  import { getDeclaredTypeOfSymbol } from './checker-declared-types.js';
41
41
  import { checkExpressionCached } from './checker-expressions.js';
@@ -52,7 +52,6 @@ import {
52
52
  import { getTypeOfSymbol } from './checker-symbol-types.js';
53
53
  import { compareSymbols } from './checker-type-factory.js';
54
54
  import { TypeFlags } from './checker-types.js';
55
- import { InternalSymbolName, type Symbol, SymbolFlags, type SymbolTable, getSymbolId } from './symbol.js';
56
55
  import { SyntaxKind } from './syntax-kind.js';
57
56
  import { SymbolAccessibility, SymbolAccessibilityResult, accessible } from './transformers/declarations-resolver.js';
58
57
  import {
@@ -63,6 +62,15 @@ import {
63
62
  } from './transformers/declarations-syntactic.js';
64
63
  import { isImplicitlyExportedJSDocDeclaration } from './binder-utilities.js';
65
64
  import { symbolToString } from './type-printer.js';
65
+ import {
66
+ declarationCount,
67
+ getDeclarations,
68
+ getSymbolId,
69
+ InternalSymbolName,
70
+ type Symbol,
71
+ SymbolFlags,
72
+ type SymbolTable,
73
+ } from './symbol.js';
66
74
 
67
75
  /** The kinds of symbol table, which with a node or symbol id name a table in a scope walk. */
68
76
  const enum TableKind {
@@ -157,7 +165,7 @@ function isSymbolAccessibleWorker(
157
165
  if (result !== undefined) return result;
158
166
  // A symbol not exported from its module, or from another module without an alias, can't be named.
159
167
  let symbolExternalModule: Symbol | undefined = undefined;
160
- for (const d of symbol.declarations) {
168
+ for (const d of getDeclarations(symbol)) {
161
169
  symbolExternalModule = getExternalModuleContainer(c, d);
162
170
  if (symbolExternalModule !== undefined) break;
163
171
  }
@@ -230,7 +238,7 @@ function isAnySymbolAccessible(
230
238
  }
231
239
 
232
240
  export function hasNonGlobalAugmentationExternalModuleDeclaration(symbol: Symbol): boolean {
233
- for (const d of symbol.declarations) if (hasNonGlobalAugmentationExternalModuleSymbol(d)) return true;
241
+ for (const d of getDeclarations(symbol)) if (hasNonGlobalAugmentationExternalModuleSymbol(d)) return true;
234
242
  return false;
235
243
  }
236
244
 
@@ -252,11 +260,16 @@ export function getQualifiedLeftMeaning(rightMeaning: SymbolFlags): SymbolFlags
252
260
  return rightMeaning === SymbolFlags.Value ? SymbolFlags.Value : SymbolFlags.Namespace;
253
261
  }
254
262
 
263
+ /** The merged symbol `symbol` resolves to through aliases. */
264
+ function getResolvedTarget(c: Checker, symbol: Symbol): Symbol | undefined {
265
+ const resolved = resolveSymbol(c, getMergedSymbol(c, symbol));
266
+ return resolved !== undefined ? getMergedSymbol(c, resolved) : undefined;
267
+ }
268
+
255
269
  /** `s1` if both symbols resolve to the same symbol, else undefined. */
256
270
  export function getSymbolIfSameReference(c: Checker, s1: Symbol, s2: Symbol): Symbol | undefined {
257
- const r1 = resolveSymbol(c, getMergedSymbol(c, s1));
258
- const r2 = resolveSymbol(c, getMergedSymbol(c, s2));
259
- if (r1 !== undefined && r2 !== undefined && getMergedSymbol(c, r1) === getMergedSymbol(c, r2)) return s1;
271
+ const r1 = getResolvedTarget(c, s1);
272
+ if (r1 !== undefined && r1 === getResolvedTarget(c, s2)) return s1;
260
273
  return undefined;
261
274
  }
262
275
 
@@ -270,7 +283,7 @@ function getWithAlternativeContainers(
270
283
  meaning: SymbolFlags,
271
284
  ): Symbol[] {
272
285
  const additionalContainers: Symbol[] = [];
273
- for (const d of container.declarations) {
286
+ for (const d of getDeclarations(container)) {
274
287
  const fileSymbol = getFileSymbolIfFileSymbolExportEqualsContainer(c, d, container);
275
288
  if (fileSymbol !== undefined) additionalContainers.push(fileSymbol);
276
289
  }
@@ -350,22 +363,104 @@ function getAlternativeContainingModules(c: Checker, symbol: Symbol, enclosingDe
350
363
  }
351
364
  const cached = cache.containers.get(symbolId);
352
365
  if (cached !== undefined) return cached;
353
- // Search every module; expensive, but independent of the location.
366
+ // Search every module; independent of the location.
367
+ const containers = getExternalModuleContainers(c, symbol);
368
+ cache.containers.set(symbolId, containers);
369
+ return containers;
370
+ }
371
+
372
+ /** The modules that export `symbol`, and its parent module, in program order. */
373
+ function getExternalModuleContainers(c: Checker, symbol: Symbol): Symbol[] {
374
+ const cache = caches(c);
375
+ if (cache.externalModuleContainers === undefined) buildExternalModuleContainerIndex(c);
376
+ const index = cache.externalModuleContainers!;
377
+ // Re-entered from an alias resolved while building the index, or too many files to index.
378
+ if (!index.complete) return scanExternalModuleContainers(c, symbol);
379
+ // The parent module contains the symbol even when the symbol is absent from its exports.
380
+ const parent = getParentOfSymbol(c, symbol);
381
+ let parentIndex = externalModuleFileIndex(c, parent);
382
+ const result: Symbol[] = [];
383
+ const target = getResolvedTarget(c, symbol);
384
+ if (target !== undefined) {
385
+ const keys = index.keys;
386
+ const first = getSymbolId(target) * fileIndexScale;
387
+ let low = 0;
388
+ let high = keys.length;
389
+ while (low < high) {
390
+ const mid = (low + high) >>> 1;
391
+ if (keys[mid]! < first) low = mid + 1;
392
+ else high = mid;
393
+ }
394
+ for (let i = low; i < keys.length && keys[i]! < first + fileIndexScale; i++) {
395
+ const fileIndex = keys[i]! - first;
396
+ if (parentIndex >= 0 && parentIndex <= fileIndex) {
397
+ if (parentIndex < fileIndex) result.push(parent!);
398
+ parentIndex = -1;
399
+ }
400
+ // `as`: scriptc passes an element of a subclass array only as that class.
401
+ result.push(getSymbolOfDeclaration(c, c.files[fileIndex]! as Node)!);
402
+ }
403
+ }
404
+ if (parentIndex >= 0) result.push(parent!);
405
+ return result;
406
+ }
407
+
408
+ /** The position in `Checker.files` of the external module `symbol`, or -1 for any other symbol. */
409
+ function externalModuleFileIndex(c: Checker, symbol: Symbol | undefined): number {
410
+ if (symbol === undefined || (symbol.flags & SymbolFlags.ValueModule) === 0) return -1;
411
+ for (const declaration of getDeclarations(symbol)) {
412
+ if (declaration.kind !== SyntaxKind.SourceFile) continue;
413
+ const file = declaration as SourceFile;
414
+ if (isExternalModule(file) && getSymbolOfDeclaration(c, declaration) === symbol) return c.fileIndex.get(file) ?? -1;
415
+ }
416
+ return -1;
417
+ }
418
+
419
+ function buildExternalModuleContainerIndex(c: Checker): void {
420
+ const index = new ExternalModuleContainerIndex();
421
+ caches(c).externalModuleContainers = index;
422
+ if (c.files.length > fileIndexScale) return;
423
+ const keys: number[] = [];
424
+ for (let fileIndex = 0; fileIndex < c.files.length; fileIndex++) {
425
+ const file = c.files[fileIndex]!;
426
+ if (!isExternalModule(file)) continue;
427
+ // `as`: scriptc passes an element of a subclass array only as that class.
428
+ const container = getSymbolOfDeclaration(c, file as Node);
429
+ if (container === undefined) continue;
430
+ for (const exported of getExportsOfSymbol(c, container).values()) {
431
+ const target = getResolvedTarget(c, exported);
432
+ if (target !== undefined) keys.push(getSymbolId(target) * fileIndexScale + fileIndex);
433
+ }
434
+ const exportEquals = container.exports?.get(InternalSymbolName.ExportEquals);
435
+ const target = exportEquals !== undefined ? getResolvedTarget(c, exportEquals) : undefined;
436
+ if (target !== undefined) keys.push(getSymbolId(target) * fileIndexScale + fileIndex);
437
+ }
438
+ keys.sort((a, b) => a - b);
439
+ // A module that exports a symbol under several names gives it one key.
440
+ let kept = 0;
441
+ for (let i = 0; i < keys.length; i++) if (kept === 0 || keys[i] !== keys[kept - 1]) keys[kept++] = keys[i]!;
442
+ // An exact-size copy: each checker keeps its own index for the rest of the compilation.
443
+ index.keys = keys.slice(0, kept);
444
+ index.complete = true;
445
+ }
446
+
447
+ /** The modules that export `symbol`, found by checking every module. */
448
+ function scanExternalModuleContainers(c: Checker, symbol: Symbol): Symbol[] {
449
+ const containers: Symbol[] = [];
354
450
  for (const file of c.host.getSourceFiles()) {
355
451
  if (!isExternalModule(file)) continue;
356
452
  // `as`: scriptc passes a for-of element of a subclass array only as that class.
357
- const fileSymbol = getSymbolOfDeclaration(c, file as Node);
358
- if (fileSymbol === undefined || getAliasForSymbolInContainer(c, fileSymbol, symbol) === undefined) continue;
359
- results.push(fileSymbol);
453
+ const container = getSymbolOfDeclaration(c, file as Node);
454
+ if (container !== undefined && getAliasForSymbolInContainer(c, container, symbol) !== undefined)
455
+ containers.push(container);
360
456
  }
361
- cache.containers.set(symbolId, results);
362
- return results;
457
+ return containers;
363
458
  }
364
459
 
365
460
  /** The variable `var a = { x: 1 }` declares, for the anonymous `__object` symbol of its literal. */
366
461
  function getVariableDeclarationOfObjectLiteral(c: Checker, symbol: Symbol, meaning: SymbolFlags): Symbol | undefined {
367
- if ((meaning & SymbolFlags.Value) === 0 || symbol.declarations.length === 0) return undefined;
368
- const firstDecl = symbol.declarations[0]!;
462
+ if ((meaning & SymbolFlags.Value) === 0 || declarationCount(symbol) === 0) return undefined;
463
+ const firstDecl = symbol.declaration!;
369
464
  const parent = firstDecl.parent;
370
465
  if (parent === undefined || !(parent instanceof VariableDeclaration)) return undefined;
371
466
  if (
@@ -417,7 +512,7 @@ export function getContainersOfSymbol(
417
512
  const addCandidate = (s: Symbol | undefined): void => {
418
513
  if (s !== undefined && candidates.indexOf(s) < 0) candidates.push(s);
419
514
  };
420
- for (const d of symbol.declarations) {
515
+ for (const d of getDeclarations(symbol)) {
421
516
  const parent = d.parent;
422
517
  if (!isAmbientModule(d) && parent !== undefined) {
423
518
  // A direct child of a module.
@@ -585,7 +680,7 @@ class ChainSearch {
585
680
  (this.useOnlyExternalAliasing && !hasExternalModuleImportEqualsDeclaration(fromTable)) ||
586
681
  (isLocalNameLookup && hasNamespaceReexportDeclaration(fromTable)) ||
587
682
  // Exports are in scope, but export specifiers aren't.
588
- (!ignoreQualification && fromTable.declarations.some((d) => d.kind === SyntaxKind.ExportSpecifier))
683
+ (!ignoreQualification && getDeclarations(fromTable).some((d) => d.kind === SyntaxKind.ExportSpecifier))
589
684
  )
590
685
  continue;
591
686
  const resolved = resolveAlias(c, fromTable);
@@ -701,11 +796,11 @@ function compareSymbolChains(c: Checker, a: Symbol[], b: Symbol[]): number {
701
796
  }
702
797
 
703
798
  function isUMDExportSymbol(symbol: Symbol): boolean {
704
- return symbol.declarations.length > 0 && symbol.declarations[0].kind === SyntaxKind.NamespaceExportDeclaration;
799
+ return declarationCount(symbol) > 0 && symbol.declaration!.kind === SyntaxKind.NamespaceExportDeclaration;
705
800
  }
706
801
 
707
802
  function hasNamespaceReexportDeclaration(symbol: Symbol): boolean {
708
- for (const d of symbol.declarations) if (isNamespaceReexportDeclaration(d)) return true;
803
+ for (const d of getDeclarations(symbol)) if (isNamespaceReexportDeclaration(d)) return true;
709
804
  return false;
710
805
  }
711
806
 
@@ -718,7 +813,7 @@ function isNamespaceReexportDeclaration(node: Node): boolean {
718
813
  }
719
814
 
720
815
  function hasExternalModuleImportEqualsDeclaration(symbol: Symbol): boolean {
721
- for (const d of symbol.declarations) if (isExternalModuleImportEqualsDeclaration(d)) return true;
816
+ for (const d of getDeclarations(symbol)) if (isExternalModuleImportEqualsDeclaration(d)) return true;
722
817
  return false;
723
818
  }
724
819
 
@@ -742,7 +837,7 @@ export function needsQualification(
742
837
  // Qualify if the symbol of this name has the meaning sought.
743
838
  const shouldResolveAlias =
744
839
  (fromTable.flags & SymbolFlags.Alias) !== 0 &&
745
- !fromTable.declarations.some((d) => d.kind === SyntaxKind.ExportSpecifier);
840
+ !getDeclarations(fromTable).some((d) => d.kind === SyntaxKind.ExportSpecifier);
746
841
  if (shouldResolveAlias) fromTable = resolveAlias(c, fromTable);
747
842
  const flags = shouldResolveAlias ? getSymbolFlags(c, fromTable) : fromTable.flags;
748
843
  if ((flags & meaning) !== 0) {
@@ -755,8 +850,8 @@ export function needsQualification(
755
850
  }
756
851
 
757
852
  function isPropertyOrMethodDeclarationSymbol(symbol: Symbol): boolean {
758
- if (symbol.declarations.length === 0) return false;
759
- for (const declaration of symbol.declarations) {
853
+ if (declarationCount(symbol) === 0) return false;
854
+ for (const declaration of getDeclarations(symbol)) {
760
855
  switch (declaration.kind) {
761
856
  case SyntaxKind.PropertyDeclaration:
762
857
  case SyntaxKind.MethodDeclaration:
@@ -1007,7 +1102,7 @@ export function hasVisibleDeclarations(
1007
1102
  markDeclarationVisible(c, declaration);
1008
1103
  if (aliases.indexOf(statement) < 0) aliases.push(statement);
1009
1104
  };
1010
- for (const declaration of symbol.declarations) {
1105
+ for (const declaration of getDeclarations(symbol)) {
1011
1106
  if (declaration.kind === SyntaxKind.Identifier || isDeclarationVisible(c, declaration)) continue;
1012
1107
  // Unexported imports can name types if their parent is visible.
1013
1108
  const anyImport = getAnyImportSyntax(declaration);
@@ -150,14 +150,26 @@ export class SymbolRareFields implements ProgramLifetime {
150
150
  members: SymbolTable | undefined = undefined;
151
151
  exports: SymbolTable | undefined = undefined;
152
152
  exportSymbol: Symbol | undefined = undefined;
153
+ /** All declarations of a symbol that has more than one (`getDeclarations`). */
154
+ declarations: Node[] | undefined = undefined;
155
+ /** The value declaration where it is not the first declaration (`Symbol.valueDeclaration`). */
156
+ valueDeclaration: Node | undefined = undefined;
153
157
  }
154
158
 
159
+ /** In `Symbol.bits`, above the check flags: the value declaration is the first declaration. */
160
+ const valueDeclarationIsFirst = 1 << 30;
161
+
155
162
  export class Symbol implements ProgramLifetime {
156
163
  flags: SymbolFlags;
157
- checkFlags: CheckFlags;
164
+ /** The check flags, and `valueDeclarationIsFirst`. */
165
+ private bits: number;
158
166
  readonly name: string;
159
- declarations: Node[];
160
- valueDeclaration: Node | undefined;
167
+ /**
168
+ * The first declaration. A symbol with more keeps all of them in its rare fields; read them with
169
+ * `declarationCount`, `declarationAt` and `getDeclarations`. Written only through `setFirst`,
170
+ * which keeps the value declaration.
171
+ */
172
+ declaration: Node | undefined;
161
173
  parent: Symbol | undefined;
162
174
  private rareFields: SymbolRareFields | undefined;
163
175
  /** Assigned on first use by `getSymbolId`, or at creation while threads share the program; 0 until then. */
@@ -165,15 +177,53 @@ export class Symbol implements ProgramLifetime {
165
177
 
166
178
  constructor(flags: SymbolFlags, name: string) {
167
179
  this.flags = flags;
168
- this.checkFlags = CheckFlags.None;
180
+ this.bits = 0;
169
181
  this.name = name;
170
- this.declarations = noDeclarations;
171
- this.valueDeclaration = undefined;
182
+ this.declaration = undefined;
172
183
  this.parent = undefined;
173
184
  this.rareFields = undefined;
174
185
  this.id = idsAtCreation ? takeSymbolId() : 0;
175
186
  }
176
187
 
188
+ get checkFlags(): CheckFlags {
189
+ return (this.bits & ~valueDeclarationIsFirst) as CheckFlags;
190
+ }
191
+
192
+ set checkFlags(flags: CheckFlags) {
193
+ this.bits = (this.bits & valueDeclarationIsFirst) | flags;
194
+ }
195
+
196
+ /** Makes `node` the first declaration, keeping the value declaration. */
197
+ setFirst(node: Node | undefined): void {
198
+ if ((this.bits & valueDeclarationIsFirst) !== 0 && node !== this.declaration) {
199
+ // The value declaration stays what it was.
200
+ this.rareFieldsOrNew().valueDeclaration = this.declaration;
201
+ this.bits &= ~valueDeclarationIsFirst;
202
+ }
203
+ this.declaration = node;
204
+ }
205
+
206
+ /**
207
+ * The declaration of the symbol's value. Almost always the first declaration, which a bit of `bits`
208
+ * says; any other is kept in the rare fields.
209
+ */
210
+ get valueDeclaration(): Node | undefined {
211
+ if ((this.bits & valueDeclarationIsFirst) !== 0) return this.declaration;
212
+ const group = this.rareFields;
213
+ return group === undefined ? undefined : group.valueDeclaration;
214
+ }
215
+
216
+ set valueDeclaration(node: Node | undefined) {
217
+ const group = this.rareFields;
218
+ if (node !== undefined && node === this.declaration) {
219
+ this.bits |= valueDeclarationIsFirst;
220
+ if (group !== undefined) group.valueDeclaration = undefined;
221
+ return;
222
+ }
223
+ this.bits &= ~valueDeclarationIsFirst;
224
+ if (node !== undefined || group !== undefined) this.rareFieldsOrNew().valueDeclaration = node;
225
+ }
226
+
177
227
  private rareFieldsOrNew(): SymbolRareFields {
178
228
  let group = this.rareFields;
179
229
  if (group === undefined) {
@@ -183,6 +233,25 @@ export class Symbol implements ProgramLifetime {
183
233
  return group;
184
234
  }
185
235
 
236
+ /**
237
+ * The declarations, for tsc-ts/api's `Symbol.declarations`. The compiler reads `declaration`,
238
+ * `declarationCount` and `declarationAt`: for a single declaration this builds a list on each read.
239
+ */
240
+ get declarations(): readonly Node[] {
241
+ return getDeclarations(this);
242
+ }
243
+
244
+ /** All declarations where there are more than one, else undefined. */
245
+ get moreDeclarations(): Node[] | undefined {
246
+ const group = this.rareFields;
247
+ return group === undefined ? undefined : group.declarations;
248
+ }
249
+
250
+ set moreDeclarations(value: Node[] | undefined) {
251
+ if (value === undefined && this.rareFields === undefined) return;
252
+ this.rareFieldsOrNew().declarations = value;
253
+ }
254
+
186
255
  get members(): SymbolTable | undefined {
187
256
  const group = this.rareFields;
188
257
  return group === undefined ? undefined : group.members;
@@ -326,9 +395,58 @@ const noDeclarations: Node[] = [];
326
395
 
327
396
  /** Appends `node` to the declarations of `symbol`. */
328
397
  export function addDeclaration(symbol: Symbol, node: Node): void {
329
- const declarations = symbol.declarations;
330
- if (declarations.length === 0) symbol.declarations = [node];
331
- else declarations.push(node);
398
+ const first = symbol.declaration;
399
+ if (first === undefined) {
400
+ symbol.setFirst(node);
401
+ return;
402
+ }
403
+ const more = symbol.moreDeclarations;
404
+ if (more !== undefined) more.push(node);
405
+ else symbol.moreDeclarations = [first, node];
406
+ }
407
+
408
+ /** The number of declarations of `symbol`. */
409
+ export function declarationCount(symbol: Symbol): number {
410
+ if (symbol.declaration === undefined) return 0;
411
+ const more = symbol.moreDeclarations;
412
+ return more !== undefined ? more.length : 1;
413
+ }
414
+
415
+ /** The declaration of `symbol` at `index`, which is below `declarationCount(symbol)`. */
416
+ export function declarationAt(symbol: Symbol, index: number): Node {
417
+ return index === 0 ? symbol.declaration! : symbol.moreDeclarations![index]!;
418
+ }
419
+
420
+ /**
421
+ * The declarations of `symbol`, in order. A symbol with one declaration gets a new list each call;
422
+ * hot paths read `declaration`, `declarationCount` and `declarationAt` instead.
423
+ */
424
+ export function getDeclarations(symbol: Symbol): readonly Node[] {
425
+ const first = symbol.declaration;
426
+ if (first === undefined) return noDeclarations;
427
+ const more = symbol.moreDeclarations;
428
+ return more !== undefined ? more : [first];
429
+ }
430
+
431
+ /** Whether `node` is a declaration of `symbol`. */
432
+ export function hasDeclaration(symbol: Symbol, node: Node): boolean {
433
+ const first = symbol.declaration;
434
+ if (first === undefined) return false;
435
+ if (first === node) return true;
436
+ const more = symbol.moreDeclarations;
437
+ return more !== undefined && more.indexOf(node) >= 0;
438
+ }
439
+
440
+ /** Gives `target` the declarations of `source`; a list of several is shared, as the list was before. */
441
+ export function copyDeclarations(target: Symbol, source: Symbol): void {
442
+ target.setFirst(source.declaration);
443
+ target.moreDeclarations = source.moreDeclarations;
444
+ }
445
+
446
+ /** Replaces the declarations of `symbol` with `declarations`, which it keeps when they are more than one. */
447
+ export function setDeclarations(symbol: Symbol, declarations: readonly Node[]): void {
448
+ symbol.setFirst(declarations.length !== 0 ? declarations[0] : undefined);
449
+ symbol.moreDeclarations = declarations.length > 1 ? (declarations as Node[]) : undefined;
332
450
  }
333
451
 
334
452
  /**
@@ -46,7 +46,6 @@ import {
46
46
  getStrictOptionValue,
47
47
  shouldPreserveConstEnums,
48
48
  } from '../options.js';
49
- import { type Symbol, SymbolFlags } from '../symbol.js';
50
49
  import { SyntaxKind } from '../syntax-kind.js';
51
50
  import { getDeclarationOfAliasSymbol, type ReferenceResolver } from './reference-resolver.js';
52
51
  import {
@@ -56,6 +55,7 @@ import {
56
55
  nodeCanBeDecorated,
57
56
  } from './decorator-utilities.js';
58
57
  import { hasDecorators, hasSyntacticModifier } from './utilities.js';
58
+ import { getDeclarations, type Symbol, SymbolFlags } from '../symbol.js';
59
59
 
60
60
  export class AliasReferences extends NodeVisitor {
61
61
  readonly options: CompilerOptions;
@@ -214,7 +214,7 @@ export class AliasReferences extends NodeVisitor {
214
214
  const symbol = this.resolver.getSymbolOfDeclaration(node);
215
215
  if (symbol === undefined) return undefined;
216
216
  const kind = node.kind === SyntaxKind.SetAccessor ? SyntaxKind.GetAccessor : SyntaxKind.SetAccessor;
217
- for (const declaration of symbol.declarations) if (declaration.kind === kind) return declaration;
217
+ for (const declaration of getDeclarations(symbol)) if (declaration.kind === kind) return declaration;
218
218
  return undefined;
219
219
  }
220
220
 
@@ -30,6 +30,7 @@ import { isStatement } from '../printer/utilities.js';
30
30
  import { SyntaxKind } from '../syntax-kind.js';
31
31
  import { isParameterPropertyDeclaration } from './utilities.js';
32
32
  import { SymbolAccessibility, type SymbolAccessibilityResult } from './declarations-resolver.js';
33
+ import { getDeclarations } from '../symbol.js';
33
34
 
34
35
  export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, args: readonly string[]): Diagnostic {
35
36
  const file = getSourceFileOfNode(node);
@@ -816,7 +817,7 @@ export function getAllAccessorDeclarations(accessor: Node): AllAccessorDeclarati
816
817
  let other: Node | undefined = undefined;
817
818
  const symbol = getSymbol(accessor);
818
819
  if (symbol !== undefined)
819
- for (const declaration of symbol.declarations)
820
+ for (const declaration of getDeclarations(symbol))
820
821
  if (declaration.kind === otherKind) {
821
822
  other = declaration;
822
823
  break;
@@ -37,9 +37,9 @@ import {
37
37
  import { isFunctionLike, nodeIsMissing } from '../ast-utilities.js';
38
38
  import { getCombinedNodeFlags, hasSyntacticModifier, isIdentifierNamed } from '../binder-utilities.js';
39
39
  import type { NameResolver } from '../name-resolver.js';
40
- import { type Symbol, SymbolFlags } from '../symbol.js';
41
40
  import { SyntaxKind } from '../syntax-kind.js';
42
41
  import { getAllAccessorDeclarations } from './declarations-diagnostics.js';
42
+ import { declarationCount, getDeclarations, type Symbol, SymbolFlags } from '../symbol.js';
43
43
 
44
44
  export const enum PseudoTypeKind {
45
45
  /** The type an annotation denotes. */
@@ -359,7 +359,7 @@ export class PseudoChecker {
359
359
  // A property declared more than once has the type of its first declaration; only the checker
360
360
  // knows which, so the type is still written from this one but counted as uncertain.
361
361
  const symbol = getSymbol(node);
362
- if (symbol !== undefined && symbol.declarations.length > 1) this.uncertain++;
362
+ if (symbol !== undefined && declarationCount(symbol) > 1) this.uncertain++;
363
363
  if (node instanceof PropertyDeclaration) {
364
364
  const initializer = node.initializer;
365
365
  if (initializer !== undefined && !isContextuallyTyped(node)) {
@@ -388,7 +388,10 @@ export class PseudoChecker {
388
388
  const initializer = declaration.initializer;
389
389
  // As tsgo, the file's own declarations; merged ones are left to the checker's type comparison.
390
390
  const symbol = declaration.symbol;
391
- if (initializer !== undefined && (symbol === undefined || countVariableDeclarations(symbol.declarations) === 1)) {
391
+ if (
392
+ initializer !== undefined &&
393
+ (symbol === undefined || countVariableDeclarations(getDeclarations(symbol)) === 1)
394
+ ) {
392
395
  if (!isContextuallyTyped(declaration)) {
393
396
  // Const template literals may become literal types, so they aren't inferred.
394
397
  if (
@@ -695,7 +698,7 @@ function accessorAnnotation(node: Node): Node | undefined {
695
698
  return undefined;
696
699
  }
697
700
 
698
- function countVariableDeclarations(declarations: Node[]): number {
701
+ function countVariableDeclarations(declarations: readonly Node[]): number {
699
702
  if (declarations.length === 1) return 1;
700
703
  let count = 0;
701
704
  for (const declaration of declarations) if (declaration.kind === SyntaxKind.VariableDeclaration) count++;