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.
- package/README.md +1 -1
- package/dist/api/compiler/ast.d.ts +2 -0
- package/dist/api/compiler/ast.js +3 -0
- package/dist/api/compiler/checker-calls.js +5 -1
- package/dist/api/compiler/checker-grammar.js +3 -2
- package/dist/api/compiler/checker-inference.js +8 -2
- package/dist/api/compiler/checker-members.js +2 -1
- package/dist/api/compiler/checker-type-factory.js +8 -2
- package/dist/api/compiler/checker.d.ts +11 -0
- package/dist/api/compiler/checker.js +40 -0
- package/dist/api/compiler/compile-program.d.ts +26 -2
- package/dist/api/compiler/compile-program.js +100 -7
- package/dist/api/compiler/diagnostics.d.ts +22 -0
- package/dist/api/compiler/diagnostics.js +86 -4
- package/dist/api/compiler/file-loader.d.ts +11 -1
- package/dist/api/compiler/file-loader.js +63 -7
- package/dist/api/compiler/parallel-parse.d.ts +3 -2
- package/dist/api/compiler/parallel-parse.js +17 -5
- package/dist/api/compiler/printer/emit-context.d.ts +2 -0
- package/dist/api/compiler/printer/emit-context.js +4 -0
- package/dist/api/compiler/printer/printer.d.ts +48 -2
- package/dist/api/compiler/printer/printer.js +238 -14
- package/dist/api/compiler/program-checker.d.ts +4 -0
- package/dist/api/compiler/program-checker.js +4 -0
- package/dist/api/compiler/program.d.ts +2 -6
- package/dist/api/compiler/program.js +5 -30
- package/dist/api/compiler/relations.js +10 -0
- package/dist/api/compiler/symbol.d.ts +1 -1
- package/dist/api/compiler/symbol.js +8 -10
- package/package.json +9 -9
- package/src/compiler/ast.ts +3 -0
- package/src/compiler/checker-calls.ts +3 -1
- package/src/compiler/checker-grammar.ts +3 -2
- package/src/compiler/checker-inference.ts +7 -2
- package/src/compiler/checker-members.ts +3 -1
- package/src/compiler/checker-type-factory.ts +4 -2
- package/src/compiler/checker.ts +37 -0
- package/src/compiler/compile-program.ts +121 -7
- package/src/compiler/diagnostics.ts +84 -3
- package/src/compiler/file-loader.ts +58 -6
- package/src/compiler/incremental.ts +80 -13
- package/src/compiler/parallel-check.ts +129 -44
- package/src/compiler/parallel-emit.ts +320 -0
- package/src/compiler/parallel-parse.ts +16 -5
- package/src/compiler/parse-thread.ts +3 -0
- package/src/compiler/printer/emit-context.ts +5 -0
- package/src/compiler/printer/printer.ts +231 -16
- package/src/compiler/program-checker.ts +4 -0
- package/src/compiler/program.ts +5 -25
- package/src/compiler/relations.ts +7 -0
- package/src/compiler/symbol.ts +15 -10
- package/src/compiler/thread-entry.ts +45 -2
- package/src/compiler/tsc-build.ts +63 -9
- package/src/compiler/tsc-cli.ts +5 -0
- 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
|
-
/**
|
|
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
|
-
|
|
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.
|
|
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 =
|
|
3772
|
-
|
|
3773
|
-
const
|
|
3774
|
-
const
|
|
3775
|
-
const
|
|
3776
|
-
const
|
|
3777
|
-
const
|
|
3778
|
-
|
|
3779
|
-
|
|
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
|
|
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
|
|
329
|
-
|
|
330
|
-
|
|
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 =
|
|
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 `
|
|
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 `
|
|
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 & ~
|
|
36
|
+
return (this.bits & ~1073741824 /* SymbolBits.ValueDeclarationIsFirst */);
|
|
39
37
|
}
|
|
40
38
|
set checkFlags(flags) {
|
|
41
|
-
this.bits = (this.bits &
|
|
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 &
|
|
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 &= ~
|
|
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 &
|
|
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 |=
|
|
63
|
+
this.bits |= 1073741824 /* SymbolBits.ValueDeclarationIsFirst */;
|
|
66
64
|
if (group !== undefined)
|
|
67
65
|
group.valueDeclaration = undefined;
|
|
68
66
|
return;
|
|
69
67
|
}
|
|
70
|
-
this.bits &= ~
|
|
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.
|
|
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.
|
|
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.
|
|
39
|
-
"@tsc-ts/darwin-x64": "0.0.
|
|
40
|
-
"@tsc-ts/linux-arm64-gnu": "0.0.
|
|
41
|
-
"@tsc-ts/linux-arm64-musl": "0.0.
|
|
42
|
-
"@tsc-ts/linux-x64-gnu": "0.0.
|
|
43
|
-
"@tsc-ts/linux-x64-musl": "0.0.
|
|
44
|
-
"@tsc-ts/win32-x64-msvc": "0.0.
|
|
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
|
}
|
package/src/compiler/ast.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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.
|
|
737
|
-
|
|
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
|
}
|