tsc-ts 0.0.7 → 0.0.9

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 (39) hide show
  1. package/README.md +1 -1
  2. package/dist/api/compiler/checker-declaration-order.js +3 -2
  3. package/dist/api/compiler/checker-declared-types.js +6 -3
  4. package/dist/api/compiler/checker-deprecation.js +14 -13
  5. package/dist/api/compiler/checker-destructuring.js +3 -2
  6. package/dist/api/compiler/checker-members.js +6 -2
  7. package/dist/api/compiler/checker-source-file.d.ts +12 -0
  8. package/dist/api/compiler/checker-source-file.js +35 -0
  9. package/dist/api/compiler/checker-symbol-types.js +5 -5
  10. package/dist/api/compiler/checker-symbols.js +5 -2
  11. package/dist/api/compiler/checker.d.ts +6 -1
  12. package/dist/api/compiler/checker.js +9 -1
  13. package/dist/api/compiler/file-loader.d.ts +2 -2
  14. package/dist/api/compiler/file-loader.js +43 -23
  15. package/dist/api/compiler/link-tables.d.ts +7 -0
  16. package/dist/api/compiler/link-tables.js +22 -0
  17. package/dist/api/compiler/parser.d.ts +7 -0
  18. package/dist/api/compiler/parser.js +55 -32
  19. package/dist/api/compiler/program-checker.d.ts +18 -0
  20. package/dist/api/compiler/program-checker.js +35 -2
  21. package/dist/api/library/diagnostics.d.ts +10 -0
  22. package/dist/api/library/diagnostics.js +20 -0
  23. package/package.json +9 -9
  24. package/src/compiler/checker-declaration-order.ts +3 -2
  25. package/src/compiler/checker-declared-types.ts +6 -3
  26. package/src/compiler/checker-deprecation.ts +13 -11
  27. package/src/compiler/checker-destructuring.ts +11 -2
  28. package/src/compiler/checker-members.ts +6 -2
  29. package/src/compiler/checker-source-file.ts +34 -0
  30. package/src/compiler/checker-symbol-types.ts +14 -4
  31. package/src/compiler/checker-symbols.ts +6 -2
  32. package/src/compiler/checker.ts +8 -1
  33. package/src/compiler/file-loader.ts +49 -24
  34. package/src/compiler/link-tables.ts +32 -0
  35. package/src/compiler/parallel-check.ts +199 -20
  36. package/src/compiler/parser.ts +55 -32
  37. package/src/compiler/program-checker.ts +36 -2
  38. package/src/compiler/thread-entry.ts +16 -1
  39. package/src/library/diagnostics.ts +23 -0
package/README.md CHANGED
@@ -31,7 +31,7 @@ npx tsc-ts -p tsconfig.json
31
31
  npx tsc-ts --noEmit src/index.ts
32
32
  ```
33
33
 
34
- `tsc-ts --api` serves the TypeScript API over stdin and stdout, like `tsc --api`.
34
+ `tsc-ts --api` serves the TypeScript API over stdin and stdout, like `tsc --api`. On Windows, `--api --pipe \\.\pipe\<name>` serves it over a named pipe it creates, as `tsc --api --pipe` does, for clients that connect to the pipe (such as scriptc under Node.js); only the native executable supports `--pipe`.
35
35
 
36
36
  `--checkers N` checks the program on N threads. Unless `--checkers` or `--singleThreaded` is given, the native executable uses one checker per CPU it may run on (up to 16), and at least tsgo's four; it uses fewer than the CPUs, but never fewer than four, when the estimated peak memory of more checkers would not fit 85% of the machine's memory (`TSC_TS_CHECKERS=fixed` keeps tsgo's four), and checkers beyond the fourth stop taking files, one at a time, when the process's memory reaches that share; it shares one program between its threads and also parses and binds the program's files on them. Unless `--singleThreaded` is given, the program's files are parsed and bound on threads also with `--checkers 1`, as tsgo does. Files that share costly declarations, such as a large generated schema and the few files importing it, are checked together on one checker. Under Node.js, where every thread builds its own copy of the program, tsc-ts checks on one thread unless `--checkers` is given. `--incremental`, `--watch` and `--build` always check on one thread. The diagnostics are the same as with one checker.
37
37
 
@@ -12,7 +12,7 @@ import { getExportSymbolOfValueSymbolIfExported } from './checker-symbols.js';
12
12
  import { getBaseTypes, getDeclaredTypeOfSymbol } from './checker-declared-types.js';
13
13
  import { getPropertyOfType } from './checker-members.js';
14
14
  import { getFunctionFlags } from './checker-utilities.js';
15
- import { getDeclarations } from './symbol.js';
15
+ import { declarationAt, declarationCount } from './symbol.js';
16
16
  /** Reports a block-scoped variable, class or enum resolved at `errorLocation` before its declaration. */
17
17
  export function checkResolvedBlockScopedVariable(c, resolved, errorLocation) {
18
18
  const result = getExportSymbolOfValueSymbolIfExported(c, resolved);
@@ -23,7 +23,8 @@ export function checkResolvedBlockScopedVariable(c, resolved, errorLocation) {
23
23
  (result.flags & 32 /* SymbolFlags.Class */) !== 0)
24
24
  return;
25
25
  let declaration;
26
- for (const d of getDeclarations(result)) {
26
+ for (let i = 0; i < declarationCount(result); i++) {
27
+ const d = declarationAt(result, i);
27
28
  if (isBlockOrCatchScoped(d) || isClassLike(d) || d.kind === 267 /* SyntaxKind.EnumDeclaration */) {
28
29
  declaration = d;
29
30
  break;
@@ -20,7 +20,7 @@ import { getIndexedAccessType, isGenericMappedType } from './checker-type-operat
20
20
  import { getSignatureInstantiation } from './checker-signatures.js';
21
21
  import { evaluateEnumMember } from './checker-evaluator.js';
22
22
  import { checkTypeAssignableTo, isTypeIdenticalTo } from './relations.js';
23
- import { getDeclarations } from './symbol.js';
23
+ import { declarationAt, declarationCount, getDeclarations } from './symbol.js';
24
24
  export { getParentOfSymbol };
25
25
  export function getDeclaredTypeOfSymbol(c, symbol) {
26
26
  return tryGetDeclaredTypeOfSymbol(c, symbol) ?? c.errorType;
@@ -752,11 +752,14 @@ export function getMinTypeArgumentCount(c, typeParameters) {
752
752
  }
753
753
  /** Whether a type parameter is declared with a default, without resolving it. */
754
754
  function hasTypeParameterDefault(t) {
755
- if (t.symbol === undefined)
755
+ const symbol = t.symbol;
756
+ if (symbol === undefined)
756
757
  return false;
757
- for (const d of getDeclarations(t.symbol))
758
+ for (let i = 0; i < declarationCount(symbol); i++) {
759
+ const d = declarationAt(symbol, i);
758
760
  if (d.kind === 169 /* SyntaxKind.TypeParameter */ && d.defaultType !== undefined)
759
761
  return true;
762
+ }
760
763
  return false;
761
764
  }
762
765
  export function fillMissingTypeArguments(c, typeArguments, typeParameters, minTypeArgumentCount, isJavaScriptImplicitAny) {
@@ -12,7 +12,7 @@ import { entityNameToString } from './checker-expressions.js';
12
12
  import { isErrorType } from './checker-type-factory.js';
13
13
  import { getPropertyOfType } from './checker-members.js';
14
14
  import { signatureToString } from './type-printer.js';
15
- import { declarationCount, getDeclarations } from './symbol.js';
15
+ import { declarationAt, declarationCount, getDeclarations } from './symbol.js';
16
16
  /** Whether `declaration`, or the statement it belongs to, has a `@deprecated` JSDoc tag. */
17
17
  export function isDeprecatedDeclaration(declaration) {
18
18
  if ((getCombinedNodeFlags(declaration) & 67108864 /* NodeFlags.PossiblyContainsDeprecatedTag */) === 0)
@@ -38,24 +38,24 @@ function getJSDocDeprecatedTag(node) {
38
38
  * members when all are.
39
39
  */
40
40
  export function isDeprecatedSymbol(c, symbol) {
41
- const declarations = getDeclarations(symbol);
41
+ const count = declarationCount(symbol);
42
42
  const parentSymbol = getParentOfSymbol(c, symbol);
43
- if (parentSymbol !== undefined && declarations.length > 1)
43
+ if (parentSymbol !== undefined && count > 1)
44
44
  return (parentSymbol.flags & 64 /* SymbolFlags.Interface */) !== 0
45
- ? someDeprecatedDeclaration(declarations)
46
- : everyDeprecatedDeclaration(declarations);
45
+ ? someDeprecatedDeclaration(symbol)
46
+ : everyDeprecatedDeclaration(symbol);
47
47
  return ((symbol.valueDeclaration !== undefined && isDeprecatedDeclaration(symbol.valueDeclaration)) ||
48
- (declarations.length !== 0 && everyDeprecatedDeclaration(declarations)));
48
+ (count !== 0 && everyDeprecatedDeclaration(symbol)));
49
49
  }
50
- function someDeprecatedDeclaration(declarations) {
51
- for (const d of declarations)
52
- if (isDeprecatedDeclaration(d))
50
+ function someDeprecatedDeclaration(symbol) {
51
+ for (let i = 0; i < declarationCount(symbol); i++)
52
+ if (isDeprecatedDeclaration(declarationAt(symbol, i)))
53
53
  return true;
54
54
  return false;
55
55
  }
56
- function everyDeprecatedDeclaration(declarations) {
57
- for (const d of declarations)
58
- if (!isDeprecatedDeclaration(d))
56
+ function everyDeprecatedDeclaration(symbol) {
57
+ for (let i = 0; i < declarationCount(symbol); i++)
58
+ if (!isDeprecatedDeclaration(declarationAt(symbol, i)))
59
59
  return false;
60
60
  return true;
61
61
  }
@@ -290,7 +290,8 @@ export function checkDeprecatedTypeReference(c, node, type) {
290
290
  const symbol = c.resolvedSymbols.get(node.id);
291
291
  if (symbol === undefined)
292
292
  return;
293
- for (const d of getDeclarations(symbol)) {
293
+ for (let i = 0; i < declarationCount(symbol); i++) {
294
+ const d = declarationAt(symbol, i);
294
295
  if (isTypeDeclaration(d) && isDeprecatedDeclaration(d)) {
295
296
  addDeprecatedSuggestion(c, getDeprecatedSuggestionNode(node), getDeclarations(symbol), symbol.name);
296
297
  return;
@@ -22,7 +22,7 @@ import { getNonNullableType, getTypeWithFacts, hasTypeFacts } from './checker-fl
22
22
  import { sliceTupleType } from './checker-signatures.js';
23
23
  import { getPropertyNameFromType, isTypeUsableAsPropertyName, maybeTypeOfKind } from './checker-utilities.js';
24
24
  import { checkPropertyAccessibility } from './checker-property-access.js';
25
- import { copyDeclarations, getDeclarations, getSymbolId } from './symbol.js';
25
+ import { copyDeclarations, declarationAt, declarationCount, getSymbolId, } from './symbol.js';
26
26
  function isBindingPatternNode(node) {
27
27
  return (node !== undefined &&
28
28
  (node.kind === 207 /* SyntaxKind.ObjectBindingPattern */ || node.kind === 208 /* SyntaxKind.ArrayBindingPattern */));
@@ -548,7 +548,8 @@ export function isSpreadableProperty(prop) {
548
548
  const notMethodOrAccessor = (prop.flags & (8192 /* SymbolFlags.Method */ | 32768 /* SymbolFlags.GetAccessor */ | 65536 /* SymbolFlags.SetAccessor */)) === 0;
549
549
  let hasPrivateName = false;
550
550
  let inClass = false;
551
- for (const d of getDeclarations(prop)) {
551
+ for (let i = 0; i < declarationCount(prop); i++) {
552
+ const d = declarationAt(prop, i);
552
553
  if (isPrivateIdentifierClassElementDeclaration(d))
553
554
  hasPrivateName = true;
554
555
  if (d.parent !== undefined && isClassLike(d.parent))
@@ -702,8 +702,12 @@ export function resolveDeclaredMembers(c, t) {
702
702
  const members = getMembersOfSymbol(c, t.symbol);
703
703
  declared.declaredMembersResolved = true;
704
704
  declared.declaredMembers = members;
705
- declared.declaredCallSignatures = getSignaturesOfSymbol(c, members.get("\uFFFEcall" /* InternalSymbolName.Call */));
706
- declared.declaredConstructSignatures = getSignaturesOfSymbol(c, members.get("\uFFFEnew" /* InternalSymbolName.New */));
705
+ // Most interfaces declare neither, and share one empty list.
706
+ const call = members.get("\uFFFEcall" /* InternalSymbolName.Call */);
707
+ const construct = members.get("\uFFFEnew" /* InternalSymbolName.New */);
708
+ declared.declaredCallSignatures = call !== undefined ? getSignaturesOfSymbol(c, call) : emptySignatures;
709
+ declared.declaredConstructSignatures =
710
+ construct !== undefined ? getSignaturesOfSymbol(c, construct) : emptySignatures;
707
711
  declared.declaredIndexInfos = getIndexInfosOfSymbol(c, t.symbol);
708
712
  }
709
713
  return declared;
@@ -5,6 +5,18 @@ import type { Checker } from './checker.js';
5
5
  * identifiers, which need the whole file checked first.
6
6
  */
7
7
  export declare function checkSourceFile(c: Checker, file: SourceFile, checkUnused?: boolean): void;
8
+ /**
9
+ * Checks the statements `start` to `end` of the declaration file `file`, one of the ranges that several
10
+ * checkers check it in (parallel-check.ts), and returns whether the checker then has diagnostics in the
11
+ * file. The range ending the file also runs the checks of the whole file. The file is not marked checked.
12
+ *
13
+ * When no range finds a diagnostic in the file, checking it whole would find none either: each statement
14
+ * is checked by the checker of its range. Otherwise the file is checked whole (`startParallelCheck`): the
15
+ * diagnostics of the ranges can differ from the file's, where they depend on the order the file's
16
+ * declarations are resolved in. A union type prints its members in the order the checker created them,
17
+ * and a check that a symbol's first declaration runs reports on all its declarations.
18
+ */
19
+ export declare function checkSourceFileRange(c: Checker, file: SourceFile, start: number, end: number): boolean;
8
20
  /** Checks a statement, declaration, class member or type node. */
9
21
  export declare function checkSourceElement(c: Checker, node: Node | undefined): void;
10
22
  /** Resolves the `@link` names of a node's JSDoc, which marks what they name referenced. */
@@ -81,6 +81,41 @@ function checkSourceFileWorker(c, file) {
81
81
  links.typeChecked = true;
82
82
  links.deferredNodes = undefined;
83
83
  }
84
+ /**
85
+ * Checks the statements `start` to `end` of the declaration file `file`, one of the ranges that several
86
+ * checkers check it in (parallel-check.ts), and returns whether the checker then has diagnostics in the
87
+ * file. The range ending the file also runs the checks of the whole file. The file is not marked checked.
88
+ *
89
+ * When no range finds a diagnostic in the file, checking it whole would find none either: each statement
90
+ * is checked by the checker of its range. Otherwise the file is checked whole (`startParallelCheck`): the
91
+ * diagnostics of the ranges can differ from the file's, where they depend on the order the file's
92
+ * declarations are resolved in. A union type prints its members in the order the checker created them,
93
+ * and a check that a symbol's first declaration runs reports on all its declarations.
94
+ */
95
+ export function checkSourceFileRange(c, file, start, end) {
96
+ const statements = getStatements(file).nodes;
97
+ c.fileBeingChecked = file;
98
+ c.saveDeferredDiagnostics = true;
99
+ for (let i = start; i < end; i++)
100
+ checkSourceElement(c, statements[i]);
101
+ checkDeferredNodes(c, file);
102
+ const whole = end === statements.length;
103
+ if (whole && isExternalOrCommonJSModule(file))
104
+ checkExternalModuleExports(c, file);
105
+ c.renamedBindingElementsInTypes.length = 0;
106
+ if (whole) {
107
+ checkGrammarSourceFile(c, file);
108
+ checkDeferredNodes(c, file);
109
+ checkPendingExternalEmitHelpers(c, file);
110
+ }
111
+ c.fileBeingChecked = undefined;
112
+ c.saveDeferredDiagnostics = false;
113
+ produceDeferredIterationErrors(c);
114
+ produceDeferredCollisionChecks(c);
115
+ // Deferred nodes of a later range are queued again (checkNodeDeferred).
116
+ c.nodeLinks(file).deferredNodes = undefined;
117
+ return c.diagnostics.forFile(file.fileName).length > 0;
118
+ }
84
119
  /** Checks a statement, declaration, class member or type node. */
85
120
  export function checkSourceElement(c, node) {
86
121
  if (node === undefined)
@@ -26,7 +26,7 @@ import { getTypeForBindingElement, getTypeFromBindingPattern } from './checker-d
26
26
  import { checkRightHandSideOfForOf } from './checker-statements.js';
27
27
  import { getTypeWithFacts, hasTypeFacts, getNonNullableType } from './checker-flow.js';
28
28
  import { getTypeOfModuleExportsSymbol, getWidenedTypeForAssignmentDeclaration } from './checker-javascript.js';
29
- import { copyDeclarations, getDeclarations, getSymbolId } from './symbol.js';
29
+ import { copyDeclarations, declarationAt, declarationCount, getDeclarations, getSymbolId, } from './symbol.js';
30
30
  export function getTypeOfSymbol(c, symbol) {
31
31
  const checkFlags = symbol.checkFlags;
32
32
  if ((checkFlags & 65536 /* CheckFlags.DeferredType */) !== 0)
@@ -748,11 +748,11 @@ export function isReadonlySymbol(c, symbol) {
748
748
  (getDeclarationNodeFlagsFromSymbol(symbol) & 6 /* NodeFlags.Constant */) !== 0) ||
749
749
  ((symbol.flags & 98304 /* SymbolFlags.Accessor */) !== 0 && (symbol.flags & 65536 /* SymbolFlags.SetAccessor */) === 0) ||
750
750
  (symbol.flags & 8 /* SymbolFlags.EnumMember */) !== 0 ||
751
- someReadonlyAssignmentDeclaration(c, getDeclarations(symbol)));
751
+ someReadonlyAssignmentDeclaration(c, symbol));
752
752
  }
753
- function someReadonlyAssignmentDeclaration(c, declarations) {
754
- for (const d of declarations)
755
- if (isReadonlyAssignmentDeclaration(c, d))
753
+ function someReadonlyAssignmentDeclaration(c, symbol) {
754
+ for (let i = 0; i < declarationCount(symbol); i++)
755
+ if (isReadonlyAssignmentDeclaration(c, declarationAt(symbol, i)))
756
756
  return true;
757
757
  return false;
758
758
  }
@@ -697,6 +697,7 @@ function setMergedSymbol(c, id, target) {
697
697
  c.mergedSymbolChanges.set(c.mergedSymbols, id, target);
698
698
  else
699
699
  c.mergedSymbols.set(id, target);
700
+ c.mergedSymbolIds.add(id);
700
701
  }
701
702
  /** Merges script locals into globals; ambient modules and augmentations wait for global types. */
702
703
  export function initializeGlobals(c) {
@@ -1033,7 +1034,7 @@ function recordMergedSymbol(c, target, source) {
1033
1034
  }
1034
1035
  export function getMergedSymbol(c, symbol) {
1035
1036
  const id = symbol.id;
1036
- if (id !== 0) {
1037
+ if (id !== 0 && c.mergedSymbolIds.has(id)) {
1037
1038
  const merged = c.mergedSymbols.get(id);
1038
1039
  if (merged !== undefined)
1039
1040
  return merged;
@@ -1459,9 +1460,11 @@ export function symbolIsValue(c, symbol) {
1459
1460
  function isDeclarationContainedBy(symbol, container) {
1460
1461
  const declaration = symbol.valueDeclaration;
1461
1462
  if (declaration !== undefined)
1462
- for (const d of getDeclarations(container))
1463
+ for (let i = 0; i < declarationCount(container); i++) {
1464
+ const d = declarationAt(container, i);
1463
1465
  if (declaration.pos >= d.pos && declaration.end <= d.end)
1464
1466
  return true;
1467
+ }
1465
1468
  return false;
1466
1469
  }
1467
1470
  /** Value members other than signatures and index signatures, declared ones first, each part ordered by declaration. */
@@ -1,7 +1,7 @@
1
1
  import type { DeferredCollisionCheck } from './checker-generated-code.js';
2
2
  import type { EmitHelperFileLinks } from './checker-emit-helpers.js';
3
3
  import type { Node, PatternAmbientModule, SourceFile } from './ast.js';
4
- import { CompactSymbolLinkTable, IntLinkTable, LinkTable, SparseLinkTable } from './link-tables.js';
4
+ import { CompactSymbolLinkTable, IntLinkTable, LinkTable, PagedIdSet, SparseLinkTable } from './link-tables.js';
5
5
  import { Diagnostic, type DiagnosticMessage, Diagnostics } from './diagnostics.js';
6
6
  import { type CompilerOptions, ModuleKind, ScriptTarget } from './options.js';
7
7
  import { CheckFlags, Symbol, SymbolFlags, type SymbolTable } from './symbol.js';
@@ -204,6 +204,11 @@ export declare class Checker implements TypeChecking {
204
204
  readonly resolvedSignatures: SparseLinkTable<Signature>;
205
205
  /** Merged symbols, indexed by the id of the symbol merged into them. */
206
206
  readonly mergedSymbols: Map<number, Symbol>;
207
+ /**
208
+ * The ids that `mergedSymbols` has, or had: most symbols are merged into none, and `getMergedSymbol`
209
+ * finds that here without probing the map.
210
+ */
211
+ readonly mergedSymbolIds: PagedIdSet;
207
212
  /** Globals merged from the default libraries, shared with other checkers. */
208
213
  libGlobals: LibGlobals | undefined;
209
214
  /** The program's globals and module augmentations as another checker merged them, shared with it. */
@@ -1,5 +1,5 @@
1
1
  import { sideOf } from './side-state.js';
2
- import { CompactSymbolLinkTable, IntLinkTable, LinkTable, SparseLinkTable } from './link-tables.js';
2
+ import { CompactSymbolLinkTable, IntLinkTable, LinkTable, PagedIdSet, SparseLinkTable } from './link-tables.js';
3
3
  import { getErrorRangeForNode, getSourceFileOfNode } from './binder-utilities.js';
4
4
  import { Diagnostic, compareDiagnostics } from './diagnostics.js';
5
5
  import { ModuleKind, ScriptTarget, getEmitScriptTarget, getIsolatedModules, getStrictOptionValue, shouldPreserveConstEnums, } from './options.js';
@@ -284,6 +284,11 @@ export class Checker {
284
284
  resolvedSignatures = new SparseLinkTable();
285
285
  /** Merged symbols, indexed by the id of the symbol merged into them. */
286
286
  mergedSymbols;
287
+ /**
288
+ * The ids that `mergedSymbols` has, or had: most symbols are merged into none, and `getMergedSymbol`
289
+ * finds that here without probing the map.
290
+ */
291
+ mergedSymbolIds = new PagedIdSet();
287
292
  /** Globals merged from the default libraries, shared with other checkers. */
288
293
  libGlobals;
289
294
  /** The program's globals and module augmentations as another checker merged them, shared with it. */
@@ -616,6 +621,8 @@ export class Checker {
616
621
  this.globals = libs.copyGlobals();
617
622
  this.mergedSymbols = libs.copyMergedSymbols();
618
623
  }
624
+ for (const id of this.mergedSymbols.keys())
625
+ this.mergedSymbolIds.add(id);
619
626
  this.globalThisSymbol = this.newSymbol(1536 /* SymbolFlags.Module */, 'globalThis');
620
627
  this.globalThisSymbol.checkFlags = 8 /* CheckFlags.Readonly */;
621
628
  this.globalThisSymbol.exports = this.globals;
@@ -890,6 +897,7 @@ export function disposeChecker(c) {
890
897
  c.mergedSymbols.clear();
891
898
  c.globals.clear();
892
899
  }
900
+ c.mergedSymbolIds.clear();
893
901
  c.sharedSymbolCopies.clear();
894
902
  c.memberPositionsInLists.clear();
895
903
  c.memberNamesOfLists.clear();
@@ -95,10 +95,10 @@ export declare class LoadedFile {
95
95
  readonly references: LoadedReference[];
96
96
  readonly resolutionsInFile: ModeAwareCache<ResolvedModule> | undefined;
97
97
  readonly typeResolutionsInFile: ModeAwareCache<ResolvedTypeReferenceDirective> | undefined;
98
- readonly processingDiagnostics: ProcessingDiagnostic[];
98
+ readonly processingDiagnostics: readonly ProcessingDiagnostic[];
99
99
  readonly importHelpersImportSpecifier: StringLiteral | undefined;
100
100
  readonly jsxRuntimeImport: JsxRuntimeImport | undefined;
101
- constructor(file: SourceFile, isLibFile: boolean, metadata: SourceFileMetadata, references: LoadedReference[], resolutionsInFile: ModeAwareCache<ResolvedModule> | undefined, typeResolutionsInFile: ModeAwareCache<ResolvedTypeReferenceDirective> | undefined, processingDiagnostics: ProcessingDiagnostic[], importHelpersImportSpecifier: StringLiteral | undefined, jsxRuntimeImport: JsxRuntimeImport | undefined);
101
+ constructor(file: SourceFile, isLibFile: boolean, metadata: SourceFileMetadata, references: LoadedReference[], resolutionsInFile: ModeAwareCache<ResolvedModule> | undefined, typeResolutionsInFile: ModeAwareCache<ResolvedTypeReferenceDirective> | undefined, processingDiagnostics: readonly ProcessingDiagnostic[], importHelpersImportSpecifier: StringLiteral | undefined, jsxRuntimeImport: JsxRuntimeImport | undefined);
102
102
  }
103
103
  /** Referenced projects, and how their sources map to declaration outputs. */
104
104
  export declare class ProjectReferenceMapper {
@@ -165,6 +165,14 @@ class SubTasksAhead {
165
165
  this.subTasks = subTasks;
166
166
  }
167
167
  }
168
+ /** Read in place of a task's lists it has not created. */
169
+ const noParseTasks = [];
170
+ const noTraces = [];
171
+ const noProcessingDiagnostics = [];
172
+ /**
173
+ * A file to load. Its lists are created on first use: most tasks never get sub-tasks, traces or processing
174
+ * diagnostics, and large programs create hundreds of thousands of tasks.
175
+ */
168
176
  class ParseTask {
169
177
  normalizedFilePath;
170
178
  libFile;
@@ -176,15 +184,15 @@ class ParseTask {
176
184
  path = '';
177
185
  file = undefined;
178
186
  redirectedParseTask = undefined;
179
- subTasks = [];
187
+ subTasks = undefined;
180
188
  loaded = false;
181
189
  startedSubTasks = false;
182
190
  metadata = libFileMetadata;
183
191
  resolutionsInFile = undefined;
184
- resolutionsTrace = [];
192
+ resolutionsTrace = undefined;
185
193
  typeResolutionsInFile = undefined;
186
- typeResolutionsTrace = [];
187
- processingDiagnostics = [];
194
+ typeResolutionsTrace = undefined;
195
+ processingDiagnostics = undefined;
188
196
  importHelpersImportSpecifier = undefined;
189
197
  jsxRuntimeImport = undefined;
190
198
  /** The task of the same file name that was loaded instead of this one. */
@@ -201,7 +209,18 @@ class ParseTask {
201
209
  this.packageId = packageId;
202
210
  }
203
211
  addSubTask(fileName, libFile, reason, increaseDepth, elideOnDepth, packageId) {
204
- this.subTasks.push(new ParseTask(normalizePath(fileName), libFile, reason, false, increaseDepth, elideOnDepth, packageId));
212
+ (this.subTasks ??= []).push(new ParseTask(normalizePath(fileName), libFile, reason, false, increaseDepth, elideOnDepth, packageId));
213
+ }
214
+ addProcessingDiagnostic(diagnostic) {
215
+ (this.processingDiagnostics ??= []).push(diagnostic);
216
+ }
217
+ /** Where module resolution traces go under `--traceResolution`; undefined without it. */
218
+ moduleTraces(trace) {
219
+ return trace ? (this.resolutionsTrace ??= []) : undefined;
220
+ }
221
+ /** Where type reference resolution traces go under `--traceResolution`; undefined without it. */
222
+ typeTraces(trace) {
223
+ return trace ? (this.typeResolutionsTrace ??= []) : undefined;
205
224
  }
206
225
  }
207
226
  /** The tasks of one path, by file name casing. */
@@ -640,7 +659,7 @@ export class FileLoader {
640
659
  return undefined;
641
660
  }
642
661
  const references = [];
643
- for (const sub of task.subTasks) {
662
+ for (const sub of task.subTasks ?? noParseTasks) {
644
663
  references.push(new LoadedReference(sub.normalizedFilePath, sub.libFile !== undefined ? sub.libFile.name : '', sub.includeReason, sub.increaseDepth, sub.elideOnDepth, sub.packageId));
645
664
  const subDepth = sub.increaseDepth ? depth + 1 : depth;
646
665
  // `run` skips these.
@@ -655,7 +674,7 @@ export class FileLoader {
655
674
  // Traces are reported in the program's order: such programs resolve on their own.
656
675
  if (file === undefined || this.options.traceResolution === true)
657
676
  return undefined;
658
- return new LoadedFile(file, task.libFile !== undefined, task.metadata, references, task.resolutionsInFile, task.typeResolutionsInFile, task.processingDiagnostics, task.importHelpersImportSpecifier, task.jsxRuntimeImport);
677
+ return new LoadedFile(file, task.libFile !== undefined, task.metadata, references, task.resolutionsInFile, task.typeResolutionsInFile, task.processingDiagnostics ?? noProcessingDiagnostics, task.importHelpersImportSpecifier, task.jsxRuntimeImport);
659
678
  }
660
679
  // ---- Project references
661
680
  loadProjectReferences() {
@@ -737,7 +756,7 @@ export class FileLoader {
737
756
  return;
738
757
  }
739
758
  const task = new ParseTask(absolute, undefined, reason, false, false, false, undefined);
740
- task.processingDiagnostics.push(ProcessingDiagnostic.explainingFileInclude('', reason, resolved.message, resolved.args));
759
+ task.addProcessingDiagnostic(ProcessingDiagnostic.explainingFileInclude('', reason, resolved.message, resolved.args));
741
760
  this.rootTasks.push(task);
742
761
  }
743
762
  isSupportedExtension(canonicalFileName) {
@@ -888,7 +907,8 @@ export class FileLoader {
888
907
  }
889
908
  if (!taskByFileName.startedSubTasks && loadSubTasks) {
890
909
  taskByFileName.startedSubTasks = true;
891
- this.start(taskByFileName.subTasks, data.lowestDepth);
910
+ if (taskByFileName.subTasks !== undefined)
911
+ this.start(taskByFileName.subTasks, data.lowestDepth);
892
912
  }
893
913
  }
894
914
  }
@@ -921,7 +941,7 @@ export class FileLoader {
921
941
  if (hasExtension(task.normalizedFilePath) && this.options.allowNonTsExtensions !== true) {
922
942
  const canonicalFileName = getCanonicalFileName(task.normalizedFilePath, fs.useCaseSensitiveFileNames);
923
943
  if (!this.isSupportedExtension(canonicalFileName)) {
924
- task.processingDiagnostics.push(hasJSFileExtension(canonicalFileName)
944
+ task.addProcessingDiagnostic(hasJSFileExtension(canonicalFileName)
925
945
  ? ProcessingDiagnostic.explainingFileInclude('', task.includeReason, 1519 /* Diagnostics.File_0_is_a_JavaScript_file_Did_you_mean_to_enable_the_allowJs_option */, [task.normalizedFilePath])
926
946
  : ProcessingDiagnostic.explainingFileInclude('', task.includeReason, 1230 /* Diagnostics.File_0_has_an_unsupported_extension_The_only_supported_extensions_are_1 */, [task.normalizedFilePath, this.supportedExtensionsList()]));
927
947
  return;
@@ -955,7 +975,7 @@ export class FileLoader {
955
975
  const reason = FileIncludeReason.reference(3 /* FileIncludeKind.LibReferenceDirective */, task.path, i, undefined);
956
976
  const name = getLibFileName(file.libReferenceDirectives[i].fileName);
957
977
  if (name === '') {
958
- task.processingDiagnostics.push(ProcessingDiagnostic.unknownReference(reason));
978
+ task.addProcessingDiagnostic(ProcessingDiagnostic.unknownReference(reason));
959
979
  continue;
960
980
  }
961
981
  const libFile = this.pathForLibFile(name);
@@ -975,7 +995,7 @@ export class FileLoader {
975
995
  else
976
996
  task.subTasks = this.subTasksOf(loaded);
977
997
  for (const diagnostic of loaded.processingDiagnostics)
978
- task.processingDiagnostics.push(diagnostic.copy());
998
+ task.addProcessingDiagnostic(diagnostic.copy());
979
999
  task.resolutionsInFile = loaded.resolutionsInFile;
980
1000
  task.typeResolutionsInFile = loaded.typeResolutionsInFile;
981
1001
  task.importHelpersImportSpecifier = loaded.importHelpersImportSpecifier;
@@ -1002,7 +1022,7 @@ export class FileLoader {
1002
1022
  const reason = FileIncludeReason.reference(1 /* FileIncludeKind.ReferenceFile */, this.toPath(containingFile), index, undefined);
1003
1023
  const resolved = this.getSourceFileFromReference(normalizePath(referencedFileName), moduleName, containingFile, reason);
1004
1024
  if (typeof resolved !== 'string') {
1005
- task.processingDiagnostics.push(ProcessingDiagnostic.explainingFileInclude('', reason, resolved.message, resolved.args));
1025
+ task.addProcessingDiagnostic(ProcessingDiagnostic.explainingFileInclude('', reason, resolved.message, resolved.args));
1006
1026
  return;
1007
1027
  }
1008
1028
  task.addSubTask(resolved, undefined, reason, false, false, undefined);
@@ -1020,14 +1040,14 @@ export class FileLoader {
1020
1040
  const mode = reference.resolutionMode !== ModuleKind.None
1021
1041
  ? reference.resolutionMode
1022
1042
  : getDefaultResolutionModeForFile(file.fileName, task.metadata, options);
1023
- const resolved = this.resolver.resolveTypeReferenceDirective(reference.fileName, containingFile, mode, redirect?.resolved, task.typeResolutionsTrace);
1043
+ const resolved = this.resolver.resolveTypeReferenceDirective(reference.fileName, containingFile, mode, redirect?.resolved, task.typeTraces(this.options.traceResolution === true));
1024
1044
  resolutions.set(modeAwareKey(reference.fileName, mode), resolved);
1025
1045
  const reason = FileIncludeReason.reference(2 /* FileIncludeKind.TypeReferenceDirective */, task.path, i, undefined);
1026
1046
  if (resolved.resolvedFileName !== '') {
1027
1047
  task.addSubTask(resolved.resolvedFileName, undefined, reason, resolved.isExternalLibraryImport, false, resolved.packageId);
1028
1048
  }
1029
1049
  else {
1030
- task.processingDiagnostics.push(ProcessingDiagnostic.unknownReference(reason));
1050
+ task.addProcessingDiagnostic(ProcessingDiagnostic.unknownReference(reason));
1031
1051
  }
1032
1052
  }
1033
1053
  task.typeResolutionsInFile = resolutions;
@@ -1039,13 +1059,13 @@ export class FileLoader {
1039
1059
  const resolutions = new Map();
1040
1060
  for (const name of names) {
1041
1061
  // Resolved without a mode: CommonJS under node16/nodenext, `import` conditions under bundler.
1042
- const resolved = this.resolver.resolveTypeReferenceDirective(name, task.normalizedFilePath, ModuleKind.None, undefined, task.typeResolutionsTrace);
1062
+ const resolved = this.resolver.resolveTypeReferenceDirective(name, task.normalizedFilePath, ModuleKind.None, undefined, task.typeTraces(this.options.traceResolution === true));
1043
1063
  resolutions.set(modeAwareKey(name, ModuleKind.None), resolved);
1044
1064
  if (resolved.resolvedFileName !== '') {
1045
1065
  task.addSubTask(resolved.resolvedFileName, undefined, FileIncludeReason.automaticTypeDirective(name, resolved.packageId), resolved.isExternalLibraryImport, false, resolved.packageId);
1046
1066
  }
1047
1067
  else {
1048
- task.processingDiagnostics.push(ProcessingDiagnostic.explainingFileInclude('', FileIncludeReason.automaticTypeDirective(name, undefined), 821 /* Diagnostics.Cannot_find_type_definition_file_for_0 */, [name]));
1068
+ task.addProcessingDiagnostic(ProcessingDiagnostic.explainingFileInclude('', FileIncludeReason.automaticTypeDirective(name, undefined), 821 /* Diagnostics.Cannot_find_type_definition_file_for_0 */, [name]));
1049
1069
  }
1050
1070
  }
1051
1071
  task.typeResolutionsInFile = resolutions;
@@ -1083,7 +1103,7 @@ export class FileLoader {
1083
1103
  if (moduleName === '')
1084
1104
  continue;
1085
1105
  const mode = getModeForUsageLocation(file.fileName, task.metadata, entry, options);
1086
- const resolved = this.resolver.resolveModuleName(moduleName, containingFile, mode, redirect?.resolved, task.resolutionsTrace);
1106
+ const resolved = this.resolver.resolveModuleName(moduleName, containingFile, mode, redirect?.resolved, task.moduleTraces(this.options.traceResolution === true));
1087
1107
  resolutions.set(modeAwareKey(moduleName, mode), resolved);
1088
1108
  const resolvedFileName = resolved.resolvedFileName;
1089
1109
  if (resolvedFileName === '')
@@ -1169,9 +1189,9 @@ export class FileLoader {
1169
1189
  tasksSeenByNameIgnoreCase.set(lowerCasePath, task);
1170
1190
  }
1171
1191
  }
1172
- for (const trace of task.typeResolutionsTrace)
1192
+ for (const trace of task.typeResolutionsTrace ?? noTraces)
1173
1193
  host.trace(trace);
1174
- for (const trace of task.resolutionsTrace)
1194
+ for (const trace of task.resolutionsTrace ?? noTraces)
1175
1195
  host.trace(trace);
1176
1196
  const file = task.file;
1177
1197
  const packageId = data.packageId;
@@ -1193,7 +1213,7 @@ export class FileLoader {
1193
1213
  if (file !== undefined)
1194
1214
  packageIdToSourceFile.set(key, file);
1195
1215
  }
1196
- if (task.subTasks.length > 0)
1216
+ if (task.subTasks !== undefined && task.subTasks.length > 0)
1197
1217
  collectFiles(task.subTasks);
1198
1218
  const redirected = task.redirectedParseTask;
1199
1219
  if (redirected !== undefined) {
@@ -1202,12 +1222,12 @@ export class FileLoader {
1202
1222
  }
1203
1223
  if (task.isForAutomaticTypeDirective) {
1204
1224
  typeResolutionsInFile.set(task.path, task.typeResolutionsInFile);
1205
- for (const diagnostic of task.processingDiagnostics)
1225
+ for (const diagnostic of task.processingDiagnostics ?? noProcessingDiagnostics)
1206
1226
  includeProcessor.addProcessingDiagnostic(diagnostic);
1207
1227
  continue;
1208
1228
  }
1209
1229
  const path = task.path;
1210
- for (const diagnostic of task.processingDiagnostics)
1230
+ for (const diagnostic of task.processingDiagnostics ?? noProcessingDiagnostics)
1211
1231
  includeProcessor.addProcessingDiagnostic(diagnostic);
1212
1232
  if (file === undefined) {
1213
1233
  missingFiles.push(task.normalizedFilePath);
@@ -58,6 +58,13 @@ export declare class ClusteredIntLinkTable {
58
58
  set(id: number, value: number): void;
59
59
  private pageOf;
60
60
  }
61
+ /** Ids in pages of `IdSetPaging.Ids` ids, one bit each; a page is created by the first id added to it. */
62
+ export declare class PagedIdSet {
63
+ readonly pages: (Int32Array | undefined)[];
64
+ has(id: number): boolean;
65
+ add(id: number): void;
66
+ clear(): void;
67
+ }
61
68
  /**
62
69
  * A page of a `CompactSymbolLinkTable`: one bit per id of the page in eight 32-id words, the number
63
70
  * of symbols stored before each word, and the symbols in id order. The words are fields, so a
@@ -146,6 +146,28 @@ export class ClusteredIntLinkTable {
146
146
  return this.lastPage;
147
147
  }
148
148
  }
149
+ /** Ids in pages of `IdSetPaging.Ids` ids, one bit each; a page is created by the first id added to it. */
150
+ export class PagedIdSet {
151
+ pages = [];
152
+ has(id) {
153
+ const page = this.pages[id >> 13 /* IdSetPaging.Bits */];
154
+ return page !== undefined && (page[(id >> 5) & 255 /* IdSetPaging.WordMask */] & (1 << (id & 31))) !== 0;
155
+ }
156
+ add(id) {
157
+ const index = id >> 13 /* IdSetPaging.Bits */;
158
+ let page = this.pages[index];
159
+ if (page === undefined) {
160
+ while (this.pages.length <= index)
161
+ this.pages.push(undefined);
162
+ page = new Int32Array(256 /* IdSetPaging.Words */);
163
+ this.pages[index] = page;
164
+ }
165
+ page[(id >> 5) & 255 /* IdSetPaging.WordMask */] |= 1 << (id & 31);
166
+ }
167
+ clear() {
168
+ this.pages.length = 0;
169
+ }
170
+ }
149
171
  /** The number of set bits of a 32-bit value. */
150
172
  function bitCount(x) {
151
173
  x = x - ((x >>> 1) & 0x55555555);
@@ -135,6 +135,8 @@ export declare class Parser extends ScannerErrorReporter {
135
135
  reparseList: Node[];
136
136
  private readonly reparseLists;
137
137
  private reparseDepth;
138
+ private readonly listScratch;
139
+ private listDepth;
138
140
  reparsedClones: Node[];
139
141
  /** Nodes with eagerly parsed JSDoc, for rewinding. */
140
142
  jsDocInfos: Node[];
@@ -209,6 +211,11 @@ export declare class Parser extends ScannerErrorReporter {
209
211
  parseList(kind: ParsingContext, element: ListElement): NodeList;
210
212
  /** The list, or undefined if an element parser returned undefined. */
211
213
  parseDelimitedList(kind: ParsingContext, element: ListElement): NodeList | undefined;
214
+ /** The scratch array for a list at the next nesting depth, empty. */
215
+ private openList;
216
+ /** The elements collected in `list` (the scratch array from `openList`) as an array of their exact
217
+ * length, or the shared empty array; empties the scratch array for the next list at its depth. */
218
+ private closeList;
212
219
  /** The list; a missing list if `opening` is absent; undefined if an element parser returned undefined. */
213
220
  parseBracketedList(kind: ParsingContext, element: ListElement, opening: SyntaxKind, closing: SyntaxKind): NodeList | undefined;
214
221
  parseEmptyNodeList(): NodeList;