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
@@ -32,9 +32,8 @@ export declare function localizeMessage(locale: Locale, message: DiagnosticMessa
32
32
  export declare function formatMessage(text: string, args: readonly string[]): string;
33
33
  /**
34
34
  * Makes this thread compute the caches of files that do not have them yet in copies of its own: the
35
- * files may be published (immutable) and shared with other threads. Declaration files leave the
36
- * parser without them (`Parser.parseSourceFile`): they make up most of the text of a typical program,
37
- * and are rarely checked or pointed into by a diagnostic.
35
+ * files may be published (immutable) and shared with other threads. Files leave the parser without
36
+ * them (`Parser.parseSourceFile`): most files are never pointed into by a diagnostic.
38
37
  */
39
38
  export declare function useThreadTextCaches(): void;
40
39
  /** The text of a file diagnostics point into. */
@@ -51,11 +50,6 @@ export declare class DiagnosticFile {
51
50
  * thread's copy where the file may be shared (`useThreadTextCaches`).
52
51
  */
53
52
  computeCaches(): void;
54
- /**
55
- * Like `computeCaches`, from the text's UTF-16 code units `units[0, text.length)`, so the text
56
- * itself is neither searched nor copied.
57
- */
58
- computeCachesFromUnits(units: Uint16Array): void;
59
53
  /** Start offsets of each line, split at CR, LF, CRLF, LS and PS. */
60
54
  getLineStarts(): readonly number[];
61
55
  private nonASCIIStarts;
@@ -125,14 +125,14 @@ function toWellFormed(text) {
125
125
  /**
126
126
  * Where this thread computes the line starts and UTF-8 offsets of files that may be shared with other
127
127
  * threads (`useThreadTextCaches`): a copy of each such file, by file, that computes them in place.
128
- * Files leave the parser with line starts, except declaration files, and without UTF-8 offsets.
128
+ * Files leave the parser without line starts and UTF-8 offsets, except JSON files, which have line
129
+ * starts.
129
130
  */
130
131
  let threadCopies = undefined;
131
132
  /**
132
133
  * Makes this thread compute the caches of files that do not have them yet in copies of its own: the
133
- * files may be published (immutable) and shared with other threads. Declaration files leave the
134
- * parser without them (`Parser.parseSourceFile`): they make up most of the text of a typical program,
135
- * and are rarely checked or pointed into by a diagnostic.
134
+ * files may be published (immutable) and shared with other threads. Files leave the parser without
135
+ * them (`Parser.parseSourceFile`): most files are never pointed into by a diagnostic.
136
136
  */
137
137
  export function useThreadTextCaches() {
138
138
  if (threadCopies === undefined)
@@ -152,21 +152,14 @@ function threadCopyOf(file) {
152
152
  }
153
153
  return copy;
154
154
  }
155
- /** The position of the first code unit at or after `pos` that is a CR or below, or not ASCII; or `end`. */
156
- function skipPlainASCII(units, pos, end) {
157
- for (let i = pos | 0; i < end; i = (i + 1) | 0) {
158
- const c = units[i] | 0;
159
- if (c <= 13 /* CharacterCodes.carriageReturn */ || c >= 0x80)
160
- return i;
161
- }
162
- return end;
163
- }
155
+ /** The empty value of a file's position tables until they are computed. */
156
+ const noNumbers = [];
164
157
  /** The text of a file diagnostics point into. */
165
158
  export class DiagnosticFile {
166
159
  fileName;
167
160
  text;
168
161
  // Computed on first use; never empty once computed.
169
- lineStarts = [];
162
+ lineStarts = noNumbers;
170
163
  /** Whether this is a thread's copy of a possibly shared file (`threadCopyOf`). */
171
164
  isThreadCopy = false;
172
165
  constructor(fileName, text) {
@@ -182,33 +175,6 @@ export class DiagnosticFile {
182
175
  if (this.lineStarts.length === 0)
183
176
  this.lineStarts = computeLineStarts(this.text);
184
177
  }
185
- /**
186
- * Like `computeCaches`, from the text's UTF-16 code units `units[0, text.length)`, so the text
187
- * itself is neither searched nor copied.
188
- */
189
- computeCachesFromUnits(units) {
190
- const text = this.text;
191
- // ASCII texts are searched faster than walked.
192
- if (this.lineStarts.length !== 0 || Buffer.byteLength(text, 'utf8') === text.length) {
193
- this.computeCaches();
194
- return;
195
- }
196
- const length = text.length | 0;
197
- const lineStarts = [0];
198
- // Visit only the code units that may break a line; `skipPlainASCII` runs over the rest without
199
- // calls, so native builds keep its loop on registers. A CR followed by an LF leaves the line start
200
- // to the LF.
201
- for (let i = skipPlainASCII(units, 0, length); i < length; i = skipPlainASCII(units, (i + 1) | 0, length)) {
202
- const ch = units[i] | 0;
203
- if (ch === 10 /* CharacterCodes.lineFeed */ ||
204
- (ch === 13 /* CharacterCodes.carriageReturn */ &&
205
- (i + 1 >= length || (units[(i + 1) | 0] | 0) !== 10 /* CharacterCodes.lineFeed */)) ||
206
- ch === 8232 /* CharacterCodes.lineSeparator */ ||
207
- ch === 8233 /* CharacterCodes.paragraphSeparator */)
208
- lineStarts.push(i + 1);
209
- }
210
- this.lineStarts = lineStarts;
211
- }
212
178
  /** Start offsets of each line, split at CR, LF, CRLF, LS and PS. */
213
179
  getLineStarts() {
214
180
  if (this.lineStarts.length === 0) {
@@ -222,8 +188,8 @@ export class DiagnosticFile {
222
188
  // The non-ASCII characters, in order: their UTF-16 offsets, UTF-8 lengths, and the UTF-8 bytes
223
189
  // beyond one per UTF-16 code unit of the text up to and including each. Unset until first used.
224
190
  nonASCIIStarts = undefined;
225
- nonASCIILengths = [];
226
- extraBytes = [];
191
+ nonASCIILengths = noNumbers;
192
+ extraBytes = noNumbers;
227
193
  getNonASCIIStarts() {
228
194
  let starts = this.nonASCIIStarts;
229
195
  if (starts === undefined) {
@@ -232,8 +198,8 @@ export class DiagnosticFile {
232
198
  if (Buffer.byteLength(text, 'utf8') !== text.length) {
233
199
  // Scanning the UTF-8 encoding is faster than reading each code unit.
234
200
  const bytes = Buffer.from(text, 'utf8');
235
- const lengths = this.nonASCIILengths;
236
- const extraBytes = this.extraBytes;
201
+ const lengths = [];
202
+ const extraBytes = [];
237
203
  let extra = 0;
238
204
  for (let i = 0; i < bytes.length; i++) {
239
205
  const b = bytes[i];
@@ -247,6 +213,8 @@ export class DiagnosticFile {
247
213
  extraBytes.push(extra);
248
214
  i += length - 1;
249
215
  }
216
+ this.nonASCIILengths = lengths;
217
+ this.extraBytes = extraBytes;
250
218
  }
251
219
  this.nonASCIIStarts = starts;
252
220
  }
@@ -14,7 +14,11 @@ export declare const enum FileIncludeKind {
14
14
  LibFile = 5,
15
15
  AutomaticTypeDirectiveFile = 6
16
16
  }
17
- /** One reason a file is in the program. */
17
+ /**
18
+ * One reason a file is in the program. Reasons are immutable, so the program's loader takes the
19
+ * reasons a parse thread found as they are; what they compute for a program is kept by its
20
+ * IncludeProcessor (`ReasonCache`).
21
+ */
18
22
  export declare class FileIncludeReason {
19
23
  readonly kind: FileIncludeKind;
20
24
  /** The referencing file's path, for references from a file. */
@@ -26,10 +30,6 @@ export declare class FileIncludeReason {
26
30
  /** The `types` entry, for automatic type directives. */
27
31
  readonly typeReference: string;
28
32
  readonly packageId: PackageId | undefined;
29
- private relativeDiagnostic;
30
- private absoluteDiagnostic;
31
- private location;
32
- private relatedInfo;
33
33
  private constructor();
34
34
  static rootFile(index: number): FileIncludeReason;
35
35
  /** A `lib` entry, or the default library with `index` -1. */
@@ -37,7 +37,7 @@ export declare class FileIncludeReason {
37
37
  static automaticTypeDirective(typeReference: string, packageId: PackageId | undefined): FileIncludeReason;
38
38
  /** An import (`index` into the file's imports and module augmentations, -1 if `synthetic`) or a `///` reference. */
39
39
  static reference(kind: FileIncludeKind, file: string, index: number, synthetic: StringLiteral | undefined): FileIncludeReason;
40
- /** The same reason without what it has computed (a parse thread's reasons are immutable). */
40
+ /** The same reason as a new object (`IncludeProcessor.copy`). */
41
41
  copy(): FileIncludeReason;
42
42
  isReferencedFile(): boolean;
43
43
  getReferencedLocation(program: Program): ReferenceFileLocation;
@@ -84,20 +84,46 @@ export declare class ProcessingDiagnostic {
84
84
  static explainingFileInclude(file: string, reason: FileIncludeReason | undefined, message: DiagnosticMessage, args: readonly string[]): ProcessingDiagnostic;
85
85
  /** The same diagnostic with a copy of its reason (`FileIncludeReason.copy`). */
86
86
  copy(): ProcessingDiagnostic;
87
+ /** This diagnostic with `renew(reason)` for its reason; itself when that is its reason. */
88
+ withReason(renew: (reason: FileIncludeReason) => FileIncludeReason): ProcessingDiagnostic;
87
89
  toDiagnostic(program: Program): Diagnostic;
88
90
  private explainFile;
89
91
  }
90
92
  /** Include reasons of every file and the diagnostics found while loading them. */
93
+ /** What a reason computed for the program of an IncludeProcessor. */
94
+ declare class ReasonCache {
95
+ relativeDiagnostic: Diagnostic | undefined;
96
+ absoluteDiagnostic: Diagnostic | undefined;
97
+ location: ReferenceFileLocation | undefined;
98
+ relatedInfo: Diagnostic | null | undefined;
99
+ }
91
100
  export declare class IncludeProcessor {
92
101
  readonly fileIncludeReasons: Map<string, FileIncludeReason[]>;
93
102
  readonly processingDiagnostics: ProcessingDiagnostic[];
94
103
  private computed;
104
+ /** What each reason computed for this processor's program, once it computed something. */
105
+ private readonly reasonCaches;
95
106
  private compilerOptionsObject;
96
107
  private compilerOptionsComputed;
97
108
  private readonly redirectAndFileFormat;
109
+ /** The number of processing diagnostics when the program was created (`noteProgramCreated`). */
110
+ private createdCount;
98
111
  constructor(fileIncludeReasons?: Map<string, FileIncludeReason[]>, processingDiagnostics?: ProcessingDiagnostic[]);
99
- /** A processor with these reasons and processing diagnostics, whose diagnostics are computed for another program. */
100
- copy(): IncludeProcessor;
112
+ /** What `reason` computed for this processor's program, if anything. */
113
+ cacheOf(reason: FileIncludeReason): ReasonCache | undefined;
114
+ /** The cache of `reason`, created if needed. */
115
+ newCacheOf(reason: FileIncludeReason): ReasonCache;
116
+ /**
117
+ * A processor with these reasons and the processing diagnostics its program was created with, whose diagnostics are
118
+ * computed for another program. Computing the common source directory later adds diagnostics that the program
119
+ * does not report (`Program.commonSourceDirectory`), and those of a program shared with checker threads are
120
+ * immutable, so the copy has its own list. The reasons written in `replaced`, the path of the file
121
+ * `Program.updateFile` swaps in, are new: a reason keeps where its file writes it, which the new text may move. Each
122
+ * is copied once, so a diagnostic and the file's reasons still share it.
123
+ */
124
+ copy(replaced?: string): IncludeProcessor;
125
+ /** The program is created: the processing diagnostics so far are those a copy takes. */
126
+ noteProgramCreated(): void;
101
127
  reasonsOf(path: string): readonly FileIncludeReason[];
102
128
  addReason(path: string, reason: FileIncludeReason): void;
103
129
  addProcessingDiagnostic(diagnostic: ProcessingDiagnostic): void;
@@ -115,3 +141,4 @@ export declare class IncludeProcessor {
115
141
  */
116
142
  explainRedirectAndImpliedFormat(program: Program, path: string, relative: boolean): readonly Diagnostic[];
117
143
  }
144
+ export {};
@@ -10,7 +10,11 @@ import { isExternalOrCommonJSModule, libNames, scriptTargetName } from './progra
10
10
  import { skipTrivia } from './scanner.js';
11
11
  import { getSpellingSuggestion } from './spelling.js';
12
12
  import { diagnosticAtNode, findArrayElement, findPropertyAssignment, findTsConfigArrayElement, getTsConfigObjectLiteral, } from './tsconfig.js';
13
- /** One reason a file is in the program. */
13
+ /**
14
+ * One reason a file is in the program. Reasons are immutable, so the program's loader takes the
15
+ * reasons a parse thread found as they are; what they compute for a program is kept by its
16
+ * IncludeProcessor (`ReasonCache`).
17
+ */
14
18
  export class FileIncludeReason {
15
19
  kind;
16
20
  file;
@@ -18,10 +22,6 @@ export class FileIncludeReason {
18
22
  synthetic;
19
23
  typeReference;
20
24
  packageId;
21
- relativeDiagnostic = undefined;
22
- absoluteDiagnostic = undefined;
23
- location = undefined;
24
- relatedInfo = undefined;
25
25
  constructor(kind,
26
26
  /** The referencing file's path, for references from a file. */
27
27
  file,
@@ -52,7 +52,7 @@ export class FileIncludeReason {
52
52
  static reference(kind, file, index, synthetic) {
53
53
  return new FileIncludeReason(kind, file, index, synthetic, '', undefined);
54
54
  }
55
- /** The same reason without what it has computed (a parse thread's reasons are immutable). */
55
+ /** The same reason as a new object (`IncludeProcessor.copy`). */
56
56
  copy() {
57
57
  return new FileIncludeReason(this.kind, this.file, this.index, this.synthetic, this.typeReference, this.packageId);
58
58
  }
@@ -60,8 +60,9 @@ export class FileIncludeReason {
60
60
  return this.kind <= 3 /* FileIncludeKind.LibReferenceDirective */;
61
61
  }
62
62
  getReferencedLocation(program) {
63
- if (this.location !== undefined)
64
- return this.location;
63
+ const cache = program.includeProcessor.cacheOf(this);
64
+ if (cache !== undefined && cache.location !== undefined)
65
+ return cache.location;
65
66
  const file = program.getSourceFileByPath(this.file);
66
67
  if (file === undefined)
67
68
  throw new Error('referencing file is not in the program');
@@ -101,21 +102,23 @@ export class FileIncludeReason {
101
102
  location = new ReferenceFileLocation(file, undefined, file.libReferenceDirectives[this.index], undefined, false);
102
103
  }
103
104
  if (!program.isShared())
104
- this.location = location;
105
+ program.includeProcessor.newCacheOf(this).location = location;
105
106
  return location;
106
107
  }
107
108
  /** The reason as a message, with file names relative to the current directory if `relative`. */
108
109
  toDiagnostic(program, relative) {
109
- const cached = relative ? this.relativeDiagnostic : this.absoluteDiagnostic;
110
+ const cache = program.includeProcessor.cacheOf(this);
111
+ const cached = cache === undefined ? undefined : relative ? cache.relativeDiagnostic : cache.absoluteDiagnostic;
110
112
  if (cached !== undefined)
111
113
  return cached;
112
114
  const diagnostic = this.computeDiagnostic(program, relative);
113
115
  if (program.isShared())
114
116
  return diagnostic;
117
+ const own = program.includeProcessor.newCacheOf(this);
115
118
  if (relative)
116
- this.relativeDiagnostic = diagnostic;
119
+ own.relativeDiagnostic = diagnostic;
117
120
  else
118
- this.absoluteDiagnostic = diagnostic;
121
+ own.absoluteDiagnostic = diagnostic;
119
122
  return diagnostic;
120
123
  }
121
124
  computeDiagnostic(program, relative) {
@@ -194,11 +197,12 @@ export class FileIncludeReason {
194
197
  }
195
198
  /** Where in the config or a file this reason is written, as related information; `undefined` if nowhere. */
196
199
  toRelatedInfo(program) {
197
- if (this.relatedInfo !== undefined)
198
- return this.relatedInfo ?? undefined;
200
+ const cache = program.includeProcessor.cacheOf(this);
201
+ if (cache !== undefined && cache.relatedInfo !== undefined)
202
+ return cache.relatedInfo ?? undefined;
199
203
  const info = this.computeRelatedInfo(program);
200
204
  if (!program.isShared())
201
- this.relatedInfo = info ?? null;
205
+ program.includeProcessor.newCacheOf(this).relatedInfo = info ?? null;
202
206
  return info;
203
207
  }
204
208
  computeRelatedInfo(program) {
@@ -330,6 +334,13 @@ export class ProcessingDiagnostic {
330
334
  copy() {
331
335
  return new ProcessingDiagnostic(this.kind, this.file, this.reason?.copy(), this.message, this.args);
332
336
  }
337
+ /** This diagnostic with `renew(reason)` for its reason; itself when that is its reason. */
338
+ withReason(renew) {
339
+ const reason = this.reason === undefined ? undefined : renew(this.reason);
340
+ return reason === this.reason
341
+ ? this
342
+ : new ProcessingDiagnostic(this.kind, this.file, reason, this.message, this.args);
343
+ }
333
344
  toDiagnostic(program) {
334
345
  const reason = this.reason;
335
346
  if (this.kind === 0 /* ProcessingDiagnosticKind.UnknownReference */ && reason !== undefined) {
@@ -414,20 +425,72 @@ function stripLibAffixes(name) {
414
425
  return result;
415
426
  }
416
427
  /** Include reasons of every file and the diagnostics found while loading them. */
428
+ /** What a reason computed for the program of an IncludeProcessor. */
429
+ class ReasonCache {
430
+ relativeDiagnostic = undefined;
431
+ absoluteDiagnostic = undefined;
432
+ location = undefined;
433
+ relatedInfo = undefined;
434
+ }
417
435
  export class IncludeProcessor {
418
436
  fileIncludeReasons;
419
437
  processingDiagnostics;
420
438
  computed = undefined;
439
+ /** What each reason computed for this processor's program, once it computed something. */
440
+ reasonCaches = new Map();
421
441
  compilerOptionsObject = undefined;
422
442
  compilerOptionsComputed = false;
423
443
  redirectAndFileFormat = new Map();
444
+ /** The number of processing diagnostics when the program was created (`noteProgramCreated`). */
445
+ createdCount = undefined;
424
446
  constructor(fileIncludeReasons = new Map(), processingDiagnostics = []) {
425
447
  this.fileIncludeReasons = fileIncludeReasons;
426
448
  this.processingDiagnostics = processingDiagnostics;
427
449
  }
428
- /** A processor with these reasons and processing diagnostics, whose diagnostics are computed for another program. */
429
- copy() {
430
- return new IncludeProcessor(this.fileIncludeReasons, this.processingDiagnostics);
450
+ /** What `reason` computed for this processor's program, if anything. */
451
+ cacheOf(reason) {
452
+ return this.reasonCaches.get(reason);
453
+ }
454
+ /** The cache of `reason`, created if needed. */
455
+ newCacheOf(reason) {
456
+ let cache = this.reasonCaches.get(reason);
457
+ if (cache === undefined) {
458
+ cache = new ReasonCache();
459
+ this.reasonCaches.set(reason, cache);
460
+ }
461
+ return cache;
462
+ }
463
+ /**
464
+ * A processor with these reasons and the processing diagnostics its program was created with, whose diagnostics are
465
+ * computed for another program. Computing the common source directory later adds diagnostics that the program
466
+ * does not report (`Program.commonSourceDirectory`), and those of a program shared with checker threads are
467
+ * immutable, so the copy has its own list. The reasons written in `replaced`, the path of the file
468
+ * `Program.updateFile` swaps in, are new: a reason keeps where its file writes it, which the new text may move. Each
469
+ * is copied once, so a diagnostic and the file's reasons still share it.
470
+ */
471
+ copy(replaced) {
472
+ const created = this.processingDiagnostics.slice(0, this.createdCount ?? this.processingDiagnostics.length);
473
+ if (replaced === undefined)
474
+ return new IncludeProcessor(this.fileIncludeReasons, created);
475
+ const copies = new Map();
476
+ const renew = (reason) => {
477
+ if (reason.file !== replaced)
478
+ return reason;
479
+ let copy = copies.get(reason);
480
+ if (copy === undefined) {
481
+ copy = reason.copy();
482
+ copies.set(reason, copy);
483
+ }
484
+ return copy;
485
+ };
486
+ const reasons = new Map();
487
+ for (const [path, list] of this.fileIncludeReasons)
488
+ reasons.set(path, list.some((reason) => reason.file === replaced) ? list.map(renew) : list);
489
+ return new IncludeProcessor(reasons, created.map((diagnostic) => diagnostic.withReason(renew)));
490
+ }
491
+ /** The program is created: the processing diagnostics so far are those a copy takes. */
492
+ noteProgramCreated() {
493
+ this.createdCount = this.processingDiagnostics.length;
431
494
  }
432
495
  reasonsOf(path) {
433
496
  return this.fileIncludeReasons.get(path) ?? [];
@@ -86,7 +86,7 @@ export declare class LoadedReference {
86
86
  * What a parse thread's FileLoader found loading a file it prepared (parallel-parse.ts): the same
87
87
  * as the program's FileLoader finds, since both load with the same options and file system. The
88
88
  * program's FileLoader takes it instead of resolving the file's references, imports and type
89
- * directives again. Published with the file, so the reasons are copied when taken.
89
+ * directives again, and takes its reasons as they are (they are immutable).
90
90
  */
91
91
  export declare class LoadedFile {
92
92
  readonly file: SourceFile;
@@ -200,6 +200,10 @@ export declare class FileLoader {
200
200
  private rootFilesAdded;
201
201
  /** The sub-tasks of prepared files, by file name, built ahead by `takeAhead`. */
202
202
  private readonly subTasksAhead;
203
+ /** Whether the work of the root tasks is queued (`startRootTasks`). */
204
+ private rootTasksStarted;
205
+ /** Set while `walkAhead` runs: the walk stops at work that would parse a file not prepared yet. */
206
+ private walkingAhead;
203
207
  /**
204
208
  * Whether a file that parse threads prepared is loaded from what its thread found (its metadata
205
209
  * and resolutions). If not, only the parsed and bound file is taken, and this loader looks up the
@@ -215,12 +219,30 @@ export declare class FileLoader {
215
219
  * task is added.
216
220
  */
217
221
  addRootFiles(count: number): boolean;
222
+ /** Builds ahead what loading takes from each of `files` (`takeLoadedFile`). */
223
+ private takeAhead;
218
224
  /**
219
- * Builds ahead what loading takes from each of `files` (`takeLoadedFile`): the main thread does
220
- * this while parse threads load more files (parallel-parse.ts).
225
+ * Loads what it can while parse threads load more files (parallel-parse.ts), the main thread's work
226
+ * for each batch they return: builds ahead what loading takes from its `files` (`takeAhead`), and once
227
+ * every root file's task is added, runs the walk `load` would run, in the same order, up to work that
228
+ * would parse a file the threads have not prepared yet. A later batch, or `load`, goes on from there.
229
+ * The order decides the program where a file is reached at several depths (the depth it is first
230
+ * loaded at decides the depths of the files it adds), so the walk keeps it.
221
231
  */
222
- takeAhead(files: readonly PreparedFile[]): void;
232
+ walkAhead(files: readonly PreparedFile[]): void;
223
233
  load(): ProcessedFiles;
234
+ /** Adds the tasks of the libraries and of the automatic type directives, after those of the root files. */
235
+ private addLastRootTasks;
236
+ /** Adds the last root tasks and queues the work of every root task, once every root file's task is added. */
237
+ private startRootTasks;
238
+ private walk;
239
+ /**
240
+ * Drops the tasks once the program has its files, so that whatever holds the loader after loading
241
+ * (a parse session's callbacks) no longer keeps every file's task, sub-task list and resolution
242
+ * traces. Freeing them takes a while on large programs, so the drivers call this once checking
243
+ * has started (`releaseLater`).
244
+ */
245
+ release(): void;
224
246
  /**
225
247
  * Parse threads (parallel-parse.ts): loads one file as `load` would, parsing it through
226
248
  * `host.getSourceFile`, and adds the files it references, imports and type directives add to `out`
@@ -242,6 +264,11 @@ export declare class FileLoader {
242
264
  private libFilePriority;
243
265
  private start;
244
266
  private run;
267
+ /**
268
+ * Whether running the work of `task` (of `data`'s path) may parse a file that parse threads have not
269
+ * prepared yet: a task of the path not loaded yet, or `task`, a new casing.
270
+ */
271
+ private parsesUnprepared;
245
272
  private loadTask;
246
273
  /** Loads `task` from what a parse thread found loading the same file (`LoadedFile`). */
247
274
  private takeLoadedFile;
@@ -254,6 +281,8 @@ export declare class FileLoader {
254
281
  private resolveImportsAndModuleAugmentations;
255
282
  private collect;
256
283
  }
284
+ /** Releases `loader` (`FileLoader.release`) on a later turn of the event loop, while checking runs. */
285
+ export declare function releaseLater(loader: FileLoader): void;
257
286
  /**
258
287
  * The metadata of `fileName` in a program with `options`: the `type` and directory of its nearest
259
288
  * package.json (`resolver`), where they apply, and its implied module format.
@@ -6,7 +6,7 @@ import { FileIncludeReason, IncludeProcessor, ProcessingDiagnostic } from './fil
6
6
  import { ModuleResolutionHost, Resolver, getAutomaticTypeDirectiveNames } from './module-resolution.js';
7
7
  import { getResolutionDiagnostic, inferredTypesContainingFile, } from './module-resolution-types.js';
8
8
  import { getAllowJS, getIsolatedModules, getModuleResolutionKind, ModuleKind, ModuleResolutionKind, } from './options.js';
9
- import { preparedLoad, preparedPackageJsonLookups, takePreparedFile, } from './parallel-parse.js';
9
+ import { isPrepared, preparedLoad, preparedPackageJsonLookups, takePreparedFile, } from './parallel-parse.js';
10
10
  import { parseSourceFile } from './parser.js';
11
11
  import { mark } from './timeline.js';
12
12
  import { combinePaths, fileExtensionIsOneOf, getCanonicalFileName, getDirectoryPath, getNormalizedAbsolutePath, getRootLength, hasJSFileExtension, isRootedDiskPath, normalizePath, normalizeSlashes, removeTrailingDirectorySeparator, supportedTSExtensionsWithJsonFlat, toFileNameLowerCase, toPath, } from './path.js';
@@ -132,7 +132,7 @@ export class LoadedReference {
132
132
  * What a parse thread's FileLoader found loading a file it prepared (parallel-parse.ts): the same
133
133
  * as the program's FileLoader finds, since both load with the same options and file system. The
134
134
  * program's FileLoader takes it instead of resolving the file's references, imports and type
135
- * directives again. Published with the file, so the reasons are copied when taken.
135
+ * directives again, and takes its reasons as they are (they are immutable).
136
136
  */
137
137
  export class LoadedFile {
138
138
  file;
@@ -358,7 +358,7 @@ export function withReplacedFile(processed, file) {
358
358
  files[files.findIndex((f) => f.path === file.path)] = file;
359
359
  const filesByPath = new Map(processed.filesByPath);
360
360
  filesByPath.set(file.path, file);
361
- return new ProcessedFiles(processed.resolver, files, filesByPath, processed.missingFiles, processed.resolvedModules, processed.typeResolutionsInFile, processed.sourceFileMetadata, processed.jsxRuntimeImports, processed.importHelpersImportSpecifiers, processed.libFiles, processed.sourceFilesFoundSearchingNodeModules, processed.includeProcessor.copy(), processed.outputFileToProjectReferenceSource, processed.redirectTargets, processed.redirectFilesByPath, processed.projectReferenceMapper, processed.preparedPackageJsons);
361
+ return new ProcessedFiles(processed.resolver, files, filesByPath, processed.missingFiles, processed.resolvedModules, processed.typeResolutionsInFile, processed.sourceFileMetadata, processed.jsxRuntimeImports, processed.importHelpersImportSpecifiers, processed.libFiles, processed.sourceFilesFoundSearchingNodeModules, processed.includeProcessor.copy(file.path), processed.outputFileToProjectReferenceSource, processed.redirectTargets, processed.redirectFilesByPath, processed.projectReferenceMapper, processed.preparedPackageJsons);
362
362
  }
363
363
  /** Whether `file` imports the `importHelpers` module (tslib) under `options`. */
364
364
  export function needsImportHelpersImportSpecifier(file, options) {
@@ -456,6 +456,10 @@ export class FileLoader {
456
456
  rootFilesAdded = 0;
457
457
  /** The sub-tasks of prepared files, by file name, built ahead by `takeAhead`. */
458
458
  subTasksAhead = new Map();
459
+ /** Whether the work of the root tasks is queued (`startRootTasks`). */
460
+ rootTasksStarted = false;
461
+ /** Set while `walkAhead` runs: the walk stops at work that would parse a file not prepared yet. */
462
+ walkingAhead = false;
459
463
  /**
460
464
  * Whether a file that parse threads prepared is loaded from what its thread found (its metadata
461
465
  * and resolutions). If not, only the parsed and bound file is taken, and this loader looks up the
@@ -498,10 +502,7 @@ export class FileLoader {
498
502
  this.rootFilesAdded = end;
499
503
  return end === rootFiles.length;
500
504
  }
501
- /**
502
- * Builds ahead what loading takes from each of `files` (`takeLoadedFile`): the main thread does
503
- * this while parse threads load more files (parallel-parse.ts).
504
- */
505
+ /** Builds ahead what loading takes from each of `files` (`takeLoadedFile`). */
505
506
  takeAhead(files) {
506
507
  for (const prepared of files) {
507
508
  const loaded = prepared.loaded;
@@ -513,10 +514,39 @@ export class FileLoader {
513
514
  this.subTasksAhead.set(prepared.fileName, new SubTasksAhead(loaded, subTasks));
514
515
  }
515
516
  }
517
+ /**
518
+ * Loads what it can while parse threads load more files (parallel-parse.ts), the main thread's work
519
+ * for each batch they return: builds ahead what loading takes from its `files` (`takeAhead`), and once
520
+ * every root file's task is added, runs the walk `load` would run, in the same order, up to work that
521
+ * would parse a file the threads have not prepared yet. A later batch, or `load`, goes on from there.
522
+ * The order decides the program where a file is reached at several depths (the depth it is first
523
+ * loaded at decides the depths of the files it adds), so the walk keeps it.
524
+ */
525
+ walkAhead(files) {
526
+ this.takeAhead(files);
527
+ if (!this.rootTasksStarted && this.rootFilesAdded < this.config.fileNames.length)
528
+ return;
529
+ this.startRootTasks();
530
+ this.walkingAhead = true;
531
+ this.walk();
532
+ this.walkingAhead = false;
533
+ }
516
534
  load() {
517
- const rootFiles = this.config.fileNames;
518
- this.addRootFiles(rootFiles.length);
519
- if (rootFiles.length > 0 && this.options.noLib !== true) {
535
+ this.addRootFiles(this.config.fileNames.length);
536
+ this.startRootTasks();
537
+ mark('loader roots added');
538
+ this.walk();
539
+ mark('loader walked');
540
+ const result = this.collect();
541
+ mark('loader collected');
542
+ this.mapper.loader = undefined;
543
+ return result;
544
+ }
545
+ /** Adds the tasks of the libraries and of the automatic type directives, after those of the root files. */
546
+ addLastRootTasks() {
547
+ if (this.config.fileNames.length === 0)
548
+ return;
549
+ if (this.options.noLib !== true) {
520
550
  const lib = this.options.lib;
521
551
  if (lib === undefined) {
522
552
  const libFile = this.pathForLibFile(getDefaultLibFileName(this.options));
@@ -532,21 +562,41 @@ export class FileLoader {
532
562
  }
533
563
  }
534
564
  }
535
- if (rootFiles.length > 0) {
536
- const containingDirectory = this.options.configFilePath !== undefined
537
- ? getDirectoryPath(this.options.configFilePath)
538
- : this.host.currentDirectory;
539
- this.rootTasks.push(new ParseTask(combinePaths(containingDirectory, inferredTypesContainingFile), undefined, undefined, true, false, false, undefined));
540
- }
541
- mark('loader roots added');
565
+ const containingDirectory = this.options.configFilePath !== undefined
566
+ ? getDirectoryPath(this.options.configFilePath)
567
+ : this.host.currentDirectory;
568
+ this.rootTasks.push(new ParseTask(combinePaths(containingDirectory, inferredTypesContainingFile), undefined, undefined, true, false, false, undefined));
569
+ }
570
+ /** Adds the last root tasks and queues the work of every root task, once every root file's task is added. */
571
+ startRootTasks() {
572
+ if (this.rootTasksStarted)
573
+ return;
574
+ this.rootTasksStarted = true;
575
+ this.addLastRootTasks();
542
576
  this.start(this.rootTasks, 0);
543
- for (let work = this.work.pop(); work !== undefined; work = this.work.pop())
577
+ }
578
+ walk() {
579
+ for (let work = this.work.pop(); work !== undefined; work = this.work.pop()) {
580
+ if (this.walkingAhead && this.parsesUnprepared(work.tasks[work.index], work.data)) {
581
+ this.work.push(work);
582
+ return;
583
+ }
544
584
  this.run(work);
545
- mark('loader walked');
546
- const result = this.collect();
547
- mark('loader collected');
548
- this.mapper.loader = undefined;
549
- return result;
585
+ }
586
+ }
587
+ /**
588
+ * Drops the tasks once the program has its files, so that whatever holds the loader after loading
589
+ * (a parse session's callbacks) no longer keeps every file's task, sub-task list and resolution
590
+ * traces. Freeing them takes a while on large programs, so the drivers call this once checking
591
+ * has started (`releaseLater`).
592
+ */
593
+ release() {
594
+ this.rootTasks.length = 0;
595
+ this.taskDataByPath.clear();
596
+ this.work.length = 0;
597
+ this.subTasksAhead.clear();
598
+ this.referenceTasks.clear();
599
+ this.paths.clear();
550
600
  }
551
601
  /**
552
602
  * Parse threads (parallel-parse.ts): loads one file as `load` would, parsing it through
@@ -842,6 +892,18 @@ export class FileLoader {
842
892
  }
843
893
  }
844
894
  }
895
+ /**
896
+ * Whether running the work of `task` (of `data`'s path) may parse a file that parse threads have not
897
+ * prepared yet: a task of the path not loaded yet, or `task`, a new casing.
898
+ */
899
+ parsesUnprepared(task, data) {
900
+ if (!data.tasks.has(task.normalizedFilePath) && !isPrepared(task.normalizedFilePath))
901
+ return true;
902
+ for (const other of data.tasks.values())
903
+ if (!other.loaded && !other.isForAutomaticTypeDirective && !isPrepared(other.normalizedFilePath))
904
+ return true;
905
+ return false;
906
+ }
845
907
  loadTask(task) {
846
908
  task.loaded = true;
847
909
  if (task.isForAutomaticTypeDirective) {
@@ -924,7 +986,7 @@ export class FileLoader {
924
986
  const subTasks = [];
925
987
  for (const reference of loaded.references) {
926
988
  const libFile = reference.libName !== '' ? this.pathForLibFile(reference.libName) : undefined;
927
- subTasks.push(new ParseTask(reference.normalizedFilePath, libFile, reference.reason.copy(), false, reference.increaseDepth, reference.elideOnDepth, reference.packageId));
989
+ subTasks.push(new ParseTask(reference.normalizedFilePath, libFile, reference.reason, false, reference.increaseDepth, reference.elideOnDepth, reference.packageId));
928
990
  }
929
991
  return subTasks;
930
992
  }
@@ -1194,6 +1256,10 @@ export class FileLoader {
1194
1256
  }
1195
1257
  }
1196
1258
  const noPackageJsonLookups = [];
1259
+ /** Releases `loader` (`FileLoader.release`) on a later turn of the event loop, while checking runs. */
1260
+ export function releaseLater(loader) {
1261
+ setImmediate(() => loader.release());
1262
+ }
1197
1263
  function addIncludeReason(processor, task, reason) {
1198
1264
  const redirected = task.redirectedParseTask;
1199
1265
  if (redirected !== undefined)