tsc-ts 0.0.7 → 0.0.8
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-symbol-types.js +5 -5
- package/dist/api/compiler/checker-symbols.js +3 -1
- package/dist/api/compiler/parser.d.ts +7 -0
- package/dist/api/compiler/parser.js +40 -18
- 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-symbol-types.ts +14 -4
- package/src/compiler/checker-symbols.ts +4 -1
- package/src/compiler/parser.ts +40 -16
package/README.md
CHANGED
|
@@ -31,7 +31,7 @@ npx tsc-ts -p tsconfig.json
|
|
|
31
31
|
npx tsc-ts --noEmit src/index.ts
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
`tsc-ts --api` serves the TypeScript API over stdin and stdout, like `tsc --api`.
|
|
34
|
+
`tsc-ts --api` serves the TypeScript API over stdin and stdout, like `tsc --api`. On Windows, `--api --pipe \\.\pipe\<name>` serves it over a named pipe it creates, as `tsc --api --pipe` does, for clients that connect to the pipe (such as scriptc under Node.js); only the native executable supports `--pipe`.
|
|
35
35
|
|
|
36
36
|
`--checkers N` checks the program on N threads. Unless `--checkers` or `--singleThreaded` is given, the native executable uses one checker per CPU it may run on (up to 16), and at least tsgo's four; it uses fewer than the CPUs, but never fewer than four, when the estimated peak memory of more checkers would not fit 85% of the machine's memory (`TSC_TS_CHECKERS=fixed` keeps tsgo's four), and checkers beyond the fourth stop taking files, one at a time, when the process's memory reaches that share; it shares one program between its threads and also parses and binds the program's files on them. Unless `--singleThreaded` is given, the program's files are parsed and bound on threads also with `--checkers 1`, as tsgo does. Files that share costly declarations, such as a large generated schema and the few files importing it, are checked together on one checker. Under Node.js, where every thread builds its own copy of the program, tsc-ts checks on one thread unless `--checkers` is given. `--incremental`, `--watch` and `--build` always check on one thread. The diagnostics are the same as with one checker.
|
|
37
37
|
|
|
@@ -12,7 +12,7 @@ import { getExportSymbolOfValueSymbolIfExported } from './checker-symbols.js';
|
|
|
12
12
|
import { getBaseTypes, getDeclaredTypeOfSymbol } from './checker-declared-types.js';
|
|
13
13
|
import { getPropertyOfType } from './checker-members.js';
|
|
14
14
|
import { getFunctionFlags } from './checker-utilities.js';
|
|
15
|
-
import {
|
|
15
|
+
import { declarationAt, declarationCount } from './symbol.js';
|
|
16
16
|
/** Reports a block-scoped variable, class or enum resolved at `errorLocation` before its declaration. */
|
|
17
17
|
export function checkResolvedBlockScopedVariable(c, resolved, errorLocation) {
|
|
18
18
|
const result = getExportSymbolOfValueSymbolIfExported(c, resolved);
|
|
@@ -23,7 +23,8 @@ export function checkResolvedBlockScopedVariable(c, resolved, errorLocation) {
|
|
|
23
23
|
(result.flags & 32 /* SymbolFlags.Class */) !== 0)
|
|
24
24
|
return;
|
|
25
25
|
let declaration;
|
|
26
|
-
for (
|
|
26
|
+
for (let i = 0; i < declarationCount(result); i++) {
|
|
27
|
+
const d = declarationAt(result, i);
|
|
27
28
|
if (isBlockOrCatchScoped(d) || isClassLike(d) || d.kind === 267 /* SyntaxKind.EnumDeclaration */) {
|
|
28
29
|
declaration = d;
|
|
29
30
|
break;
|
|
@@ -20,7 +20,7 @@ import { getIndexedAccessType, isGenericMappedType } from './checker-type-operat
|
|
|
20
20
|
import { getSignatureInstantiation } from './checker-signatures.js';
|
|
21
21
|
import { evaluateEnumMember } from './checker-evaluator.js';
|
|
22
22
|
import { checkTypeAssignableTo, isTypeIdenticalTo } from './relations.js';
|
|
23
|
-
import { getDeclarations } from './symbol.js';
|
|
23
|
+
import { declarationAt, declarationCount, getDeclarations } from './symbol.js';
|
|
24
24
|
export { getParentOfSymbol };
|
|
25
25
|
export function getDeclaredTypeOfSymbol(c, symbol) {
|
|
26
26
|
return tryGetDeclaredTypeOfSymbol(c, symbol) ?? c.errorType;
|
|
@@ -752,11 +752,14 @@ export function getMinTypeArgumentCount(c, typeParameters) {
|
|
|
752
752
|
}
|
|
753
753
|
/** Whether a type parameter is declared with a default, without resolving it. */
|
|
754
754
|
function hasTypeParameterDefault(t) {
|
|
755
|
-
|
|
755
|
+
const symbol = t.symbol;
|
|
756
|
+
if (symbol === undefined)
|
|
756
757
|
return false;
|
|
757
|
-
for (
|
|
758
|
+
for (let i = 0; i < declarationCount(symbol); i++) {
|
|
759
|
+
const d = declarationAt(symbol, i);
|
|
758
760
|
if (d.kind === 169 /* SyntaxKind.TypeParameter */ && d.defaultType !== undefined)
|
|
759
761
|
return true;
|
|
762
|
+
}
|
|
760
763
|
return false;
|
|
761
764
|
}
|
|
762
765
|
export function fillMissingTypeArguments(c, typeArguments, typeParameters, minTypeArgumentCount, isJavaScriptImplicitAny) {
|
|
@@ -12,7 +12,7 @@ import { entityNameToString } from './checker-expressions.js';
|
|
|
12
12
|
import { isErrorType } from './checker-type-factory.js';
|
|
13
13
|
import { getPropertyOfType } from './checker-members.js';
|
|
14
14
|
import { signatureToString } from './type-printer.js';
|
|
15
|
-
import { declarationCount, getDeclarations } from './symbol.js';
|
|
15
|
+
import { declarationAt, declarationCount, getDeclarations } from './symbol.js';
|
|
16
16
|
/** Whether `declaration`, or the statement it belongs to, has a `@deprecated` JSDoc tag. */
|
|
17
17
|
export function isDeprecatedDeclaration(declaration) {
|
|
18
18
|
if ((getCombinedNodeFlags(declaration) & 67108864 /* NodeFlags.PossiblyContainsDeprecatedTag */) === 0)
|
|
@@ -38,24 +38,24 @@ function getJSDocDeprecatedTag(node) {
|
|
|
38
38
|
* members when all are.
|
|
39
39
|
*/
|
|
40
40
|
export function isDeprecatedSymbol(c, symbol) {
|
|
41
|
-
const
|
|
41
|
+
const count = declarationCount(symbol);
|
|
42
42
|
const parentSymbol = getParentOfSymbol(c, symbol);
|
|
43
|
-
if (parentSymbol !== undefined &&
|
|
43
|
+
if (parentSymbol !== undefined && count > 1)
|
|
44
44
|
return (parentSymbol.flags & 64 /* SymbolFlags.Interface */) !== 0
|
|
45
|
-
? someDeprecatedDeclaration(
|
|
46
|
-
: everyDeprecatedDeclaration(
|
|
45
|
+
? someDeprecatedDeclaration(symbol)
|
|
46
|
+
: everyDeprecatedDeclaration(symbol);
|
|
47
47
|
return ((symbol.valueDeclaration !== undefined && isDeprecatedDeclaration(symbol.valueDeclaration)) ||
|
|
48
|
-
(
|
|
48
|
+
(count !== 0 && everyDeprecatedDeclaration(symbol)));
|
|
49
49
|
}
|
|
50
|
-
function someDeprecatedDeclaration(
|
|
51
|
-
for (
|
|
52
|
-
if (isDeprecatedDeclaration(
|
|
50
|
+
function someDeprecatedDeclaration(symbol) {
|
|
51
|
+
for (let i = 0; i < declarationCount(symbol); i++)
|
|
52
|
+
if (isDeprecatedDeclaration(declarationAt(symbol, i)))
|
|
53
53
|
return true;
|
|
54
54
|
return false;
|
|
55
55
|
}
|
|
56
|
-
function everyDeprecatedDeclaration(
|
|
57
|
-
for (
|
|
58
|
-
if (!isDeprecatedDeclaration(
|
|
56
|
+
function everyDeprecatedDeclaration(symbol) {
|
|
57
|
+
for (let i = 0; i < declarationCount(symbol); i++)
|
|
58
|
+
if (!isDeprecatedDeclaration(declarationAt(symbol, i)))
|
|
59
59
|
return false;
|
|
60
60
|
return true;
|
|
61
61
|
}
|
|
@@ -290,7 +290,8 @@ export function checkDeprecatedTypeReference(c, node, type) {
|
|
|
290
290
|
const symbol = c.resolvedSymbols.get(node.id);
|
|
291
291
|
if (symbol === undefined)
|
|
292
292
|
return;
|
|
293
|
-
for (
|
|
293
|
+
for (let i = 0; i < declarationCount(symbol); i++) {
|
|
294
|
+
const d = declarationAt(symbol, i);
|
|
294
295
|
if (isTypeDeclaration(d) && isDeprecatedDeclaration(d)) {
|
|
295
296
|
addDeprecatedSuggestion(c, getDeprecatedSuggestionNode(node), getDeclarations(symbol), symbol.name);
|
|
296
297
|
return;
|
|
@@ -22,7 +22,7 @@ import { getNonNullableType, getTypeWithFacts, hasTypeFacts } from './checker-fl
|
|
|
22
22
|
import { sliceTupleType } from './checker-signatures.js';
|
|
23
23
|
import { getPropertyNameFromType, isTypeUsableAsPropertyName, maybeTypeOfKind } from './checker-utilities.js';
|
|
24
24
|
import { checkPropertyAccessibility } from './checker-property-access.js';
|
|
25
|
-
import { copyDeclarations,
|
|
25
|
+
import { copyDeclarations, declarationAt, declarationCount, getSymbolId, } from './symbol.js';
|
|
26
26
|
function isBindingPatternNode(node) {
|
|
27
27
|
return (node !== undefined &&
|
|
28
28
|
(node.kind === 207 /* SyntaxKind.ObjectBindingPattern */ || node.kind === 208 /* SyntaxKind.ArrayBindingPattern */));
|
|
@@ -548,7 +548,8 @@ export function isSpreadableProperty(prop) {
|
|
|
548
548
|
const notMethodOrAccessor = (prop.flags & (8192 /* SymbolFlags.Method */ | 32768 /* SymbolFlags.GetAccessor */ | 65536 /* SymbolFlags.SetAccessor */)) === 0;
|
|
549
549
|
let hasPrivateName = false;
|
|
550
550
|
let inClass = false;
|
|
551
|
-
for (
|
|
551
|
+
for (let i = 0; i < declarationCount(prop); i++) {
|
|
552
|
+
const d = declarationAt(prop, i);
|
|
552
553
|
if (isPrivateIdentifierClassElementDeclaration(d))
|
|
553
554
|
hasPrivateName = true;
|
|
554
555
|
if (d.parent !== undefined && isClassLike(d.parent))
|
|
@@ -26,7 +26,7 @@ import { getTypeForBindingElement, getTypeFromBindingPattern } from './checker-d
|
|
|
26
26
|
import { checkRightHandSideOfForOf } from './checker-statements.js';
|
|
27
27
|
import { getTypeWithFacts, hasTypeFacts, getNonNullableType } from './checker-flow.js';
|
|
28
28
|
import { getTypeOfModuleExportsSymbol, getWidenedTypeForAssignmentDeclaration } from './checker-javascript.js';
|
|
29
|
-
import { copyDeclarations, getDeclarations, getSymbolId } from './symbol.js';
|
|
29
|
+
import { copyDeclarations, declarationAt, declarationCount, getDeclarations, getSymbolId, } from './symbol.js';
|
|
30
30
|
export function getTypeOfSymbol(c, symbol) {
|
|
31
31
|
const checkFlags = symbol.checkFlags;
|
|
32
32
|
if ((checkFlags & 65536 /* CheckFlags.DeferredType */) !== 0)
|
|
@@ -748,11 +748,11 @@ export function isReadonlySymbol(c, symbol) {
|
|
|
748
748
|
(getDeclarationNodeFlagsFromSymbol(symbol) & 6 /* NodeFlags.Constant */) !== 0) ||
|
|
749
749
|
((symbol.flags & 98304 /* SymbolFlags.Accessor */) !== 0 && (symbol.flags & 65536 /* SymbolFlags.SetAccessor */) === 0) ||
|
|
750
750
|
(symbol.flags & 8 /* SymbolFlags.EnumMember */) !== 0 ||
|
|
751
|
-
someReadonlyAssignmentDeclaration(c,
|
|
751
|
+
someReadonlyAssignmentDeclaration(c, symbol));
|
|
752
752
|
}
|
|
753
|
-
function someReadonlyAssignmentDeclaration(c,
|
|
754
|
-
for (
|
|
755
|
-
if (isReadonlyAssignmentDeclaration(c,
|
|
753
|
+
function someReadonlyAssignmentDeclaration(c, symbol) {
|
|
754
|
+
for (let i = 0; i < declarationCount(symbol); i++)
|
|
755
|
+
if (isReadonlyAssignmentDeclaration(c, declarationAt(symbol, i)))
|
|
756
756
|
return true;
|
|
757
757
|
return false;
|
|
758
758
|
}
|
|
@@ -1459,9 +1459,11 @@ export function symbolIsValue(c, symbol) {
|
|
|
1459
1459
|
function isDeclarationContainedBy(symbol, container) {
|
|
1460
1460
|
const declaration = symbol.valueDeclaration;
|
|
1461
1461
|
if (declaration !== undefined)
|
|
1462
|
-
for (
|
|
1462
|
+
for (let i = 0; i < declarationCount(container); i++) {
|
|
1463
|
+
const d = declarationAt(container, i);
|
|
1463
1464
|
if (declaration.pos >= d.pos && declaration.end <= d.end)
|
|
1464
1465
|
return true;
|
|
1466
|
+
}
|
|
1465
1467
|
return false;
|
|
1466
1468
|
}
|
|
1467
1469
|
/** Value members other than signatures and index signatures, declared ones first, each part ordered by declaration. */
|
|
@@ -135,6 +135,8 @@ export declare class Parser extends ScannerErrorReporter {
|
|
|
135
135
|
reparseList: Node[];
|
|
136
136
|
private readonly reparseLists;
|
|
137
137
|
private reparseDepth;
|
|
138
|
+
private readonly listScratch;
|
|
139
|
+
private listDepth;
|
|
138
140
|
reparsedClones: Node[];
|
|
139
141
|
/** Nodes with eagerly parsed JSDoc, for rewinding. */
|
|
140
142
|
jsDocInfos: Node[];
|
|
@@ -209,6 +211,11 @@ export declare class Parser extends ScannerErrorReporter {
|
|
|
209
211
|
parseList(kind: ParsingContext, element: ListElement): NodeList;
|
|
210
212
|
/** The list, or undefined if an element parser returned undefined. */
|
|
211
213
|
parseDelimitedList(kind: ParsingContext, element: ListElement): NodeList | undefined;
|
|
214
|
+
/** The scratch array for a list at the next nesting depth, empty. */
|
|
215
|
+
private openList;
|
|
216
|
+
/** The elements collected in `list` (the scratch array from `openList`) as an array of their exact
|
|
217
|
+
* length, or the shared empty array; empties the scratch array for the next list at its depth. */
|
|
218
|
+
private closeList;
|
|
212
219
|
/** The list; a missing list if `opening` is absent; undefined if an element parser returned undefined. */
|
|
213
220
|
parseBracketedList(kind: ParsingContext, element: ListElement, opening: SyntaxKind, closing: SyntaxKind): NodeList | undefined;
|
|
214
221
|
parseEmptyNodeList(): NodeList;
|
|
@@ -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
|
}
|
|
@@ -3175,14 +3200,14 @@ export class Parser extends ScannerErrorReporter {
|
|
|
3175
3200
|
}
|
|
3176
3201
|
parseTemplateTypeSpans() {
|
|
3177
3202
|
const pos = this.nodePos();
|
|
3178
|
-
const list =
|
|
3203
|
+
const list = this.openList();
|
|
3179
3204
|
for (;;) {
|
|
3180
3205
|
const span = this.parseTemplateTypeSpan();
|
|
3181
3206
|
list.push(span);
|
|
3182
3207
|
if (span.literal.kind !== 16 /* SyntaxKind.TemplateMiddle */)
|
|
3183
3208
|
break;
|
|
3184
3209
|
}
|
|
3185
|
-
return this.newNodeList(pos, this.nodePos(), list);
|
|
3210
|
+
return this.newNodeList(pos, this.nodePos(), this.closeList(list));
|
|
3186
3211
|
}
|
|
3187
3212
|
parseTemplateTypeSpan() {
|
|
3188
3213
|
const pos = this.nodePos();
|
|
@@ -3282,12 +3307,10 @@ export class Parser extends ScannerErrorReporter {
|
|
|
3282
3307
|
let hasTrailingModifier = false;
|
|
3283
3308
|
let hasStaticModifier = false;
|
|
3284
3309
|
const pos = this.nodePos();
|
|
3285
|
-
|
|
3310
|
+
const list = this.openList();
|
|
3286
3311
|
for (;;) {
|
|
3287
3312
|
if (allowDecorators && this.token() === 59 /* SyntaxKind.AtToken */ && !hasTrailingModifier) {
|
|
3288
3313
|
const decorator = this.parseDecorator();
|
|
3289
|
-
if (list === undefined)
|
|
3290
|
-
list = [];
|
|
3291
3314
|
list.push(decorator);
|
|
3292
3315
|
if (hasLeadingModifier)
|
|
3293
3316
|
hasTrailingDecorator = true;
|
|
@@ -3298,8 +3321,6 @@ export class Parser extends ScannerErrorReporter {
|
|
|
3298
3321
|
break;
|
|
3299
3322
|
if (modifier.kind === 125 /* SyntaxKind.StaticKeyword */)
|
|
3300
3323
|
hasStaticModifier = true;
|
|
3301
|
-
if (list === undefined)
|
|
3302
|
-
list = [];
|
|
3303
3324
|
list.push(modifier);
|
|
3304
3325
|
if (hasTrailingDecorator)
|
|
3305
3326
|
hasTrailingModifier = true;
|
|
@@ -3307,7 +3328,8 @@ export class Parser extends ScannerErrorReporter {
|
|
|
3307
3328
|
hasLeadingModifier = true;
|
|
3308
3329
|
}
|
|
3309
3330
|
}
|
|
3310
|
-
|
|
3331
|
+
const nodes = this.closeList(list);
|
|
3332
|
+
return nodes.length === 0 ? undefined : this.newModifierList(pos, this.nodePos(), nodes);
|
|
3311
3333
|
}
|
|
3312
3334
|
parseDecorator() {
|
|
3313
3335
|
const pos = this.nodePos();
|
|
@@ -3941,7 +3963,7 @@ export class Parser extends ScannerErrorReporter {
|
|
|
3941
3963
|
const pos = this.nodePos();
|
|
3942
3964
|
const saveParsingContexts = this.parsingContexts;
|
|
3943
3965
|
this.parsingContexts |= 1 << 14 /* ParsingContext.JsxChildren */;
|
|
3944
|
-
const list =
|
|
3966
|
+
const list = this.openList();
|
|
3945
3967
|
for (;;) {
|
|
3946
3968
|
// Like tsgo, this leaves the parser's current token unchanged.
|
|
3947
3969
|
const currentToken = this.scanner.reScanJsxToken(true);
|
|
@@ -3957,7 +3979,7 @@ export class Parser extends ScannerErrorReporter {
|
|
|
3957
3979
|
break;
|
|
3958
3980
|
}
|
|
3959
3981
|
this.parsingContexts = saveParsingContexts;
|
|
3960
|
-
return this.newNodeList(pos, this.nodePos(), list);
|
|
3982
|
+
return this.newNodeList(pos, this.nodePos(), this.closeList(list));
|
|
3961
3983
|
}
|
|
3962
3984
|
parseJsxChild(openingTag, token) {
|
|
3963
3985
|
switch (token) {
|
|
@@ -4519,14 +4541,14 @@ export class Parser extends ScannerErrorReporter {
|
|
|
4519
4541
|
}
|
|
4520
4542
|
parseTemplateSpans(isTaggedTemplate) {
|
|
4521
4543
|
const pos = this.nodePos();
|
|
4522
|
-
const list =
|
|
4544
|
+
const list = this.openList();
|
|
4523
4545
|
for (;;) {
|
|
4524
4546
|
const span = this.parseTemplateSpan(isTaggedTemplate);
|
|
4525
4547
|
list.push(span);
|
|
4526
4548
|
if (span.literal.kind !== 16 /* SyntaxKind.TemplateMiddle */)
|
|
4527
4549
|
break;
|
|
4528
4550
|
}
|
|
4529
|
-
return this.newNodeList(pos, this.nodePos(), list);
|
|
4551
|
+
return this.newNodeList(pos, this.nodePos(), this.closeList(list));
|
|
4530
4552
|
}
|
|
4531
4553
|
parseTemplateSpan(isTaggedTemplate) {
|
|
4532
4554
|
const pos = this.nodePos();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tsc-ts",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
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.8",
|
|
39
|
+
"@tsc-ts/darwin-x64": "0.0.8",
|
|
40
|
+
"@tsc-ts/linux-arm64-gnu": "0.0.8",
|
|
41
|
+
"@tsc-ts/linux-arm64-musl": "0.0.8",
|
|
42
|
+
"@tsc-ts/linux-x64-gnu": "0.0.8",
|
|
43
|
+
"@tsc-ts/linux-x64-musl": "0.0.8",
|
|
44
|
+
"@tsc-ts/win32-x64-msvc": "0.0.8"
|
|
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
|
}
|
|
@@ -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
|
|
|
@@ -1761,7 +1761,10 @@ export function symbolIsValue(c: Checker, symbol: Symbol): boolean {
|
|
|
1761
1761
|
function isDeclarationContainedBy(symbol: Symbol, container: Symbol): boolean {
|
|
1762
1762
|
const declaration = symbol.valueDeclaration;
|
|
1763
1763
|
if (declaration !== undefined)
|
|
1764
|
-
for (
|
|
1764
|
+
for (let i = 0; i < declarationCount(container); i++) {
|
|
1765
|
+
const d = declarationAt(container, i);
|
|
1766
|
+
if (declaration.pos >= d.pos && declaration.end <= d.end) return true;
|
|
1767
|
+
}
|
|
1765
1768
|
return false;
|
|
1766
1769
|
}
|
|
1767
1770
|
|
package/src/compiler/parser.ts
CHANGED
|
@@ -503,6 +503,10 @@ export class Parser extends ScannerErrorReporter {
|
|
|
503
503
|
// receives reparsed nodes, and a fresh array per parsed list would be one more allocation each.
|
|
504
504
|
private readonly reparseLists: Node[][];
|
|
505
505
|
private reparseDepth: number;
|
|
506
|
+
// One scratch array per nesting depth of the lists being parsed. A list collects its elements in
|
|
507
|
+
// its depth's array and is copied out at its exact length, so the tree keeps no spare capacity.
|
|
508
|
+
private readonly listScratch: Node[][];
|
|
509
|
+
private listDepth: number;
|
|
506
510
|
reparsedClones: Node[];
|
|
507
511
|
/** Nodes with eagerly parsed JSDoc, for rewinding. */
|
|
508
512
|
jsDocInfos: Node[];
|
|
@@ -562,6 +566,8 @@ export class Parser extends ScannerErrorReporter {
|
|
|
562
566
|
this.reparseList = [];
|
|
563
567
|
this.reparseLists = [this.reparseList];
|
|
564
568
|
this.reparseDepth = 0;
|
|
569
|
+
this.listScratch = [];
|
|
570
|
+
this.listDepth = -1;
|
|
565
571
|
this.reparsedClones = [];
|
|
566
572
|
this.jsDocInfos = [];
|
|
567
573
|
this.jsDocTable = undefined;
|
|
@@ -1024,7 +1030,7 @@ export class Parser extends ScannerErrorReporter {
|
|
|
1024
1030
|
if (depth === this.reparseLists.length) this.reparseLists.push([]);
|
|
1025
1031
|
const reparseList = this.reparseLists[depth]!;
|
|
1026
1032
|
this.reparseList = reparseList;
|
|
1027
|
-
const list
|
|
1033
|
+
const list = this.openList();
|
|
1028
1034
|
while (!this.isListTerminator(kind)) {
|
|
1029
1035
|
if (this.isListElement(kind, false)) {
|
|
1030
1036
|
const elt = this.parseListElement(element, list.length);
|
|
@@ -1049,7 +1055,7 @@ export class Parser extends ScannerErrorReporter {
|
|
|
1049
1055
|
this.reparseDepth = depth - 1;
|
|
1050
1056
|
this.reparseList = outerReparseList;
|
|
1051
1057
|
this.parsingContexts = saveParsingContexts;
|
|
1052
|
-
return list;
|
|
1058
|
+
return this.closeList(list);
|
|
1053
1059
|
}
|
|
1054
1060
|
|
|
1055
1061
|
parseList(kind: ParsingContext, element: ListElement): NodeList {
|
|
@@ -1063,12 +1069,13 @@ export class Parser extends ScannerErrorReporter {
|
|
|
1063
1069
|
const pos = this.nodePos();
|
|
1064
1070
|
const saveParsingContexts = this.parsingContexts;
|
|
1065
1071
|
this.parsingContexts |= 1 << kind;
|
|
1066
|
-
const list
|
|
1072
|
+
const list = this.openList();
|
|
1067
1073
|
for (;;) {
|
|
1068
1074
|
if (this.isListElement(kind, false)) {
|
|
1069
1075
|
const startPos = this.nodePos();
|
|
1070
1076
|
const result = this.parseListElement(element, list.length);
|
|
1071
1077
|
if (result === this.noElement) {
|
|
1078
|
+
this.closeList(list);
|
|
1072
1079
|
this.parsingContexts = saveParsingContexts;
|
|
1073
1080
|
return undefined;
|
|
1074
1081
|
}
|
|
@@ -1094,7 +1101,24 @@ export class Parser extends ScannerErrorReporter {
|
|
|
1094
1101
|
if (this.abortParsingListOrMoveToNextToken(kind)) break;
|
|
1095
1102
|
}
|
|
1096
1103
|
this.parsingContexts = saveParsingContexts;
|
|
1097
|
-
return this.newNodeList(pos, this.nodePos(), list);
|
|
1104
|
+
return this.newNodeList(pos, this.nodePos(), this.closeList(list));
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
/** The scratch array for a list at the next nesting depth, empty. */
|
|
1108
|
+
private openList(): Node[] {
|
|
1109
|
+
const depth = ++this.listDepth;
|
|
1110
|
+
if (depth === this.listScratch.length) this.listScratch.push([]);
|
|
1111
|
+
return this.listScratch[depth]!;
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
/** The elements collected in `list` (the scratch array from `openList`) as an array of their exact
|
|
1115
|
+
* length, or the shared empty array; empties the scratch array for the next list at its depth. */
|
|
1116
|
+
private closeList(list: Node[]): Node[] {
|
|
1117
|
+
this.listDepth--;
|
|
1118
|
+
if (list.length === 0) return emptyListNodes;
|
|
1119
|
+
const nodes = list.slice();
|
|
1120
|
+
list.length = 0;
|
|
1121
|
+
return nodes;
|
|
1098
1122
|
}
|
|
1099
1123
|
|
|
1100
1124
|
/** The list; a missing list if `opening` is absent; undefined if an element parser returned undefined. */
|
|
@@ -3123,9 +3147,10 @@ export class Parser extends ScannerErrorReporter {
|
|
|
3123
3147
|
? this.parseFunctionOrConstructorTypeToError(isUnionType)
|
|
3124
3148
|
: this.parseConstituentType(isUnionType);
|
|
3125
3149
|
if (this.token() === operator || hasLeadingOperator) {
|
|
3126
|
-
const types
|
|
3150
|
+
const types = this.openList();
|
|
3151
|
+
types.push(type);
|
|
3127
3152
|
while (this.parseOptional(operator)) types.push(this.parseFunctionOrConstructorTypeToError(isUnionType));
|
|
3128
|
-
const list = this.newNodeList(pos, this.nodePos(), types);
|
|
3153
|
+
const list = this.newNodeList(pos, this.nodePos(), this.closeList(types));
|
|
3129
3154
|
type = isUnionType ? new UnionTypeNode(list) : new IntersectionTypeNode(list);
|
|
3130
3155
|
this.finishNode(type, pos);
|
|
3131
3156
|
}
|
|
@@ -4059,13 +4084,13 @@ export class Parser extends ScannerErrorReporter {
|
|
|
4059
4084
|
|
|
4060
4085
|
parseTemplateTypeSpans(): NodeList {
|
|
4061
4086
|
const pos = this.nodePos();
|
|
4062
|
-
const list
|
|
4087
|
+
const list = this.openList();
|
|
4063
4088
|
for (;;) {
|
|
4064
4089
|
const span = this.parseTemplateTypeSpan();
|
|
4065
4090
|
list.push(span);
|
|
4066
4091
|
if (span.literal.kind !== SyntaxKind.TemplateMiddle) break;
|
|
4067
4092
|
}
|
|
4068
|
-
return this.newNodeList(pos, this.nodePos(), list);
|
|
4093
|
+
return this.newNodeList(pos, this.nodePos(), this.closeList(list));
|
|
4069
4094
|
}
|
|
4070
4095
|
|
|
4071
4096
|
parseTemplateTypeSpan(): TemplateLiteralTypeSpan {
|
|
@@ -4189,24 +4214,23 @@ export class Parser extends ScannerErrorReporter {
|
|
|
4189
4214
|
let hasTrailingModifier = false;
|
|
4190
4215
|
let hasStaticModifier = false;
|
|
4191
4216
|
const pos = this.nodePos();
|
|
4192
|
-
|
|
4217
|
+
const list = this.openList();
|
|
4193
4218
|
for (;;) {
|
|
4194
4219
|
if (allowDecorators && this.token() === SyntaxKind.AtToken && !hasTrailingModifier) {
|
|
4195
4220
|
const decorator = this.parseDecorator();
|
|
4196
|
-
if (list === undefined) list = [];
|
|
4197
4221
|
list.push(decorator);
|
|
4198
4222
|
if (hasLeadingModifier) hasTrailingDecorator = true;
|
|
4199
4223
|
} else {
|
|
4200
4224
|
const modifier = this.tryParseModifier(hasStaticModifier, permitConstAsModifier, stopOnStartOfClassStaticBlock);
|
|
4201
4225
|
if (modifier === undefined) break;
|
|
4202
4226
|
if (modifier.kind === SyntaxKind.StaticKeyword) hasStaticModifier = true;
|
|
4203
|
-
if (list === undefined) list = [];
|
|
4204
4227
|
list.push(modifier);
|
|
4205
4228
|
if (hasTrailingDecorator) hasTrailingModifier = true;
|
|
4206
4229
|
else hasLeadingModifier = true;
|
|
4207
4230
|
}
|
|
4208
4231
|
}
|
|
4209
|
-
|
|
4232
|
+
const nodes = this.closeList(list);
|
|
4233
|
+
return nodes.length === 0 ? undefined : this.newModifierList(pos, this.nodePos(), nodes);
|
|
4210
4234
|
}
|
|
4211
4235
|
|
|
4212
4236
|
parseDecorator(): Node {
|
|
@@ -4938,7 +4962,7 @@ export class Parser extends ScannerErrorReporter {
|
|
|
4938
4962
|
const pos = this.nodePos();
|
|
4939
4963
|
const saveParsingContexts = this.parsingContexts;
|
|
4940
4964
|
this.parsingContexts |= 1 << ParsingContext.JsxChildren;
|
|
4941
|
-
const list
|
|
4965
|
+
const list = this.openList();
|
|
4942
4966
|
for (;;) {
|
|
4943
4967
|
// Like tsgo, this leaves the parser's current token unchanged.
|
|
4944
4968
|
const currentToken = this.scanner.reScanJsxToken(true);
|
|
@@ -4958,7 +4982,7 @@ export class Parser extends ScannerErrorReporter {
|
|
|
4958
4982
|
break;
|
|
4959
4983
|
}
|
|
4960
4984
|
this.parsingContexts = saveParsingContexts;
|
|
4961
|
-
return this.newNodeList(pos, this.nodePos(), list);
|
|
4985
|
+
return this.newNodeList(pos, this.nodePos(), this.closeList(list));
|
|
4962
4986
|
}
|
|
4963
4987
|
|
|
4964
4988
|
parseJsxChild(openingTag: Node, token: SyntaxKind): Expression | undefined {
|
|
@@ -5633,13 +5657,13 @@ export class Parser extends ScannerErrorReporter {
|
|
|
5633
5657
|
|
|
5634
5658
|
parseTemplateSpans(isTaggedTemplate: boolean): NodeList {
|
|
5635
5659
|
const pos = this.nodePos();
|
|
5636
|
-
const list
|
|
5660
|
+
const list = this.openList();
|
|
5637
5661
|
for (;;) {
|
|
5638
5662
|
const span = this.parseTemplateSpan(isTaggedTemplate);
|
|
5639
5663
|
list.push(span);
|
|
5640
5664
|
if (span.literal.kind !== SyntaxKind.TemplateMiddle) break;
|
|
5641
5665
|
}
|
|
5642
|
-
return this.newNodeList(pos, this.nodePos(), list);
|
|
5666
|
+
return this.newNodeList(pos, this.nodePos(), this.closeList(list));
|
|
5643
5667
|
}
|
|
5644
5668
|
|
|
5645
5669
|
parseTemplateSpan(isTaggedTemplate: boolean): TemplateSpan {
|