tsc-ts 0.0.9 → 0.0.10

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 (55) hide show
  1. package/README.md +1 -1
  2. package/dist/api/compiler/ast.d.ts +2 -0
  3. package/dist/api/compiler/ast.js +3 -0
  4. package/dist/api/compiler/checker-calls.js +5 -1
  5. package/dist/api/compiler/checker-grammar.js +3 -2
  6. package/dist/api/compiler/checker-inference.js +8 -2
  7. package/dist/api/compiler/checker-members.js +2 -1
  8. package/dist/api/compiler/checker-type-factory.js +8 -2
  9. package/dist/api/compiler/checker.d.ts +11 -0
  10. package/dist/api/compiler/checker.js +40 -0
  11. package/dist/api/compiler/compile-program.d.ts +26 -2
  12. package/dist/api/compiler/compile-program.js +100 -7
  13. package/dist/api/compiler/diagnostics.d.ts +22 -0
  14. package/dist/api/compiler/diagnostics.js +86 -4
  15. package/dist/api/compiler/file-loader.d.ts +11 -1
  16. package/dist/api/compiler/file-loader.js +63 -7
  17. package/dist/api/compiler/parallel-parse.d.ts +3 -2
  18. package/dist/api/compiler/parallel-parse.js +17 -5
  19. package/dist/api/compiler/printer/emit-context.d.ts +2 -0
  20. package/dist/api/compiler/printer/emit-context.js +4 -0
  21. package/dist/api/compiler/printer/printer.d.ts +48 -2
  22. package/dist/api/compiler/printer/printer.js +238 -14
  23. package/dist/api/compiler/program-checker.d.ts +4 -0
  24. package/dist/api/compiler/program-checker.js +4 -0
  25. package/dist/api/compiler/program.d.ts +2 -6
  26. package/dist/api/compiler/program.js +5 -30
  27. package/dist/api/compiler/relations.js +10 -0
  28. package/dist/api/compiler/symbol.d.ts +1 -1
  29. package/dist/api/compiler/symbol.js +8 -10
  30. package/package.json +9 -9
  31. package/src/compiler/ast.ts +3 -0
  32. package/src/compiler/checker-calls.ts +3 -1
  33. package/src/compiler/checker-grammar.ts +3 -2
  34. package/src/compiler/checker-inference.ts +7 -2
  35. package/src/compiler/checker-members.ts +3 -1
  36. package/src/compiler/checker-type-factory.ts +4 -2
  37. package/src/compiler/checker.ts +37 -0
  38. package/src/compiler/compile-program.ts +121 -7
  39. package/src/compiler/diagnostics.ts +84 -3
  40. package/src/compiler/file-loader.ts +58 -6
  41. package/src/compiler/incremental.ts +80 -13
  42. package/src/compiler/parallel-check.ts +129 -44
  43. package/src/compiler/parallel-emit.ts +320 -0
  44. package/src/compiler/parallel-parse.ts +16 -5
  45. package/src/compiler/parse-thread.ts +3 -0
  46. package/src/compiler/printer/emit-context.ts +5 -0
  47. package/src/compiler/printer/printer.ts +231 -16
  48. package/src/compiler/program-checker.ts +4 -0
  49. package/src/compiler/program.ts +5 -25
  50. package/src/compiler/relations.ts +7 -0
  51. package/src/compiler/symbol.ts +15 -10
  52. package/src/compiler/thread-entry.ts +45 -2
  53. package/src/compiler/tsc-build.ts +63 -9
  54. package/src/compiler/tsc-cli.ts +5 -0
  55. package/src/compiler/tsc-compile.ts +278 -3
@@ -39,6 +39,8 @@ export class PrinterOptions {
39
39
  this.terminateUnterminatedLiterals = false;
40
40
  }
41
41
  }
42
+ /** The saved emit flags of a node whose comments were not looked for (`Printer.inCommentFreeRange`). */
43
+ const commentFreeNode = -1;
42
44
  export class Printer extends NameGeneratorHost {
43
45
  options;
44
46
  context;
@@ -50,6 +52,13 @@ export class Printer extends NameGeneratorHost {
50
52
  currentSourceFile;
51
53
  sourceText;
52
54
  lineStarts;
55
+ /**
56
+ * The line of the last `lineOf` lookup, `lookupLine`, and the positions it spans, `[lookupLineStart, lookupLineEnd)`,
57
+ * with `lookupLineEnd` -1 after the last line: printing reads positions mostly in order, so most lookups fall on that line.
58
+ */
59
+ lookupLine;
60
+ lookupLineStart;
61
+ lookupLineEnd;
53
62
  writer;
54
63
  ownWriter;
55
64
  uniqueHelperNames;
@@ -63,8 +72,25 @@ export class Printer extends NameGeneratorHost {
63
72
  commentsDisabled;
64
73
  /** Emitting the `extends` clause of a conditional or infer type. */
65
74
  inExtends;
66
- /** Saved comment state: emit flags, comment pos, comment end, container pos, container end, declaration list end. */
75
+ /**
76
+ * Saved comment state, 32-bit values: emit flags, comment pos, comment end, container pos, container end,
77
+ * declaration list end.
78
+ * Flags are `commentFreeNode` for a node that `emitCommentsBeforeNode` handled in a comment-free range.
79
+ */
67
80
  commentStack;
81
+ /** The used length of `commentStack`: entries are written in place and kept for reuse once popped. */
82
+ commentDepth;
83
+ /** Start positions of `//` and `/*` in `sourceText`, ascending; made on first use for each file. */
84
+ commentStarts;
85
+ /**
86
+ * A range of `sourceText`, `[freeStart, freeEnd)`, where no comment starts and the last character is not trivia,
87
+ * so no comment is found from any position in it; -1 when there is none. `freeOwner` is the node it was made for.
88
+ */
89
+ freeStart;
90
+ freeEnd;
91
+ /** Whether no trailing comment follows `freeEnd`. */
92
+ freeEndTrailingNone;
93
+ freeOwner;
68
94
  /** Saved source map state: emit flags, pos, end, has token range. */
69
95
  sourceMapStack;
70
96
  /** The token position after `enterToken` skipped trivia. */
@@ -94,6 +120,9 @@ export class Printer extends NameGeneratorHost {
94
120
  this.currentSourceFile = undefined;
95
121
  this.sourceText = '';
96
122
  this.lineStarts = [];
123
+ this.lookupLine = -1;
124
+ this.lookupLineStart = 0;
125
+ this.lookupLineEnd = 0;
97
126
  this.writer = new TextWriter(options.newLine, 4);
98
127
  this.ownWriter = undefined;
99
128
  this.uniqueHelperNames = undefined;
@@ -105,7 +134,13 @@ export class Printer extends NameGeneratorHost {
105
134
  this.detachedComments = [];
106
135
  this.commentsDisabled = options.removeComments;
107
136
  this.inExtends = false;
108
- this.commentStack = [];
137
+ this.commentStack = new Int32Array(96);
138
+ this.commentDepth = 0;
139
+ this.commentStarts = undefined;
140
+ this.freeStart = -1;
141
+ this.freeEnd = -1;
142
+ this.freeEndTrailingNone = false;
143
+ this.freeOwner = undefined;
109
144
  this.sourceMapStack = [];
110
145
  this.tokenPos = 0;
111
146
  this.sourceMapsDisabled = true;
@@ -150,6 +185,11 @@ export class Printer extends NameGeneratorHost {
150
185
  this.currentSourceFile = sourceFile;
151
186
  this.sourceText = sourceFile === undefined ? '' : sourceFile.text;
152
187
  this.lineStarts = sourceFile === undefined ? [] : sourceFile.lineStarts();
188
+ this.lookupLine = -1;
189
+ this.lookupLineStart = 0;
190
+ this.lookupLineEnd = 0;
191
+ this.commentStarts = undefined;
192
+ this.endCommentFreeRange();
153
193
  return true;
154
194
  }
155
195
  /** Prints `node` into `writer`, adding mappings to `sourceMapGenerator` if given. */
@@ -234,6 +274,9 @@ export class Printer extends NameGeneratorHost {
234
274
  case 79 /* SyntaxKind.Identifier */:
235
275
  case 80 /* SyntaxKind.PrivateIdentifier */:
236
276
  case 296 /* SyntaxKind.JsxNamespacedName */:
277
+ // Its text either way: the source text, or the text of a node from elsewhere.
278
+ if (this.textIsSourceText(node))
279
+ return node.text;
237
280
  if (!canUseSourceFile || !this.isInCurrentSourceFile(node)) {
238
281
  if (node instanceof Identifier)
239
282
  return node.text;
@@ -256,6 +299,39 @@ export class Printer extends NameGeneratorHost {
256
299
  }
257
300
  return getSourceTextOfNode(this.sourceText, node);
258
301
  }
302
+ /**
303
+ * Whether the source text of an identifier or private identifier of the current file, from the end of its leading
304
+ * trivia to its end, is its text: the text ends the node, and the character before it is not part of the token, as
305
+ * it would be in an identifier written with escapes. Nodes from JSDoc may span other text, so they are left to the
306
+ * general path.
307
+ */
308
+ textIsSourceText(node) {
309
+ if (!(node instanceof Identifier) && !(node instanceof PrivateIdentifier))
310
+ return false;
311
+ if ((node.flags & (8 /* NodeFlags.Reparsed */ | 4194304 /* NodeFlags.JSDoc */ | 268435456 /* NodeFlags.ReparserTransformedLiteral */)) !== 0)
312
+ return false;
313
+ const text = node.text;
314
+ const source = this.sourceText;
315
+ const end = node.end;
316
+ const start = end - text.length;
317
+ if (text.length === 0 || start < node.pos || end > source.length)
318
+ return false;
319
+ if (!source.startsWith(text, start))
320
+ return false;
321
+ if (start === node.pos)
322
+ return true;
323
+ const before = source.charCodeAt(start - 1);
324
+ return !((before >= 97 /* CharacterCodes.a */ && before <= 122 /* CharacterCodes.z */) ||
325
+ (before >= 65 /* CharacterCodes.A */ && before <= 90 /* CharacterCodes.Z */) ||
326
+ (before >= 48 /* CharacterCodes._0 */ && before <= 57 /* CharacterCodes._9 */) ||
327
+ before === 95 /* CharacterCodes._ */ ||
328
+ before === 36 /* CharacterCodes.$ */ ||
329
+ before === 92 /* CharacterCodes.backslash */ ||
330
+ before === 123 /* CharacterCodes.openBrace */ ||
331
+ before === 125 /* CharacterCodes.closeBrace */ ||
332
+ before === 35 /* CharacterCodes.hash */ ||
333
+ before > 127 /* CharacterCodes.maxAsciiCharacter */);
334
+ }
259
335
  isInCurrentSourceFile(node) {
260
336
  const file = this.currentSourceFile;
261
337
  if (file === undefined)
@@ -331,7 +407,28 @@ export class Printer extends NameGeneratorHost {
331
407
  }
332
408
  // Lines between nodes
333
409
  positionsAreOnSameLine(pos1, pos2) {
334
- return getLinesBetweenPositions(this.lineStarts, pos1, pos2) === 0;
410
+ if (pos1 === pos2)
411
+ return true;
412
+ const lower = pos1 < pos2 ? pos1 : pos2;
413
+ const upper = pos1 < pos2 ? pos2 : pos1;
414
+ // What getLinesBetweenPositions finds: no line starts in (lower, upper].
415
+ if (lower < 0) {
416
+ const first = this.lineStarts.length > 0 ? this.lineStarts[0] | 0 : -1;
417
+ return first < 0 || upper < first;
418
+ }
419
+ this.lineOf(lower);
420
+ return this.lookupLineEnd < 0 || upper < this.lookupLineEnd;
421
+ }
422
+ /** The zero-based line of `pos` (-1 before the first line), which becomes the line of the last lookup. */
423
+ lineOf(pos) {
424
+ if (pos >= this.lookupLineStart && (pos < this.lookupLineEnd || this.lookupLineEnd < 0) && this.lookupLine >= 0)
425
+ return this.lookupLine;
426
+ const starts = this.lineStarts;
427
+ const line = computeLineOfPosition(starts, pos);
428
+ this.lookupLine = line;
429
+ this.lookupLineStart = line >= 0 ? starts[line] | 0 : 0;
430
+ this.lookupLineEnd = line + 1 < starts.length ? starts[line + 1] | 0 : -1;
431
+ return line;
335
432
  }
336
433
  rangeStart(pos) {
337
434
  return getStartPositionOfRange(this.sourceText, pos, false);
@@ -617,8 +714,13 @@ export class Printer extends NameGeneratorHost {
617
714
  return true;
618
715
  }
619
716
  // Names
620
- // Source text of names reparsed from JSDoc can span lines.
717
+ // Source text of names reparsed from JSDoc can span lines; an identifier's own source text has no line breaks.
621
718
  emitIdentifierText(node) {
719
+ if (!this.context.autoGenerate.has(node) && this.textIsSourceText(node)) {
720
+ // writeText's answer for text without line breaks.
721
+ this.writer.write(node.text);
722
+ return false;
723
+ }
622
724
  return this.writer.writeText(this.getTextOfNode(node));
623
725
  }
624
726
  emitIdentifierName(node) {
@@ -3751,10 +3853,19 @@ export class Printer extends NameGeneratorHost {
3751
3853
  emitCommentsBeforeNode(node) {
3752
3854
  if (!this.shouldEmitComments(node))
3753
3855
  return false;
3856
+ if (this.inCommentFreeRange(node)) {
3857
+ // What the general path does for a node without emit data and without comments.
3858
+ this.pushCommentState(commentFreeNode, node.pos, node.end);
3859
+ this.containerPos = node.pos;
3860
+ this.containerEnd = node.end;
3861
+ if (node.kind === 262 /* SyntaxKind.VariableDeclarationList */)
3862
+ this.declarationListContainerEnd = node.end;
3863
+ return true;
3864
+ }
3754
3865
  const flags = this.context.getEmitFlags(node);
3755
3866
  const pos = this.context.commentPos(node);
3756
3867
  const end = this.context.commentEnd(node);
3757
- this.commentStack.push(flags, pos, end, this.containerPos, this.containerEnd, this.declarationListContainerEnd);
3868
+ this.pushCommentState(flags, pos, end);
3758
3869
  this.emitLeadingCommentsOfNode(node, flags, pos, end);
3759
3870
  if ((flags & 128 /* EmitFlags.NoLeadingComments */) === 0) {
3760
3871
  const synthesized = this.context.getSyntheticLeadingComments(node);
@@ -3766,17 +3877,43 @@ export class Printer extends NameGeneratorHost {
3766
3877
  this.commentsDisabled = true;
3767
3878
  return true;
3768
3879
  }
3880
+ /** Saves the comment state of a node: its emit flags (or `commentFreeNode`), comment range and the containers. */
3881
+ pushCommentState(flags, pos, end) {
3882
+ let stack = this.commentStack;
3883
+ const at = this.commentDepth;
3884
+ if (at + 6 > stack.length) {
3885
+ const grown = new Int32Array(stack.length * 2);
3886
+ grown.set(stack);
3887
+ this.commentStack = grown;
3888
+ stack = grown;
3889
+ }
3890
+ stack[at] = flags;
3891
+ stack[at + 1] = pos;
3892
+ stack[at + 2] = end;
3893
+ stack[at + 3] = this.containerPos;
3894
+ stack[at + 4] = this.containerEnd;
3895
+ stack[at + 5] = this.declarationListContainerEnd;
3896
+ this.commentDepth = at + 6;
3897
+ return true;
3898
+ }
3769
3899
  emitCommentsAfterNode(node) {
3770
3900
  const stack = this.commentStack;
3771
- const base = stack.length - 6;
3772
- // `| 0` keeps scriptc from typing array reads as possibly undefined.
3773
- const flags = stack[base] | 0;
3774
- const pos = stack[base + 1] | 0;
3775
- const end = stack[base + 2] | 0;
3776
- const containerPos = stack[base + 3] | 0;
3777
- const containerEnd = stack[base + 4] | 0;
3778
- const declarationListContainerEnd = stack[base + 5] | 0;
3779
- stack.length = base;
3901
+ const base = this.commentDepth - 6;
3902
+ const flags = stack[base];
3903
+ const pos = stack[base + 1];
3904
+ const end = stack[base + 2];
3905
+ const containerPos = stack[base + 3];
3906
+ const containerEnd = stack[base + 4];
3907
+ const declarationListContainerEnd = stack[base + 5];
3908
+ this.commentDepth = base;
3909
+ if (node === this.freeOwner)
3910
+ this.endCommentFreeRange();
3911
+ if (flags === commentFreeNode) {
3912
+ this.containerPos = containerPos;
3913
+ this.containerEnd = containerEnd;
3914
+ this.declarationListContainerEnd = declarationListContainerEnd;
3915
+ return true;
3916
+ }
3780
3917
  if ((flags & 512 /* EmitFlags.NoNestedComments */) !== 0)
3781
3918
  this.commentsDisabled = false;
3782
3919
  if ((flags & 256 /* EmitFlags.NoTrailingComments */) === 0) {
@@ -3792,6 +3929,87 @@ export class Printer extends NameGeneratorHost {
3792
3929
  this.emitTrailingCommentsOfNode(node, flags, typeNode.pos, typeNode.end, containerPos, containerEnd, declarationListContainerEnd);
3793
3930
  return true;
3794
3931
  }
3932
+ /**
3933
+ * Whether `node` has no emit data and lies in a range of the source text where no comment is found, so that its
3934
+ * comments need not be looked for. Outside such a range, a node whose own range is one starts it (`freeOwner`).
3935
+ */
3936
+ inCommentFreeRange(node) {
3937
+ const pos = node.pos;
3938
+ const end = node.end;
3939
+ if (pos < 0 || end <= pos || node.kind === 11 /* SyntaxKind.JsxText */ || node.kind === 347 /* SyntaxKind.NotEmittedStatement */)
3940
+ return false;
3941
+ if (this.freeEnd < 0) {
3942
+ if (!this.startCommentFreeRange(pos, end))
3943
+ return false;
3944
+ this.freeOwner = node;
3945
+ }
3946
+ else if (pos < this.freeStart)
3947
+ return false;
3948
+ if (this.context.hasEmitNode(node))
3949
+ return false;
3950
+ return end < this.freeEnd || (end === this.freeEnd && this.freeEndTrailingNone);
3951
+ }
3952
+ endCommentFreeRange() {
3953
+ this.freeStart = -1;
3954
+ this.freeEnd = -1;
3955
+ this.freeEndTrailingNone = false;
3956
+ this.freeOwner = undefined;
3957
+ return true;
3958
+ }
3959
+ /** Whether the comment-free range shows that no trailing comment follows `pos`. */
3960
+ noCommentsAfter(pos) {
3961
+ return pos >= this.freeStart && (pos < this.freeEnd || (pos === this.freeEnd && this.freeEndTrailingNone));
3962
+ }
3963
+ /** Makes `[pos, end)` the comment-free range if no comment starts in it and its last character is not trivia. */
3964
+ startCommentFreeRange(pos, end) {
3965
+ const text = this.sourceText;
3966
+ if (end > text.length)
3967
+ return false;
3968
+ const last = text.charCodeAt(end - 1);
3969
+ if (last === 32 /* CharacterCodes.space */ ||
3970
+ last === 9 /* CharacterCodes.tab */ ||
3971
+ last === 10 /* CharacterCodes.lineFeed */ ||
3972
+ last === 13 /* CharacterCodes.carriageReturn */ ||
3973
+ last === 11 /* CharacterCodes.verticalTab */ ||
3974
+ last === 12 /* CharacterCodes.formFeed */ ||
3975
+ last > 127 /* CharacterCodes.maxAsciiCharacter */)
3976
+ return false;
3977
+ const starts = this.commentStartsOfFile();
3978
+ // The first comment start at or after `pos`.
3979
+ let low = 0;
3980
+ let high = starts.length;
3981
+ while (low < high) {
3982
+ const middle = (low + high) >>> 1;
3983
+ if (starts[middle] < pos)
3984
+ low = middle + 1;
3985
+ else
3986
+ high = middle;
3987
+ }
3988
+ if (low < starts.length && starts[low] < end)
3989
+ return false;
3990
+ this.freeStart = pos;
3991
+ this.freeEnd = end;
3992
+ this.freeEndTrailingNone = getTrailingCommentRanges(text, end) === undefined;
3993
+ return true;
3994
+ }
3995
+ commentStartsOfFile() {
3996
+ const cached = this.commentStarts;
3997
+ if (cached !== undefined)
3998
+ return cached;
3999
+ const text = this.sourceText;
4000
+ const length = text.length;
4001
+ const list = [];
4002
+ for (let i = text.indexOf('/'); i >= 0 && i + 1 < length; i = text.indexOf('/', i + 1)) {
4003
+ const next = text.charCodeAt(i + 1);
4004
+ if (next === 47 /* CharacterCodes.slash */ || next === 42 /* CharacterCodes.asterisk */)
4005
+ list.push(i);
4006
+ }
4007
+ const starts = new Int32Array(list.length);
4008
+ for (let i = 0; i < list.length; i++)
4009
+ starts[i] = list[i];
4010
+ this.commentStarts = starts;
4011
+ return starts;
4012
+ }
3795
4013
  /** Emits comments before a token; returns whether `emitCommentsAfterToken` applies, with the token's position in `tokenPos`. */
3796
4014
  emitCommentsBeforeToken(pos, contextNode, flags) {
3797
4015
  if ((flags & 1 /* TokenEmitFlags.NoComments */) !== 0 || this.commentsDisabled) {
@@ -3897,6 +4115,8 @@ export class Printer extends NameGeneratorHost {
3897
4115
  emitLeadingComments(pos, elided) {
3898
4116
  if (this.commentsDisabled || this.currentSourceFile === undefined || pos < 0 || pos === this.containerPos)
3899
4117
  return false;
4118
+ if (pos >= this.freeStart && pos < this.freeEnd)
4119
+ return false;
3900
4120
  // 1: only triple-slash comments, 2: all but triple-slash comments, 0: all.
3901
4121
  let tripleSlash = 0;
3902
4122
  if (!elided) {
@@ -3947,6 +4167,8 @@ export class Printer extends NameGeneratorHost {
3947
4167
  this.currentSourceFile === undefined ||
3948
4168
  (this.containerEnd !== -1 && (pos === this.containerEnd || pos === this.declarationListContainerEnd)))
3949
4169
  return false;
4170
+ if (this.noCommentsAfter(pos))
4171
+ return false;
3950
4172
  const ranges = getTrailingCommentRanges(this.sourceText, pos);
3951
4173
  if (ranges === undefined)
3952
4174
  return false;
@@ -3965,6 +4187,8 @@ export class Printer extends NameGeneratorHost {
3965
4187
  return false;
3966
4188
  if (this.containerEnd !== -1 && (pos === this.containerEnd || pos === this.declarationListContainerEnd))
3967
4189
  return false;
4190
+ if (this.noCommentsAfter(pos))
4191
+ return false;
3968
4192
  const comments = getTrailingCommentRanges(this.sourceText, pos);
3969
4193
  if (comments === undefined)
3970
4194
  return false;
@@ -120,6 +120,10 @@ export declare class CheckedProgram {
120
120
  * emit. Set once every file is checked, when checker threads emit (parallel-check.ts).
121
121
  */
122
122
  emittedInParallel: (EmitResult | undefined)[] | undefined;
123
+ /** Emit threads emitted only the JavaScript of `emittedInParallel`: declarations are emitted here. */
124
+ javaScriptEmittedOnThreads: boolean;
125
+ /** The declaration emit of each file on the declaration thread (parallel-emit.ts); undefined for one it didn't emit. */
126
+ declarationsEmittedAhead: (EmitResult | undefined)[] | undefined;
123
127
  /**
124
128
  * The global diagnostics of this thread's checker before it emitted files while checker threads
125
129
  * checked (`emitUncheckedFiles`), reported instead of its current ones.
@@ -210,6 +210,10 @@ export class CheckedProgram {
210
210
  * emit. Set once every file is checked, when checker threads emit (parallel-check.ts).
211
211
  */
212
212
  emittedInParallel = undefined;
213
+ /** Emit threads emitted only the JavaScript of `emittedInParallel`: declarations are emitted here. */
214
+ javaScriptEmittedOnThreads = false;
215
+ /** The declaration emit of each file on the declaration thread (parallel-emit.ts); undefined for one it didn't emit. */
216
+ declarationsEmittedAhead = undefined;
213
217
  /**
214
218
  * The global diagnostics of this thread's checker before it emitted files while checker threads
215
219
  * checked (`emitUncheckedFiles`), reported instead of its current ones.
@@ -111,12 +111,8 @@ export declare class Program implements OutputPathsHost {
111
111
  /** Packages that modules resolved into, by name: whether any resolution into them was a declaration file. */
112
112
  getPackagesMap(): ReadonlyMap<string, boolean>;
113
113
  getResolvedModule(file: SourceFile, moduleName: string, mode: ModuleKind): ResolvedModule | undefined;
114
- /** The program files that the imports and type reference directives of `file` resolved to. */
115
- /**
116
- * The files `file` imports and references through type directives. `byFileName`, the program's
117
- * files by file name, finds a file without computing its path when it is resolved by that name.
118
- */
119
- getResolvedFilesOf(file: SourceFile, byFileName?: ReadonlyMap<string, SourceFile>): SourceFile[];
114
+ /** The files each file added to the program (`ProcessedFiles.addedFiles`), as indices of `getSourceFiles`. */
115
+ addedFiles(): readonly (readonly number[])[];
120
116
  /** The specifier of the implicit JSX runtime import of `file`, if any. */
121
117
  jsxRuntimeImportSpecifier(path: string): Node | undefined;
122
118
  getResolvedModuleFromModuleSpecifier(file: SourceFile, specifier: Node): ResolvedModule | undefined;
@@ -7,7 +7,7 @@
7
7
  * ```
8
8
  */
9
9
  import { ArrayLiteralExpression, Decorator, getText, NodeVisitor, ObjectLiteralExpression, ParameterDeclaration, } from './ast.js';
10
- import { compareDiagnostics, createCompilerDiagnostic, Diagnostic, equalDiagnostics, equalDiagnosticsNoRelatedInfo, useThreadTextCaches, } from './diagnostics.js';
10
+ import { compareDiagnostics, createCompilerDiagnostic, Diagnostic, equalDiagnostics, equalDiagnosticsNoRelatedInfo, sortDiagnostics, useThreadTextCaches, } from './diagnostics.js';
11
11
  import { canReplaceFile, FileLoader, jsxRuntimeImportOf, modeAwareKey, needsImportHelpersImportSpecifier, withReplacedFile, } from './file-loader.js';
12
12
  import { PackageJsonLookup } from './package-json.js';
13
13
  import { ProcessingDiagnostic } from './file-include.js';
@@ -325,34 +325,9 @@ export class Program {
325
325
  getResolvedModule(file, moduleName, mode) {
326
326
  return this.processed.resolvedModules.get(file.path)?.get(modeAwareKey(moduleName, mode));
327
327
  }
328
- /** The program files that the imports and type reference directives of `file` resolved to. */
329
- /**
330
- * The files `file` imports and references through type directives. `byFileName`, the program's
331
- * files by file name, finds a file without computing its path when it is resolved by that name.
332
- */
333
- getResolvedFilesOf(file, byFileName) {
334
- const result = [];
335
- const modules = this.processed.resolvedModules.get(file.path);
336
- if (modules !== undefined)
337
- for (const resolved of modules.values()) {
338
- const name = resolved.resolvedFileName;
339
- if (name === '')
340
- continue;
341
- const target = byFileName?.get(name) ?? this.getSourceFileForResolvedModule(name);
342
- if (target !== undefined)
343
- result.push(target);
344
- }
345
- const types = this.processed.typeResolutionsInFile.get(file.path);
346
- if (types !== undefined)
347
- for (const resolved of types.values()) {
348
- const name = resolved.resolvedFileName;
349
- if (name === '')
350
- continue;
351
- const target = byFileName?.get(name) ?? this.getSourceFile(name);
352
- if (target !== undefined)
353
- result.push(target);
354
- }
355
- return result;
328
+ /** The files each file added to the program (`ProcessedFiles.addedFiles`), as indices of `getSourceFiles`. */
329
+ addedFiles() {
330
+ return this.processed.addedFiles;
356
331
  }
357
332
  /** The specifier of the implicit JSX runtime import of `file`, if any. */
358
333
  jsxRuntimeImportSpecifier(path) {
@@ -986,7 +961,7 @@ class NodeCollector extends NodeVisitor {
986
961
  }
987
962
  /** Sorts diagnostics and merges duplicates, combining their related information. */
988
963
  export function sortAndDeduplicateDiagnostics(diagnostics) {
989
- const sorted = [...diagnostics].sort(compareDiagnostics);
964
+ const sorted = sortDiagnostics(diagnostics);
990
965
  if (sorted.length < 2)
991
966
  return sorted;
992
967
  const result = [];
@@ -232,6 +232,16 @@ export function isTypeRelatedTo(c, source, target, relation) {
232
232
  if ((source.flags & 394239 /* TypeFlags.Singleton */) !== 0)
233
233
  return true;
234
234
  }
235
+ else {
236
+ // What the relater decides first for types that may simplify (Relater.isRelatedToEx): their normal forms are
237
+ // one type, or can be identical only with identical flags.
238
+ const s = getNormalizedType(c, source, false);
239
+ const t = getNormalizedType(c, target, true);
240
+ if (s === t)
241
+ return true;
242
+ if (s.flags !== t.flags)
243
+ return false;
244
+ }
235
245
  if ((source.flags & 1048576 /* TypeFlags.Object */) !== 0 && (target.flags & 1048576 /* TypeFlags.Object */) !== 0) {
236
246
  const related = relation.get(getRelationKey(c, source, target, 0 /* IntersectionState.None */, relation === c.identityRelation, false).key);
237
247
  if (related !== 0 /* RelationComparisonResult.None */)
@@ -139,7 +139,7 @@ export declare class SymbolRareFields implements ProgramLifetime {
139
139
  }
140
140
  export declare class Symbol implements ProgramLifetime {
141
141
  flags: SymbolFlags;
142
- /** The check flags, and `valueDeclarationIsFirst`. */
142
+ /** The check flags, and `SymbolBits.ValueDeclarationIsFirst`. */
143
143
  private bits;
144
144
  readonly name: string;
145
145
  /**
@@ -8,11 +8,9 @@ export class SymbolRareFields {
8
8
  /** The value declaration where it is not the first declaration (`Symbol.valueDeclaration`). */
9
9
  valueDeclaration = undefined;
10
10
  }
11
- /** In `Symbol.bits`, above the check flags: the value declaration is the first declaration. */
12
- const valueDeclarationIsFirst = 1 << 30;
13
11
  export class Symbol {
14
12
  flags;
15
- /** The check flags, and `valueDeclarationIsFirst`. */
13
+ /** The check flags, and `SymbolBits.ValueDeclarationIsFirst`. */
16
14
  bits;
17
15
  name;
18
16
  /**
@@ -35,17 +33,17 @@ export class Symbol {
35
33
  this.id = idsAtCreation ? takeSymbolId() : 0;
36
34
  }
37
35
  get checkFlags() {
38
- return (this.bits & ~valueDeclarationIsFirst);
36
+ return (this.bits & ~1073741824 /* SymbolBits.ValueDeclarationIsFirst */);
39
37
  }
40
38
  set checkFlags(flags) {
41
- this.bits = (this.bits & valueDeclarationIsFirst) | flags;
39
+ this.bits = (this.bits & 1073741824 /* SymbolBits.ValueDeclarationIsFirst */) | flags;
42
40
  }
43
41
  /** Makes `node` the first declaration, keeping the value declaration. */
44
42
  setFirst(node) {
45
- if ((this.bits & valueDeclarationIsFirst) !== 0 && node !== this.declaration) {
43
+ if ((this.bits & 1073741824 /* SymbolBits.ValueDeclarationIsFirst */) !== 0 && node !== this.declaration) {
46
44
  // The value declaration stays what it was.
47
45
  this.rareFieldsOrNew().valueDeclaration = this.declaration;
48
- this.bits &= ~valueDeclarationIsFirst;
46
+ this.bits &= ~1073741824 /* SymbolBits.ValueDeclarationIsFirst */;
49
47
  }
50
48
  this.declaration = node;
51
49
  }
@@ -54,7 +52,7 @@ export class Symbol {
54
52
  * says; any other is kept in the rare fields.
55
53
  */
56
54
  get valueDeclaration() {
57
- if ((this.bits & valueDeclarationIsFirst) !== 0)
55
+ if ((this.bits & 1073741824 /* SymbolBits.ValueDeclarationIsFirst */) !== 0)
58
56
  return this.declaration;
59
57
  const group = this.rareFields;
60
58
  return group === undefined ? undefined : group.valueDeclaration;
@@ -62,12 +60,12 @@ export class Symbol {
62
60
  set valueDeclaration(node) {
63
61
  const group = this.rareFields;
64
62
  if (node !== undefined && node === this.declaration) {
65
- this.bits |= valueDeclarationIsFirst;
63
+ this.bits |= 1073741824 /* SymbolBits.ValueDeclarationIsFirst */;
66
64
  if (group !== undefined)
67
65
  group.valueDeclaration = undefined;
68
66
  return;
69
67
  }
70
- this.bits &= ~valueDeclarationIsFirst;
68
+ this.bits &= ~1073741824 /* SymbolBits.ValueDeclarationIsFirst */;
71
69
  if (node !== undefined || group !== undefined)
72
70
  this.rareFieldsOrNew().valueDeclaration = node;
73
71
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tsc-ts",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "description": "The TypeScript 7 compiler, ported to TypeScript and compiled to a native executable.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -29,18 +29,18 @@
29
29
  "./package.json": "./package.json"
30
30
  },
31
31
  "dependencies": {
32
- "@scriptc/threads": "0.4.2"
32
+ "@scriptc/threads": "0.4.5"
33
33
  },
34
34
  "engines": {
35
35
  "node": ">=20"
36
36
  },
37
37
  "optionalDependencies": {
38
- "@tsc-ts/darwin-arm64": "0.0.9",
39
- "@tsc-ts/darwin-x64": "0.0.9",
40
- "@tsc-ts/linux-arm64-gnu": "0.0.9",
41
- "@tsc-ts/linux-arm64-musl": "0.0.9",
42
- "@tsc-ts/linux-x64-gnu": "0.0.9",
43
- "@tsc-ts/linux-x64-musl": "0.0.9",
44
- "@tsc-ts/win32-x64-msvc": "0.0.9"
38
+ "@tsc-ts/darwin-arm64": "0.0.10",
39
+ "@tsc-ts/darwin-x64": "0.0.10",
40
+ "@tsc-ts/linux-arm64-gnu": "0.0.10",
41
+ "@tsc-ts/linux-arm64-musl": "0.0.10",
42
+ "@tsc-ts/linux-x64-gnu": "0.0.10",
43
+ "@tsc-ts/linux-x64-musl": "0.0.10",
44
+ "@tsc-ts/win32-x64-msvc": "0.0.10"
45
45
  }
46
46
  }
@@ -8258,6 +8258,8 @@ export class SourceFile extends Node {
8258
8258
  identifierCount: number;
8259
8259
  nodeCount: number;
8260
8260
  textCount: number;
8261
+ /** The API's binary encoding of this file, when an API server keeps it (`keptEncodingOf`). */
8262
+ apiEncoding: Uint8Array | undefined;
8261
8263
  /** Module specifiers of imports, exports, `require` calls and `import()` types, in source order. */
8262
8264
  imports: Node[];
8263
8265
  /** Names of `declare module "x"` augmentations and `declare global` blocks in modules. */
@@ -8325,6 +8327,7 @@ export class SourceFile extends Node {
8325
8327
  this.identifierCount = 0;
8326
8328
  this.nodeCount = 0;
8327
8329
  this.textCount = 0;
8330
+ this.apiEncoding = undefined;
8328
8331
  this.imports = [];
8329
8332
  this.moduleAugmentations = emptyNodes;
8330
8333
  this.ambientModuleNames = emptyStrings;
@@ -975,7 +975,9 @@ export function reorderCandidates(c: Checker, signatures: Signature[], callChain
975
975
  cutoffIndex++;
976
976
  } else spliceIndex = index;
977
977
  if (callChainFlags !== 0) signature = getOptionalCallSignature(c, signature, callChainFlags);
978
- result.splice(spliceIndex, 0, signature);
978
+ // Most signatures go at the end, where a push is cheaper than an inserting splice.
979
+ if (spliceIndex === result.length) result.push(signature);
980
+ else result.splice(spliceIndex, 0, signature);
979
981
  }
980
982
  return result;
981
983
  }
@@ -3143,7 +3143,8 @@ function checkGrammarObjectLiteralExpression(
3143
3143
  node: ObjectLiteralExpression,
3144
3144
  inDestructuring: boolean,
3145
3145
  ): boolean {
3146
- const seen = new Map<string, DeclarationMeaning>();
3146
+ // An object literal with one property can't repeat a name, so it needs no table of names.
3147
+ const seen = node.properties.nodes.length > 1 ? new Map<string, DeclarationMeaning>() : undefined;
3147
3148
  for (const property of node.properties.nodes) {
3148
3149
  if (property.kind === SyntaxKind.SpreadAssignment) {
3149
3150
  if (inDestructuring) {
@@ -3222,7 +3223,7 @@ function checkGrammarObjectLiteralExpression(
3222
3223
  }
3223
3224
  if (inDestructuring) continue;
3224
3225
  const effectiveName = getEffectivePropertyNameForPropertyNameNode(g.c, name);
3225
- if (effectiveName === undefined) continue;
3226
+ if (effectiveName === undefined || seen === undefined) continue;
3226
3227
  const existingKind = seen.get(effectiveName);
3227
3228
  if (existingKind === undefined) {
3228
3229
  seen.set(effectiveName, currentKind);
@@ -733,8 +733,13 @@ class InferenceState {
733
733
  // Keep candidates with the highest depth first.
734
734
  index = 0;
735
735
  while (index < inference.candidateDepths.length && inference.candidateDepths[index] >= this.depth) index++;
736
- inference.candidates.splice(index, 0, candidate);
737
- inference.candidateDepths.splice(index, 0, this.depth);
736
+ if (index === inference.candidates.length) {
737
+ inference.candidates.push(candidate);
738
+ inference.candidateDepths.push(this.depth);
739
+ } else {
740
+ inference.candidates.splice(index, 0, candidate);
741
+ inference.candidateDepths.splice(index, 0, this.depth);
742
+ }
738
743
  clearCachedInferences(this.inferences);
739
744
  }
740
745
  }