tsc-ts 0.0.7 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/api/compiler/checker-declaration-order.js +3 -2
- package/dist/api/compiler/checker-declared-types.js +6 -3
- package/dist/api/compiler/checker-deprecation.js +14 -13
- package/dist/api/compiler/checker-destructuring.js +3 -2
- package/dist/api/compiler/checker-members.js +6 -2
- package/dist/api/compiler/checker-source-file.d.ts +12 -0
- package/dist/api/compiler/checker-source-file.js +35 -0
- package/dist/api/compiler/checker-symbol-types.js +5 -5
- package/dist/api/compiler/checker-symbols.js +5 -2
- package/dist/api/compiler/checker.d.ts +6 -1
- package/dist/api/compiler/checker.js +9 -1
- package/dist/api/compiler/file-loader.d.ts +2 -2
- package/dist/api/compiler/file-loader.js +43 -23
- package/dist/api/compiler/link-tables.d.ts +7 -0
- package/dist/api/compiler/link-tables.js +22 -0
- package/dist/api/compiler/parser.d.ts +7 -0
- package/dist/api/compiler/parser.js +55 -32
- package/dist/api/compiler/program-checker.d.ts +18 -0
- package/dist/api/compiler/program-checker.js +35 -2
- package/dist/api/library/diagnostics.d.ts +10 -0
- package/dist/api/library/diagnostics.js +20 -0
- package/package.json +9 -9
- package/src/compiler/checker-declaration-order.ts +3 -2
- package/src/compiler/checker-declared-types.ts +6 -3
- package/src/compiler/checker-deprecation.ts +13 -11
- package/src/compiler/checker-destructuring.ts +11 -2
- package/src/compiler/checker-members.ts +6 -2
- package/src/compiler/checker-source-file.ts +34 -0
- package/src/compiler/checker-symbol-types.ts +14 -4
- package/src/compiler/checker-symbols.ts +6 -2
- package/src/compiler/checker.ts +8 -1
- package/src/compiler/file-loader.ts +49 -24
- package/src/compiler/link-tables.ts +32 -0
- package/src/compiler/parallel-check.ts +199 -20
- package/src/compiler/parser.ts +55 -32
- package/src/compiler/program-checker.ts +36 -2
- package/src/compiler/thread-entry.ts +16 -1
- package/src/library/diagnostics.ts +23 -0
|
@@ -147,6 +147,10 @@ export class Parser extends ScannerErrorReporter {
|
|
|
147
147
|
// receives reparsed nodes, and a fresh array per parsed list would be one more allocation each.
|
|
148
148
|
reparseLists;
|
|
149
149
|
reparseDepth;
|
|
150
|
+
// One scratch array per nesting depth of the lists being parsed. A list collects its elements in
|
|
151
|
+
// its depth's array and is copied out at its exact length, so the tree keeps no spare capacity.
|
|
152
|
+
listScratch;
|
|
153
|
+
listDepth;
|
|
150
154
|
reparsedClones;
|
|
151
155
|
/** Nodes with eagerly parsed JSDoc, for rewinding. */
|
|
152
156
|
jsDocInfos;
|
|
@@ -200,6 +204,8 @@ export class Parser extends ScannerErrorReporter {
|
|
|
200
204
|
this.reparseList = [];
|
|
201
205
|
this.reparseLists = [this.reparseList];
|
|
202
206
|
this.reparseDepth = 0;
|
|
207
|
+
this.listScratch = [];
|
|
208
|
+
this.listDepth = -1;
|
|
203
209
|
this.reparsedClones = [];
|
|
204
210
|
this.jsDocInfos = [];
|
|
205
211
|
this.jsDocTable = undefined;
|
|
@@ -610,7 +616,7 @@ export class Parser extends ScannerErrorReporter {
|
|
|
610
616
|
this.reparseLists.push([]);
|
|
611
617
|
const reparseList = this.reparseLists[depth];
|
|
612
618
|
this.reparseList = reparseList;
|
|
613
|
-
const list =
|
|
619
|
+
const list = this.openList();
|
|
614
620
|
while (!this.isListTerminator(kind)) {
|
|
615
621
|
if (this.isListElement(kind, false)) {
|
|
616
622
|
const elt = this.parseListElement(element, list.length);
|
|
@@ -636,7 +642,7 @@ export class Parser extends ScannerErrorReporter {
|
|
|
636
642
|
this.reparseDepth = depth - 1;
|
|
637
643
|
this.reparseList = outerReparseList;
|
|
638
644
|
this.parsingContexts = saveParsingContexts;
|
|
639
|
-
return list;
|
|
645
|
+
return this.closeList(list);
|
|
640
646
|
}
|
|
641
647
|
parseList(kind, element) {
|
|
642
648
|
const pos = this.nodePos();
|
|
@@ -648,12 +654,13 @@ export class Parser extends ScannerErrorReporter {
|
|
|
648
654
|
const pos = this.nodePos();
|
|
649
655
|
const saveParsingContexts = this.parsingContexts;
|
|
650
656
|
this.parsingContexts |= 1 << kind;
|
|
651
|
-
const list =
|
|
657
|
+
const list = this.openList();
|
|
652
658
|
for (;;) {
|
|
653
659
|
if (this.isListElement(kind, false)) {
|
|
654
660
|
const startPos = this.nodePos();
|
|
655
661
|
const result = this.parseListElement(element, list.length);
|
|
656
662
|
if (result === this.noElement) {
|
|
663
|
+
this.closeList(list);
|
|
657
664
|
this.parsingContexts = saveParsingContexts;
|
|
658
665
|
return undefined;
|
|
659
666
|
}
|
|
@@ -683,7 +690,24 @@ export class Parser extends ScannerErrorReporter {
|
|
|
683
690
|
break;
|
|
684
691
|
}
|
|
685
692
|
this.parsingContexts = saveParsingContexts;
|
|
686
|
-
return this.newNodeList(pos, this.nodePos(), list);
|
|
693
|
+
return this.newNodeList(pos, this.nodePos(), this.closeList(list));
|
|
694
|
+
}
|
|
695
|
+
/** The scratch array for a list at the next nesting depth, empty. */
|
|
696
|
+
openList() {
|
|
697
|
+
const depth = ++this.listDepth;
|
|
698
|
+
if (depth === this.listScratch.length)
|
|
699
|
+
this.listScratch.push([]);
|
|
700
|
+
return this.listScratch[depth];
|
|
701
|
+
}
|
|
702
|
+
/** The elements collected in `list` (the scratch array from `openList`) as an array of their exact
|
|
703
|
+
* length, or the shared empty array; empties the scratch array for the next list at its depth. */
|
|
704
|
+
closeList(list) {
|
|
705
|
+
this.listDepth--;
|
|
706
|
+
if (list.length === 0)
|
|
707
|
+
return emptyListNodes;
|
|
708
|
+
const nodes = list.slice();
|
|
709
|
+
list.length = 0;
|
|
710
|
+
return nodes;
|
|
687
711
|
}
|
|
688
712
|
/** The list; a missing list if `opening` is absent; undefined if an element parser returned undefined. */
|
|
689
713
|
parseBracketedList(kind, element, opening, closing) {
|
|
@@ -2373,10 +2397,11 @@ export class Parser extends ScannerErrorReporter {
|
|
|
2373
2397
|
? this.parseFunctionOrConstructorTypeToError(isUnionType)
|
|
2374
2398
|
: this.parseConstituentType(isUnionType);
|
|
2375
2399
|
if (this.token() === operator || hasLeadingOperator) {
|
|
2376
|
-
const types =
|
|
2400
|
+
const types = this.openList();
|
|
2401
|
+
types.push(type);
|
|
2377
2402
|
while (this.parseOptional(operator))
|
|
2378
2403
|
types.push(this.parseFunctionOrConstructorTypeToError(isUnionType));
|
|
2379
|
-
const list = this.newNodeList(pos, this.nodePos(), types);
|
|
2404
|
+
const list = this.newNodeList(pos, this.nodePos(), this.closeList(types));
|
|
2380
2405
|
type = isUnionType ? new UnionTypeNode(list) : new IntersectionTypeNode(list);
|
|
2381
2406
|
this.finishNode(type, pos);
|
|
2382
2407
|
}
|
|
@@ -2985,17 +3010,12 @@ export class Parser extends ScannerErrorReporter {
|
|
|
2985
3010
|
return false;
|
|
2986
3011
|
}
|
|
2987
3012
|
parseTypeOrTypePredicate() {
|
|
2988
|
-
|
|
2989
|
-
|
|
3013
|
+
// `x is T`: the identifier is parsed only once `is` is known to follow it.
|
|
3014
|
+
if (this.isIdentifier() && this.lookAhead(nextTokenIsIsKeywordOnSameLine)) {
|
|
2990
3015
|
const pos = this.nodePos();
|
|
2991
3016
|
const id = this.parseIdentifier(1 /* IdentifierUse.Name */);
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
this.nextToken();
|
|
2995
|
-
return this.finishNode(new TypePredicateNode(undefined, id, this.parseType()), pos);
|
|
2996
|
-
}
|
|
2997
|
-
this.rewind(state);
|
|
2998
|
-
this.endSpeculation(state);
|
|
3017
|
+
this.nextToken();
|
|
3018
|
+
return this.finishNode(new TypePredicateNode(undefined, id, this.parseType()), pos);
|
|
2999
3019
|
}
|
|
3000
3020
|
return this.parseType();
|
|
3001
3021
|
}
|
|
@@ -3175,14 +3195,14 @@ export class Parser extends ScannerErrorReporter {
|
|
|
3175
3195
|
}
|
|
3176
3196
|
parseTemplateTypeSpans() {
|
|
3177
3197
|
const pos = this.nodePos();
|
|
3178
|
-
const list =
|
|
3198
|
+
const list = this.openList();
|
|
3179
3199
|
for (;;) {
|
|
3180
3200
|
const span = this.parseTemplateTypeSpan();
|
|
3181
3201
|
list.push(span);
|
|
3182
3202
|
if (span.literal.kind !== 16 /* SyntaxKind.TemplateMiddle */)
|
|
3183
3203
|
break;
|
|
3184
3204
|
}
|
|
3185
|
-
return this.newNodeList(pos, this.nodePos(), list);
|
|
3205
|
+
return this.newNodeList(pos, this.nodePos(), this.closeList(list));
|
|
3186
3206
|
}
|
|
3187
3207
|
parseTemplateTypeSpan() {
|
|
3188
3208
|
const pos = this.nodePos();
|
|
@@ -3282,12 +3302,10 @@ export class Parser extends ScannerErrorReporter {
|
|
|
3282
3302
|
let hasTrailingModifier = false;
|
|
3283
3303
|
let hasStaticModifier = false;
|
|
3284
3304
|
const pos = this.nodePos();
|
|
3285
|
-
|
|
3305
|
+
const list = this.openList();
|
|
3286
3306
|
for (;;) {
|
|
3287
3307
|
if (allowDecorators && this.token() === 59 /* SyntaxKind.AtToken */ && !hasTrailingModifier) {
|
|
3288
3308
|
const decorator = this.parseDecorator();
|
|
3289
|
-
if (list === undefined)
|
|
3290
|
-
list = [];
|
|
3291
3309
|
list.push(decorator);
|
|
3292
3310
|
if (hasLeadingModifier)
|
|
3293
3311
|
hasTrailingDecorator = true;
|
|
@@ -3298,8 +3316,6 @@ export class Parser extends ScannerErrorReporter {
|
|
|
3298
3316
|
break;
|
|
3299
3317
|
if (modifier.kind === 125 /* SyntaxKind.StaticKeyword */)
|
|
3300
3318
|
hasStaticModifier = true;
|
|
3301
|
-
if (list === undefined)
|
|
3302
|
-
list = [];
|
|
3303
3319
|
list.push(modifier);
|
|
3304
3320
|
if (hasTrailingDecorator)
|
|
3305
3321
|
hasTrailingModifier = true;
|
|
@@ -3307,7 +3323,8 @@ export class Parser extends ScannerErrorReporter {
|
|
|
3307
3323
|
hasLeadingModifier = true;
|
|
3308
3324
|
}
|
|
3309
3325
|
}
|
|
3310
|
-
|
|
3326
|
+
const nodes = this.closeList(list);
|
|
3327
|
+
return nodes.length === 0 ? undefined : this.newModifierList(pos, this.nodePos(), nodes);
|
|
3311
3328
|
}
|
|
3312
3329
|
parseDecorator() {
|
|
3313
3330
|
const pos = this.nodePos();
|
|
@@ -3941,7 +3958,7 @@ export class Parser extends ScannerErrorReporter {
|
|
|
3941
3958
|
const pos = this.nodePos();
|
|
3942
3959
|
const saveParsingContexts = this.parsingContexts;
|
|
3943
3960
|
this.parsingContexts |= 1 << 14 /* ParsingContext.JsxChildren */;
|
|
3944
|
-
const list =
|
|
3961
|
+
const list = this.openList();
|
|
3945
3962
|
for (;;) {
|
|
3946
3963
|
// Like tsgo, this leaves the parser's current token unchanged.
|
|
3947
3964
|
const currentToken = this.scanner.reScanJsxToken(true);
|
|
@@ -3957,7 +3974,7 @@ export class Parser extends ScannerErrorReporter {
|
|
|
3957
3974
|
break;
|
|
3958
3975
|
}
|
|
3959
3976
|
this.parsingContexts = saveParsingContexts;
|
|
3960
|
-
return this.newNodeList(pos, this.nodePos(), list);
|
|
3977
|
+
return this.newNodeList(pos, this.nodePos(), this.closeList(list));
|
|
3961
3978
|
}
|
|
3962
3979
|
parseJsxChild(openingTag, token) {
|
|
3963
3980
|
switch (token) {
|
|
@@ -4519,14 +4536,14 @@ export class Parser extends ScannerErrorReporter {
|
|
|
4519
4536
|
}
|
|
4520
4537
|
parseTemplateSpans(isTaggedTemplate) {
|
|
4521
4538
|
const pos = this.nodePos();
|
|
4522
|
-
const list =
|
|
4539
|
+
const list = this.openList();
|
|
4523
4540
|
for (;;) {
|
|
4524
4541
|
const span = this.parseTemplateSpan(isTaggedTemplate);
|
|
4525
4542
|
list.push(span);
|
|
4526
4543
|
if (span.literal.kind !== 16 /* SyntaxKind.TemplateMiddle */)
|
|
4527
4544
|
break;
|
|
4528
4545
|
}
|
|
4529
|
-
return this.newNodeList(pos, this.nodePos(), list);
|
|
4546
|
+
return this.newNodeList(pos, this.nodePos(), this.closeList(list));
|
|
4530
4547
|
}
|
|
4531
4548
|
parseTemplateSpan(isTaggedTemplate) {
|
|
4532
4549
|
const pos = this.nodePos();
|
|
@@ -5960,6 +5977,9 @@ function nextTokenCanFollowExportModifier(p) {
|
|
|
5960
5977
|
function nextTokenIsClassKeywordOnSameLine(p) {
|
|
5961
5978
|
return p.nextToken() === 85 /* SyntaxKind.ClassKeyword */ && !p.hasPrecedingLineBreak();
|
|
5962
5979
|
}
|
|
5980
|
+
function nextTokenIsIsKeywordOnSameLine(p) {
|
|
5981
|
+
return p.nextToken() === 142 /* SyntaxKind.IsKeyword */ && !p.hasPrecedingLineBreak();
|
|
5982
|
+
}
|
|
5963
5983
|
function nextTokenIsFunctionKeywordOnSameLine(p) {
|
|
5964
5984
|
return p.nextToken() === 99 /* SyntaxKind.FunctionKeyword */ && !p.hasPrecedingLineBreak();
|
|
5965
5985
|
}
|
|
@@ -6012,11 +6032,14 @@ function nextIsUnParenthesizedAsyncArrowFunction(p) {
|
|
|
6012
6032
|
// `async =>` is a simple arrow function with a parameter named `async`.
|
|
6013
6033
|
if (p.hasPrecedingLineBreak() || p.token() === 38 /* SyntaxKind.EqualsGreaterThanToken */)
|
|
6014
6034
|
return false;
|
|
6015
|
-
|
|
6016
|
-
|
|
6017
|
-
|
|
6018
|
-
|
|
6019
|
-
|
|
6035
|
+
// The binary expression after `async` is a lone identifier followed by `=>` only when an identifier
|
|
6036
|
+
// token is followed by `=>`. Any other first token starts another kind of expression or none, and any
|
|
6037
|
+
// other token after the identifier continues the expression or ends it before `=>`. Checking the
|
|
6038
|
+
// tokens gives the same answer as parsing the expression, whose nodes would be discarded.
|
|
6039
|
+
if (!p.isIdentifier())
|
|
6040
|
+
return false;
|
|
6041
|
+
p.nextToken();
|
|
6042
|
+
return !p.hasPrecedingLineBreak() && p.token() === 38 /* SyntaxKind.EqualsGreaterThanToken */;
|
|
6020
6043
|
}
|
|
6021
6044
|
return false;
|
|
6022
6045
|
}
|
|
@@ -134,6 +134,23 @@ export declare class CheckedProgram {
|
|
|
134
134
|
* incremental program keeps them unfiltered under `noEmit` too.
|
|
135
135
|
*/
|
|
136
136
|
unfilteredDiagnosticsOfFile(file: SourceFile): Diagnostic[];
|
|
137
|
+
/**
|
|
138
|
+
* Checks the statements `start` to `end` of the declaration file `file` with this checker, one of the
|
|
139
|
+
* ranges that several checkers check it in (`checkSourceFileRange`, parallel-check.ts), and returns
|
|
140
|
+
* whether the checker then has diagnostics in the file.
|
|
141
|
+
*/
|
|
142
|
+
checkRange(file: SourceFile, start: number, end: number): boolean;
|
|
143
|
+
/**
|
|
144
|
+
* The diagnostics of `file`, as `unfilteredDiagnosticsOfFile` gives them, where checkers checked it in
|
|
145
|
+
* ranges and found no diagnostics in it (`checkRange`).
|
|
146
|
+
*/
|
|
147
|
+
unfilteredDiagnosticsOfCleanRanges(file: SourceFile): Diagnostic[];
|
|
148
|
+
/**
|
|
149
|
+
* The diagnostics of `file`, as `unfilteredDiagnosticsOfFile` gives them, from a new checker that checks it
|
|
150
|
+
* whole: for a file checked in ranges that found diagnostics in it (parallel-check.ts), part of which this
|
|
151
|
+
* thread's checker may have checked.
|
|
152
|
+
*/
|
|
153
|
+
unfilteredDiagnosticsOfFileOnNewChecker(file: SourceFile): Diagnostic[];
|
|
137
154
|
/**
|
|
138
155
|
* The bind and check diagnostics of `file` before `noEmit` filtering and without include errors.
|
|
139
156
|
* Once checker threads checked the program, they come from the threads' diagnostics of the file,
|
|
@@ -156,6 +173,7 @@ export declare class CheckedProgram {
|
|
|
156
173
|
skipTypeChecking(file: SourceFile): boolean;
|
|
157
174
|
private collect;
|
|
158
175
|
private collectChecked;
|
|
176
|
+
/** `checks` are the checker's diagnostics of `file`. */
|
|
159
177
|
private getBindAndCheckDiagnostics;
|
|
160
178
|
getIncludeProcessorDiagnostics(file: SourceFile): Diagnostic[];
|
|
161
179
|
}
|
|
@@ -4,6 +4,7 @@ import { ModuleSpecifierHost } from './module-specifiers.js';
|
|
|
4
4
|
import { sortAndDeduplicateDiagnostics } from './program.js';
|
|
5
5
|
import { getEmitModuleFormatOfFile, getEmitSyntaxForUsageLocation, isCheckJsEnabledForFile, } from './program-utilities.js';
|
|
6
6
|
import { bindSourceFile } from './binder.js';
|
|
7
|
+
import { checkSourceFileRange } from './checker-source-file.js';
|
|
7
8
|
import { computeLineOfPosition } from './scanner.js';
|
|
8
9
|
/** What the checker needs, answered by a program. */
|
|
9
10
|
export class ProgramCheckerHost extends CheckerHost {
|
|
@@ -250,6 +251,37 @@ export class CheckedProgram {
|
|
|
250
251
|
result.push(d);
|
|
251
252
|
return result;
|
|
252
253
|
}
|
|
254
|
+
/**
|
|
255
|
+
* Checks the statements `start` to `end` of the declaration file `file` with this checker, one of the
|
|
256
|
+
* ranges that several checkers check it in (`checkSourceFileRange`, parallel-check.ts), and returns
|
|
257
|
+
* whether the checker then has diagnostics in the file.
|
|
258
|
+
*/
|
|
259
|
+
checkRange(file, start, end) {
|
|
260
|
+
return checkSourceFileRange(this.checker, file, start, end);
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* The diagnostics of `file`, as `unfilteredDiagnosticsOfFile` gives them, where checkers checked it in
|
|
264
|
+
* ranges and found no diagnostics in it (`checkRange`).
|
|
265
|
+
*/
|
|
266
|
+
unfilteredDiagnosticsOfCleanRanges(file) {
|
|
267
|
+
const result = this.getBindAndCheckDiagnostics(file, []);
|
|
268
|
+
for (const d of this.getIncludeProcessorDiagnostics(file))
|
|
269
|
+
result.push(d);
|
|
270
|
+
return result;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* The diagnostics of `file`, as `unfilteredDiagnosticsOfFile` gives them, from a new checker that checks it
|
|
274
|
+
* whole: for a file checked in ranges that found diagnostics in it (parallel-check.ts), part of which this
|
|
275
|
+
* thread's checker may have checked.
|
|
276
|
+
*/
|
|
277
|
+
unfilteredDiagnosticsOfFileOnNewChecker(file) {
|
|
278
|
+
const checker = this.createChecker();
|
|
279
|
+
const result = this.getBindAndCheckDiagnostics(file, checker.getDiagnostics(file));
|
|
280
|
+
disposeChecker(checker);
|
|
281
|
+
for (const d of this.getIncludeProcessorDiagnostics(file))
|
|
282
|
+
result.push(d);
|
|
283
|
+
return result;
|
|
284
|
+
}
|
|
253
285
|
/**
|
|
254
286
|
* The bind and check diagnostics of `file` before `noEmit` filtering and without include errors.
|
|
255
287
|
* Once checker threads checked the program, they come from the threads' diagnostics of the file,
|
|
@@ -331,10 +363,11 @@ export class CheckedProgram {
|
|
|
331
363
|
}
|
|
332
364
|
return sortAndDeduplicateDiagnostics(result);
|
|
333
365
|
}
|
|
334
|
-
|
|
366
|
+
/** `checks` are the checker's diagnostics of `file`. */
|
|
367
|
+
getBindAndCheckDiagnostics(file, checks) {
|
|
335
368
|
const options = this.program.options;
|
|
336
369
|
const diagnostics = file.bindDiagnostics.slice();
|
|
337
|
-
for (const d of this.checker.getDiagnostics(file))
|
|
370
|
+
for (const d of checks ?? this.checker.getDiagnostics(file))
|
|
338
371
|
diagnostics.push(d);
|
|
339
372
|
if (isPlainJSFile(file, options)) {
|
|
340
373
|
const result = [];
|
|
@@ -11,3 +11,13 @@ export declare function diagnosticOf(d: CompilerDiagnostic): Diagnostic;
|
|
|
11
11
|
* them. Declaration diagnostics are empty, as tsgo's API returns them.
|
|
12
12
|
*/
|
|
13
13
|
export declare function programDiagnostics(checked: CheckedProgram, kind: DiagnosticKind, file: SourceFile | undefined): readonly CompilerDiagnostic[];
|
|
14
|
+
/**
|
|
15
|
+
* What `semantic` answers for each of `files` and what `global` answers, after checking `files` and
|
|
16
|
+
* no other file. Checking one file can add diagnostics located in another, so every file is checked
|
|
17
|
+
* before any file's diagnostics are collected. With every file of the program listed, the answers are
|
|
18
|
+
* those of the full check.
|
|
19
|
+
*/
|
|
20
|
+
export declare function checkedFileDiagnostics(checked: CheckedProgram, files: readonly SourceFile[]): {
|
|
21
|
+
files: (readonly CompilerDiagnostic[])[];
|
|
22
|
+
global: readonly CompilerDiagnostic[];
|
|
23
|
+
};
|
|
@@ -48,3 +48,23 @@ export function programDiagnostics(checked, kind, file) {
|
|
|
48
48
|
return [];
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* What `semantic` answers for each of `files` and what `global` answers, after checking `files` and
|
|
53
|
+
* no other file. Checking one file can add diagnostics located in another, so every file is checked
|
|
54
|
+
* before any file's diagnostics are collected. With every file of the program listed, the answers are
|
|
55
|
+
* those of the full check.
|
|
56
|
+
*/
|
|
57
|
+
export function checkedFileDiagnostics(checked, files) {
|
|
58
|
+
for (const file of files)
|
|
59
|
+
checked.getSemanticDiagnostics(file);
|
|
60
|
+
const program = checked.program;
|
|
61
|
+
const global = [
|
|
62
|
+
...program.getConfigFileParsingDiagnostics(),
|
|
63
|
+
...program.getProgramDiagnostics(),
|
|
64
|
+
...checked.getGlobalDiagnostics(),
|
|
65
|
+
];
|
|
66
|
+
return {
|
|
67
|
+
files: files.map((file) => checked.getSemanticDiagnostics(file)),
|
|
68
|
+
global: sortAndDeduplicateDiagnostics(global).filter((d) => d.file === undefined),
|
|
69
|
+
};
|
|
70
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tsc-ts",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
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.2"
|
|
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.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"
|
|
45
45
|
}
|
|
46
46
|
}
|
|
@@ -37,7 +37,7 @@ import { getExportSymbolOfValueSymbolIfExported } from './checker-symbols.js';
|
|
|
37
37
|
import { getBaseTypes, getDeclaredTypeOfSymbol } from './checker-declared-types.js';
|
|
38
38
|
import { getPropertyOfType } from './checker-members.js';
|
|
39
39
|
import { FunctionFlags, getFunctionFlags } from './checker-utilities.js';
|
|
40
|
-
import {
|
|
40
|
+
import { declarationAt, declarationCount, type Symbol, SymbolFlags } from './symbol.js';
|
|
41
41
|
|
|
42
42
|
/** Reports a block-scoped variable, class or enum resolved at `errorLocation` before its declaration. */
|
|
43
43
|
export function checkResolvedBlockScopedVariable(c: Checker, resolved: Symbol, errorLocation: Node): void {
|
|
@@ -50,7 +50,8 @@ export function checkResolvedBlockScopedVariable(c: Checker, resolved: Symbol, e
|
|
|
50
50
|
)
|
|
51
51
|
return;
|
|
52
52
|
let declaration: Node | undefined;
|
|
53
|
-
for (
|
|
53
|
+
for (let i = 0; i < declarationCount(result); i++) {
|
|
54
|
+
const d = declarationAt(result, i);
|
|
54
55
|
if (isBlockOrCatchScoped(d) || isClassLike(d) || d.kind === SyntaxKind.EnumDeclaration) {
|
|
55
56
|
declaration = d;
|
|
56
57
|
break;
|
|
@@ -87,7 +87,7 @@ import { getIndexedAccessType, isGenericMappedType } from './checker-type-operat
|
|
|
87
87
|
import { getSignatureInstantiation } from './checker-signatures.js';
|
|
88
88
|
import { evaluateEnumMember, EvaluatedFlags, EvaluatedKind } from './checker-evaluator.js';
|
|
89
89
|
import { checkTypeAssignableTo, isTypeIdenticalTo } from './relations.js';
|
|
90
|
-
import { getDeclarations, type Symbol, SymbolFlags } from './symbol.js';
|
|
90
|
+
import { declarationAt, declarationCount, getDeclarations, type Symbol, SymbolFlags } from './symbol.js';
|
|
91
91
|
|
|
92
92
|
export { getParentOfSymbol };
|
|
93
93
|
|
|
@@ -877,9 +877,12 @@ export function getMinTypeArgumentCount(c: Checker, typeParameters: readonly Typ
|
|
|
877
877
|
|
|
878
878
|
/** Whether a type parameter is declared with a default, without resolving it. */
|
|
879
879
|
function hasTypeParameterDefault(t: Type): boolean {
|
|
880
|
-
|
|
881
|
-
|
|
880
|
+
const symbol = t.symbol;
|
|
881
|
+
if (symbol === undefined) return false;
|
|
882
|
+
for (let i = 0; i < declarationCount(symbol); i++) {
|
|
883
|
+
const d = declarationAt(symbol, i);
|
|
882
884
|
if (d.kind === SyntaxKind.TypeParameter && (d as TypeParameterDeclaration).defaultType !== undefined) return true;
|
|
885
|
+
}
|
|
883
886
|
return false;
|
|
884
887
|
}
|
|
885
888
|
|
|
@@ -32,7 +32,7 @@ import { entityNameToString } from './checker-expressions.js';
|
|
|
32
32
|
import { isErrorType } from './checker-type-factory.js';
|
|
33
33
|
import { getPropertyOfType } from './checker-members.js';
|
|
34
34
|
import { signatureToString } from './type-printer.js';
|
|
35
|
-
import { declarationCount, getDeclarations, type Symbol, SymbolFlags } from './symbol.js';
|
|
35
|
+
import { declarationAt, declarationCount, getDeclarations, type Symbol, SymbolFlags } from './symbol.js';
|
|
36
36
|
|
|
37
37
|
/** Whether `declaration`, or the statement it belongs to, has a `@deprecated` JSDoc tag. */
|
|
38
38
|
export function isDeprecatedDeclaration(declaration: Node): boolean {
|
|
@@ -56,25 +56,26 @@ function getJSDocDeprecatedTag(node: Node): Node | undefined {
|
|
|
56
56
|
* members when all are.
|
|
57
57
|
*/
|
|
58
58
|
export function isDeprecatedSymbol(c: Checker, symbol: Symbol): boolean {
|
|
59
|
-
const
|
|
59
|
+
const count = declarationCount(symbol);
|
|
60
60
|
const parentSymbol = getParentOfSymbol(c, symbol);
|
|
61
|
-
if (parentSymbol !== undefined &&
|
|
61
|
+
if (parentSymbol !== undefined && count > 1)
|
|
62
62
|
return (parentSymbol.flags & SymbolFlags.Interface) !== 0
|
|
63
|
-
? someDeprecatedDeclaration(
|
|
64
|
-
: everyDeprecatedDeclaration(
|
|
63
|
+
? someDeprecatedDeclaration(symbol)
|
|
64
|
+
: everyDeprecatedDeclaration(symbol);
|
|
65
65
|
return (
|
|
66
66
|
(symbol.valueDeclaration !== undefined && isDeprecatedDeclaration(symbol.valueDeclaration)) ||
|
|
67
|
-
(
|
|
67
|
+
(count !== 0 && everyDeprecatedDeclaration(symbol))
|
|
68
68
|
);
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
function someDeprecatedDeclaration(
|
|
72
|
-
for (
|
|
71
|
+
function someDeprecatedDeclaration(symbol: Symbol): boolean {
|
|
72
|
+
for (let i = 0; i < declarationCount(symbol); i++) if (isDeprecatedDeclaration(declarationAt(symbol, i))) return true;
|
|
73
73
|
return false;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
function everyDeprecatedDeclaration(
|
|
77
|
-
for (
|
|
76
|
+
function everyDeprecatedDeclaration(symbol: Symbol): boolean {
|
|
77
|
+
for (let i = 0; i < declarationCount(symbol); i++)
|
|
78
|
+
if (!isDeprecatedDeclaration(declarationAt(symbol, i))) return false;
|
|
78
79
|
return true;
|
|
79
80
|
}
|
|
80
81
|
|
|
@@ -330,7 +331,8 @@ export function checkDeprecatedTypeReference(c: Checker, node: Node, type: Type)
|
|
|
330
331
|
if (isErrorType(c, type)) return;
|
|
331
332
|
const symbol = c.resolvedSymbols.get(node.id);
|
|
332
333
|
if (symbol === undefined) return;
|
|
333
|
-
for (
|
|
334
|
+
for (let i = 0; i < declarationCount(symbol); i++) {
|
|
335
|
+
const d = declarationAt(symbol, i);
|
|
334
336
|
if (isTypeDeclaration(d) && isDeprecatedDeclaration(d)) {
|
|
335
337
|
addDeprecatedSuggestion(c, getDeprecatedSuggestionNode(node), getDeclarations(symbol), symbol.name);
|
|
336
338
|
return;
|
|
@@ -115,7 +115,15 @@ import { TypeFacts, getNonNullableType, getTypeWithFacts, hasTypeFacts } from '.
|
|
|
115
115
|
import { sliceTupleType } from './checker-signatures.js';
|
|
116
116
|
import { getPropertyNameFromType, isTypeUsableAsPropertyName, maybeTypeOfKind } from './checker-utilities.js';
|
|
117
117
|
import { checkPropertyAccessibility } from './checker-property-access.js';
|
|
118
|
-
import {
|
|
118
|
+
import {
|
|
119
|
+
CheckFlags,
|
|
120
|
+
copyDeclarations,
|
|
121
|
+
declarationAt,
|
|
122
|
+
declarationCount,
|
|
123
|
+
getSymbolId,
|
|
124
|
+
type Symbol,
|
|
125
|
+
SymbolFlags,
|
|
126
|
+
} from './symbol.js';
|
|
119
127
|
|
|
120
128
|
function isBindingPatternNode(node: Node | undefined): boolean {
|
|
121
129
|
return (
|
|
@@ -766,7 +774,8 @@ export function isSpreadableProperty(prop: Symbol): boolean {
|
|
|
766
774
|
(prop.flags & (SymbolFlags.Method | SymbolFlags.GetAccessor | SymbolFlags.SetAccessor)) === 0;
|
|
767
775
|
let hasPrivateName = false;
|
|
768
776
|
let inClass = false;
|
|
769
|
-
for (
|
|
777
|
+
for (let i = 0; i < declarationCount(prop); i++) {
|
|
778
|
+
const d = declarationAt(prop, i);
|
|
770
779
|
if (isPrivateIdentifierClassElementDeclaration(d)) hasPrivateName = true;
|
|
771
780
|
if (d.parent !== undefined && isClassLike(d.parent)) inClass = true;
|
|
772
781
|
}
|
|
@@ -923,8 +923,12 @@ export function resolveDeclaredMembers(c: Checker, t: InterfaceType): InterfaceT
|
|
|
923
923
|
const members = getMembersOfSymbol(c, t.symbol!);
|
|
924
924
|
declared.declaredMembersResolved = true;
|
|
925
925
|
declared.declaredMembers = members;
|
|
926
|
-
|
|
927
|
-
|
|
926
|
+
// Most interfaces declare neither, and share one empty list.
|
|
927
|
+
const call = members.get(InternalSymbolName.Call);
|
|
928
|
+
const construct = members.get(InternalSymbolName.New);
|
|
929
|
+
declared.declaredCallSignatures = call !== undefined ? getSignaturesOfSymbol(c, call) : emptySignatures;
|
|
930
|
+
declared.declaredConstructSignatures =
|
|
931
|
+
construct !== undefined ? getSignaturesOfSymbol(c, construct) : emptySignatures;
|
|
928
932
|
declared.declaredIndexInfos = getIndexInfosOfSymbol(c, t.symbol!);
|
|
929
933
|
}
|
|
930
934
|
return declared;
|
|
@@ -161,6 +161,40 @@ function checkSourceFileWorker(c: Checker, file: SourceFile): void {
|
|
|
161
161
|
links.deferredNodes = undefined;
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
+
/**
|
|
165
|
+
* Checks the statements `start` to `end` of the declaration file `file`, one of the ranges that several
|
|
166
|
+
* checkers check it in (parallel-check.ts), and returns whether the checker then has diagnostics in the
|
|
167
|
+
* file. The range ending the file also runs the checks of the whole file. The file is not marked checked.
|
|
168
|
+
*
|
|
169
|
+
* When no range finds a diagnostic in the file, checking it whole would find none either: each statement
|
|
170
|
+
* is checked by the checker of its range. Otherwise the file is checked whole (`startParallelCheck`): the
|
|
171
|
+
* diagnostics of the ranges can differ from the file's, where they depend on the order the file's
|
|
172
|
+
* declarations are resolved in. A union type prints its members in the order the checker created them,
|
|
173
|
+
* and a check that a symbol's first declaration runs reports on all its declarations.
|
|
174
|
+
*/
|
|
175
|
+
export function checkSourceFileRange(c: Checker, file: SourceFile, start: number, end: number): boolean {
|
|
176
|
+
const statements = getStatements(file)!.nodes;
|
|
177
|
+
c.fileBeingChecked = file;
|
|
178
|
+
c.saveDeferredDiagnostics = true;
|
|
179
|
+
for (let i = start; i < end; i++) checkSourceElement(c, statements[i]!);
|
|
180
|
+
checkDeferredNodes(c, file);
|
|
181
|
+
const whole = end === statements.length;
|
|
182
|
+
if (whole && isExternalOrCommonJSModule(file)) checkExternalModuleExports(c, file);
|
|
183
|
+
c.renamedBindingElementsInTypes.length = 0;
|
|
184
|
+
if (whole) {
|
|
185
|
+
checkGrammarSourceFile(c, file);
|
|
186
|
+
checkDeferredNodes(c, file);
|
|
187
|
+
checkPendingExternalEmitHelpers(c, file);
|
|
188
|
+
}
|
|
189
|
+
c.fileBeingChecked = undefined;
|
|
190
|
+
c.saveDeferredDiagnostics = false;
|
|
191
|
+
produceDeferredIterationErrors(c);
|
|
192
|
+
produceDeferredCollisionChecks(c);
|
|
193
|
+
// Deferred nodes of a later range are queued again (checkNodeDeferred).
|
|
194
|
+
c.nodeLinks(file).deferredNodes = undefined;
|
|
195
|
+
return c.diagnostics.forFile(file.fileName).length > 0;
|
|
196
|
+
}
|
|
197
|
+
|
|
164
198
|
/** Checks a statement, declaration, class member or type node. */
|
|
165
199
|
export function checkSourceElement(c: Checker, node: Node | undefined): void {
|
|
166
200
|
if (node === undefined) return;
|
|
@@ -129,7 +129,16 @@ import { getTypeForBindingElement, getTypeFromBindingPattern } from './checker-d
|
|
|
129
129
|
import { checkRightHandSideOfForOf } from './checker-statements.js';
|
|
130
130
|
import { getTypeWithFacts, TypeFacts, hasTypeFacts, getNonNullableType } from './checker-flow.js';
|
|
131
131
|
import { getTypeOfModuleExportsSymbol, getWidenedTypeForAssignmentDeclaration } from './checker-javascript.js';
|
|
132
|
-
import {
|
|
132
|
+
import {
|
|
133
|
+
CheckFlags,
|
|
134
|
+
copyDeclarations,
|
|
135
|
+
declarationAt,
|
|
136
|
+
declarationCount,
|
|
137
|
+
getDeclarations,
|
|
138
|
+
getSymbolId,
|
|
139
|
+
type Symbol,
|
|
140
|
+
SymbolFlags,
|
|
141
|
+
} from './symbol.js';
|
|
133
142
|
|
|
134
143
|
export function getTypeOfSymbol(c: Checker, symbol: Symbol): Type {
|
|
135
144
|
const checkFlags = symbol.checkFlags;
|
|
@@ -932,12 +941,13 @@ export function isReadonlySymbol(c: Checker, symbol: Symbol): boolean {
|
|
|
932
941
|
(getDeclarationNodeFlagsFromSymbol(symbol) & NodeFlags.Constant) !== 0) ||
|
|
933
942
|
((symbol.flags & SymbolFlags.Accessor) !== 0 && (symbol.flags & SymbolFlags.SetAccessor) === 0) ||
|
|
934
943
|
(symbol.flags & SymbolFlags.EnumMember) !== 0 ||
|
|
935
|
-
someReadonlyAssignmentDeclaration(c,
|
|
944
|
+
someReadonlyAssignmentDeclaration(c, symbol)
|
|
936
945
|
);
|
|
937
946
|
}
|
|
938
947
|
|
|
939
|
-
function someReadonlyAssignmentDeclaration(c: Checker,
|
|
940
|
-
for (
|
|
948
|
+
function someReadonlyAssignmentDeclaration(c: Checker, symbol: Symbol): boolean {
|
|
949
|
+
for (let i = 0; i < declarationCount(symbol); i++)
|
|
950
|
+
if (isReadonlyAssignmentDeclaration(c, declarationAt(symbol, i))) return true;
|
|
941
951
|
return false;
|
|
942
952
|
}
|
|
943
953
|
|
|
@@ -957,6 +957,7 @@ export function setGlobal(c: Checker, name: string, symbol: Symbol): void {
|
|
|
957
957
|
function setMergedSymbol(c: Checker, id: number, target: Symbol): void {
|
|
958
958
|
if (c.mergedSymbolChanges !== undefined) c.mergedSymbolChanges.set(c.mergedSymbols, id, target);
|
|
959
959
|
else c.mergedSymbols.set(id, target);
|
|
960
|
+
c.mergedSymbolIds.add(id);
|
|
960
961
|
}
|
|
961
962
|
|
|
962
963
|
/** Merges script locals into globals; ambient modules and augmentations wait for global types. */
|
|
@@ -1298,7 +1299,7 @@ function recordMergedSymbol(c: Checker, target: Symbol, source: Symbol): void {
|
|
|
1298
1299
|
|
|
1299
1300
|
export function getMergedSymbol(c: Checker, symbol: Symbol): Symbol {
|
|
1300
1301
|
const id = symbol.id;
|
|
1301
|
-
if (id !== 0) {
|
|
1302
|
+
if (id !== 0 && c.mergedSymbolIds.has(id)) {
|
|
1302
1303
|
const merged = c.mergedSymbols.get(id);
|
|
1303
1304
|
if (merged !== undefined) return merged;
|
|
1304
1305
|
}
|
|
@@ -1761,7 +1762,10 @@ export function symbolIsValue(c: Checker, symbol: Symbol): boolean {
|
|
|
1761
1762
|
function isDeclarationContainedBy(symbol: Symbol, container: Symbol): boolean {
|
|
1762
1763
|
const declaration = symbol.valueDeclaration;
|
|
1763
1764
|
if (declaration !== undefined)
|
|
1764
|
-
for (
|
|
1765
|
+
for (let i = 0; i < declarationCount(container); i++) {
|
|
1766
|
+
const d = declarationAt(container, i);
|
|
1767
|
+
if (declaration.pos >= d.pos && declaration.end <= d.end) return true;
|
|
1768
|
+
}
|
|
1765
1769
|
return false;
|
|
1766
1770
|
}
|
|
1767
1771
|
|