tsc-ts 0.1.0 → 0.1.2
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 +7 -1
- package/dist/api/compiler/ast.d.ts +15 -3
- package/dist/api/compiler/ast.js +36 -15
- package/dist/api/compiler/checker-classes.js +2 -1
- package/dist/api/compiler/checker-contextual.d.ts +20 -0
- package/dist/api/compiler/checker-contextual.js +111 -1
- package/dist/api/compiler/checker-expressions.js +14 -1
- package/dist/api/compiler/checker-grammar.d.ts +39 -4
- package/dist/api/compiler/checker-grammar.js +239 -75
- package/dist/api/compiler/checker-heritage.js +20 -14
- package/dist/api/compiler/checker-jsx.js +2 -1
- package/dist/api/compiler/checker-modules.js +4 -2
- package/dist/api/compiler/checker-source-file.js +1 -1
- package/dist/api/compiler/checker-type-factory.js +70 -19
- package/dist/api/compiler/checker-type-nodes.d.ts +1 -1
- package/dist/api/compiler/checker-type-nodes.js +5 -5
- package/dist/api/compiler/checker-unused.js +15 -10
- package/dist/api/compiler/checker.d.ts +7 -1
- package/dist/api/compiler/checker.js +14 -4
- package/dist/api/compiler/compile-program.d.ts +5 -0
- package/dist/api/compiler/compile-program.js +8 -0
- package/dist/api/compiler/expr-record.d.ts +11 -0
- package/dist/api/compiler/expr-record.js +53 -0
- package/dist/api/compiler/file-loader.d.ts +5 -0
- package/dist/api/compiler/file-loader.js +7 -0
- package/dist/api/compiler/identifier-name.d.ts +9 -0
- package/dist/api/compiler/identifier-name.js +10 -0
- package/dist/api/compiler/jsdoc.js +4 -2
- package/dist/api/compiler/parser.d.ts +2 -1
- package/dist/api/compiler/parser.js +10 -8
- package/dist/api/compiler/printer/factory.js +3 -2
- package/dist/api/compiler/printer/printer.js +3 -2
- package/dist/api/compiler/program-checker.d.ts +18 -0
- package/dist/api/compiler/program-checker.js +27 -0
- package/dist/api/compiler/reparser.js +4 -3
- package/dist/api/compiler/scanner.d.ts +8 -0
- package/dist/api/compiler/scanner.js +58 -42
- package/dist/api/compiler/shared-results.d.ts +376 -143
- package/dist/api/compiler/shared-results.js +1550 -773
- package/dist/api/compiler/transformers/declarations.js +2 -1
- package/package.json +15 -10
- package/src/compiler/ast.ts +39 -15
- package/src/compiler/cgroup.ts +157 -0
- package/src/compiler/checker-classes.ts +2 -1
- package/src/compiler/checker-contextual.ts +104 -0
- package/src/compiler/checker-expressions.ts +16 -1
- package/src/compiler/checker-grammar.ts +247 -88
- package/src/compiler/checker-heritage.ts +31 -17
- package/src/compiler/checker-jsx.ts +2 -1
- package/src/compiler/checker-modules.ts +4 -2
- package/src/compiler/checker-source-file.ts +1 -1
- package/src/compiler/checker-type-factory.ts +67 -21
- package/src/compiler/checker-type-nodes.ts +5 -5
- package/src/compiler/checker-unused.ts +13 -8
- package/src/compiler/checker.ts +15 -4
- package/src/compiler/compile-program.ts +8 -0
- package/src/compiler/decoder.ts +2 -1
- package/src/compiler/doctor-report.ts +133 -0
- package/src/compiler/expr-record.ts +59 -0
- package/src/compiler/file-loader.ts +8 -0
- package/src/compiler/identifier-name.ts +13 -0
- package/src/compiler/jsdoc.ts +4 -2
- package/src/compiler/parallel-check.ts +364 -146
- package/src/compiler/parallel-emit.ts +3 -3
- package/src/compiler/parse-thread.ts +24 -2
- package/src/compiler/parser.ts +10 -8
- package/src/compiler/printer/factory.ts +3 -2
- package/src/compiler/printer/printer.ts +4 -2
- package/src/compiler/program-checker.ts +28 -0
- package/src/compiler/reparser.ts +7 -3
- package/src/compiler/run-config.ts +1383 -0
- package/src/compiler/run-record-read.ts +87 -0
- package/src/compiler/run-records.ts +575 -0
- package/src/compiler/scanner.ts +57 -41
- package/src/compiler/shared-results.ts +1626 -896
- package/src/compiler/thread-entry.ts +3 -1
- package/src/compiler/transformers/declarations.ts +2 -1
- package/src/compiler/tsc-build.ts +64 -6
- package/src/compiler/tsc-cli.ts +33 -4
- package/src/compiler/tsc-compile.ts +223 -9
- package/src/compiler/tsc-watch.ts +25 -4
package/src/compiler/scanner.ts
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
isWhiteSpaceSingleLine,
|
|
14
14
|
} from './character-codes.js';
|
|
15
15
|
import { Diagnostics } from './diagnostic-messages.js';
|
|
16
|
+
import { IdentifierName } from './identifier-name.js';
|
|
16
17
|
import type { DiagnosticMessage } from './diagnostics.js';
|
|
17
18
|
import { parsePseudoBigInt } from './pseudo-bigint.js';
|
|
18
19
|
import {
|
|
@@ -358,59 +359,60 @@ function finishHash(hash: number): number {
|
|
|
358
359
|
return hash ^ (hash >>> 15);
|
|
359
360
|
}
|
|
360
361
|
|
|
361
|
-
/**
|
|
362
|
+
/**
|
|
363
|
+
* Names for ranges of one text, keyed by their code units: equal identifiers share one
|
|
364
|
+
* `IdentifierName`.
|
|
365
|
+
*/
|
|
362
366
|
class IdentifierTable {
|
|
363
|
-
private text: string;
|
|
364
367
|
// Pairs of (entry index + 1, hash) per slot, (0, 0) when empty; linear probing.
|
|
365
368
|
private slots: Int32Array;
|
|
366
369
|
// Each entry's length in code units.
|
|
367
370
|
private lengths: Int32Array;
|
|
368
|
-
private
|
|
371
|
+
private names: IdentifierName[];
|
|
369
372
|
private count: number;
|
|
370
|
-
// Per entry: 1 once its
|
|
373
|
+
// Per entry: 1 once its name was recorded among the file's identifier texts (`markRecorded`).
|
|
371
374
|
private recorded: Uint8Array;
|
|
372
|
-
// The entry the last `intern` returned.
|
|
373
|
-
private lastEntry: number;
|
|
374
375
|
|
|
375
|
-
constructor(
|
|
376
|
-
this.text = text;
|
|
376
|
+
constructor() {
|
|
377
377
|
this.slots = new Int32Array(512);
|
|
378
378
|
this.lengths = new Int32Array(128);
|
|
379
|
-
this.
|
|
379
|
+
this.names = [];
|
|
380
380
|
this.count = 0;
|
|
381
381
|
this.recorded = new Uint8Array(128);
|
|
382
|
-
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/** Empties the table for a new text. */
|
|
385
|
+
clear(): void {
|
|
386
|
+
if (this.count === 0) return;
|
|
387
|
+
this.slots.fill(0);
|
|
388
|
+
this.names.length = 0;
|
|
389
|
+
this.recorded.fill(0, 0, this.count);
|
|
390
|
+
this.count = 0;
|
|
383
391
|
}
|
|
384
392
|
|
|
385
393
|
/**
|
|
386
|
-
* Whether `text`,
|
|
387
|
-
* texts; marks it recorded. Texts the table doesn't know are
|
|
394
|
+
* Whether `text`, the text of the entry `entry` that `intern` returned (-1 for none), still needs
|
|
395
|
+
* recording among the file's identifier texts; marks it recorded. Texts the table doesn't know are
|
|
396
|
+
* always recorded.
|
|
388
397
|
*/
|
|
389
|
-
markRecorded(text: string): boolean {
|
|
390
|
-
|
|
391
|
-
if (entry < 0 || this.texts[entry] !== text) return true;
|
|
398
|
+
markRecorded(entry: number, text: string): boolean {
|
|
399
|
+
if (entry < 0 || this.names[entry]!.text !== text) return true;
|
|
392
400
|
if (this.recorded[entry] !== 0) return false;
|
|
393
401
|
this.recorded[entry] = 1;
|
|
394
402
|
return true;
|
|
395
403
|
}
|
|
396
404
|
|
|
397
|
-
/**
|
|
398
|
-
|
|
399
|
-
this.
|
|
400
|
-
if (this.count === 0) return;
|
|
401
|
-
this.slots.fill(0);
|
|
402
|
-
this.recorded.fill(0, 0, this.count);
|
|
403
|
-
this.texts.length = 0;
|
|
404
|
-
this.count = 0;
|
|
405
|
-
this.lastEntry = -1;
|
|
405
|
+
/** The name of the entry `intern` returned. */
|
|
406
|
+
name(entry: number): IdentifierName {
|
|
407
|
+
return this.names[entry]!;
|
|
406
408
|
}
|
|
407
409
|
|
|
408
410
|
/**
|
|
409
|
-
* `text.substring(start, end)`,
|
|
410
|
-
* A candidate of the same hash and length is compared with `startsWith`, which natively
|
|
411
|
-
* the bytes of both strings at once.
|
|
411
|
+
* The entry of `text.substring(start, end)`, added when the table has no equal range; `hash` is its
|
|
412
|
+
* `rangeHash`. A candidate of the same hash and length is compared with `startsWith`, which natively
|
|
413
|
+
* compares the bytes of both strings at once.
|
|
412
414
|
*/
|
|
413
|
-
intern(start: number, end: number, hash: number):
|
|
415
|
+
intern(text: string, start: number, end: number, hash: number): number {
|
|
414
416
|
start = start | 0;
|
|
415
417
|
end = end | 0;
|
|
416
418
|
hash = hash | 0;
|
|
@@ -422,15 +424,10 @@ class IdentifierTable {
|
|
|
422
424
|
const entry = slots[(slot * 2) | 0] | 0;
|
|
423
425
|
if (entry === 0) break;
|
|
424
426
|
if ((slots[(slot * 2 + 1) | 0] | 0) === hash && (this.lengths[(entry - 1) | 0] | 0) === length) {
|
|
425
|
-
|
|
426
|
-
if (this.text.startsWith(candidate, start)) {
|
|
427
|
-
this.lastEntry = (entry - 1) | 0;
|
|
428
|
-
return candidate;
|
|
429
|
-
}
|
|
427
|
+
if (text.startsWith(this.names[(entry - 1) | 0]!.text, start)) return (entry - 1) | 0;
|
|
430
428
|
}
|
|
431
429
|
slot = (slot + 1) & mask;
|
|
432
430
|
}
|
|
433
|
-
const value = this.text.substring(start, end);
|
|
434
431
|
const index = this.count | 0;
|
|
435
432
|
if (index === this.lengths.length) {
|
|
436
433
|
const lengths = new Int32Array(index * 2);
|
|
@@ -441,13 +438,12 @@ class IdentifierTable {
|
|
|
441
438
|
this.recorded = recorded;
|
|
442
439
|
}
|
|
443
440
|
this.lengths[index] = length;
|
|
444
|
-
this.
|
|
441
|
+
this.names.push(new IdentifierName(text.substring(start, end)));
|
|
445
442
|
this.count = (index + 1) | 0;
|
|
446
|
-
this.lastEntry = index;
|
|
447
443
|
slots[(slot * 2) | 0] = (index + 1) | 0;
|
|
448
444
|
slots[(slot * 2 + 1) | 0] = hash;
|
|
449
445
|
if (this.count * 2 > mask + 1) this.slots = rehash(slots);
|
|
450
|
-
return
|
|
446
|
+
return index;
|
|
451
447
|
}
|
|
452
448
|
}
|
|
453
449
|
|
|
@@ -619,6 +615,8 @@ export class Scanner {
|
|
|
619
615
|
// so identifiers and keywords don't allocate until their value is read.
|
|
620
616
|
/** @internal */ tokenValue: string;
|
|
621
617
|
/** @internal */ valueStart: number;
|
|
618
|
+
// The name `getIdentifierValue` last interned, whose text `tokenValue` then holds.
|
|
619
|
+
private tokenName: IdentifierName | undefined;
|
|
622
620
|
/** @internal */ valueEnd: number;
|
|
623
621
|
// `rangeHash` of `chars[hashStart, hashEnd)`, which the ASCII identifier scan computes as it goes.
|
|
624
622
|
private valueHash: number;
|
|
@@ -629,6 +627,8 @@ export class Scanner {
|
|
|
629
627
|
// The code units zeroed by `setTextEnd`.
|
|
630
628
|
private readonly cutUnits: Uint16Array;
|
|
631
629
|
private readonly identifiers: IdentifierTable;
|
|
630
|
+
// The entry `getIdentifierValue` last interned, -1 for none.
|
|
631
|
+
private lastEntry: number;
|
|
632
632
|
// With code units on demand: per block of `unitBlockSize` code units, 1 once `chars` holds them
|
|
633
633
|
// (`loadUnits`); `chars` is zero elsewhere.
|
|
634
634
|
private loadedBlocks: Uint8Array | undefined;
|
|
@@ -667,6 +667,7 @@ export class Scanner {
|
|
|
667
667
|
this.tokenFlags = TokenFlags.None;
|
|
668
668
|
this.tokenValue = '';
|
|
669
669
|
this.valueStart = -1;
|
|
670
|
+
this.tokenName = undefined;
|
|
670
671
|
this.valueEnd = -1;
|
|
671
672
|
this.valueHash = 0;
|
|
672
673
|
this.hashStart = -1;
|
|
@@ -674,7 +675,8 @@ export class Scanner {
|
|
|
674
675
|
this.commentDirectives = [];
|
|
675
676
|
this.skipJSDocLeadingAsterisks = 0;
|
|
676
677
|
this.cutUnits = new Uint16Array(4);
|
|
677
|
-
this.identifiers = new IdentifierTable(
|
|
678
|
+
this.identifiers = new IdentifierTable();
|
|
679
|
+
this.lastEntry = -1;
|
|
678
680
|
this.textKind = TextKind.Unknown;
|
|
679
681
|
this.lineFeedFrom = -1;
|
|
680
682
|
this.lineFeedAt = -1;
|
|
@@ -687,7 +689,8 @@ export class Scanner {
|
|
|
687
689
|
this.text = text;
|
|
688
690
|
this.chars = toCodeUnits(text);
|
|
689
691
|
this.loadedBlocks = undefined;
|
|
690
|
-
this.identifiers.
|
|
692
|
+
this.identifiers.clear();
|
|
693
|
+
this.lastEntry = -1;
|
|
691
694
|
this.textKind = TextKind.Unknown;
|
|
692
695
|
this.lineFeedFrom = -1;
|
|
693
696
|
this.lineFeedAt = -1;
|
|
@@ -820,7 +823,7 @@ export class Scanner {
|
|
|
820
823
|
* file to be recorded; files record each identifier text once.
|
|
821
824
|
*/
|
|
822
825
|
recordIdentifierValue(text: string): boolean {
|
|
823
|
-
return this.identifiers.markRecorded(text);
|
|
826
|
+
return this.identifiers.markRecorded(this.lastEntry, text);
|
|
824
827
|
}
|
|
825
828
|
|
|
826
829
|
/** @internal Like `getTokenValue`, but identifiers with the same text share one string. */
|
|
@@ -830,12 +833,25 @@ export class Scanner {
|
|
|
830
833
|
const end = this.valueEnd;
|
|
831
834
|
const hash =
|
|
832
835
|
start === this.hashStart && end === this.hashEnd ? this.valueHash : rangeHash(this.chars, start, end);
|
|
833
|
-
|
|
836
|
+
const entry = this.identifiers.intern(this.text, start, end, hash);
|
|
837
|
+
this.lastEntry = entry;
|
|
838
|
+
this.tokenName = this.identifiers.name(entry);
|
|
839
|
+
this.tokenValue = this.tokenName.text;
|
|
834
840
|
this.valueStart = -1;
|
|
835
841
|
}
|
|
836
842
|
return this.tokenValue;
|
|
837
843
|
}
|
|
838
844
|
|
|
845
|
+
/**
|
|
846
|
+
* The identifier value as a name that identifiers with the same text share, after
|
|
847
|
+
* `getIdentifierValue`; a cooked value (with escapes) gets a name of its own.
|
|
848
|
+
*/
|
|
849
|
+
getIdentifierName(): IdentifierName {
|
|
850
|
+
const name = this.tokenName;
|
|
851
|
+
if (name !== undefined && name.text === this.tokenValue) return name;
|
|
852
|
+
return new IdentifierName(this.tokenValue);
|
|
853
|
+
}
|
|
854
|
+
|
|
839
855
|
getCommentDirectives(): readonly CommentDirective[] {
|
|
840
856
|
return this.commentDirectives;
|
|
841
857
|
}
|