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
@@ -6,6 +6,7 @@
6
6
  // for (const statement of file.statements.nodes) console.log(statement.kind);
7
7
  // ```
8
8
  import {
9
+ appendToList,
9
10
  ArrayLiteralExpression,
10
11
  ArrayTypeNode,
11
12
  ArrowFunction,
@@ -38,6 +39,11 @@ import {
38
39
  DeleteExpression,
39
40
  DoStatement,
40
41
  ElementAccessExpression,
42
+ emptyCommentDirectives,
43
+ emptyDiagnostics,
44
+ emptyFileReferences,
45
+ emptyNodes,
46
+ emptyPragmas,
41
47
  EmptyStatement,
42
48
  EnumDeclaration,
43
49
  EnumMember,
@@ -133,6 +139,7 @@ import {
133
139
  PropertyDeclaration,
134
140
  PropertySignatureDeclaration,
135
141
  QualifiedName,
142
+ ReferenceIdentifier,
136
143
  RegularExpressionLiteral,
137
144
  RestTypeNode,
138
145
  ReturnStatement,
@@ -192,6 +199,8 @@ import {
192
199
  type Expression,
193
200
  type Statement,
194
201
  type TypeNode,
202
+ newCallExpression,
203
+ newPropertyAssignment,
195
204
  } from './ast.js';
196
205
  import {
197
206
  OperatorPrecedence,
@@ -311,6 +320,16 @@ export const enum ParseFlags {
311
320
  JSDoc = 1 << 5,
312
321
  }
313
322
 
323
+ /** How an identifier is used, which decides whether it holds a flow node. */
324
+ export const enum IdentifierUse {
325
+ /** An expression or another reference: a `ReferenceIdentifier`. */
326
+ Reference,
327
+ /** A declaration, property, property access or type name, whose flow node nothing reads: an `Identifier`. */
328
+ Name,
329
+ /** An object literal element's name: a name before `:`, `(` or `<`, a reference in a shorthand property. */
330
+ ElementName,
331
+ }
332
+
314
333
  /** What the scanner saw of the JSDoc comments preceding a token. */
315
334
  export const enum JSDocScannerInfo {
316
335
  None = 0,
@@ -381,6 +400,11 @@ function appendRange(to: Node[], from: readonly Node[], start: number, end: numb
381
400
  for (let i = start; i < end; i += 1) to.push(from[i]!);
382
401
  }
383
402
 
403
+ // The nodes of every empty parsed list. A list's nodes are pushed into a new `[]`, which natively
404
+ // reserves room for its first elements (112 bytes); a parsed list never changes, so an empty one
405
+ // keeps this shared array instead and its builder is freed.
406
+ const emptyListNodes: Node[] = [];
407
+
384
408
  /** Parses `text` as the file `fileName`. The script kind defaults to the one implied by the extension. */
385
409
  export function parseSourceFile(fileName: string, text: string, options?: ParseOptions): SourceFile {
386
410
  const path = options === undefined ? fileName : options.path;
@@ -491,7 +515,7 @@ export class Parser extends ScannerErrorReporter {
491
515
  signatureParameterFlags: ParseFlags;
492
516
 
493
517
  /** Parses JSDoc comments and, in JavaScript files, reparses their tags. */
494
- readonly jsdoc: JSDocParser;
518
+ jsdoc: JSDocParser;
495
519
  /**
496
520
  * Returned instead of `undefined` by hot element parsers: a `Node | undefined` result is boxed natively
497
521
  * for every node returned.
@@ -554,12 +578,15 @@ export class Parser extends ScannerErrorReporter {
554
578
  }
555
579
 
556
580
  /**
557
- * Frees the scanner's copy of the text once the parser is done. The parser and its scanner and
558
- * JSDoc parser refer to each other, so natively they're freed only by a cycle collection, which may
559
- * come much later.
581
+ * Frees the scanner's copy of the text once the parser is done, and drops the references back to
582
+ * this parser from its scanner and JSDoc parser. Natively, the parser is then freed as soon as its
583
+ * caller lets go of it, instead of at a cycle collection, which may come much later (on a parse
584
+ * thread, not before the thread exits).
560
585
  */
561
586
  release(): void {
562
587
  this.scanner.setText('');
588
+ this.scanner.setOnError(undefined);
589
+ this.jsdoc = releasedParser().jsdoc;
563
590
  }
564
591
 
565
592
  token(): SyntaxKind {
@@ -745,11 +772,11 @@ export class Parser extends ScannerErrorReporter {
745
772
  // Nodes
746
773
 
747
774
  newNodeList(pos: number, end: number, nodes: Node[]): NodeList {
748
- return new NodeList(pos, end, nodes);
775
+ return new NodeList(pos, end, nodes.length === 0 ? emptyListNodes : nodes);
749
776
  }
750
777
 
751
778
  newModifierList(pos: number, end: number, nodes: Node[]): ModifierList {
752
- return new ModifierList(pos, end, nodes, modifiersToFlags(nodes));
779
+ return new ModifierList(pos, end, nodes.length === 0 ? emptyListNodes : nodes, modifiersToFlags(nodes));
753
780
  }
754
781
 
755
782
  finishNode(node: Node, pos: number): Node {
@@ -806,14 +833,10 @@ export class Parser extends ScannerErrorReporter {
806
833
  }
807
834
  collectExternalModuleReferences(result);
808
835
  if (result.isJS()) result.jsDiagnostics = attachFileToDiagnostics(this.jsDiagnostics, result);
809
- // Declaration files get their caches on first use (in a thread's copy once they may be shared,
810
- // `useThreadTextCaches`); the file's DiagnosticFile exists from here on, so reading it never
811
- // writes to the file. The scanner holds the text's code units unless a nested parse cut its text short.
812
- const scanner = this.scanner;
813
- if (result.isDeclarationFile) result.diagnosticFile();
814
- else if (scanner.text === result.text && scanner.end === result.text.length)
815
- result.computeCachesFromUnits(scanner.chars);
816
- else result.computeCaches();
836
+ // Files get their line starts on first use (in a thread's copy once they may be shared,
837
+ // `useThreadTextCaches`): most files are never pointed into by a diagnostic. The file's
838
+ // DiagnosticFile exists from here on, so reading it never writes to the file.
839
+ result.diagnosticFile();
817
840
  return result;
818
841
  }
819
842
 
@@ -829,7 +852,8 @@ export class Parser extends ScannerErrorReporter {
829
852
  }
830
853
 
831
854
  finishSourceFile(result: SourceFile, isDeclarationFile: boolean): void {
832
- result.commentDirectives = this.scanner.getCommentDirectives();
855
+ const commentDirectives = this.scanner.getCommentDirectives();
856
+ result.commentDirectives = commentDirectives.length === 0 ? emptyCommentDirectives : commentDirectives;
833
857
  result.pragmas = getCommentPragmas(this.sourceText);
834
858
  this.processPragmasIntoFields(result);
835
859
  result.diagnostics = attachFileToDiagnostics(this.diagnostics, result);
@@ -847,9 +871,12 @@ export class Parser extends ScannerErrorReporter {
847
871
  // The table stays with the parser: when top-level await reparsing produces a second source
848
872
  // file, it finishes with the same table, which still holds the JSDoc of retained statements.
849
873
  result.jsDocs = this.jsDocTable;
850
- const clones = this.reparsedClones.slice();
851
- clones.sort(compareNodePositions);
852
- result.reparsedClones = clones;
874
+ if (this.reparsedClones.length === 0) result.reparsedClones = emptyNodes;
875
+ else {
876
+ const clones = this.reparsedClones.slice();
877
+ clones.sort(compareNodePositions);
878
+ result.reparsedClones = clones;
879
+ }
853
880
  setExternalModuleIndicator(result);
854
881
  }
855
882
 
@@ -1789,7 +1816,7 @@ export class Parser extends ScannerErrorReporter {
1789
1816
  }
1790
1817
 
1791
1818
  parseIdentifierUnlessAtSemicolon(): Identifier | undefined {
1792
- return this.canParseSemicolon() ? undefined : this.parseIdentifier();
1819
+ return this.canParseSemicolon() ? undefined : this.parseIdentifier(IdentifierUse.Name);
1793
1820
  }
1794
1821
 
1795
1822
  parseReturnStatement(): Statement {
@@ -2186,7 +2213,7 @@ export class Parser extends ScannerErrorReporter {
2186
2213
  // named `implements`.
2187
2214
  if (this.isBindingIdentifier() && !this.isImplementsClause()) {
2188
2215
  const saveHasAwaitIdentifier = this.statementHasAwaitIdentifier;
2189
- const id = this.createIdentifier(this.isBindingIdentifier());
2216
+ const id = this.createIdentifier(this.isBindingIdentifier(), IdentifierUse.Name);
2190
2217
  this.statementHasAwaitIdentifier = saveHasAwaitIdentifier;
2191
2218
  return id;
2192
2219
  }
@@ -2503,7 +2530,7 @@ export class Parser extends ScannerErrorReporter {
2503
2530
 
2504
2531
  parseInterfaceDeclaration(pos: number, jsdoc: JSDocScannerInfo, modifiers: ModifierList | undefined): Statement {
2505
2532
  this.parseExpected(SyntaxKind.InterfaceKeyword);
2506
- const name = this.parseIdentifier();
2533
+ const name = this.parseIdentifier(IdentifierUse.Name);
2507
2534
  const typeParameters = this.parseTypeParameters();
2508
2535
  const heritageClauses = this.parseHeritageClauses();
2509
2536
  const members = this.parseObjectTypeMembers();
@@ -2519,7 +2546,7 @@ export class Parser extends ScannerErrorReporter {
2519
2546
  parseTypeAliasDeclaration(pos: number, jsdoc: JSDocScannerInfo, modifiers: ModifierList | undefined): Statement {
2520
2547
  this.parseExpected(SyntaxKind.TypeKeyword);
2521
2548
  if (this.hasPrecedingLineBreak()) this.parseErrorAtCurrentToken(Diagnostics.Line_break_not_permitted_here);
2522
- const name = this.parseIdentifier();
2549
+ const name = this.parseIdentifier(IdentifierUse.Name);
2523
2550
  const typeParameters = this.parseTypeParameters();
2524
2551
  this.parseExpected(SyntaxKind.EqualsToken);
2525
2552
  const type =
@@ -2552,7 +2579,7 @@ export class Parser extends ScannerErrorReporter {
2552
2579
  parseEnumDeclaration(pos: number, jsdoc: JSDocScannerInfo, modifiers: ModifierList | undefined): Statement {
2553
2580
  const saveHasAwaitIdentifier = this.statementHasAwaitIdentifier;
2554
2581
  this.parseExpected(SyntaxKind.EnumKeyword);
2555
- const name = this.parseIdentifier();
2582
+ const name = this.parseIdentifier(IdentifierUse.Name);
2556
2583
  let members: NodeList;
2557
2584
  if (this.parseExpected(SyntaxKind.OpenBraceToken)) {
2558
2585
  const saveContextFlags = this.contextFlags;
@@ -2594,7 +2621,7 @@ export class Parser extends ScannerErrorReporter {
2594
2621
  const saveHasAwaitIdentifier = this.statementHasAwaitIdentifier;
2595
2622
  if (this.token() === SyntaxKind.GlobalKeyword) {
2596
2623
  // `global` names the global scope augmentation.
2597
- name = this.parseIdentifier();
2624
+ name = this.parseIdentifier(IdentifierUse.Name);
2598
2625
  keyword = SyntaxKind.GlobalKeyword;
2599
2626
  } else {
2600
2627
  name = this.parseLiteralExpression(true);
@@ -2627,7 +2654,7 @@ export class Parser extends ScannerErrorReporter {
2627
2654
  keyword: SyntaxKind,
2628
2655
  ): Node {
2629
2656
  const saveHasAwaitIdentifier = this.statementHasAwaitIdentifier;
2630
- const name = nested ? this.parseIdentifierName() : this.parseIdentifier();
2657
+ const name = nested ? this.parseIdentifierName(IdentifierUse.Name) : this.parseIdentifier(IdentifierUse.Name);
2631
2658
  let body: Node;
2632
2659
  if (this.parseOptional(SyntaxKind.DotToken)) {
2633
2660
  const implicitExport = new Token(SyntaxKind.ExportKeyword);
@@ -2660,7 +2687,7 @@ export class Parser extends ScannerErrorReporter {
2660
2687
  const afterImportPos = this.nodePos();
2661
2688
  // The identifier isn't parsed in an await context; the checker reports `await`.
2662
2689
  const saveHasAwaitIdentifier = this.statementHasAwaitIdentifier;
2663
- let identifier = this.isIdentifier() ? this.parseIdentifier() : undefined;
2690
+ let identifier = this.isIdentifier() ? this.parseIdentifier(IdentifierUse.Name) : undefined;
2664
2691
  let phaseModifier = SyntaxKind.Unknown;
2665
2692
  if (
2666
2693
  identifier !== undefined &&
@@ -2670,7 +2697,7 @@ export class Parser extends ScannerErrorReporter {
2670
2697
  (this.isIdentifier() || this.tokenAfterImportDefinitelyProducesImportDeclaration())
2671
2698
  ) {
2672
2699
  phaseModifier = SyntaxKind.TypeKeyword;
2673
- identifier = this.isIdentifier() ? this.parseIdentifier() : undefined;
2700
+ identifier = this.isIdentifier() ? this.parseIdentifier(IdentifierUse.Name) : undefined;
2674
2701
  } else if (identifier !== undefined && identifier.text === 'defer') {
2675
2702
  const shouldParseAsDeferModifier =
2676
2703
  this.token() === SyntaxKind.FromKeyword
@@ -2678,7 +2705,7 @@ export class Parser extends ScannerErrorReporter {
2678
2705
  : this.token() !== SyntaxKind.CommaToken && this.token() !== SyntaxKind.EqualsToken;
2679
2706
  if (shouldParseAsDeferModifier) {
2680
2707
  phaseModifier = SyntaxKind.DeferKeyword;
2681
- identifier = this.isIdentifier() ? this.parseIdentifier() : undefined;
2708
+ identifier = this.isIdentifier() ? this.parseIdentifier(IdentifierUse.Name) : undefined;
2682
2709
  }
2683
2710
  }
2684
2711
  if (
@@ -2809,7 +2836,7 @@ export class Parser extends ScannerErrorReporter {
2809
2836
  const pos = this.nodePos();
2810
2837
  this.parseExpected(SyntaxKind.AsteriskToken);
2811
2838
  this.parseExpected(SyntaxKind.AsKeyword);
2812
- const name = this.parseIdentifier();
2839
+ const name = this.parseIdentifier(IdentifierUse.Name);
2813
2840
  return this.finishNode(new NamespaceImport(name), pos);
2814
2841
  }
2815
2842
 
@@ -2850,9 +2877,9 @@ export class Parser extends ScannerErrorReporter {
2850
2877
  // import { type as as } from "mod"; - isTypeOnly: false, name: as, propertyName: type
2851
2878
  // import { type as as as } from "mod"; - isTypeOnly: true, name: as, propertyName: as
2852
2879
  if (this.token() === SyntaxKind.AsKeyword) {
2853
- const firstAs = this.parseIdentifierName();
2880
+ const firstAs = this.parseIdentifierName(IdentifierUse.Name);
2854
2881
  if (this.token() === SyntaxKind.AsKeyword) {
2855
- const secondAs = this.parseIdentifierName();
2882
+ const secondAs = this.parseIdentifierName(IdentifierUse.Name);
2856
2883
  if (this.canParseModuleExportName()) {
2857
2884
  // { type as as something }
2858
2885
  isTypeOnly = true;
@@ -2921,7 +2948,7 @@ export class Parser extends ScannerErrorReporter {
2921
2948
 
2922
2949
  parseModuleExportName(): Node {
2923
2950
  if (this.token() === SyntaxKind.StringLiteral) return this.parseLiteralExpression(false);
2924
- return this.parseIdentifierName();
2951
+ return this.parseIdentifierName(IdentifierUse.Name);
2925
2952
  }
2926
2953
 
2927
2954
  tryParseImportAttributes(): ImportAttributes | undefined {
@@ -2966,7 +2993,7 @@ export class Parser extends ScannerErrorReporter {
2966
2993
  this.parseExpected(SyntaxKind.AsKeyword);
2967
2994
  this.parseExpected(SyntaxKind.NamespaceKeyword);
2968
2995
  const saveHasAwaitIdentifier = this.statementHasAwaitIdentifier;
2969
- const name = this.parseIdentifier();
2996
+ const name = this.parseIdentifier(IdentifierUse.Name);
2970
2997
  this.statementHasAwaitIdentifier = saveHasAwaitIdentifier;
2971
2998
  this.parseSemicolon();
2972
2999
  // Modifiers are kept so the grammar checker can report them.
@@ -3136,7 +3163,7 @@ export class Parser extends ScannerErrorReporter {
3136
3163
 
3137
3164
  parseTypeParameterOfInferType(): TypeParameterDeclaration {
3138
3165
  const pos = this.nodePos();
3139
- const name = this.parseIdentifier();
3166
+ const name = this.parseIdentifier(IdentifierUse.Name);
3140
3167
  const constraint = this.tryParseConstraintOfInferType();
3141
3168
  const result = new TypeParameterDeclaration(undefined, name, constraint, undefined, undefined);
3142
3169
  this.finishNode(result, pos);
@@ -3342,11 +3369,16 @@ export class Parser extends ScannerErrorReporter {
3342
3369
  return this.parseEntityName(true, Diagnostics.Type_expected);
3343
3370
  }
3344
3371
 
3345
- parseEntityName(allowReservedWords: boolean, diagnosticMessage: DiagnosticMessage | undefined): EntityName {
3372
+ /** An entity name; `use` is for its first identifier, the qualified names' right sides are names. */
3373
+ parseEntityName(
3374
+ allowReservedWords: boolean,
3375
+ diagnosticMessage: DiagnosticMessage | undefined,
3376
+ use: IdentifierUse = IdentifierUse.Name,
3377
+ ): EntityName {
3346
3378
  const pos = this.nodePos();
3347
3379
  let entity: Node = allowReservedWords
3348
- ? this.parseIdentifierNameWithDiagnostic(diagnosticMessage)
3349
- : this.parseIdentifierWithDiagnostic(diagnosticMessage, undefined);
3380
+ ? this.parseIdentifierNameWithDiagnostic(diagnosticMessage, use)
3381
+ : this.parseIdentifierWithDiagnostic(diagnosticMessage, undefined, use);
3350
3382
  while (this.parseOptional(SyntaxKind.DotToken)) {
3351
3383
  // A JSDoc-style generic; the checker reports the gap between the name and the type arguments.
3352
3384
  if (this.token() === SyntaxKind.LessThanToken) break;
@@ -3382,19 +3414,19 @@ export class Parser extends ScannerErrorReporter {
3382
3414
  // after it). Report a missing identifier right after the dot rather than on the next token.
3383
3415
  if (this.isKeywordStartingNextLine()) {
3384
3416
  this.parseErrorAt(this.nodePos(), this.nodePos(), Diagnostics.Identifier_expected);
3385
- return this.createMissingIdentifier();
3417
+ return this.createMissingIdentifier(IdentifierUse.Name);
3386
3418
  }
3387
3419
  if (this.token() === SyntaxKind.PrivateIdentifier) {
3388
3420
  this.parsePrivateIdentifier();
3389
3421
  this.parseErrorAt(this.nodePos(), this.nodePos(), Diagnostics.Identifier_expected);
3390
- return this.createMissingIdentifier();
3422
+ return this.createMissingIdentifier(IdentifierUse.Name);
3391
3423
  }
3392
3424
  if (allowIdentifierNames) {
3393
- if (allowUnicodeEscapeSequenceInIdentifierName) return this.parseIdentifierName();
3394
- return this.parseIdentifierNameErrorOnUnicodeEscapeSequence();
3425
+ if (allowUnicodeEscapeSequenceInIdentifierName) return this.parseIdentifierName(IdentifierUse.Name);
3426
+ return this.parseIdentifierNameErrorOnUnicodeEscapeSequence(IdentifierUse.Name);
3395
3427
  }
3396
3428
  const saveHasAwaitIdentifier = this.statementHasAwaitIdentifier;
3397
- const id = this.parseIdentifier();
3429
+ const id = this.parseIdentifier(IdentifierUse.Name);
3398
3430
  this.statementHasAwaitIdentifier = saveHasAwaitIdentifier;
3399
3431
  return id;
3400
3432
  }
@@ -3408,14 +3440,26 @@ export class Parser extends ScannerErrorReporter {
3408
3440
  );
3409
3441
  }
3410
3442
 
3411
- newIdentifier(text: string): Identifier {
3443
+ /**
3444
+ * A new identifier of the class `use` calls for. Callers create it after the identifier's token, so
3445
+ * for an element name the current token tells a shorthand property from an assignment or a method.
3446
+ */
3447
+ newIdentifier(text: string, use: IdentifierUse = IdentifierUse.Reference): Identifier {
3412
3448
  this.identifierCount++;
3413
3449
  if (text === 'await') this.statementHasAwaitIdentifier = true;
3414
- return new Identifier(text);
3450
+ if (use === IdentifierUse.Name || (use === IdentifierUse.ElementName && this.isElementNameEnd()))
3451
+ return new Identifier(text);
3452
+ return new ReferenceIdentifier(text);
3453
+ }
3454
+
3455
+ /** Whether the current token ends an object literal element name that is not a shorthand property. */
3456
+ isElementNameEnd(): boolean {
3457
+ const token = this.token();
3458
+ return token === SyntaxKind.ColonToken || token === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken;
3415
3459
  }
3416
3460
 
3417
- createMissingIdentifier(): Identifier {
3418
- const result = this.newIdentifier('');
3461
+ createMissingIdentifier(use: IdentifierUse = IdentifierUse.Reference): Identifier {
3462
+ const result = this.newIdentifier('', use);
3419
3463
  this.finishNode(result, this.nodePos());
3420
3464
  return result;
3421
3465
  }
@@ -3516,7 +3560,7 @@ export class Parser extends ScannerErrorReporter {
3516
3560
  parseImportAttribute(): Node {
3517
3561
  const pos = this.nodePos();
3518
3562
  let name: Node | undefined;
3519
- if (tokenIsIdentifierOrKeyword(this.token())) name = this.parseIdentifierName();
3563
+ if (tokenIsIdentifierOrKeyword(this.token())) name = this.parseIdentifierName(IdentifierUse.Name);
3520
3564
  else if (this.token() === SyntaxKind.StringLiteral) name = this.parseLiteralExpression(false);
3521
3565
  if (name !== undefined) this.parseExpected(SyntaxKind.ColonToken);
3522
3566
  else this.parseErrorAtCurrentToken(Diagnostics.Identifier_or_string_literal_expected);
@@ -3545,7 +3589,7 @@ export class Parser extends ScannerErrorReporter {
3545
3589
  parseTypeQuery(): TypeNode {
3546
3590
  const pos = this.nodePos();
3547
3591
  this.parseExpected(SyntaxKind.TypeOfKeyword);
3548
- const entityName = this.parseEntityName(true, undefined);
3592
+ const entityName = this.parseEntityName(true, undefined, IdentifierUse.Reference);
3549
3593
  // ASI: don't parse the next line's type arguments as part of an instantiation expression.
3550
3594
  const typeArguments = this.hasPrecedingLineBreak() ? undefined : this.parseTypeArguments();
3551
3595
  return this.finishNode(new TypeQueryNode(entityName, typeArguments), pos);
@@ -3588,7 +3632,7 @@ export class Parser extends ScannerErrorReporter {
3588
3632
 
3589
3633
  parseMappedTypeParameter(): TypeParameterDeclaration {
3590
3634
  const pos = this.nodePos();
3591
- const name = this.parseIdentifierName();
3635
+ const name = this.parseIdentifierName(IdentifierUse.Name);
3592
3636
  this.parseExpected(SyntaxKind.InKeyword);
3593
3637
  const type = this.parseType();
3594
3638
  const result = new TypeParameterDeclaration(undefined, name, type, undefined, undefined);
@@ -3641,7 +3685,7 @@ export class Parser extends ScannerErrorReporter {
3641
3685
  parseTypeParameter(): Node {
3642
3686
  const pos = this.nodePos();
3643
3687
  const modifiers = this.parseModifiersEx(false, true, false);
3644
- const name = this.parseIdentifier();
3688
+ const name = this.parseIdentifier(IdentifierUse.Name);
3645
3689
  let constraint: TypeNode | undefined;
3646
3690
  let expression: Expression | undefined;
3647
3691
  if (this.parseOptional(SyntaxKind.ExtendsKeyword)) {
@@ -3700,7 +3744,7 @@ export class Parser extends ScannerErrorReporter {
3700
3744
  const result = new ParameterDeclaration(
3701
3745
  modifiers,
3702
3746
  undefined,
3703
- this.createIdentifier(true),
3747
+ this.createIdentifier(true, IdentifierUse.Name),
3704
3748
  undefined,
3705
3749
  this.parseTypeAnnotation(),
3706
3750
  undefined,
@@ -3780,7 +3824,7 @@ export class Parser extends ScannerErrorReporter {
3780
3824
  if (this.isIdentifier()) {
3781
3825
  const state = this.beginSpeculation();
3782
3826
  const pos = this.nodePos();
3783
- const id = this.parseIdentifier();
3827
+ const id = this.parseIdentifier(IdentifierUse.Name);
3784
3828
  if (this.token() === SyntaxKind.IsKeyword && !this.hasPrecedingLineBreak()) {
3785
3829
  this.endSpeculation(state);
3786
3830
  this.nextToken();
@@ -3819,20 +3863,20 @@ export class Parser extends ScannerErrorReporter {
3819
3863
  return result;
3820
3864
  }
3821
3865
 
3822
- parsePropertyName(): Node {
3866
+ parsePropertyName(use: IdentifierUse = IdentifierUse.Name): Node {
3823
3867
  const saveHasAwaitIdentifier = this.statementHasAwaitIdentifier;
3824
- const prop = this.parsePropertyNameWorker(true);
3868
+ const prop = this.parsePropertyNameWorker(true, use);
3825
3869
  this.statementHasAwaitIdentifier = saveHasAwaitIdentifier;
3826
3870
  return prop;
3827
3871
  }
3828
3872
 
3829
- parsePropertyNameWorker(allowComputedPropertyNames: boolean): Node {
3873
+ parsePropertyNameWorker(allowComputedPropertyNames: boolean, use: IdentifierUse = IdentifierUse.Name): Node {
3830
3874
  const token = this.token();
3831
3875
  if (token === SyntaxKind.StringLiteral || token === SyntaxKind.NumericLiteral || token === SyntaxKind.BigIntLiteral)
3832
3876
  return this.parseLiteralExpression(true);
3833
3877
  if (allowComputedPropertyNames && token === SyntaxKind.OpenBracketToken) return this.parseComputedPropertyName();
3834
3878
  if (token === SyntaxKind.PrivateIdentifier) return this.parsePrivateIdentifier();
3835
- return this.parseIdentifierName();
3879
+ return this.parseIdentifierName(use);
3836
3880
  }
3837
3881
 
3838
3882
  parseComputedPropertyName(): Node {
@@ -3944,7 +3988,7 @@ export class Parser extends ScannerErrorReporter {
3944
3988
  const pos = this.nodePos();
3945
3989
  const jsdoc = this.jsdocScannerInfo();
3946
3990
  const dotDotDotToken = this.parseOptionalToken(SyntaxKind.DotDotDotToken);
3947
- const name = this.parseIdentifierName();
3991
+ const name = this.parseIdentifierName(IdentifierUse.Name);
3948
3992
  const questionToken = this.parseOptionalToken(SyntaxKind.QuestionToken);
3949
3993
  this.parseExpected(SyntaxKind.ColonToken);
3950
3994
  const type = this.parseTupleElementType();
@@ -3980,7 +4024,7 @@ export class Parser extends ScannerErrorReporter {
3980
4024
  const pos = this.nodePos();
3981
4025
  const assertsModifier = this.parseExpectedToken(SyntaxKind.AssertsKeyword);
3982
4026
  const parameterName: Node =
3983
- this.token() === SyntaxKind.ThisKeyword ? this.parseThisTypeNode() : this.parseIdentifier();
4027
+ this.token() === SyntaxKind.ThisKeyword ? this.parseThisTypeNode() : this.parseIdentifier(IdentifierUse.Name);
3984
4028
  const type = this.parseOptional(SyntaxKind.IsKeyword) ? this.parseType() : undefined;
3985
4029
  return this.finishNode(new TypePredicateNode(assertsModifier, parameterName, type), pos);
3986
4030
  }
@@ -5092,11 +5136,11 @@ export class Parser extends ScannerErrorReporter {
5092
5136
  parseJsxAttributeName(): Node {
5093
5137
  const pos = this.nodePos();
5094
5138
  this.scanJsxIdentifier();
5095
- const attrName = this.parseIdentifierNameErrorOnUnicodeEscapeSequence();
5139
+ const attrName = this.parseIdentifierNameErrorOnUnicodeEscapeSequence(IdentifierUse.Name);
5096
5140
  if (this.parseOptional(SyntaxKind.ColonToken)) {
5097
5141
  this.scanJsxIdentifier();
5098
5142
  return this.finishNode(
5099
- new JsxNamespacedName(attrName, this.parseIdentifierNameErrorOnUnicodeEscapeSequence()),
5143
+ new JsxNamespacedName(attrName, this.parseIdentifierNameErrorOnUnicodeEscapeSequence(IdentifierUse.Name)),
5100
5144
  pos,
5101
5145
  );
5102
5146
  }
@@ -5227,7 +5271,7 @@ export class Parser extends ScannerErrorReporter {
5227
5271
  // An `import.*` meta property, such as `import.meta`.
5228
5272
  this.nextToken();
5229
5273
  this.nextToken();
5230
- const name = this.parseIdentifierName();
5274
+ const name = this.parseIdentifierName(IdentifierUse.Name);
5231
5275
  expression = this.finishNode(new MetaProperty(SyntaxKind.ImportKeyword, name), pos);
5232
5276
  if (name.text === 'defer') {
5233
5277
  if (this.token() === SyntaxKind.OpenParenToken || this.token() === SyntaxKind.LessThanToken)
@@ -5493,12 +5537,13 @@ export class Parser extends ScannerErrorReporter {
5493
5537
  const isOptionalChain = questionDotToken !== undefined || this.tryReparseOptionalChain(expression);
5494
5538
  expression = this.checkJSSyntax(
5495
5539
  this.finishNode(
5496
- new CallExpression(
5540
+ newCallExpression(
5497
5541
  expression,
5498
5542
  questionDotToken,
5499
5543
  typeArguments,
5500
5544
  argumentList,
5501
5545
  isOptionalChain ? NodeFlags.OptionalChain : NodeFlags.None,
5546
+ (this.contextFlags & NodeFlags.JavaScriptFile) !== 0,
5502
5547
  ),
5503
5548
  pos,
5504
5549
  ),
@@ -5705,7 +5750,7 @@ export class Parser extends ScannerErrorReporter {
5705
5750
  return this.parseAccessorDeclaration(pos, jsdoc, modifiers, SyntaxKind.SetAccessor, ParseFlags.None);
5706
5751
  const asteriskToken = this.parseOptionalToken(SyntaxKind.AsteriskToken);
5707
5752
  const tokenIsIdentifier = this.isIdentifier();
5708
- const name = this.parsePropertyName();
5753
+ const name = this.parsePropertyName(IdentifierUse.ElementName);
5709
5754
  // The grammar checker reports optional property assignments, definite assignment assertions,
5710
5755
  // decorators and modifiers.
5711
5756
  let postfixToken = this.parseOptionalToken(SyntaxKind.QuestionToken);
@@ -5726,7 +5771,14 @@ export class Parser extends ScannerErrorReporter {
5726
5771
  } else {
5727
5772
  this.parseExpected(SyntaxKind.ColonToken);
5728
5773
  const initializer = this.parseAssignmentExpressionOrHigherAllowIn();
5729
- node = new PropertyAssignment(modifiers, name, postfixToken, undefined, initializer);
5774
+ node = newPropertyAssignment(
5775
+ modifiers,
5776
+ name,
5777
+ postfixToken,
5778
+ undefined,
5779
+ initializer,
5780
+ (this.contextFlags & NodeFlags.JavaScriptFile) !== 0,
5781
+ );
5730
5782
  }
5731
5783
  return this.finishWithJSDoc(node, pos, jsdoc);
5732
5784
  }
@@ -5788,7 +5840,7 @@ export class Parser extends ScannerErrorReporter {
5788
5840
  const pos = this.nodePos();
5789
5841
  this.parseExpected(SyntaxKind.NewKeyword);
5790
5842
  if (this.parseOptional(SyntaxKind.DotToken)) {
5791
- const name = this.parseIdentifierName();
5843
+ const name = this.parseIdentifierName(IdentifierUse.Name);
5792
5844
  return this.finishNode(new MetaProperty(SyntaxKind.NewKeyword, name), pos);
5793
5845
  }
5794
5846
  const expressionPos = this.nodePos();
@@ -5847,10 +5899,10 @@ export class Parser extends ScannerErrorReporter {
5847
5899
 
5848
5900
  // Identifiers
5849
5901
 
5850
- parseIdentifierNameErrorOnUnicodeEscapeSequence(): Identifier {
5902
+ parseIdentifierNameErrorOnUnicodeEscapeSequence(use: IdentifierUse = IdentifierUse.Reference): Identifier {
5851
5903
  if (this.scanner.hasUnicodeEscape() || this.scanner.hasExtendedUnicodeEscape())
5852
5904
  this.parseErrorAtCurrentToken(Diagnostics.Unicode_escape_sequence_cannot_appear_here);
5853
- return this.createIdentifier(tokenIsIdentifierOrKeyword(this.token()));
5905
+ return this.createIdentifier(tokenIsIdentifierOrKeyword(this.token()), use);
5854
5906
  }
5855
5907
 
5856
5908
  parseBindingIdentifier(): Identifier {
@@ -5863,42 +5915,54 @@ export class Parser extends ScannerErrorReporter {
5863
5915
  this.isBindingIdentifier(),
5864
5916
  undefined,
5865
5917
  privateIdentifierDiagnosticMessage,
5918
+ IdentifierUse.Name,
5866
5919
  );
5867
5920
  this.statementHasAwaitIdentifier = saveHasAwaitIdentifier;
5868
5921
  return id;
5869
5922
  }
5870
5923
 
5871
- parseIdentifierName(): Identifier {
5872
- return this.parseIdentifierNameWithDiagnostic(undefined);
5924
+ parseIdentifierName(use: IdentifierUse = IdentifierUse.Reference): Identifier {
5925
+ return this.parseIdentifierNameWithDiagnostic(undefined, use);
5873
5926
  }
5874
5927
 
5875
- parseIdentifierNameWithDiagnostic(diagnosticMessage: DiagnosticMessage | undefined): Identifier {
5876
- return this.createIdentifierWithDiagnostic(tokenIsIdentifierOrKeyword(this.token()), diagnosticMessage, undefined);
5928
+ parseIdentifierNameWithDiagnostic(
5929
+ diagnosticMessage: DiagnosticMessage | undefined,
5930
+ use: IdentifierUse = IdentifierUse.Reference,
5931
+ ): Identifier {
5932
+ return this.createIdentifierWithDiagnostic(
5933
+ tokenIsIdentifierOrKeyword(this.token()),
5934
+ diagnosticMessage,
5935
+ undefined,
5936
+ use,
5937
+ );
5877
5938
  }
5878
5939
 
5879
- parseIdentifier(): Identifier {
5880
- return this.parseIdentifierWithDiagnostic(undefined, undefined);
5940
+ parseIdentifier(use: IdentifierUse = IdentifierUse.Reference): Identifier {
5941
+ return this.parseIdentifierWithDiagnostic(undefined, undefined, use);
5881
5942
  }
5882
5943
 
5883
5944
  parseIdentifierWithDiagnostic(
5884
5945
  diagnosticMessage: DiagnosticMessage | undefined,
5885
5946
  privateIdentifierDiagnosticMessage: DiagnosticMessage | undefined,
5947
+ use: IdentifierUse = IdentifierUse.Reference,
5886
5948
  ): Identifier {
5887
5949
  return this.createIdentifierWithDiagnostic(
5888
5950
  this.isIdentifier(),
5889
5951
  diagnosticMessage,
5890
5952
  privateIdentifierDiagnosticMessage,
5953
+ use,
5891
5954
  );
5892
5955
  }
5893
5956
 
5894
- createIdentifier(isIdentifier: boolean): Identifier {
5895
- return this.createIdentifierWithDiagnostic(isIdentifier, undefined, undefined);
5957
+ createIdentifier(isIdentifier: boolean, use: IdentifierUse = IdentifierUse.Reference): Identifier {
5958
+ return this.createIdentifierWithDiagnostic(isIdentifier, undefined, undefined, use);
5896
5959
  }
5897
5960
 
5898
5961
  createIdentifierWithDiagnostic(
5899
5962
  isIdentifier: boolean,
5900
5963
  diagnosticMessage: DiagnosticMessage | undefined,
5901
5964
  privateIdentifierDiagnosticMessage: DiagnosticMessage | undefined,
5965
+ use: IdentifierUse = IdentifierUse.Reference,
5902
5966
  ): Identifier {
5903
5967
  if (isIdentifier) {
5904
5968
  const pos = this.scanner.hasPrecedingJSDocLeadingAsterisks() ? this.scanner.getTokenStart() : this.nodePos();
@@ -5906,7 +5970,7 @@ export class Parser extends ScannerErrorReporter {
5906
5970
  const record = this.scanner.recordIdentifierValue(text);
5907
5971
  this.nextTokenWithoutCheck();
5908
5972
  if (record) this.identifierTexts.push(text);
5909
- const result = this.newIdentifier(text);
5973
+ const result = this.newIdentifier(text, use);
5910
5974
  this.finishNode(result, pos);
5911
5975
  return result;
5912
5976
  }
@@ -5916,7 +5980,7 @@ export class Parser extends ScannerErrorReporter {
5916
5980
  ? privateIdentifierDiagnosticMessage
5917
5981
  : Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies,
5918
5982
  );
5919
- return this.createIdentifier(true);
5983
+ return this.createIdentifier(true, use);
5920
5984
  }
5921
5985
  // Report at the current position only at the end of the file: elsewhere the error would land
5922
5986
  // incorrectly on embedded script tags.
@@ -5944,7 +6008,7 @@ export class Parser extends ScannerErrorReporter {
5944
6008
  } else {
5945
6009
  this.parseErrorAtCurrentToken(Diagnostics.Identifier_expected);
5946
6010
  }
5947
- return this.createMissingIdentifier();
6011
+ return this.createMissingIdentifier(use);
5948
6012
  }
5949
6013
 
5950
6014
  internIdentifier(text: string): string {
@@ -6763,9 +6827,9 @@ export class Parser extends ScannerErrorReporter {
6763
6827
 
6764
6828
  processPragmasIntoFields(file: SourceFile): void {
6765
6829
  file.checkJsDirective = undefined;
6766
- file.referencedFiles = [];
6767
- file.typeReferenceDirectives = [];
6768
- file.libReferenceDirectives = [];
6830
+ file.referencedFiles = emptyFileReferences;
6831
+ file.typeReferenceDirectives = emptyFileReferences;
6832
+ file.libReferenceDirectives = emptyFileReferences;
6769
6833
  for (const pragma of file.pragmas) {
6770
6834
  switch (pragma.name) {
6771
6835
  case 'reference': {
@@ -6784,15 +6848,20 @@ export class Parser extends ScannerErrorReporter {
6784
6848
  resolutionMode !== undefined
6785
6849
  ? this.parseResolutionMode(resolutionMode.value, resolutionMode.pos, resolutionMode.end)
6786
6850
  : ModuleKind.None;
6787
- file.typeReferenceDirectives.push(
6851
+ file.typeReferenceDirectives = appendToList(
6852
+ file.typeReferenceDirectives,
6788
6853
  new FileReference(types.pos, types.end, types.value, parsed, isPreserved),
6789
6854
  );
6790
6855
  } else if (lib !== undefined) {
6791
- file.libReferenceDirectives.push(
6856
+ file.libReferenceDirectives = appendToList(
6857
+ file.libReferenceDirectives,
6792
6858
  new FileReference(lib.pos, lib.end, lib.value, ModuleKind.None, isPreserved),
6793
6859
  );
6794
6860
  } else if (path !== undefined) {
6795
- file.referencedFiles.push(new FileReference(path.pos, path.end, path.value, ModuleKind.None, isPreserved));
6861
+ file.referencedFiles = appendToList(
6862
+ file.referencedFiles,
6863
+ new FileReference(path.pos, path.end, path.value, ModuleKind.None, isPreserved),
6864
+ );
6796
6865
  } else {
6797
6866
  this.parseErrorAt(pragma.range.pos, pragma.range.end, Diagnostics.Invalid_reference_directive_syntax);
6798
6867
  }
@@ -6934,6 +7003,17 @@ export function forgetLazyJSDocFile(): void {
6934
7003
 
6935
7004
  const viableKeywordSuggestions = getViableKeywordSuggestions();
6936
7005
 
7006
+ // A parser whose JSDoc parser released parsers keep (`Parser.release`), created on first use.
7007
+ let releasedParserValue: Parser | undefined;
7008
+ function releasedParser(): Parser {
7009
+ let parser = releasedParserValue;
7010
+ if (parser === undefined) {
7011
+ parser = new Parser('/', '/', '', ScriptKind.TS, new ExternalModuleIndicatorOptions(false, false));
7012
+ releasedParserValue = parser;
7013
+ }
7014
+ return parser;
7015
+ }
7016
+
6937
7017
  function getSpaceSuggestion(expressionText: string): string {
6938
7018
  for (const keyword of viableKeywordSuggestions)
6939
7019
  if (expressionText.length > keyword.length + 2 && expressionText.startsWith(keyword))
@@ -6992,8 +7072,8 @@ function typeHasBlockingError(node: TypeNode | undefined): boolean {
6992
7072
  return node !== undefined && typeHasArrowFunctionBlockingParseError(node);
6993
7073
  }
6994
7074
 
6995
- function attachFileToDiagnostics(diagnostics: Diagnostic[], file: SourceFile): Diagnostic[] {
6996
- if (diagnostics.length === 0) return diagnostics;
7075
+ function attachFileToDiagnostics(diagnostics: Diagnostic[], file: SourceFile): readonly Diagnostic[] {
7076
+ if (diagnostics.length === 0) return emptyDiagnostics;
6997
7077
  const diagnosticFile = file.diagnosticFile();
6998
7078
  for (const d of diagnostics) {
6999
7079
  d.file = diagnosticFile;
@@ -7304,12 +7384,12 @@ function nextTokenIsNotColon(p: Parser): boolean {
7304
7384
 
7305
7385
  // Pragmas
7306
7386
 
7307
- function getCommentPragmas(sourceText: string): Pragma[] {
7308
- const pragmas: Pragma[] = [];
7387
+ function getCommentPragmas(sourceText: string): readonly Pragma[] {
7309
7388
  const ranges = getLeadingCommentRanges(sourceText, 0);
7310
- if (ranges !== undefined)
7311
- for (const range of ranges) extractPragmas(range, sourceText.substring(range.pos, range.end), pragmas);
7312
- return pragmas;
7389
+ if (ranges === undefined) return emptyPragmas;
7390
+ const pragmas: Pragma[] = [];
7391
+ for (const range of ranges) extractPragmas(range, sourceText.substring(range.pos, range.end), pragmas);
7392
+ return pragmas.length === 0 ? emptyPragmas : pragmas;
7313
7393
  }
7314
7394
 
7315
7395
  function extractPragmas(range: CommentRange, text: string, pragmas: Pragma[]): void {
@@ -7478,9 +7558,9 @@ function collectModuleReferences(file: SourceFile, node: Statement, inAmbientMod
7478
7558
  ) {
7479
7559
  const nameText = getText((node as ModuleDeclaration).name);
7480
7560
  if (file.externalModuleIndicator !== undefined || (inAmbientModule && !isExternalModuleNameRelative(nameText))) {
7481
- file.moduleAugmentations.push((node as ModuleDeclaration).name);
7561
+ file.moduleAugmentations = appendToList(file.moduleAugmentations, (node as ModuleDeclaration).name);
7482
7562
  } else if (!inAmbientModule) {
7483
- file.ambientModuleNames.push(nameText);
7563
+ file.ambientModuleNames = appendToList(file.ambientModuleNames, nameText);
7484
7564
  const body = (node as ModuleDeclaration).body;
7485
7565
  if (body !== undefined) {
7486
7566
  const statements = getStatements(body);