tsc-ts 0.0.5 → 0.0.7

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 (203) hide show
  1. package/README.md +1 -1
  2. package/dist/api/compiler/ast.d.ts +67 -27
  3. package/dist/api/compiler/ast.js +156 -55
  4. package/dist/api/compiler/binder-utilities.js +4 -3
  5. package/dist/api/compiler/binder.js +14 -13
  6. package/dist/api/compiler/checker-calls.js +7 -6
  7. package/dist/api/compiler/checker-contextual.js +1 -1
  8. package/dist/api/compiler/checker-declaration-order.js +2 -1
  9. package/dist/api/compiler/checker-declarations.js +14 -14
  10. package/dist/api/compiler/checker-declared-types.d.ts +1 -1
  11. package/dist/api/compiler/checker-declared-types.js +12 -11
  12. package/dist/api/compiler/checker-decorators.js +3 -3
  13. package/dist/api/compiler/checker-deprecation.js +17 -18
  14. package/dist/api/compiler/checker-destructuring.d.ts +1 -1
  15. package/dist/api/compiler/checker-destructuring.js +3 -3
  16. package/dist/api/compiler/checker-elaboration.js +8 -7
  17. package/dist/api/compiler/checker-emit-helpers.d.ts +2 -1
  18. package/dist/api/compiler/checker-emit-helpers.js +5 -4
  19. package/dist/api/compiler/checker-emit-resolver.d.ts +1 -1
  20. package/dist/api/compiler/checker-emit-resolver.js +5 -4
  21. package/dist/api/compiler/checker-grammar.js +23 -9
  22. package/dist/api/compiler/checker-heritage.d.ts +1 -1
  23. package/dist/api/compiler/checker-heritage.js +14 -13
  24. package/dist/api/compiler/checker-inference.d.ts +21 -11
  25. package/dist/api/compiler/checker-inference.js +57 -34
  26. package/dist/api/compiler/checker-javascript.d.ts +1 -1
  27. package/dist/api/compiler/checker-javascript.js +5 -4
  28. package/dist/api/compiler/checker-jsx.d.ts +1 -1
  29. package/dist/api/compiler/checker-jsx.js +4 -4
  30. package/dist/api/compiler/checker-literals.js +2 -2
  31. package/dist/api/compiler/checker-members.d.ts +32 -3
  32. package/dist/api/compiler/checker-members.js +240 -53
  33. package/dist/api/compiler/checker-modules.d.ts +15 -1
  34. package/dist/api/compiler/checker-modules.js +86 -14
  35. package/dist/api/compiler/checker-object-literals.d.ts +1 -1
  36. package/dist/api/compiler/checker-object-literals.js +11 -7
  37. package/dist/api/compiler/checker-overloads.d.ts +1 -1
  38. package/dist/api/compiler/checker-overloads.js +4 -3
  39. package/dist/api/compiler/checker-property-access.d.ts +1 -1
  40. package/dist/api/compiler/checker-property-access.js +2 -2
  41. package/dist/api/compiler/checker-services.js +2 -2
  42. package/dist/api/compiler/checker-signatures.d.ts +1 -1
  43. package/dist/api/compiler/checker-signatures.js +9 -8
  44. package/dist/api/compiler/checker-symbol-types.d.ts +2 -18
  45. package/dist/api/compiler/checker-symbol-types.js +22 -952
  46. package/dist/api/compiler/checker-symbols.d.ts +2 -2
  47. package/dist/api/compiler/checker-symbols.js +29 -27
  48. package/dist/api/compiler/checker-type-factory.d.ts +2 -2
  49. package/dist/api/compiler/checker-type-factory.js +57 -16
  50. package/dist/api/compiler/checker-type-nodes.d.ts +1 -1
  51. package/dist/api/compiler/checker-type-nodes.js +2 -2
  52. package/dist/api/compiler/checker-type-operators.d.ts +1 -1
  53. package/dist/api/compiler/checker-type-operators.js +5 -5
  54. package/dist/api/compiler/checker-types.d.ts +73 -7
  55. package/dist/api/compiler/checker-types.js +220 -43
  56. package/dist/api/compiler/checker-unused.d.ts +1 -1
  57. package/dist/api/compiler/checker-unused.js +3 -3
  58. package/dist/api/compiler/checker.d.ts +45 -8
  59. package/dist/api/compiler/checker.js +46 -9
  60. package/dist/api/compiler/diagnostics.d.ts +2 -8
  61. package/dist/api/compiler/diagnostics.js +13 -45
  62. package/dist/api/compiler/file-include.d.ts +35 -8
  63. package/dist/api/compiler/file-include.js +81 -18
  64. package/dist/api/compiler/file-loader.d.ts +33 -4
  65. package/dist/api/compiler/file-loader.js +90 -24
  66. package/dist/api/compiler/instantiation.d.ts +1 -1
  67. package/dist/api/compiler/instantiation.js +86 -50
  68. package/dist/api/compiler/link-tables.d.ts +69 -0
  69. package/dist/api/compiler/link-tables.js +236 -0
  70. package/dist/api/compiler/name-resolver.js +3 -3
  71. package/dist/api/compiler/node-builder-names.d.ts +1 -1
  72. package/dist/api/compiler/node-builder-names.js +12 -12
  73. package/dist/api/compiler/node-builder-pseudo.d.ts +1 -1
  74. package/dist/api/compiler/node-builder-pseudo.js +2 -1
  75. package/dist/api/compiler/node-builder.d.ts +1 -1
  76. package/dist/api/compiler/node-builder.js +16 -16
  77. package/dist/api/compiler/parallel-parse.d.ts +2 -0
  78. package/dist/api/compiler/parallel-parse.js +7 -1
  79. package/dist/api/compiler/parser.d.ts +33 -16
  80. package/dist/api/compiler/parser.js +127 -98
  81. package/dist/api/compiler/printer/emit-context.d.ts +5 -2
  82. package/dist/api/compiler/printer/emit-context.js +19 -13
  83. package/dist/api/compiler/printer/factory-base.js +8 -8
  84. package/dist/api/compiler/printer/factory.js +4 -4
  85. package/dist/api/compiler/printer/printer.js +6 -6
  86. package/dist/api/compiler/program-checker.d.ts +5 -0
  87. package/dist/api/compiler/program-checker.js +14 -1
  88. package/dist/api/compiler/program.js +9 -1
  89. package/dist/api/compiler/relations.d.ts +1 -1
  90. package/dist/api/compiler/relations.js +18 -13
  91. package/dist/api/compiler/reparser.js +13 -5
  92. package/dist/api/compiler/symbol-accessibility.d.ts +1 -1
  93. package/dist/api/compiler/symbol-accessibility.js +123 -26
  94. package/dist/api/compiler/symbol.d.ts +45 -3
  95. package/dist/api/compiler/symbol.js +121 -10
  96. package/dist/api/compiler/transformers/alias-references.d.ts +1 -1
  97. package/dist/api/compiler/transformers/alias-references.js +2 -1
  98. package/dist/api/compiler/transformers/class-fields.js +3 -3
  99. package/dist/api/compiler/transformers/commonjs-module.js +3 -3
  100. package/dist/api/compiler/transformers/declarations-diagnostics.js +2 -1
  101. package/dist/api/compiler/transformers/declarations-pseudo.js +6 -4
  102. package/dist/api/compiler/transformers/declarations-syntactic.d.ts +1 -1
  103. package/dist/api/compiler/transformers/declarations-syntactic.js +9 -9
  104. package/dist/api/compiler/transformers/declarations-tracker.d.ts +1 -1
  105. package/dist/api/compiler/transformers/declarations-tracker.js +3 -2
  106. package/dist/api/compiler/transformers/declarations.js +6 -5
  107. package/dist/api/compiler/transformers/module.js +2 -2
  108. package/dist/api/compiler/transformers/optional-chain.js +3 -3
  109. package/dist/api/compiler/transformers/reference-resolver.d.ts +2 -1
  110. package/dist/api/compiler/transformers/reference-resolver.js +26 -24
  111. package/dist/api/compiler/transformers/subtree-facts.d.ts +1 -0
  112. package/dist/api/compiler/transformers/subtree-facts.js +9 -7
  113. package/dist/api/compiler/transformers/syntax-facts.d.ts +1 -0
  114. package/dist/api/compiler/transformers/syntax-facts.js +9 -5
  115. package/dist/api/compiler/transformers/tagged-template.js +2 -2
  116. package/dist/api/compiler/transformers/type-eraser.js +2 -2
  117. package/dist/api/compiler/transformers/type-serialization.js +12 -12
  118. package/dist/api/compiler/transformers/visitor-base.js +3 -3
  119. package/dist/api/compiler/tsconfig.js +2 -2
  120. package/package.json +9 -9
  121. package/src/compiler/ast.ts +211 -78
  122. package/src/compiler/binder-utilities.ts +4 -3
  123. package/src/compiler/binder.ts +26 -16
  124. package/src/compiler/checker-calls.ts +8 -6
  125. package/src/compiler/checker-contextual.ts +1 -1
  126. package/src/compiler/checker-declaration-order.ts +2 -2
  127. package/src/compiler/checker-declarations.ts +21 -14
  128. package/src/compiler/checker-declared-types.ts +12 -12
  129. package/src/compiler/checker-decorators.ts +3 -3
  130. package/src/compiler/checker-deprecation.ts +17 -21
  131. package/src/compiler/checker-destructuring.ts +3 -3
  132. package/src/compiler/checker-elaboration.ts +8 -8
  133. package/src/compiler/checker-emit-helpers.ts +5 -4
  134. package/src/compiler/checker-emit-resolver.ts +5 -5
  135. package/src/compiler/checker-grammar.ts +22 -8
  136. package/src/compiler/checker-heritage.ts +21 -14
  137. package/src/compiler/checker-inference.ts +66 -34
  138. package/src/compiler/checker-javascript.ts +5 -5
  139. package/src/compiler/checker-jsx.ts +12 -8
  140. package/src/compiler/checker-literals.ts +2 -2
  141. package/src/compiler/checker-members.ts +255 -47
  142. package/src/compiler/checker-modules.ts +115 -14
  143. package/src/compiler/checker-object-literals.ts +22 -6
  144. package/src/compiler/checker-overloads.ts +6 -6
  145. package/src/compiler/checker-property-access.ts +2 -2
  146. package/src/compiler/checker-services.ts +2 -2
  147. package/src/compiler/checker-signatures.ts +9 -9
  148. package/src/compiler/checker-symbol-types.ts +20 -940
  149. package/src/compiler/checker-symbols.ts +42 -35
  150. package/src/compiler/checker-type-factory.ts +53 -16
  151. package/src/compiler/checker-type-nodes.ts +2 -2
  152. package/src/compiler/checker-type-operators.ts +13 -5
  153. package/src/compiler/checker-types.ts +223 -43
  154. package/src/compiler/checker-unused.ts +3 -3
  155. package/src/compiler/checker.ts +50 -9
  156. package/src/compiler/decoder.ts +5 -4
  157. package/src/compiler/diagnostics.ts +14 -48
  158. package/src/compiler/encoder.ts +10 -5
  159. package/src/compiler/file-include.ts +85 -17
  160. package/src/compiler/file-loader.ts +104 -35
  161. package/src/compiler/incremental.ts +39 -5
  162. package/src/compiler/instantiation.ts +99 -55
  163. package/src/compiler/link-tables.ts +245 -0
  164. package/src/compiler/name-resolver.ts +3 -3
  165. package/src/compiler/node-builder-names.ts +21 -19
  166. package/src/compiler/node-builder-pseudo.ts +2 -2
  167. package/src/compiler/node-builder.ts +24 -16
  168. package/src/compiler/parallel-check.ts +11 -8
  169. package/src/compiler/parallel-parse.ts +8 -1
  170. package/src/compiler/parse-thread.ts +0 -4
  171. package/src/compiler/parser.ts +173 -93
  172. package/src/compiler/printer/emit-context.ts +20 -15
  173. package/src/compiler/printer/factory-base.ts +14 -7
  174. package/src/compiler/printer/factory.ts +5 -3
  175. package/src/compiler/printer/printer.ts +8 -6
  176. package/src/compiler/program-checker.ts +12 -1
  177. package/src/compiler/program.ts +8 -1
  178. package/src/compiler/relations.ts +20 -12
  179. package/src/compiler/reparser.ts +14 -4
  180. package/src/compiler/symbol-accessibility.ts +120 -25
  181. package/src/compiler/symbol.ts +127 -9
  182. package/src/compiler/transformers/alias-references.ts +2 -2
  183. package/src/compiler/transformers/class-fields.ts +12 -2
  184. package/src/compiler/transformers/commonjs-module.ts +3 -2
  185. package/src/compiler/transformers/declarations-diagnostics.ts +2 -1
  186. package/src/compiler/transformers/declarations-pseudo.ts +9 -5
  187. package/src/compiler/transformers/declarations-syntactic.ts +17 -9
  188. package/src/compiler/transformers/declarations-tracker.ts +3 -3
  189. package/src/compiler/transformers/declarations.ts +7 -7
  190. package/src/compiler/transformers/module.ts +2 -1
  191. package/src/compiler/transformers/optional-chain.ts +5 -2
  192. package/src/compiler/transformers/reference-resolver.ts +37 -25
  193. package/src/compiler/transformers/subtree-facts.ts +15 -6
  194. package/src/compiler/transformers/syntax-facts.ts +10 -5
  195. package/src/compiler/transformers/tagged-template.ts +2 -2
  196. package/src/compiler/transformers/type-eraser.ts +2 -1
  197. package/src/compiler/transformers/type-serialization.ts +12 -12
  198. package/src/compiler/transformers/visitor-base.ts +10 -5
  199. package/src/compiler/tsc-build.ts +17 -13
  200. package/src/compiler/tsc-cli.ts +9 -6
  201. package/src/compiler/tsc-compile.ts +16 -7
  202. package/src/compiler/tsc-watch.ts +94 -26
  203. package/src/compiler/tsconfig.ts +2 -1
@@ -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
 
@@ -55,6 +55,9 @@ import {
55
55
  getMembers,
56
56
  getModifiers,
57
57
  getName,
58
+ callQuestionDotToken,
59
+ callTypeArguments,
60
+ newCallExpression,
58
61
  } from '../ast.js';
59
62
  import { isLeftHandSideExpression } from '../ast-utilities.js';
60
63
  import {
@@ -1209,7 +1212,14 @@ export class ClassFieldsTransformer extends Transformer {
1209
1212
  if (node instanceof CallExpression)
1210
1213
  return factory.cloneNode(
1211
1214
  node,
1212
- new CallExpression(node.expression, node.questionDotToken, node.typeArguments, node.arguments, node.flags),
1215
+ newCallExpression(
1216
+ node.expression,
1217
+ callQuestionDotToken(node),
1218
+ callTypeArguments(node),
1219
+ node.arguments,
1220
+ node.flags,
1221
+ false,
1222
+ ),
1213
1223
  );
1214
1224
  return factory.cloneNode(node, node.deepClone());
1215
1225
  }
@@ -1232,7 +1242,7 @@ export class ClassFieldsTransformer extends Transformer {
1232
1242
  const call = factory.created(
1233
1243
  new PropertyAccessExpression(
1234
1244
  target,
1235
- optional ? node.questionDotToken : undefined,
1245
+ optional ? callQuestionDotToken(node) : undefined,
1236
1246
  factory.createIdentifier('call'),
1237
1247
  optional ? NodeFlags.OptionalChain : NodeFlags.None,
1238
1248
  ),
@@ -63,6 +63,7 @@ import {
63
63
  ModifierList,
64
64
  getElements,
65
65
  getName,
66
+ callQuestionDotToken,
66
67
  } from '../ast.js';
67
68
  import { getExternalModuleName, isImportCall, isInJSFile, isRequireCall } from '../ast-utilities.js';
68
69
  import { isAssignmentExpression, isDestructuringAssignment } from '../binder-utilities.js';
@@ -1248,7 +1249,7 @@ export class CommonJSModuleTransformer extends Transformer {
1248
1249
  const updated = this.factory.updateCallExpression(
1249
1250
  node,
1250
1251
  expression,
1251
- node.questionDotToken,
1252
+ callQuestionDotToken(node),
1252
1253
  undefined,
1253
1254
  this.visitNodes(node.arguments)!,
1254
1255
  node.flags,
@@ -1340,7 +1341,7 @@ export class CommonJSModuleTransformer extends Transformer {
1340
1341
  if (rewritten !== first || visitedRest !== rest)
1341
1342
  args = new NodeList(args.pos, args.end, [rewritten].concat(visitedRest));
1342
1343
  }
1343
- return factory.updateCallExpression(node, expression, node.questionDotToken, undefined, args, node.flags);
1344
+ return factory.updateCallExpression(node, expression, callQuestionDotToken(node), undefined, args, node.flags);
1344
1345
  }
1345
1346
 
1346
1347
  private visitTaggedTemplateExpression(node: TaggedTemplateExpression): Node {
@@ -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;
@@ -33,13 +33,14 @@ import {
33
33
  getSymbol,
34
34
  getType,
35
35
  getTypeParameters,
36
+ propertyAssignmentPostfixToken,
36
37
  } from '../ast.js';
37
38
  import { isFunctionLike, nodeIsMissing } from '../ast-utilities.js';
38
39
  import { getCombinedNodeFlags, hasSyntacticModifier, isIdentifierNamed } from '../binder-utilities.js';
39
40
  import type { NameResolver } from '../name-resolver.js';
40
- import { type Symbol, SymbolFlags } from '../symbol.js';
41
41
  import { SyntaxKind } from '../syntax-kind.js';
42
42
  import { getAllAccessorDeclarations } from './declarations-diagnostics.js';
43
+ import { declarationCount, getDeclarations, type Symbol, SymbolFlags } from '../symbol.js';
43
44
 
44
45
  export const enum PseudoTypeKind {
45
46
  /** The type an annotation denotes. */
@@ -359,7 +360,7 @@ export class PseudoChecker {
359
360
  // A property declared more than once has the type of its first declaration; only the checker
360
361
  // knows which, so the type is still written from this one but counted as uncertain.
361
362
  const symbol = getSymbol(node);
362
- if (symbol !== undefined && symbol.declarations.length > 1) this.uncertain++;
363
+ if (symbol !== undefined && declarationCount(symbol) > 1) this.uncertain++;
363
364
  if (node instanceof PropertyDeclaration) {
364
365
  const initializer = node.initializer;
365
366
  if (initializer !== undefined && !isContextuallyTyped(node)) {
@@ -388,7 +389,10 @@ export class PseudoChecker {
388
389
  const initializer = declaration.initializer;
389
390
  // As tsgo, the file's own declarations; merged ones are left to the checker's type comparison.
390
391
  const symbol = declaration.symbol;
391
- if (initializer !== undefined && (symbol === undefined || countVariableDeclarations(symbol.declarations) === 1)) {
392
+ if (
393
+ initializer !== undefined &&
394
+ (symbol === undefined || countVariableDeclarations(getDeclarations(symbol)) === 1)
395
+ ) {
392
396
  if (!isContextuallyTyped(declaration)) {
393
397
  // Const template literals may become literal types, so they aren't inferred.
394
398
  if (
@@ -541,7 +545,7 @@ export class PseudoChecker {
541
545
  }
542
546
  case SyntaxKind.PropertyAssignment: {
543
547
  const assignment = property as PropertyAssignment;
544
- const postfix = assignment.postfixToken;
548
+ const postfix = propertyAssignmentPostfixToken(assignment);
545
549
  members.push(
546
550
  new PseudoMember(
547
551
  PseudoMemberKind.Property,
@@ -695,7 +699,7 @@ function accessorAnnotation(node: Node): Node | undefined {
695
699
  return undefined;
696
700
  }
697
701
 
698
- function countVariableDeclarations(declarations: Node[]): number {
702
+ function countVariableDeclarations(declarations: readonly Node[]): number {
699
703
  if (declarations.length === 1) return 1;
700
704
  let count = 0;
701
705
  for (const declaration of declarations) if (declaration.kind === SyntaxKind.VariableDeclaration) count++;