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
@@ -170,6 +170,11 @@ import {
170
170
  WithStatement,
171
171
  YieldExpression,
172
172
  type Node,
173
+ propertyAssignmentPostfixToken,
174
+ propertyAssignmentType,
175
+ callQuestionDotToken,
176
+ propertyAssignmentModifiers,
177
+ callTypeArguments,
173
178
  } from '../ast.js';
174
179
  import { SyntaxKind } from '../syntax-kind.js';
175
180
  import { VisitorHooks } from './visitor-hooks.js';
@@ -381,8 +386,8 @@ export abstract class VisitorBase extends VisitorHooks {
381
386
  return this.factory.updateCallExpression(
382
387
  node,
383
388
  required(this.visitNode(node.expression), node.expression),
384
- asOptionalToken(this.visitNode(node.questionDotToken)),
385
- this.visitNodes(node.typeArguments),
389
+ asOptionalToken(this.visitNode(callQuestionDotToken(node))),
390
+ this.visitNodes(callTypeArguments(node)),
386
391
  this.visitNodes(node.arguments)!,
387
392
  node.flags,
388
393
  );
@@ -1301,10 +1306,10 @@ export abstract class VisitorBase extends VisitorHooks {
1301
1306
  if (node instanceof PropertyAssignment)
1302
1307
  return this.factory.updatePropertyAssignment(
1303
1308
  node,
1304
- this.visitModifiers(node.modifiers),
1309
+ this.visitModifiers(propertyAssignmentModifiers(node)),
1305
1310
  required(this.visitNode(node.name), node.name),
1306
- asOptionalToken(this.visitNode(node.postfixToken)),
1307
- this.visitNode(node.type),
1311
+ asOptionalToken(this.visitNode(propertyAssignmentPostfixToken(node))),
1312
+ this.visitNode(propertyAssignmentType(node)),
1308
1313
  required(this.visitNode(node.initializer), node.initializer),
1309
1314
  );
1310
1315
  break;
@@ -721,16 +721,13 @@ export class Orchestrator {
721
721
  const host = new BuildCompilerHost(sys, this.fs, this.locale);
722
722
  const configOptions = config.options;
723
723
  const checkers = threads ? checkerThreads(configOptions.checkers, configOptions.singleThreaded) : 1;
724
- if (checkers > 1 && parallelParse.spawn !== undefined) {
724
+ if (threads && configOptions.singleThreaded !== true && parallelParse.spawn !== undefined) {
725
725
  // Threads parse and bind the program's files ahead of it (parallel-parse.ts), as for plain
726
- // compiles that check on threads. Here also when the program is checked on this thread, as
727
- // after a change with old build info, whose program is parsed in full all the same. The
728
- // program's FileLoader takes the files they prepared, and resolves their imports and
729
- // references itself (`takesPreparedResolutions`): the build info lists the `package.json`
730
- // files the program's module resolution looked up, and which ones it looks up depends on the
731
- // order of its resolutions and on what its own caches hold. Declaration files that earlier
732
- // projects of the build parsed come from the build's cache, and parse threads don't load
733
- // them again.
726
+ // compiles. Here also when the program is checked on this thread, with one checker or after a
727
+ // change with old build info, whose program is parsed in full all the same. The
728
+ // program's FileLoader takes the files they prepared and the resolutions found loading them.
729
+ // Declaration files that earlier projects of the build parsed come from the build's cache,
730
+ // and parse threads don't load them again.
734
731
  const libraryDirectory = getNormalizedAbsolutePath(sys.defaultLibraryPath, sys.currentDirectory);
735
732
  const session = new ParseSession(
736
733
  parseThreads(checkers),
@@ -742,9 +739,15 @@ export class Orchestrator {
742
739
  buildSourceFileNames.has(kind === LoadKind.Library ? combinePaths(libraryDirectory, name) : name),
743
740
  );
744
741
  session.start(config.fileNames, () => {
745
- const loader = new FileLoader(host, config);
746
- loader.takesPreparedResolutions = false;
747
- const program = new Program(config, host, loader);
742
+ // The program takes the resolutions the threads found, as `tsc -p` does, and is loaded
743
+ // again resolving every file itself only where their `package.json` lookups may miss some
744
+ // of its own (`hasAllPackageJsonLookups`), which the build info lists.
745
+ let program = new Program(config, host, new FileLoader(host, config));
746
+ if (!program.hasAllPackageJsonLookups()) {
747
+ const loader = new FileLoader(host, config);
748
+ loader.takesPreparedResolutions = false;
749
+ program = new Program(config, host, loader);
750
+ }
748
751
  reportPreparedFiles(program.getSourceFiles().map((f) => f.fileName));
749
752
  if (!this.checkAndEmit(task, program, parseStart, times, oldSnapshot, mayUseThreads, then)) then();
750
753
  });
@@ -824,7 +827,7 @@ export class Orchestrator {
824
827
  this.emitAndReport(task, checked, times, oldSnapshot, undefined, incrementalProgram);
825
828
  return false;
826
829
  }
827
- const files = incrementalProgram.filesToCheck();
830
+ const files = incrementalProgram.filesForCheckers();
828
831
  if (!rechecksOnThreads(files, count, options.checkers !== undefined)) {
829
832
  this.emitAndReport(task, checked, times, oldSnapshot, undefined, incrementalProgram);
830
833
  return false;
@@ -839,6 +842,7 @@ export class Orchestrator {
839
842
  },
840
843
  true,
841
844
  incrementalProgram.emitKindsOnCheckers(files),
845
+ incrementalProgram.checksOnCheckers,
842
846
  );
843
847
  return true;
844
848
  }
@@ -18,7 +18,7 @@ import {
18
18
  type Locale,
19
19
  type MessageWithArgs,
20
20
  } from './diagnostics.js';
21
- import { CompilerHost, FileLoader } from './file-loader.js';
21
+ import { CompilerHost, FileLoader, releaseLater } from './file-loader.js';
22
22
  import { CachedFileSystem, FileSystem, type DirectoryEntries } from './file-system.js';
23
23
  import { Program, sortAndDeduplicateDiagnostics } from './program.js';
24
24
  import { ConfigParser, ParsedCommandLine as ProjectConfig } from './tsconfig.js';
@@ -437,7 +437,7 @@ function executeCompile(sys: System, commandLine: ParsedCommandLine): CommandLin
437
437
  config.fileNames.length > 0,
438
438
  );
439
439
  // While the threads load files, the program's first step (a task per root file, which looks
440
- // the file up) runs, and the tasks of the files they return are built ahead.
440
+ // the file up) runs, and the program's loader takes the files they return as they come.
441
441
  const host = new SystemCompilerHost(sys, fs, locale);
442
442
  const loader = new FileLoader(host, config);
443
443
  let rootFilesAdded = false;
@@ -447,7 +447,7 @@ function executeCompile(sys: System, commandLine: ParsedCommandLine): CommandLin
447
447
  const resolvesPackageJsons = config.configName !== '' && config.buildInfoFileName() !== '';
448
448
  session.onIdle = (batch) => {
449
449
  if (!rootFilesAdded) rootFilesAdded = loader.addRootFiles(rootFilesPerChunk);
450
- loader.takeAhead(batch.files);
450
+ loader.walkAhead(batch.files);
451
451
  if (resolvesPackageJsons) {
452
452
  const lookups = batch.packageJsons;
453
453
  for (let k = 0; k < lookups.directories.length; k++)
@@ -471,6 +471,8 @@ function executeCompile(sys: System, commandLine: ParsedCommandLine): CommandLin
471
471
  result = createProgram(host, own);
472
472
  }
473
473
  done(result);
474
+ // The session's callbacks keep the loader: its tasks go once checking has started.
475
+ releaseLater(loader);
474
476
  });
475
477
  // The build info of an incremental program is read while the threads parse: reading it needs
476
478
  // only the config (compile and recheckInParallel, tsc-compile.ts, take it from here).
@@ -504,11 +506,12 @@ export const rootFilesPerChunk = 32;
504
506
 
505
507
  /**
506
508
  * Whether threads parse and bind the files of a program with `options` ahead of it (parallel-parse.ts):
507
- * where checker threads may be used. Also for an incremental program with build info, which is checked
508
- * on this thread (`checksIncrementalOnThreads`) but parsed in full all the same, as in build mode.
509
+ * unless `--singleThreaded` is given, as tsgo parses on every core whatever its checker count. Also with
510
+ * one checker, which checks on this thread, and for an incremental program with build info, whose
511
+ * program is parsed in full all the same, as in build mode.
509
512
  */
510
513
  function parsesAhead(options: CompilerOptions): boolean {
511
- return checkerThreads(options.checkers, options.singleThreaded) > 1 && parallelParse.spawn !== undefined;
514
+ return options.singleThreaded !== true && parallelParse.spawn !== undefined;
512
515
  }
513
516
 
514
517
  /**
@@ -182,9 +182,10 @@ export function compileInParallel(
182
182
  /**
183
183
  * The rest of `compileInParallel` for an incremental program with build info: its program is shared with
184
184
  * the checker threads first, then the incremental program finds the files a change affects
185
- * (`IncrementalProgram.filesToCheck`); the threads check those when they are many enough to be worth it
186
- * (`rechecksOnThreads`), each emitting what the incremental program's emit would of the files it
187
- * checks (`emitKindsOnCheckers`), and this thread checks and emits them otherwise.
185
+ * and those whose outputs are pending (`IncrementalProgram.filesForCheckers`); the threads check those
186
+ * when they are many enough to be worth it (`rechecksOnThreads`), each emitting what the incremental
187
+ * program's emit would of the files it checks (`emitKindsOnCheckers`), and this thread checks and emits
188
+ * them otherwise.
188
189
  */
189
190
  function recheckInParallel(
190
191
  sys: System,
@@ -234,11 +235,18 @@ function recheckInParallel(
234
235
  incrementalProgram.getGlobalDiagnostics(false).length > 0
235
236
  )
236
237
  return finish();
237
- const files = incrementalProgram.filesToCheck();
238
- mark(`${files.length} files to check`);
238
+ const files = incrementalProgram.filesForCheckers();
239
+ mark(`${files.length} files to check or emit`);
239
240
  if (!rechecksOnThreads(files, threads, options.checkers !== undefined)) return finish();
240
241
  checked.checkOnly = new Set(files);
241
- startParallelCheck(checked, threads, finish, true, incrementalProgram.emitKindsOnCheckers(files));
242
+ startParallelCheck(
243
+ checked,
244
+ threads,
245
+ finish,
246
+ true,
247
+ incrementalProgram.emitKindsOnCheckers(files),
248
+ incrementalProgram.checksOnCheckers,
249
+ );
242
250
  }
243
251
 
244
252
  /**
@@ -251,7 +259,8 @@ export function rechecksOnThreads(files: readonly SourceFile[], threads: number,
251
259
  if (files.length < 2 * threads) return false;
252
260
  if (checkersGiven) return true;
253
261
  let text = 0;
254
- for (const file of files) text += file.text.length;
262
+ // A file's `end` is its text length (reading `text.length` scans a non-ASCII text in scriptc builds).
263
+ for (const file of files) text += file.end;
255
264
  return text >= recheckOnThreadsText;
256
265
  }
257
266
 
@@ -14,7 +14,7 @@ import {
14
14
  type MessageWithArgs,
15
15
  } from './diagnostics.js';
16
16
  import { type ExternalModuleIndicatorOptions, ParseOptions, ScriptKind, type SourceFile } from './ast.js';
17
- import { CompilerHost, FileLoader } from './file-loader.js';
17
+ import { CompilerHost, FileLoader, releaseLater } from './file-loader.js';
18
18
  import { CachedFileSystem } from './file-system.js';
19
19
  import { clearLibGlobalsCache } from './checker-symbols.js';
20
20
  import { forgetLazyJSDocFile, parseSourceFile } from './parser.js';
@@ -162,6 +162,25 @@ class Stamps {
162
162
  return false;
163
163
  }
164
164
 
165
+ /**
166
+ * The files whose time stamps changed, or `undefined` when a watched directory's did: a file was added,
167
+ * removed or renamed there.
168
+ */
169
+ changedFiles(): string[] | undefined {
170
+ const files: string[] = [];
171
+ for (const [path, time] of this.times) {
172
+ if (this.sys.getMTime(path) === time) continue;
173
+ if (this.directories.has(path)) return undefined;
174
+ files.push(path);
175
+ }
176
+ return files;
177
+ }
178
+
179
+ /** Takes the current time stamps of `paths`. */
180
+ refresh(paths: readonly string[]): void {
181
+ for (const path of paths) if (this.times.has(path)) this.times.set(path, this.sys.getMTime(path));
182
+ }
183
+
165
184
  /**
166
185
  * Adds the directories whose events report changes of these paths: each directory, and each file's,
167
186
  * and for a file that is a symbolic link, its target's.
@@ -428,6 +447,8 @@ class Watcher {
428
447
  * (`computeLastSignatures`).
429
448
  */
430
449
  private lastChecked: CheckedProgram | undefined = undefined;
450
+ /** The program of the last build, which a rebuild updates when only the text of its files changed. */
451
+ private lastProgram: Program | undefined = undefined;
431
452
  /** Whether a rebuild is running (`poll`), and whether a check came during it. */
432
453
  private building = false;
433
454
  private checkPending = false;
@@ -519,10 +540,12 @@ class Watcher {
519
540
  let rootFilesAdded = false;
520
541
  session.onIdle = (batch) => {
521
542
  if (!rootFilesAdded) rootFilesAdded = loader.addRootFiles(rootFilesPerChunk);
522
- loader.takeAhead(batch.files);
543
+ loader.walkAhead(batch.files);
523
544
  };
524
545
  session.start(config.fileNames, () => {
525
546
  const program = new Program(config, host, loader);
547
+ // The session's callbacks keep the loader: its tasks go once checking has started.
548
+ releaseLater(loader);
526
549
  this.files = this.files.next();
527
550
  for (const file of program.getSourceFiles()) {
528
551
  const indicator = file.externalModuleIndicatorOptions;
@@ -574,7 +597,7 @@ class Watcher {
574
597
  if (configChanged && !this.reloadConfig()) return done();
575
598
  if (this.configRead && watchRestart.restartsBeforeRebuild()) return done();
576
599
  this.status.report(Diagnostics.File_change_detected_Starting_incremental_compilation);
577
- this.build(done);
600
+ this.build(done, configChanged ? undefined : this.stamps.changedFiles());
578
601
  }
579
602
 
580
603
  /** Rereads the config file; false (after reporting) if it can't be used. */
@@ -597,24 +620,31 @@ class Watcher {
597
620
  return true;
598
621
  }
599
622
 
600
- /** Builds, on checker threads when the change affects many files, then calls `done`. */
601
- private build(done: () => void): void {
623
+ /**
624
+ * Builds, on checker threads when the change affects many files, then calls `done`. `changedFiles` are
625
+ * the files whose time stamps changed, when no watched directory's and no config file's did.
626
+ */
627
+ private build(done: () => void, changedFiles?: readonly string[]): void {
602
628
  releaseProgramCaches();
603
629
  const sys = this.sys;
604
630
  const fs = new CachedFileSystem(new SystemFileSystem(sys));
605
- if (this.config.configName !== '') {
606
- // Pick up files added to or removed from included directories.
607
- const parsed = new ConfigParser(fs, sys.currentDirectory).parseConfigFile(
608
- this.config.configName,
609
- this.commandLine.options,
610
- this.commandLine.raw,
611
- [],
612
- );
613
- if (parsed !== undefined) this.config = parsed;
631
+ let program = changedFiles !== undefined ? this.updatedProgram(changedFiles, fs) : undefined;
632
+ if (program === undefined) {
633
+ changedFiles = undefined;
634
+ if (this.config.configName !== '') {
635
+ // Pick up files added to or removed from included directories.
636
+ const parsed = new ConfigParser(fs, sys.currentDirectory).parseConfigFile(
637
+ this.config.configName,
638
+ this.commandLine.options,
639
+ this.commandLine.raw,
640
+ [],
641
+ );
642
+ if (parsed !== undefined) this.config = parsed;
643
+ }
644
+ this.files = this.files.next();
645
+ // A copy: a program shared with checker threads holds its config's errors (`copyCommandLine`).
646
+ program = new Program(copyCommandLine(this.config), new WatchCompilerHost(sys, fs, this.locale, this.files));
614
647
  }
615
- this.files = this.files.next();
616
- // A copy: a program shared with checker threads holds its config's errors (`copyCommandLine`).
617
- const program = new Program(copyCommandLine(this.config), new WatchCompilerHost(sys, fs, this.locale, this.files));
618
648
  // The signatures the last build left as versions, for the files this one parsed.
619
649
  if (this.lastChecked !== undefined && this.snapshot !== undefined)
620
650
  computeLastSignatures(this.snapshot, this.lastChecked, this.files.parsed);
@@ -623,11 +653,36 @@ class Watcher {
623
653
  const signatures = new Map<string, string>();
624
654
  const threads = this.rebuildThreads(checked, signatures);
625
655
  // A new checker for checker threads: `rebuildThreads` may have emitted declarations with this one.
626
- if (threads > 1) return this.recheckOnThreads(new CheckedProgram(program), threads, signatures, done);
627
- this.finishBuild(checked, signatures);
656
+ if (threads > 1) return this.recheckOnThreads(new CheckedProgram(program), threads, signatures, done, changedFiles);
657
+ this.finishBuild(checked, signatures, changedFiles);
628
658
  done();
629
659
  }
630
660
 
661
+ /**
662
+ * The last build's program with `changedFiles` read again (`Program.updateFile`, as tsgo's watch swaps a
663
+ * changed file into its program), or `undefined` when one of them cannot be swapped in and the program
664
+ * must be loaded again. No directory and no config file changed, so the root files are the same. The
665
+ * source files of the updated program are those of the next build (`WatchSourceFiles`), which takes the
666
+ * unchanged ones without reading them.
667
+ */
668
+ private updatedProgram(changedFiles: readonly string[], fs: CachedFileSystem): Program | undefined {
669
+ let program = this.lastProgram;
670
+ if (program === undefined) return undefined;
671
+ const files = this.files.next();
672
+ const host = new WatchCompilerHost(this.sys, fs, this.locale, files);
673
+ for (const fileName of changedFiles) {
674
+ const file = program.getSourceFile(fileName);
675
+ if (file === undefined) return undefined;
676
+ program = program.updateFile(file.path, host);
677
+ if (program === undefined) return undefined;
678
+ }
679
+ for (const file of program.getSourceFiles())
680
+ files.current.set(watchFileKey(file.fileName, file.path, file.externalModuleIndicatorOptions), file);
681
+ this.files = files;
682
+ mark(`program updated, ${changedFiles.length} files`);
683
+ return program;
684
+ }
685
+
631
686
  /**
632
687
  * The checker threads for a rebuild of `checked`, or 1 to check it on this thread: threads where the
633
688
  * change may affect enough files for them (`rechecksOnThreads`), counting each changed file and every
@@ -696,6 +751,7 @@ class Watcher {
696
751
  threads: number,
697
752
  signatures: ReadonlyMap<string, string>,
698
753
  done: () => void,
754
+ changedFiles?: readonly string[],
699
755
  ): void {
700
756
  const sys = this.sys;
701
757
  const program = checked.program;
@@ -714,14 +770,14 @@ class Watcher {
714
770
  if (rechecksOnThreads(files, threads, options.checkers !== undefined)) {
715
771
  checked.checkOnly = new Set(files);
716
772
  const finish = (): void => {
717
- this.report(incremental);
773
+ this.report(incremental, changedFiles);
718
774
  done();
719
775
  };
720
776
  startParallelCheck(checked, threads, finish, true, incremental.emitKindsOnCheckers(files));
721
777
  return;
722
778
  }
723
779
  }
724
- this.report(incremental);
780
+ this.report(incremental, changedFiles);
725
781
  done();
726
782
  }
727
783
 
@@ -729,13 +785,23 @@ class Watcher {
729
785
  * Checks (where checker threads didn't), emits and reports `checked`, and watches its inputs. `signatures`
730
786
  * are the shape signatures computed for `checked`'s files before (`rebuildThreads`).
731
787
  */
732
- private finishBuild(checked: CheckedProgram, signatures?: ReadonlyMap<string, string>): void {
788
+ private finishBuild(
789
+ checked: CheckedProgram,
790
+ signatures?: ReadonlyMap<string, string>,
791
+ changedFiles?: readonly string[],
792
+ ): void {
733
793
  const times = new CompileTimes();
734
- this.report(new IncrementalProgram(checked, times, this.snapshot, new SystemTimeStamps(this.sys), signatures));
794
+ this.report(
795
+ new IncrementalProgram(checked, times, this.snapshot, new SystemTimeStamps(this.sys), signatures),
796
+ changedFiles,
797
+ );
735
798
  }
736
799
 
737
- /** Checks (where checker threads didn't), emits and reports `incremental`, and watches its inputs. */
738
- private report(incremental: IncrementalProgram): void {
800
+ /**
801
+ * Checks (where checker threads didn't), emits and reports `incremental`, and watches its inputs: those of a
802
+ * program `updatedProgram` made are the last build's, with new time stamps for `changedFiles`.
803
+ */
804
+ private report(incremental: IncrementalProgram, changedFiles?: readonly string[]): void {
739
805
  const sys = this.sys;
740
806
  const program = incremental.program;
741
807
  const result = emitFilesAndReportErrors(
@@ -748,7 +814,9 @@ class Watcher {
748
814
  );
749
815
  this.snapshot = incremental.snapshot;
750
816
  this.lastChecked = incremental.checked;
751
- this.watchInputs(program);
817
+ this.lastProgram = program;
818
+ if (changedFiles !== undefined) this.stamps.refresh(changedFiles);
819
+ else this.watchInputs(program);
752
820
  this.status.reportErrorCount(result.diagnostics.length);
753
821
  }
754
822
 
@@ -22,6 +22,7 @@ import {
22
22
  StringLiteral,
23
23
  type Node,
24
24
  type SourceFile,
25
+ propertyAssignmentPostfixToken,
25
26
  } from './ast.js';
26
27
  import { enumNamesList } from './command-line.js';
27
28
  import {
@@ -868,7 +869,7 @@ class ConfigFileConverter {
868
869
  this.errors.push(diagnosticAtRange(this.file, element, Diagnostics.Property_assignment_expected));
869
870
  continue;
870
871
  }
871
- const postfix = element.postfixToken;
872
+ const postfix = propertyAssignmentPostfixToken(element);
872
873
  if (postfix !== undefined && postfix.kind === SyntaxKind.QuestionToken) {
873
874
  this.errors.push(
874
875
  diagnosticAtRange(this.file, postfix, Diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, '?'),