@systemfsoftware/stryker-js-instrumenter 7.0.0 → 8.0.0
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/CHANGELOG.md +16 -0
- package/dist/index.d.mts +196 -22
- package/dist/index.mjs +2100 -1894
- package/package.json +4 -5
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { INSTRUMENTER_CONSTANTS, Mutant } from "@systemfsoftware/stryker-js-language";
|
|
2
1
|
import * as Effect from "effect/Effect";
|
|
3
2
|
import * as Predicate from "effect/Predicate";
|
|
4
3
|
import * as S from "effect/Schema";
|
|
@@ -8,6 +7,59 @@ import * as Option from "effect/Option";
|
|
|
8
7
|
import { walk } from "oxc-walker";
|
|
9
8
|
import { Schema } from "effect";
|
|
10
9
|
import { RegExpParser, visitRegExpAST } from "@eslint-community/regexpp";
|
|
10
|
+
//#region src/Location.schema.ts
|
|
11
|
+
const PositionSchema = S.Struct({
|
|
12
|
+
line: S.Finite,
|
|
13
|
+
column: S.Finite
|
|
14
|
+
});
|
|
15
|
+
const LocationSchema = S.Struct({
|
|
16
|
+
start: PositionSchema,
|
|
17
|
+
end: PositionSchema
|
|
18
|
+
});
|
|
19
|
+
const OpenEndLocationSchema = S.Struct({
|
|
20
|
+
start: PositionSchema,
|
|
21
|
+
end: S.optional(PositionSchema)
|
|
22
|
+
});
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/Mutant.schema.ts
|
|
25
|
+
const MutantStatusSchema = S.Literals([
|
|
26
|
+
"Killed",
|
|
27
|
+
"Survived",
|
|
28
|
+
"NoCoverage",
|
|
29
|
+
"CompileError",
|
|
30
|
+
"RuntimeError",
|
|
31
|
+
"Timeout",
|
|
32
|
+
"Ignored",
|
|
33
|
+
"Pending"
|
|
34
|
+
]);
|
|
35
|
+
var Mutant = class extends S.TaggedClass()("Mutant", {
|
|
36
|
+
id: S.NonEmptyString,
|
|
37
|
+
fileName: S.NonEmptyString,
|
|
38
|
+
mutatorName: S.NonEmptyString,
|
|
39
|
+
replacement: S.String,
|
|
40
|
+
location: LocationSchema,
|
|
41
|
+
status: S.optional(MutantStatusSchema),
|
|
42
|
+
statusReason: S.optional(S.String),
|
|
43
|
+
coveredBy: S.optional(S.Array(S.String)),
|
|
44
|
+
static: S.optional(S.Boolean),
|
|
45
|
+
testsCompleted: S.optional(S.Finite),
|
|
46
|
+
description: S.optional(S.String)
|
|
47
|
+
}) {};
|
|
48
|
+
const RunOptionsFields = {
|
|
49
|
+
timeout: S.Finite,
|
|
50
|
+
disableBail: S.Boolean
|
|
51
|
+
};
|
|
52
|
+
const MutantActivationSchema = S.Literals(["runtime", "static"]);
|
|
53
|
+
const MutantRunOptionsSchema = S.Struct({
|
|
54
|
+
...RunOptionsFields,
|
|
55
|
+
activeMutant: Mutant,
|
|
56
|
+
sandboxFileName: S.String,
|
|
57
|
+
mutantActivation: MutantActivationSchema,
|
|
58
|
+
reloadEnvironment: S.Boolean,
|
|
59
|
+
testFilter: S.optionalKey(S.Array(S.String)),
|
|
60
|
+
hitLimit: S.optionalKey(S.Finite)
|
|
61
|
+
});
|
|
62
|
+
//#endregion
|
|
11
63
|
//#region src/Instrument.schema.ts
|
|
12
64
|
var InstrumentError = class extends S.TaggedError("@systemfsoftware/stryker-js-instrumenter/Instrument.schema/InstrumentError")("InstrumentError", {
|
|
13
65
|
message: S.String,
|
|
@@ -18,13 +70,13 @@ var InstrumentError = class extends S.TaggedError("@systemfsoftware/stryker-js-i
|
|
|
18
70
|
return this.message;
|
|
19
71
|
}
|
|
20
72
|
};
|
|
21
|
-
const PositionSchema = S.Struct({
|
|
73
|
+
const PositionSchema$1 = S.Struct({
|
|
22
74
|
line: S.Finite,
|
|
23
75
|
column: S.Finite
|
|
24
76
|
});
|
|
25
77
|
const RangeSchema = S.Struct({
|
|
26
|
-
start: PositionSchema,
|
|
27
|
-
end: PositionSchema
|
|
78
|
+
start: PositionSchema$1,
|
|
79
|
+
end: PositionSchema$1
|
|
28
80
|
});
|
|
29
81
|
const MutateDescriptionSchema = S.Union([S.Boolean, S.Array(RangeSchema)]);
|
|
30
82
|
const FileSchema = S.Struct({
|
|
@@ -33,7 +85,7 @@ const FileSchema = S.Struct({
|
|
|
33
85
|
mutate: MutateDescriptionSchema
|
|
34
86
|
});
|
|
35
87
|
const IgnorerSchema = S.Unknown;
|
|
36
|
-
S.Struct({
|
|
88
|
+
const InstrumenterOptionsSchema = S.Struct({
|
|
37
89
|
excludedMutations: S.Array(S.String),
|
|
38
90
|
ignorers: S.Array(IgnorerSchema),
|
|
39
91
|
noHeader: S.optional(S.Boolean)
|
|
@@ -52,6 +104,9 @@ S.Literals([
|
|
|
52
104
|
//#endregion
|
|
53
105
|
//#region src/Syntax.ts
|
|
54
106
|
/**
|
|
107
|
+
* Syntax — the instrumenter's AST shapes, location helpers and syntax utilities.
|
|
108
|
+
*/
|
|
109
|
+
/**
|
|
55
110
|
* Determines if a location (needle) is included in an other location (haystack)
|
|
56
111
|
* @param haystack The range to look in
|
|
57
112
|
* @param needle the range to search for
|
|
@@ -264,7 +319,7 @@ function memberExpression(object, property, optional, loc) {
|
|
|
264
319
|
}, loc);
|
|
265
320
|
}
|
|
266
321
|
function arrowFunctionExpression(params, body, loc) {
|
|
267
|
-
const fnBody = body;
|
|
322
|
+
const fnBody = arrowFunctionBody(body);
|
|
268
323
|
return mark({
|
|
269
324
|
type: "ArrowFunctionExpression",
|
|
270
325
|
id: null,
|
|
@@ -275,6 +330,16 @@ function arrowFunctionExpression(params, body, loc) {
|
|
|
275
330
|
expression: fnBody.type !== "BlockStatement"
|
|
276
331
|
}, loc);
|
|
277
332
|
}
|
|
333
|
+
function arrowFunctionBody(body) {
|
|
334
|
+
if (isArrowBody(body)) return body;
|
|
335
|
+
throw new Error(`Invalid arrow function body: ${body.type}`);
|
|
336
|
+
}
|
|
337
|
+
function isArrowBody(body) {
|
|
338
|
+
return isBlockStatementNode(body) || isExpressionKind(body);
|
|
339
|
+
}
|
|
340
|
+
function isBlockStatementNode(node) {
|
|
341
|
+
return nodeType(node) === "BlockStatement";
|
|
342
|
+
}
|
|
278
343
|
function blockStatement(body, loc) {
|
|
279
344
|
return mark({
|
|
280
345
|
type: "BlockStatement",
|
|
@@ -426,9 +491,13 @@ function pushComment(map, node, comment) {
|
|
|
426
491
|
else list.push(comment);
|
|
427
492
|
}
|
|
428
493
|
const isNodeList = (value) => Array.isArray(value);
|
|
494
|
+
const walkableNode = (node) => {
|
|
495
|
+
if (isAstNode(node)) return node;
|
|
496
|
+
throw new Error("Expected an AST node to walk");
|
|
497
|
+
};
|
|
429
498
|
const walker = (root, visitors) => {
|
|
430
499
|
const ancestors = [];
|
|
431
|
-
walk(root, {
|
|
500
|
+
walk(walkableNode(root), {
|
|
432
501
|
enter(node) {
|
|
433
502
|
visitors.enter?.(node, [...ancestors]);
|
|
434
503
|
ancestors.push(node);
|
|
@@ -475,7 +544,7 @@ function isCommentKey(key) {
|
|
|
475
544
|
function traverse(root, visitors) {
|
|
476
545
|
const stack = [];
|
|
477
546
|
try {
|
|
478
|
-
walk(root, {
|
|
547
|
+
walk(walkableNode(root), {
|
|
479
548
|
enter(node, _parent, context) {
|
|
480
549
|
readPath(stack, node, this, context, visitors);
|
|
481
550
|
},
|
|
@@ -508,8 +577,11 @@ function notify(visitor, path) {
|
|
|
508
577
|
const relay = (visitor, path) => {
|
|
509
578
|
if (path !== void 0) visitor(path);
|
|
510
579
|
};
|
|
580
|
+
const keyOf = (context) => {
|
|
581
|
+
if (typeof context.key === "string") return context.key;
|
|
582
|
+
};
|
|
511
583
|
function createPath(node, parentPath, controls, context) {
|
|
512
|
-
const key =
|
|
584
|
+
const key = keyOf(context);
|
|
513
585
|
const path = {
|
|
514
586
|
node,
|
|
515
587
|
parentPath,
|
|
@@ -649,7 +721,7 @@ function hasContent(value) {
|
|
|
649
721
|
function hasHtml(value) {
|
|
650
722
|
return hasField(value, "html");
|
|
651
723
|
}
|
|
652
|
-
function fieldOf(value, key) {
|
|
724
|
+
function fieldOf$1(value, key) {
|
|
653
725
|
return Match.value(value).pipe(Match.when(isPlainRecord, (record) => record[key]), Match.orElse(() => void 0));
|
|
654
726
|
}
|
|
655
727
|
function appendIfDefined(values, value) {
|
|
@@ -733,7 +805,8 @@ const dotBeforeSlash = (dot, slash) => dot >= 0 && dot > slash;
|
|
|
733
805
|
const extensionOf = (fileName) => {
|
|
734
806
|
const dot = fileName.lastIndexOf(".");
|
|
735
807
|
const slash = Math.max(fileName.lastIndexOf("/"), fileName.lastIndexOf("\\"));
|
|
736
|
-
|
|
808
|
+
if (!dotBeforeSlash(dot, slash)) return "";
|
|
809
|
+
return fileName.slice(dot).toLowerCase();
|
|
737
810
|
};
|
|
738
811
|
function createJSParser() {
|
|
739
812
|
return (text, fileName) => Effect.map(parseWithOxc(text, fileName, "js"), ({ root, comments }) => ({
|
|
@@ -1040,7 +1113,7 @@ function htmlRootOf(ast) {
|
|
|
1040
1113
|
}));
|
|
1041
1114
|
}
|
|
1042
1115
|
function instanceScriptRange(ast) {
|
|
1043
|
-
return Match.value(fieldOf(ast, "instance")).pipe(Match.when(hasContent, (instance) => scriptContentRange(instance["content"], INSTANCE_RANGE_MISSING)), Match.orElse(() => void 0));
|
|
1116
|
+
return Match.value(fieldOf$1(ast, "instance")).pipe(Match.when(hasContent, (instance) => scriptContentRange(instance["content"], INSTANCE_RANGE_MISSING)), Match.orElse(() => void 0));
|
|
1044
1117
|
}
|
|
1045
1118
|
function scriptContentRange(content, missingRange) {
|
|
1046
1119
|
return Match.value(content).pipe(Match.when(isRange, (range) => ({
|
|
@@ -1052,7 +1125,7 @@ function scriptContentRange(content, missingRange) {
|
|
|
1052
1125
|
}));
|
|
1053
1126
|
}
|
|
1054
1127
|
function getModuleScriptRange(svelteAst) {
|
|
1055
|
-
return Match.value(fieldOf(svelteAst, "module")).pipe(Match.when(void 0, () => void 0), Match.when(null, () => void 0), Match.orElse((block) => moduleBlockRange(block)));
|
|
1128
|
+
return Match.value(fieldOf$1(svelteAst, "module")).pipe(Match.when(void 0, () => void 0), Match.when(null, () => void 0), Match.orElse((block) => moduleBlockRange(block)));
|
|
1056
1129
|
}
|
|
1057
1130
|
function moduleBlockRange(block) {
|
|
1058
1131
|
return Match.value(block).pipe(Match.when(hasContent, (record) => scriptContentRange(record["content"], MODULE_RANGE_MISSING)), Match.orElse(() => {
|
|
@@ -1110,10 +1183,10 @@ function scriptFormatOf(script) {
|
|
|
1110
1183
|
//#endregion
|
|
1111
1184
|
//#region src/print/index.ts
|
|
1112
1185
|
function printProgram(program, opts = {}) {
|
|
1113
|
-
return
|
|
1186
|
+
return renderProgram(createState(opts), program);
|
|
1114
1187
|
}
|
|
1115
1188
|
function printNode(node, opts = {}) {
|
|
1116
|
-
return
|
|
1189
|
+
return renderAnyNode(createState(opts), node);
|
|
1117
1190
|
}
|
|
1118
1191
|
const PREC = {
|
|
1119
1192
|
Sequence: 0,
|
|
@@ -1175,1740 +1248,1728 @@ const LOGICAL_PRECEDENCE = {
|
|
|
1175
1248
|
function logicalPrec(op) {
|
|
1176
1249
|
return LOGICAL_PRECEDENCE[op] ?? PREC.LogicalAND;
|
|
1177
1250
|
}
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
}
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
}
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1251
|
+
function createState(opts) {
|
|
1252
|
+
const hashbang = opts.hashbang ?? null;
|
|
1253
|
+
return {
|
|
1254
|
+
out: "",
|
|
1255
|
+
indentLevel: 0,
|
|
1256
|
+
hashbang,
|
|
1257
|
+
commentIdx: 0,
|
|
1258
|
+
sortedComments: [...sortedCommentsWithoutHashbang(opts.comments, hashbang), END_OF_COMMENTS]
|
|
1259
|
+
};
|
|
1260
|
+
}
|
|
1261
|
+
function renderProgram(state, program) {
|
|
1262
|
+
state.out = "";
|
|
1263
|
+
state.indentLevel = 0;
|
|
1264
|
+
state.commentIdx = 0;
|
|
1265
|
+
printHashbang(state);
|
|
1266
|
+
emitCommentsBefore(state, program.body[0]?.start);
|
|
1267
|
+
printProgramBody(state, program.body);
|
|
1268
|
+
emitCommentsBefore(state, void 0);
|
|
1269
|
+
return state.out;
|
|
1270
|
+
}
|
|
1271
|
+
function renderAnyNode(state, node) {
|
|
1272
|
+
state.out = "";
|
|
1273
|
+
state.indentLevel = 0;
|
|
1274
|
+
printNodePrec(state, node, PREC.Sequence);
|
|
1275
|
+
return state.out;
|
|
1276
|
+
}
|
|
1277
|
+
function printHashbang(state) {
|
|
1278
|
+
if (state.hashbang !== null) state.out += `#!${state.hashbang.value}\n`;
|
|
1279
|
+
}
|
|
1280
|
+
function printProgramBody(state, body) {
|
|
1281
|
+
body.forEach((statement) => printProgramStatement(state, statement));
|
|
1282
|
+
}
|
|
1283
|
+
function printProgramStatement(state, statement) {
|
|
1284
|
+
emitCommentsBefore(state, statement.start ?? -1);
|
|
1285
|
+
printStatement(state, statement);
|
|
1286
|
+
state.out += "\n";
|
|
1287
|
+
}
|
|
1288
|
+
function printJumpStatement(state, keyword, label) {
|
|
1289
|
+
state.out += keyword;
|
|
1290
|
+
if (label !== null) state.out += ` ${label.name}`;
|
|
1291
|
+
state.out += ";";
|
|
1292
|
+
}
|
|
1293
|
+
function emitCommentsBefore(state, pos) {
|
|
1294
|
+
emitPendingCommentsBefore(state, pos ?? EVERY_COMMENT_POSITION);
|
|
1295
|
+
}
|
|
1296
|
+
function emitPendingCommentsBefore(state, pos) {
|
|
1297
|
+
let comment = state.sortedComments[state.commentIdx];
|
|
1298
|
+
while (isCommentBefore(comment, pos)) {
|
|
1299
|
+
emitComment(state, comment);
|
|
1300
|
+
state.commentIdx++;
|
|
1301
|
+
comment = state.sortedComments[state.commentIdx];
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
function isCommentBefore(comment, pos) {
|
|
1305
|
+
return comment !== void 0 && comment.start < pos;
|
|
1306
|
+
}
|
|
1307
|
+
function emitComment(state, c) {
|
|
1308
|
+
if (c.type === "Line") state.out += `//${c.value}\n`;
|
|
1309
|
+
else state.out += `/*${c.value}*/\n`;
|
|
1310
|
+
}
|
|
1311
|
+
function indent(state) {
|
|
1312
|
+
return " ".repeat(state.indentLevel);
|
|
1313
|
+
}
|
|
1314
|
+
function capture(state, render) {
|
|
1315
|
+
const saved = state.out;
|
|
1316
|
+
state.out = "";
|
|
1317
|
+
render();
|
|
1318
|
+
const result = state.out;
|
|
1319
|
+
state.out = saved;
|
|
1320
|
+
return result;
|
|
1321
|
+
}
|
|
1322
|
+
function needsParens(childPrec, parentPrec, isRight, op) {
|
|
1323
|
+
if (childPrec === parentPrec) return equalPrecedenceNeedsParens(isRight, op);
|
|
1324
|
+
return childPrec < parentPrec;
|
|
1325
|
+
}
|
|
1326
|
+
function equalPrecedenceNeedsParens(isRight, op) {
|
|
1327
|
+
if (op === "**") return !isRight;
|
|
1328
|
+
return isRight;
|
|
1329
|
+
}
|
|
1330
|
+
function wrapIfNeeded(state, node, prec, parentPrec, isRight, op) {
|
|
1331
|
+
const inner = printExpressionToString(state, node, prec);
|
|
1332
|
+
if (needsParens(prec, parentPrec, isRight, op)) return `(${inner})`;
|
|
1333
|
+
return inner;
|
|
1334
|
+
}
|
|
1335
|
+
function printExpressionToString(state, node, prec) {
|
|
1336
|
+
return capture(state, () => printNodePrec(state, node, prec));
|
|
1337
|
+
}
|
|
1338
|
+
function sequenceNodeText(state, node) {
|
|
1339
|
+
return capture(state, () => printNodePrec(state, node, PREC.Sequence));
|
|
1340
|
+
}
|
|
1341
|
+
function assignmentNodeText(state, node) {
|
|
1342
|
+
return capture(state, () => printNodePrec(state, node, PREC.Assignment));
|
|
1343
|
+
}
|
|
1344
|
+
function nodeListText(state, nodes, prec) {
|
|
1345
|
+
return nodes.map((node) => capture(state, () => printNodePrec(state, node, prec))).join(", ");
|
|
1346
|
+
}
|
|
1347
|
+
function wrappedExpressionText(state, node, prec, wrappedKinds) {
|
|
1348
|
+
const printed = printExpressionToString(state, node, prec);
|
|
1349
|
+
if (wrappedKinds[node.type] === true) return `(${printed})`;
|
|
1350
|
+
return printed;
|
|
1351
|
+
}
|
|
1352
|
+
function printNodePrec(state, node, prec) {
|
|
1353
|
+
if (node == null) return;
|
|
1354
|
+
dispatchNode(state, node, prec);
|
|
1355
|
+
}
|
|
1356
|
+
function dispatchNode(state, node, prec) {
|
|
1357
|
+
switch (node.type) {
|
|
1358
|
+
case "Literal":
|
|
1359
|
+
printLiteral(state, node);
|
|
1360
|
+
break;
|
|
1361
|
+
case "Identifier":
|
|
1362
|
+
printIdentifier(state, node);
|
|
1363
|
+
break;
|
|
1364
|
+
case "PrivateIdentifier":
|
|
1365
|
+
state.out += `#${node.name}`;
|
|
1366
|
+
break;
|
|
1367
|
+
case "ThisExpression":
|
|
1368
|
+
state.out += "this";
|
|
1369
|
+
break;
|
|
1370
|
+
case "Super":
|
|
1371
|
+
state.out += "super";
|
|
1372
|
+
break;
|
|
1373
|
+
case "ArrayExpression":
|
|
1374
|
+
printArrayExpression(state, node);
|
|
1375
|
+
break;
|
|
1376
|
+
case "ObjectExpression":
|
|
1377
|
+
printObjectExpression(state, node);
|
|
1378
|
+
break;
|
|
1379
|
+
case "Property":
|
|
1380
|
+
printProperty(state, node);
|
|
1381
|
+
break;
|
|
1382
|
+
case "TemplateLiteral":
|
|
1383
|
+
printTemplateLiteral(state, node);
|
|
1384
|
+
break;
|
|
1385
|
+
case "TemplateElement":
|
|
1386
|
+
state.out += node.value.raw;
|
|
1387
|
+
break;
|
|
1388
|
+
case "TaggedTemplateExpression":
|
|
1389
|
+
printTaggedTemplate(state, node);
|
|
1390
|
+
break;
|
|
1391
|
+
case "MemberExpression":
|
|
1392
|
+
printMemberExpression(state, node, prec);
|
|
1393
|
+
break;
|
|
1394
|
+
case "CallExpression":
|
|
1395
|
+
printCallExpression(state, node, prec);
|
|
1396
|
+
break;
|
|
1397
|
+
case "NewExpression":
|
|
1398
|
+
printNewExpression(state, node, prec);
|
|
1399
|
+
break;
|
|
1400
|
+
case "MetaProperty":
|
|
1401
|
+
printMetaProperty(state, node);
|
|
1402
|
+
break;
|
|
1403
|
+
case "SpreadElement":
|
|
1404
|
+
state.out += "...";
|
|
1405
|
+
printNodePrec(state, node.argument, PREC.Assignment);
|
|
1406
|
+
break;
|
|
1407
|
+
case "RestElement":
|
|
1408
|
+
state.out += "...";
|
|
1409
|
+
printNodePrec(state, node.argument, PREC.Assignment);
|
|
1410
|
+
break;
|
|
1411
|
+
case "UpdateExpression":
|
|
1412
|
+
printUpdateExpression(state, node, prec);
|
|
1413
|
+
break;
|
|
1414
|
+
case "UnaryExpression":
|
|
1415
|
+
printUnaryExpression(state, node, prec);
|
|
1416
|
+
break;
|
|
1417
|
+
case "BinaryExpression":
|
|
1418
|
+
printBinaryExpression(state, node, prec);
|
|
1419
|
+
break;
|
|
1420
|
+
case "LogicalExpression":
|
|
1421
|
+
printLogicalExpression(state, node, prec);
|
|
1422
|
+
break;
|
|
1423
|
+
case "ConditionalExpression":
|
|
1424
|
+
printConditionalExpression(state, node, prec);
|
|
1425
|
+
break;
|
|
1426
|
+
case "AssignmentExpression":
|
|
1427
|
+
printAssignmentExpression(state, node, prec);
|
|
1428
|
+
break;
|
|
1429
|
+
case "AssignmentPattern":
|
|
1430
|
+
printAssignmentPattern(state, node, prec);
|
|
1431
|
+
break;
|
|
1432
|
+
case "ObjectPattern":
|
|
1433
|
+
printObjectPattern(state, node);
|
|
1434
|
+
break;
|
|
1435
|
+
case "ArrayPattern":
|
|
1436
|
+
printArrayPattern(state, node);
|
|
1437
|
+
break;
|
|
1438
|
+
case "SequenceExpression":
|
|
1439
|
+
printSequenceExpression(state, node, prec);
|
|
1440
|
+
break;
|
|
1441
|
+
case "AwaitExpression":
|
|
1442
|
+
state.out += "await ";
|
|
1443
|
+
printNodePrec(state, node.argument, PREC.Unary);
|
|
1444
|
+
break;
|
|
1445
|
+
case "YieldExpression":
|
|
1446
|
+
printYieldExpression(state, node, prec);
|
|
1447
|
+
break;
|
|
1448
|
+
case "ChainExpression":
|
|
1449
|
+
printNodePrec(state, node.expression, prec);
|
|
1450
|
+
break;
|
|
1451
|
+
case "ParenthesizedExpression":
|
|
1452
|
+
state.out += "(";
|
|
1453
|
+
printNodePrec(state, node.expression, PREC.Sequence);
|
|
1454
|
+
state.out += ")";
|
|
1455
|
+
break;
|
|
1456
|
+
case "ImportExpression":
|
|
1457
|
+
printImportExpression(state, node);
|
|
1458
|
+
break;
|
|
1459
|
+
case "V8IntrinsicExpression":
|
|
1460
|
+
printV8Intrinsic(state, node);
|
|
1461
|
+
break;
|
|
1462
|
+
case "ArrowFunctionExpression":
|
|
1463
|
+
printArrowFunction(state, node, prec);
|
|
1464
|
+
break;
|
|
1465
|
+
case "FunctionExpression":
|
|
1466
|
+
case "FunctionDeclaration":
|
|
1467
|
+
case "TSDeclareFunction":
|
|
1468
|
+
case "TSEmptyBodyFunctionExpression":
|
|
1469
|
+
printFunction(state, node, prec);
|
|
1470
|
+
break;
|
|
1471
|
+
case "ClassDeclaration":
|
|
1472
|
+
case "ClassExpression":
|
|
1473
|
+
printClass(state, node, prec);
|
|
1474
|
+
break;
|
|
1475
|
+
case "JSXElement":
|
|
1476
|
+
printJSXElement(state, node);
|
|
1477
|
+
break;
|
|
1478
|
+
case "JSXFragment":
|
|
1479
|
+
printJSXFragment(state, node);
|
|
1480
|
+
break;
|
|
1481
|
+
case "JSXOpeningElement":
|
|
1482
|
+
printJSXOpeningElement(state, node);
|
|
1483
|
+
break;
|
|
1484
|
+
case "JSXClosingElement": break;
|
|
1485
|
+
case "JSXIdentifier":
|
|
1486
|
+
state.out += node.name;
|
|
1487
|
+
break;
|
|
1488
|
+
case "JSXNamespacedName":
|
|
1489
|
+
state.out += `${node.namespace.name}:${node.name.name}`;
|
|
1490
|
+
break;
|
|
1491
|
+
case "JSXMemberExpression":
|
|
1492
|
+
printJSXMemberExpression(state, node);
|
|
1493
|
+
break;
|
|
1494
|
+
case "JSXAttribute":
|
|
1495
|
+
printJSXAttribute(state, node);
|
|
1496
|
+
break;
|
|
1497
|
+
case "JSXSpreadAttribute":
|
|
1498
|
+
state.out += "{...";
|
|
1499
|
+
printNodePrec(state, node.argument, PREC.Assignment);
|
|
1500
|
+
state.out += "}";
|
|
1501
|
+
break;
|
|
1502
|
+
case "JSXExpressionContainer":
|
|
1503
|
+
state.out += "{";
|
|
1504
|
+
printNodePrec(state, node.expression, PREC.Sequence);
|
|
1505
|
+
state.out += "}";
|
|
1506
|
+
break;
|
|
1507
|
+
case "JSXEmptyExpression": break;
|
|
1508
|
+
case "JSXText":
|
|
1509
|
+
state.out += node.value;
|
|
1510
|
+
break;
|
|
1511
|
+
case "JSXSpreadChild":
|
|
1512
|
+
state.out += "{...";
|
|
1513
|
+
printNodePrec(state, node.expression, PREC.Assignment);
|
|
1514
|
+
state.out += "}";
|
|
1515
|
+
break;
|
|
1516
|
+
case "TSAsExpression":
|
|
1517
|
+
printTSAsExpression(state, node, prec);
|
|
1518
|
+
break;
|
|
1519
|
+
case "TSSatisfiesExpression":
|
|
1520
|
+
printTSSatisfiesExpression(state, node, prec);
|
|
1521
|
+
break;
|
|
1522
|
+
case "TSTypeAssertion":
|
|
1523
|
+
printTSTypeAssertion(state, node, prec);
|
|
1524
|
+
break;
|
|
1525
|
+
case "TSNonNullExpression":
|
|
1526
|
+
printNodePrec(state, node.expression, PREC.Member);
|
|
1527
|
+
state.out += "!";
|
|
1528
|
+
break;
|
|
1529
|
+
case "TSInstantiationExpression":
|
|
1530
|
+
printTSInstantiationExpression(state, node, prec);
|
|
1531
|
+
break;
|
|
1532
|
+
case "BlockStatement":
|
|
1533
|
+
printBlockStatement(state, node);
|
|
1534
|
+
break;
|
|
1535
|
+
case "EmptyStatement":
|
|
1536
|
+
state.out += ";";
|
|
1537
|
+
break;
|
|
1538
|
+
case "ExpressionStatement":
|
|
1539
|
+
printExpressionStatement(state, node);
|
|
1540
|
+
break;
|
|
1541
|
+
case "IfStatement":
|
|
1542
|
+
printIfStatement(state, node);
|
|
1543
|
+
break;
|
|
1544
|
+
case "DoWhileStatement":
|
|
1545
|
+
printDoWhileStatement(state, node);
|
|
1546
|
+
break;
|
|
1547
|
+
case "WhileStatement":
|
|
1548
|
+
printWhileStatement(state, node);
|
|
1549
|
+
break;
|
|
1550
|
+
case "ForStatement":
|
|
1551
|
+
printForStatement(state, node);
|
|
1552
|
+
break;
|
|
1553
|
+
case "ForInStatement":
|
|
1554
|
+
printForInStatement(state, node);
|
|
1555
|
+
break;
|
|
1556
|
+
case "ForOfStatement":
|
|
1557
|
+
printForOfStatement(state, node);
|
|
1558
|
+
break;
|
|
1559
|
+
case "ContinueStatement":
|
|
1560
|
+
printJumpStatement(state, "continue", node.label);
|
|
1561
|
+
break;
|
|
1562
|
+
case "BreakStatement":
|
|
1563
|
+
printJumpStatement(state, "break", node.label);
|
|
1564
|
+
break;
|
|
1565
|
+
case "ReturnStatement":
|
|
1566
|
+
printReturnStatement(state, node);
|
|
1567
|
+
break;
|
|
1568
|
+
case "WithStatement":
|
|
1569
|
+
printWithStatement(state, node);
|
|
1570
|
+
break;
|
|
1571
|
+
case "SwitchStatement":
|
|
1572
|
+
printSwitchStatement(state, node);
|
|
1573
|
+
break;
|
|
1574
|
+
case "SwitchCase": break;
|
|
1575
|
+
case "LabeledStatement":
|
|
1576
|
+
printLabeledStatement(state, node);
|
|
1577
|
+
break;
|
|
1578
|
+
case "ThrowStatement":
|
|
1579
|
+
state.out += "throw ";
|
|
1580
|
+
printNodePrec(state, node.argument, PREC.Sequence);
|
|
1581
|
+
state.out += ";";
|
|
1582
|
+
break;
|
|
1583
|
+
case "TryStatement":
|
|
1584
|
+
printTryStatement(state, node);
|
|
1585
|
+
break;
|
|
1586
|
+
case "CatchClause": break;
|
|
1587
|
+
case "DebuggerStatement":
|
|
1588
|
+
state.out += "debugger;";
|
|
1589
|
+
break;
|
|
1590
|
+
case "VariableDeclaration":
|
|
1591
|
+
printVariableDeclaration(state, node);
|
|
1592
|
+
break;
|
|
1593
|
+
case "VariableDeclarator":
|
|
1594
|
+
printVariableDeclarator(state, node);
|
|
1595
|
+
break;
|
|
1596
|
+
case "ClassBody":
|
|
1597
|
+
printClassBody(state, node);
|
|
1598
|
+
break;
|
|
1599
|
+
case "MethodDefinition":
|
|
1600
|
+
case "TSAbstractMethodDefinition":
|
|
1601
|
+
printMethodDefinition(state, node);
|
|
1602
|
+
break;
|
|
1603
|
+
case "PropertyDefinition":
|
|
1604
|
+
case "TSAbstractPropertyDefinition":
|
|
1605
|
+
printPropertyDefinition(state, node);
|
|
1606
|
+
break;
|
|
1607
|
+
case "AccessorProperty":
|
|
1608
|
+
case "TSAbstractAccessorProperty":
|
|
1609
|
+
printAccessorProperty(state, node);
|
|
1610
|
+
break;
|
|
1611
|
+
case "StaticBlock":
|
|
1612
|
+
printStaticBlock(state, node);
|
|
1613
|
+
break;
|
|
1614
|
+
case "ImportDeclaration":
|
|
1615
|
+
printImportDeclaration(state, node);
|
|
1616
|
+
break;
|
|
1617
|
+
case "ExportNamedDeclaration":
|
|
1618
|
+
printExportNamedDeclaration(state, node);
|
|
1619
|
+
break;
|
|
1620
|
+
case "ExportDefaultDeclaration":
|
|
1621
|
+
printExportDefaultDeclaration(state, node);
|
|
1622
|
+
break;
|
|
1623
|
+
case "ExportAllDeclaration":
|
|
1624
|
+
printExportAllDeclaration(state, node);
|
|
1625
|
+
break;
|
|
1626
|
+
case "Decorator":
|
|
1627
|
+
state.out += "@";
|
|
1628
|
+
printNodePrec(state, node.expression, PREC.Member);
|
|
1629
|
+
break;
|
|
1630
|
+
case "TSTypeAliasDeclaration":
|
|
1631
|
+
printTSTypeAliasDeclaration(state, node);
|
|
1632
|
+
break;
|
|
1633
|
+
case "TSInterfaceDeclaration":
|
|
1634
|
+
printTSInterfaceDeclaration(state, node);
|
|
1635
|
+
break;
|
|
1636
|
+
case "TSEnumDeclaration":
|
|
1637
|
+
printTSEnumDeclaration(state, node);
|
|
1638
|
+
break;
|
|
1639
|
+
case "TSModuleDeclaration":
|
|
1640
|
+
printTSModuleDeclaration(state, node);
|
|
1641
|
+
break;
|
|
1642
|
+
case "TSImportEqualsDeclaration":
|
|
1643
|
+
printTSImportEqualsDeclaration(state, node);
|
|
1644
|
+
break;
|
|
1645
|
+
case "TSExportAssignment":
|
|
1646
|
+
state.out += `export = `;
|
|
1647
|
+
printNodePrec(state, node.expression, PREC.Sequence);
|
|
1648
|
+
state.out += ";";
|
|
1649
|
+
break;
|
|
1650
|
+
case "TSNamespaceExportDeclaration":
|
|
1651
|
+
state.out += `export as namespace ${node.id.name};`;
|
|
1652
|
+
break;
|
|
1653
|
+
case "Program":
|
|
1654
|
+
case "ExportSpecifier":
|
|
1655
|
+
case "Hashbang":
|
|
1656
|
+
case "ImportAttribute":
|
|
1657
|
+
case "ImportDefaultSpecifier":
|
|
1658
|
+
case "ImportNamespaceSpecifier":
|
|
1659
|
+
case "ImportSpecifier":
|
|
1660
|
+
case "JSXClosingFragment":
|
|
1661
|
+
case "JSXOpeningFragment":
|
|
1662
|
+
case "TSAnyKeyword":
|
|
1663
|
+
case "TSArrayType":
|
|
1664
|
+
case "TSBigIntKeyword":
|
|
1665
|
+
case "TSBooleanKeyword":
|
|
1666
|
+
case "TSCallSignatureDeclaration":
|
|
1667
|
+
case "TSClassImplements":
|
|
1668
|
+
case "TSConditionalType":
|
|
1669
|
+
case "TSConstructSignatureDeclaration":
|
|
1670
|
+
case "TSConstructorType":
|
|
1671
|
+
case "TSEnumBody":
|
|
1672
|
+
case "TSEnumMember":
|
|
1673
|
+
case "TSExternalModuleReference":
|
|
1674
|
+
case "TSFunctionType":
|
|
1675
|
+
case "TSImportType":
|
|
1676
|
+
case "TSIndexSignature":
|
|
1677
|
+
case "TSIndexedAccessType":
|
|
1678
|
+
case "TSInferType":
|
|
1679
|
+
case "TSInterfaceBody":
|
|
1680
|
+
case "TSInterfaceHeritage":
|
|
1681
|
+
case "TSIntersectionType":
|
|
1682
|
+
case "TSIntrinsicKeyword":
|
|
1683
|
+
case "TSJSDocNonNullableType":
|
|
1684
|
+
case "TSJSDocNullableType":
|
|
1685
|
+
case "TSJSDocUnknownType":
|
|
1686
|
+
case "TSLiteralType":
|
|
1687
|
+
case "TSMappedType":
|
|
1688
|
+
case "TSMethodSignature":
|
|
1689
|
+
case "TSModuleBlock":
|
|
1690
|
+
case "TSNamedTupleMember":
|
|
1691
|
+
case "TSNeverKeyword":
|
|
1692
|
+
case "TSNullKeyword":
|
|
1693
|
+
case "TSNumberKeyword":
|
|
1694
|
+
case "TSObjectKeyword":
|
|
1695
|
+
case "TSOptionalType":
|
|
1696
|
+
case "TSParameterProperty":
|
|
1697
|
+
case "TSParenthesizedType":
|
|
1698
|
+
case "TSPropertySignature":
|
|
1699
|
+
case "TSQualifiedName":
|
|
1700
|
+
case "TSRestType":
|
|
1701
|
+
case "TSStringKeyword":
|
|
1702
|
+
case "TSSymbolKeyword":
|
|
1703
|
+
case "TSTemplateLiteralType":
|
|
1704
|
+
case "TSThisType":
|
|
1705
|
+
case "TSTupleType":
|
|
1706
|
+
case "TSTypeAnnotation":
|
|
1707
|
+
case "TSTypeLiteral":
|
|
1708
|
+
case "TSTypeOperator":
|
|
1709
|
+
case "TSTypeParameter":
|
|
1710
|
+
case "TSTypeParameterDeclaration":
|
|
1711
|
+
case "TSTypeParameterInstantiation":
|
|
1712
|
+
case "TSTypePredicate":
|
|
1713
|
+
case "TSTypeQuery":
|
|
1714
|
+
case "TSTypeReference":
|
|
1715
|
+
case "TSUndefinedKeyword":
|
|
1716
|
+
case "TSUnionType":
|
|
1717
|
+
case "TSUnknownKeyword":
|
|
1718
|
+
case "TSVoidKeyword": printUnclassifiedNode(state, node, node.type);
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1721
|
+
function printUnclassifiedNode(state, node, kind) {
|
|
1722
|
+
if (isTSType(node)) {
|
|
1723
|
+
printTSType(state, node);
|
|
1724
|
+
return;
|
|
1725
|
+
}
|
|
1726
|
+
printTypeHolderNode(state, node, kind);
|
|
1727
|
+
}
|
|
1728
|
+
function printTypeHolderNode(state, node, kind) {
|
|
1729
|
+
switch (kind) {
|
|
1730
|
+
case "TSTypeAnnotation":
|
|
1731
|
+
printTypeAnnotationHolder(state, node);
|
|
1732
|
+
break;
|
|
1733
|
+
case "TSTypeParameterDeclaration":
|
|
1734
|
+
printTypeParameterDeclarationHolder(state, node);
|
|
1735
|
+
break;
|
|
1736
|
+
case "TSTypeParameterInstantiation":
|
|
1737
|
+
printTypeParameterInstantiationHolder(state, node);
|
|
1738
|
+
break;
|
|
1739
|
+
case "TSTypeParameter":
|
|
1740
|
+
printTypeParameterHolder(state, node);
|
|
1741
|
+
break;
|
|
1742
|
+
default: state.out += `/* unknown:${kind} */`;
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
function printTypeAnnotationHolder(state, node) {
|
|
1746
|
+
if (isNodeOfKind(node, "TSTypeAnnotation")) {
|
|
1747
|
+
state.out += ": ";
|
|
1748
|
+
printTSType(state, node.typeAnnotation);
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
function printTypeParameterDeclarationHolder(state, node) {
|
|
1752
|
+
if (isNodeOfKind(node, "TSTypeParameterDeclaration")) printTSTypeParameterDeclaration(state, node);
|
|
1753
|
+
}
|
|
1754
|
+
function printTypeParameterInstantiationHolder(state, node) {
|
|
1755
|
+
if (isNodeOfKind(node, "TSTypeParameterInstantiation")) printTSTypeParameterInstantiation(state, node);
|
|
1756
|
+
}
|
|
1757
|
+
function printTypeParameterHolder(state, node) {
|
|
1758
|
+
if (isNodeOfKind(node, "TSTypeParameter")) printTSTypeParameter(state, node);
|
|
1759
|
+
}
|
|
1760
|
+
function printLiteral(state, node) {
|
|
1761
|
+
state.out += literalText(node);
|
|
1762
|
+
}
|
|
1763
|
+
function printIdentifier(state, node) {
|
|
1764
|
+
state.out += node.name;
|
|
1765
|
+
}
|
|
1766
|
+
function printArrayExpression(state, node) {
|
|
1767
|
+
state.out += `[${node.elements.map((element) => arrayElementText(state, element)).join(", ")}]`;
|
|
1768
|
+
}
|
|
1769
|
+
function arrayElementText(state, element) {
|
|
1770
|
+
if (element === null) return "";
|
|
1771
|
+
return assignmentNodeText(state, element);
|
|
1772
|
+
}
|
|
1773
|
+
function printObjectExpression(state, node) {
|
|
1774
|
+
switch (node.properties.length) {
|
|
1775
|
+
case 0:
|
|
1776
|
+
state.out += "{}";
|
|
1777
|
+
break;
|
|
1778
|
+
default: state.out += `{ ${nodeListText(state, node.properties, PREC.Sequence)} }`;
|
|
1779
|
+
}
|
|
1780
|
+
}
|
|
1781
|
+
function printProperty(state, node) {
|
|
1782
|
+
switch (propertyForm(node)) {
|
|
1783
|
+
case "accessor":
|
|
1784
|
+
state.out += `${node.kind} `;
|
|
1785
|
+
state.out += propertyKeyText(state, node.key, node.computed === true, PREC.Assignment);
|
|
1786
|
+
printFunctionValueTail(state, node.value);
|
|
1787
|
+
break;
|
|
1788
|
+
case "method":
|
|
1789
|
+
state.out += propertyKeyText(state, node.key, node.computed === true, PREC.Assignment);
|
|
1790
|
+
printFunctionValueTail(state, node.value);
|
|
1791
|
+
break;
|
|
1792
|
+
case "shorthand":
|
|
1793
|
+
state.out += identifierNameText(node.key);
|
|
1794
|
+
break;
|
|
1795
|
+
case "shorthandDefault":
|
|
1796
|
+
printShorthandDefaultProperty(state, node);
|
|
1797
|
+
break;
|
|
1798
|
+
default:
|
|
1799
|
+
state.out += propertyKeyText(state, node.key, node.computed === true, PREC.Assignment);
|
|
1800
|
+
state.out += ": ";
|
|
1801
|
+
printNodePrec(state, node.value, PREC.Assignment);
|
|
1802
|
+
}
|
|
1803
|
+
}
|
|
1804
|
+
function printFunctionValueTail(state, value) {
|
|
1805
|
+
if (isFunctionNode(value)) printFunctionTail(state, value);
|
|
1806
|
+
}
|
|
1807
|
+
function printShorthandDefaultProperty(state, node) {
|
|
1808
|
+
if (!isAssignmentPattern(node.value)) return;
|
|
1809
|
+
const right = assignmentNodeText(state, node.value.right);
|
|
1810
|
+
state.out += `${identifierNameText(node.key)} = ${right}`;
|
|
1811
|
+
}
|
|
1812
|
+
function propertyKeyText(state, key, computed, computedPrec) {
|
|
1813
|
+
if (computed) return `[${capture(state, () => printNodePrec(state, key, computedPrec))}]`;
|
|
1814
|
+
return plainPropertyKeyText(state, key);
|
|
1815
|
+
}
|
|
1816
|
+
function plainPropertyKeyText(state, key) {
|
|
1817
|
+
switch (nodeKind(key)) {
|
|
1818
|
+
case "Identifier": return identifierNameText(key);
|
|
1819
|
+
case "PrivateIdentifier": return privateIdentifierText(key);
|
|
1820
|
+
case "Literal": return literalCapture(state, key);
|
|
1821
|
+
default: return capture(state, () => printNodePrec(state, key, PREC.Assignment));
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
function printFunctionTail(state, fn) {
|
|
1825
|
+
state.out += typeParametersText(state, fn.typeParameters);
|
|
1826
|
+
state.out += `(${paramsText(state, fn.params)})`;
|
|
1827
|
+
state.out += typeAnnotationText(state, fn.returnType);
|
|
1828
|
+
state.out += functionBodyText(state, fn);
|
|
1829
|
+
}
|
|
1830
|
+
function functionBodyText(state, fn) {
|
|
1831
|
+
const body = fn.body;
|
|
1832
|
+
if (body !== null) return ` ${capture(state, () => printBlockStatement(state, body))}`;
|
|
1833
|
+
return ";";
|
|
1834
|
+
}
|
|
1835
|
+
function paramsText(state, params) {
|
|
1836
|
+
return capture(state, () => printParams(state, params));
|
|
1837
|
+
}
|
|
1838
|
+
function typeParametersText(state, params) {
|
|
1839
|
+
if (params == null) return "";
|
|
1840
|
+
return capture(state, () => printTSTypeParameterDeclaration(state, params));
|
|
1841
|
+
}
|
|
1842
|
+
function typeArgumentsText(state, args) {
|
|
1843
|
+
if (args == null) return "";
|
|
1844
|
+
return capture(state, () => printTSTypeParameterInstantiation(state, args));
|
|
1845
|
+
}
|
|
1846
|
+
function typeAnnotationText(state, annotation) {
|
|
1847
|
+
if (annotation == null) return "";
|
|
1848
|
+
return capture(state, () => printTSTypeAnnotation(state, annotation));
|
|
1849
|
+
}
|
|
1850
|
+
function printTemplateLiteral(state, node) {
|
|
1851
|
+
state.out += `\`${node.quasis.map((quasi, index) => quasiText(state, quasi, node.expressions[index])).join("")}\``;
|
|
1852
|
+
}
|
|
1853
|
+
function quasiText(state, quasi, expression) {
|
|
1854
|
+
if (quasi.tail) return quasi.value.raw;
|
|
1855
|
+
return `${quasi.value.raw}\${${sequenceNodeText(state, expression)}}`;
|
|
1856
|
+
}
|
|
1857
|
+
function printTaggedTemplate(state, node) {
|
|
1858
|
+
printNodePrec(state, node.tag, PREC.Member);
|
|
1859
|
+
if (node.typeArguments != null) printTSTypeParameterInstantiation(state, node.typeArguments);
|
|
1860
|
+
printTemplateLiteral(state, node.quasi);
|
|
1861
|
+
}
|
|
1862
|
+
function printMemberExpression(state, node, _prec) {
|
|
1863
|
+
state.out += wrappedExpressionText(state, node.object, PREC.Member, MEMBER_OBJECT_WRAPPED_KINDS);
|
|
1864
|
+
state.out += flagText(node.optional, "?.");
|
|
1865
|
+
state.out += memberSelectorText(state, node);
|
|
1866
|
+
}
|
|
1867
|
+
function memberSelectorText(state, access) {
|
|
1868
|
+
if (access.computed) return `[${sequenceNodeText(state, access.property)}]`;
|
|
1869
|
+
return `${flagText(!access.optional, ".")}${memberPropertyText(state, access.property)}`;
|
|
1870
|
+
}
|
|
1871
|
+
function memberPropertyText(state, property) {
|
|
1872
|
+
switch (nodeKind(property)) {
|
|
1873
|
+
case "Identifier": return identifierNameText(property);
|
|
1874
|
+
case "PrivateIdentifier": return privateIdentifierText(property);
|
|
1875
|
+
default: return sequenceNodeText(state, property);
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
function printCallExpression(state, node, _prec) {
|
|
1879
|
+
state.out += wrappedExpressionText(state, node.callee, PREC.Member, CALLEE_WRAPPED_KINDS);
|
|
1880
|
+
state.out += flagText(node.optional, "?.");
|
|
1881
|
+
state.out += typeArgumentsText(state, node.typeArguments);
|
|
1882
|
+
state.out += `(${nodeListText(state, node.arguments, PREC.Assignment)})`;
|
|
1883
|
+
}
|
|
1884
|
+
function printNewExpression(state, node, _prec) {
|
|
1885
|
+
state.out += "new ";
|
|
1886
|
+
state.out += printExpressionToString(state, node.callee, PREC.Member);
|
|
1887
|
+
state.out += typeArgumentsText(state, node.typeArguments);
|
|
1888
|
+
state.out += `(${nodeListText(state, node.arguments, PREC.Assignment)})`;
|
|
1889
|
+
}
|
|
1890
|
+
function printMetaProperty(state, node) {
|
|
1891
|
+
state.out += `${node.meta.name}.${node.property.name}`;
|
|
1892
|
+
}
|
|
1893
|
+
function printV8Intrinsic(state, node) {
|
|
1894
|
+
state.out += `%${node.name.name}(${nodeListText(state, node.arguments, PREC.Assignment)})`;
|
|
1895
|
+
}
|
|
1896
|
+
function printImportExpression(state, node) {
|
|
1897
|
+
state.out += `import${flagText(node.phase, `.${node.phase}`)}(`;
|
|
1898
|
+
state.out += assignmentNodeText(state, node.source);
|
|
1899
|
+
state.out += flagText(node.options, `, ${assignmentNodeText(state, node.options)}`);
|
|
1900
|
+
state.out += ")";
|
|
1901
|
+
}
|
|
1902
|
+
function printUpdateExpression(state, node, _prec) {
|
|
1903
|
+
const operand = wrappedExpressionText(state, node.argument, PREC.Update, MEMBER_OBJECT_WRAPPED_KINDS);
|
|
1904
|
+
if (node.prefix) {
|
|
1905
|
+
state.out += `${node.operator}${operand}`;
|
|
1906
|
+
return;
|
|
1907
|
+
}
|
|
1908
|
+
state.out += `${operand}${node.operator}`;
|
|
1909
|
+
}
|
|
1910
|
+
function printUnaryExpression(state, node, _prec) {
|
|
1911
|
+
state.out += node.operator;
|
|
1912
|
+
state.out += flagText(UNARY_WORD_OPERATORS[node.operator] === true, " ");
|
|
1913
|
+
state.out += wrappedExpressionText(state, node.argument, PREC.Unary, UNARY_OPERAND_WRAPPED_KINDS);
|
|
1914
|
+
}
|
|
1915
|
+
function printBinaryExpression(state, node, prec) {
|
|
1916
|
+
const myPrec = binaryPrec(node.operator);
|
|
1917
|
+
const leftStr = wrapIfNeeded(state, node.left, precOf(node.left), myPrec, false, node.operator);
|
|
1918
|
+
const rightStr = wrapIfNeeded(state, node.right, precOf(node.right), myPrec, true, node.operator);
|
|
1919
|
+
const whole = `${leftStr} ${node.operator} ${rightStr}`;
|
|
1920
|
+
if (myPrec < prec) state.out += `(${whole})`;
|
|
1921
|
+
else state.out += whole;
|
|
1922
|
+
}
|
|
1923
|
+
function printLogicalExpression(state, node, prec) {
|
|
1924
|
+
const myPrec = logicalPrec(node.operator);
|
|
1925
|
+
const leftStr = wrapIfNeeded(state, node.left, precOf(node.left), myPrec, false, node.operator);
|
|
1926
|
+
const rightStr = wrapIfNeeded(state, node.right, precOf(node.right), myPrec, true, node.operator);
|
|
1927
|
+
const whole = `${leftStr} ${node.operator} ${rightStr}`;
|
|
1928
|
+
if (myPrec < prec) state.out += `(${whole})`;
|
|
1929
|
+
else state.out += whole;
|
|
1930
|
+
}
|
|
1931
|
+
function printConditionalExpression(state, node, prec) {
|
|
1932
|
+
const myPrec = PREC.Conditional;
|
|
1933
|
+
const whole = `${wrapIfNeeded(state, node.test, precOf(node.test), myPrec, false)} ? ${printExpressionToString(state, node.consequent, PREC.Assignment)} : ${printExpressionToString(state, node.alternate, PREC.Assignment)}`;
|
|
1934
|
+
if (myPrec < prec) state.out += `(${whole})`;
|
|
1935
|
+
else state.out += whole;
|
|
1936
|
+
}
|
|
1937
|
+
function printAssignmentExpression(state, node, prec) {
|
|
1938
|
+
const myPrec = PREC.Assignment;
|
|
1939
|
+
const leftStr = printExpressionToString(state, node.left, myPrec);
|
|
1940
|
+
const rightStr = printExpressionToString(state, node.right, myPrec - .1);
|
|
1941
|
+
const whole = `${leftStr} ${node.operator} ${rightStr}`;
|
|
1942
|
+
if (myPrec < prec) state.out += `(${whole})`;
|
|
1943
|
+
else state.out += whole;
|
|
1944
|
+
}
|
|
1945
|
+
function printAssignmentPattern(state, node, prec) {
|
|
1946
|
+
const leftText = printExpressionToString(state, node.left, PREC.Assignment) + typeAnnotationText(state, bindingTypeAnnotation(node.left));
|
|
1947
|
+
const rightText = printExpressionToString(state, node.right, PREC.Assignment);
|
|
1948
|
+
state.out += parenthesizedIf(PREC.Assignment < prec, `${leftText} = ${rightText}`);
|
|
1949
|
+
}
|
|
1950
|
+
function printObjectPattern(state, node) {
|
|
1951
|
+
switch (node.properties.length) {
|
|
1952
|
+
case 0:
|
|
1953
|
+
state.out += "{}";
|
|
1954
|
+
break;
|
|
1955
|
+
default: state.out += `{ ${nodeListText(state, node.properties, PREC.Sequence)} }`;
|
|
1956
|
+
}
|
|
1957
|
+
}
|
|
1958
|
+
function printArrayPattern(state, node) {
|
|
1959
|
+
state.out += `[${node.elements.map((element) => arrayElementText(state, element)).join(", ")}]`;
|
|
1960
|
+
}
|
|
1961
|
+
function printSequenceExpression(state, node, prec) {
|
|
1962
|
+
const whole = node.expressions.map((expression) => printExpressionToString(state, expression, PREC.Sequence)).join(", ");
|
|
1963
|
+
state.out += parenthesizedIf(PREC.Sequence < prec, whole);
|
|
1964
|
+
}
|
|
1965
|
+
function printYieldExpression(state, node, _prec) {
|
|
1966
|
+
if (node.delegate) state.out += "yield*";
|
|
1967
|
+
else state.out += "yield";
|
|
1968
|
+
state.out += flagText(node.argument, ` ${assignmentNodeText(state, node.argument)}`);
|
|
1969
|
+
}
|
|
1970
|
+
function printArrowFunction(state, node, prec) {
|
|
1971
|
+
const arrow = `${flagText(node.async, "async ")}${typeParametersText(state, node.typeParameters)}${arrowParamsText(state, node)}${typeAnnotationText(state, node.returnType)} => ${arrowBodyText(state, node)}`;
|
|
1972
|
+
state.out += parenthesizedIf(PREC.Assignment < prec, arrow);
|
|
1973
|
+
}
|
|
1974
|
+
function arrowParamsText(state, node) {
|
|
1975
|
+
const bareParam = bareArrowParamName(node);
|
|
1976
|
+
if (bareParam.length === 0) return `(${paramsText(state, node.params)})`;
|
|
1977
|
+
return bareParam;
|
|
1978
|
+
}
|
|
1979
|
+
function arrowBodyText(state, node) {
|
|
1980
|
+
const body = node.body;
|
|
1981
|
+
if (arrowBodyIsBlock(body)) return capture(state, () => printBlockStatement(state, body));
|
|
1982
|
+
return assignmentNodeText(state, body);
|
|
1983
|
+
}
|
|
1984
|
+
function printFunction(state, node, _prec) {
|
|
1985
|
+
state.out += functionHeaderText(node);
|
|
1986
|
+
printFunctionTail(state, node);
|
|
1987
|
+
}
|
|
1988
|
+
function printClass(state, node, _prec) {
|
|
1989
|
+
state.out += capture(state, () => printDecorators(state, node.decorators));
|
|
1990
|
+
state.out += `${flagText(node.declare, "declare ")}${flagText(node.abstract, "abstract ")}class${namedDeclarationText(node)}`;
|
|
1991
|
+
state.out += typeParametersText(state, node.typeParameters);
|
|
1992
|
+
state.out += classHeritageText(state, node);
|
|
1993
|
+
state.out += classImplementsText(state, node);
|
|
1994
|
+
state.out += " ";
|
|
1995
|
+
printClassBody(state, node.body);
|
|
1996
|
+
}
|
|
1997
|
+
function classHeritageText(state, node) {
|
|
1998
|
+
if (node.superClass !== null) return ` extends ${assignmentNodeText(state, node.superClass)}${typeArgumentsText(state, node.superTypeArguments)}`;
|
|
1999
|
+
return "";
|
|
2000
|
+
}
|
|
2001
|
+
function classImplementsText(state, node) {
|
|
2002
|
+
const rendered = (node.implements ?? []).map((heritage) => heritageText(state, heritage)).join(", ");
|
|
2003
|
+
return flagText(rendered, ` implements ${rendered}`);
|
|
2004
|
+
}
|
|
2005
|
+
function heritageText(state, heritage) {
|
|
2006
|
+
return `${assignmentNodeText(state, heritage.expression)}${typeArgumentsText(state, heritage.typeArguments)}`;
|
|
2007
|
+
}
|
|
2008
|
+
function printDecorators(state, decorators) {
|
|
2009
|
+
const rendered = (decorators ?? []).map((decorator) => decoratorText(state, decorator)).join(" ");
|
|
2010
|
+
state.out += flagText(rendered, `${rendered} `);
|
|
2011
|
+
}
|
|
2012
|
+
function decoratorText(state, decorator) {
|
|
2013
|
+
return `@${capture(state, () => printNodePrec(state, decorator.expression, PREC.Member))}`;
|
|
2014
|
+
}
|
|
2015
|
+
function printJSXElement(state, node) {
|
|
2016
|
+
printJSXOpeningElement(state, node.openingElement);
|
|
2017
|
+
node.children.forEach((child) => printJSXChild(state, child));
|
|
2018
|
+
printJSXClosingElement(state, node);
|
|
2019
|
+
}
|
|
2020
|
+
function printJSXClosingElement(state, node) {
|
|
2021
|
+
if (node.closingElement === null) return;
|
|
2022
|
+
state.out += `</${jsxElementNameText(state, node.closingElement.name)}>`;
|
|
2023
|
+
}
|
|
2024
|
+
function printJSXFragment(state, node) {
|
|
2025
|
+
state.out += "<>";
|
|
2026
|
+
for (const child of node.children) printJSXChild(state, child);
|
|
2027
|
+
state.out += "</>";
|
|
2028
|
+
}
|
|
2029
|
+
function printJSXOpeningElement(state, node) {
|
|
2030
|
+
state.out += `<${jsxElementNameText(state, node.name)}`;
|
|
2031
|
+
state.out += typeArgumentsText(state, node.typeArguments);
|
|
2032
|
+
state.out += node.attributes.map((attribute) => ` ${sequenceNodeText(state, attribute)}`).join("");
|
|
2033
|
+
if (node.selfClosing) {
|
|
2034
|
+
state.out += " />";
|
|
2035
|
+
return;
|
|
1275
2036
|
}
|
|
1276
|
-
|
|
1277
|
-
|
|
2037
|
+
state.out += ">";
|
|
2038
|
+
}
|
|
2039
|
+
function jsxElementNameText(state, name) {
|
|
2040
|
+
switch (name.type) {
|
|
2041
|
+
case "JSXIdentifier": return name.name;
|
|
2042
|
+
case "JSXNamespacedName": return `${name.namespace.name}:${name.name.name}`;
|
|
2043
|
+
case "JSXMemberExpression": return capture(state, () => printJSXMemberExpression(state, name));
|
|
1278
2044
|
}
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
2045
|
+
}
|
|
2046
|
+
function printJSXMemberExpression(state, node) {
|
|
2047
|
+
const obj = node.object;
|
|
2048
|
+
if (obj.type === "JSXIdentifier") {
|
|
2049
|
+
state.out += `${obj.name}.${node.property.name}`;
|
|
2050
|
+
return;
|
|
1285
2051
|
}
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
this.out += "super";
|
|
1304
|
-
break;
|
|
1305
|
-
case "ArrayExpression":
|
|
1306
|
-
this.printArrayExpression(node);
|
|
1307
|
-
break;
|
|
1308
|
-
case "ObjectExpression":
|
|
1309
|
-
this.printObjectExpression(node);
|
|
1310
|
-
break;
|
|
1311
|
-
case "Property":
|
|
1312
|
-
this.printProperty(node);
|
|
1313
|
-
break;
|
|
1314
|
-
case "TemplateLiteral":
|
|
1315
|
-
this.printTemplateLiteral(node);
|
|
1316
|
-
break;
|
|
1317
|
-
case "TemplateElement":
|
|
1318
|
-
this.out += node.value.raw;
|
|
1319
|
-
break;
|
|
1320
|
-
case "TaggedTemplateExpression":
|
|
1321
|
-
this.printTaggedTemplate(node);
|
|
1322
|
-
break;
|
|
1323
|
-
case "MemberExpression":
|
|
1324
|
-
this.printMemberExpression(node, prec);
|
|
1325
|
-
break;
|
|
1326
|
-
case "CallExpression":
|
|
1327
|
-
this.printCallExpression(node, prec);
|
|
1328
|
-
break;
|
|
1329
|
-
case "NewExpression":
|
|
1330
|
-
this.printNewExpression(node, prec);
|
|
1331
|
-
break;
|
|
1332
|
-
case "MetaProperty":
|
|
1333
|
-
this.printMetaProperty(node);
|
|
1334
|
-
break;
|
|
1335
|
-
case "SpreadElement":
|
|
1336
|
-
this.out += "...";
|
|
1337
|
-
this.printNode(node.argument, PREC.Assignment);
|
|
1338
|
-
break;
|
|
1339
|
-
case "RestElement":
|
|
1340
|
-
this.out += "...";
|
|
1341
|
-
this.printNode(node.argument, PREC.Assignment);
|
|
1342
|
-
break;
|
|
1343
|
-
case "UpdateExpression":
|
|
1344
|
-
this.printUpdateExpression(node, prec);
|
|
1345
|
-
break;
|
|
1346
|
-
case "UnaryExpression":
|
|
1347
|
-
this.printUnaryExpression(node, prec);
|
|
1348
|
-
break;
|
|
1349
|
-
case "BinaryExpression":
|
|
1350
|
-
this.printBinaryExpression(node, prec);
|
|
1351
|
-
break;
|
|
1352
|
-
case "LogicalExpression":
|
|
1353
|
-
this.printLogicalExpression(node, prec);
|
|
1354
|
-
break;
|
|
1355
|
-
case "ConditionalExpression":
|
|
1356
|
-
this.printConditionalExpression(node, prec);
|
|
1357
|
-
break;
|
|
1358
|
-
case "AssignmentExpression":
|
|
1359
|
-
this.printAssignmentExpression(node, prec);
|
|
1360
|
-
break;
|
|
1361
|
-
case "AssignmentPattern":
|
|
1362
|
-
this.printAssignmentPattern(node, prec);
|
|
1363
|
-
break;
|
|
1364
|
-
case "ObjectPattern":
|
|
1365
|
-
this.printObjectPattern(node);
|
|
1366
|
-
break;
|
|
1367
|
-
case "ArrayPattern":
|
|
1368
|
-
this.printArrayPattern(node);
|
|
1369
|
-
break;
|
|
1370
|
-
case "SequenceExpression":
|
|
1371
|
-
this.printSequenceExpression(node, prec);
|
|
1372
|
-
break;
|
|
1373
|
-
case "AwaitExpression":
|
|
1374
|
-
this.out += "await ";
|
|
1375
|
-
this.printNode(node.argument, PREC.Unary);
|
|
1376
|
-
break;
|
|
1377
|
-
case "YieldExpression":
|
|
1378
|
-
this.printYieldExpression(node, prec);
|
|
1379
|
-
break;
|
|
1380
|
-
case "ChainExpression":
|
|
1381
|
-
this.printNode(node.expression, prec);
|
|
1382
|
-
break;
|
|
1383
|
-
case "ParenthesizedExpression":
|
|
1384
|
-
this.out += "(";
|
|
1385
|
-
this.printNode(node.expression, PREC.Sequence);
|
|
1386
|
-
this.out += ")";
|
|
1387
|
-
break;
|
|
1388
|
-
case "ImportExpression":
|
|
1389
|
-
this.printImportExpression(node);
|
|
1390
|
-
break;
|
|
1391
|
-
case "V8IntrinsicExpression":
|
|
1392
|
-
this.printV8Intrinsic(node);
|
|
1393
|
-
break;
|
|
1394
|
-
case "ArrowFunctionExpression":
|
|
1395
|
-
this.printArrowFunction(node, prec);
|
|
1396
|
-
break;
|
|
1397
|
-
case "FunctionExpression":
|
|
1398
|
-
case "FunctionDeclaration":
|
|
1399
|
-
case "TSDeclareFunction":
|
|
1400
|
-
case "TSEmptyBodyFunctionExpression":
|
|
1401
|
-
this.printFunction(node, prec);
|
|
1402
|
-
break;
|
|
1403
|
-
case "ClassDeclaration":
|
|
1404
|
-
case "ClassExpression":
|
|
1405
|
-
this.printClass(node, prec);
|
|
1406
|
-
break;
|
|
1407
|
-
case "JSXElement":
|
|
1408
|
-
this.printJSXElement(node);
|
|
1409
|
-
break;
|
|
1410
|
-
case "JSXFragment":
|
|
1411
|
-
this.printJSXFragment(node);
|
|
1412
|
-
break;
|
|
1413
|
-
case "JSXOpeningElement":
|
|
1414
|
-
this.printJSXOpeningElement(node);
|
|
1415
|
-
break;
|
|
1416
|
-
case "JSXClosingElement": break;
|
|
1417
|
-
case "JSXIdentifier":
|
|
1418
|
-
this.out += node.name;
|
|
1419
|
-
break;
|
|
1420
|
-
case "JSXNamespacedName":
|
|
1421
|
-
this.out += `${node.namespace.name}:${node.name.name}`;
|
|
1422
|
-
break;
|
|
1423
|
-
case "JSXMemberExpression":
|
|
1424
|
-
this.printJSXMemberExpression(node);
|
|
1425
|
-
break;
|
|
1426
|
-
case "JSXAttribute":
|
|
1427
|
-
this.printJSXAttribute(node);
|
|
1428
|
-
break;
|
|
1429
|
-
case "JSXSpreadAttribute":
|
|
1430
|
-
this.out += "{...";
|
|
1431
|
-
this.printNode(node.argument, PREC.Assignment);
|
|
1432
|
-
this.out += "}";
|
|
1433
|
-
break;
|
|
1434
|
-
case "JSXExpressionContainer":
|
|
1435
|
-
this.out += "{";
|
|
1436
|
-
this.printNode(node.expression, PREC.Sequence);
|
|
1437
|
-
this.out += "}";
|
|
1438
|
-
break;
|
|
1439
|
-
case "JSXEmptyExpression": break;
|
|
1440
|
-
case "JSXText":
|
|
1441
|
-
this.out += node.value;
|
|
1442
|
-
break;
|
|
1443
|
-
case "JSXSpreadChild":
|
|
1444
|
-
this.out += "{...";
|
|
1445
|
-
this.printNode(node.expression, PREC.Assignment);
|
|
1446
|
-
this.out += "}";
|
|
1447
|
-
break;
|
|
1448
|
-
case "TSAsExpression":
|
|
1449
|
-
this.printTSAsExpression(node, prec);
|
|
1450
|
-
break;
|
|
1451
|
-
case "TSSatisfiesExpression":
|
|
1452
|
-
this.printTSSatisfiesExpression(node, prec);
|
|
1453
|
-
break;
|
|
1454
|
-
case "TSTypeAssertion":
|
|
1455
|
-
this.printTSTypeAssertion(node, prec);
|
|
1456
|
-
break;
|
|
1457
|
-
case "TSNonNullExpression":
|
|
1458
|
-
this.printNode(node.expression, PREC.Member);
|
|
1459
|
-
this.out += "!";
|
|
1460
|
-
break;
|
|
1461
|
-
case "TSInstantiationExpression":
|
|
1462
|
-
this.printTSInstantiationExpression(node, prec);
|
|
1463
|
-
break;
|
|
1464
|
-
case "BlockStatement":
|
|
1465
|
-
this.printBlockStatement(node);
|
|
1466
|
-
break;
|
|
1467
|
-
case "EmptyStatement":
|
|
1468
|
-
this.out += ";";
|
|
1469
|
-
break;
|
|
1470
|
-
case "ExpressionStatement":
|
|
1471
|
-
this.printExpressionStatement(node);
|
|
1472
|
-
break;
|
|
1473
|
-
case "IfStatement":
|
|
1474
|
-
this.printIfStatement(node);
|
|
1475
|
-
break;
|
|
1476
|
-
case "DoWhileStatement":
|
|
1477
|
-
this.printDoWhileStatement(node);
|
|
1478
|
-
break;
|
|
1479
|
-
case "WhileStatement":
|
|
1480
|
-
this.printWhileStatement(node);
|
|
1481
|
-
break;
|
|
1482
|
-
case "ForStatement":
|
|
1483
|
-
this.printForStatement(node);
|
|
1484
|
-
break;
|
|
1485
|
-
case "ForInStatement":
|
|
1486
|
-
this.printForInStatement(node);
|
|
1487
|
-
break;
|
|
1488
|
-
case "ForOfStatement":
|
|
1489
|
-
this.printForOfStatement(node);
|
|
1490
|
-
break;
|
|
1491
|
-
case "ContinueStatement":
|
|
1492
|
-
this.printJumpStatement("continue", node.label);
|
|
1493
|
-
break;
|
|
1494
|
-
case "BreakStatement":
|
|
1495
|
-
this.printJumpStatement("break", node.label);
|
|
1496
|
-
break;
|
|
1497
|
-
case "ReturnStatement":
|
|
1498
|
-
this.printReturnStatement(node);
|
|
1499
|
-
break;
|
|
1500
|
-
case "WithStatement":
|
|
1501
|
-
this.printWithStatement(node);
|
|
1502
|
-
break;
|
|
1503
|
-
case "SwitchStatement":
|
|
1504
|
-
this.printSwitchStatement(node);
|
|
1505
|
-
break;
|
|
1506
|
-
case "SwitchCase": break;
|
|
1507
|
-
case "LabeledStatement":
|
|
1508
|
-
this.printLabeledStatement(node);
|
|
1509
|
-
break;
|
|
1510
|
-
case "ThrowStatement":
|
|
1511
|
-
this.out += "throw ";
|
|
1512
|
-
this.printNode(node.argument, PREC.Sequence);
|
|
1513
|
-
this.out += ";";
|
|
1514
|
-
break;
|
|
1515
|
-
case "TryStatement":
|
|
1516
|
-
this.printTryStatement(node);
|
|
1517
|
-
break;
|
|
1518
|
-
case "CatchClause": break;
|
|
1519
|
-
case "DebuggerStatement":
|
|
1520
|
-
this.out += "debugger;";
|
|
1521
|
-
break;
|
|
1522
|
-
case "VariableDeclaration":
|
|
1523
|
-
this.printVariableDeclaration(node);
|
|
1524
|
-
break;
|
|
1525
|
-
case "VariableDeclarator":
|
|
1526
|
-
this.printVariableDeclarator(node);
|
|
1527
|
-
break;
|
|
1528
|
-
case "ClassBody":
|
|
1529
|
-
this.printClassBody(node);
|
|
1530
|
-
break;
|
|
1531
|
-
case "MethodDefinition":
|
|
1532
|
-
case "TSAbstractMethodDefinition":
|
|
1533
|
-
this.printMethodDefinition(node);
|
|
1534
|
-
break;
|
|
1535
|
-
case "PropertyDefinition":
|
|
1536
|
-
case "TSAbstractPropertyDefinition":
|
|
1537
|
-
this.printPropertyDefinition(node);
|
|
1538
|
-
break;
|
|
1539
|
-
case "AccessorProperty":
|
|
1540
|
-
case "TSAbstractAccessorProperty":
|
|
1541
|
-
this.printAccessorProperty(node);
|
|
1542
|
-
break;
|
|
1543
|
-
case "StaticBlock":
|
|
1544
|
-
this.printStaticBlock(node);
|
|
1545
|
-
break;
|
|
1546
|
-
case "ImportDeclaration":
|
|
1547
|
-
this.printImportDeclaration(node);
|
|
1548
|
-
break;
|
|
1549
|
-
case "ExportNamedDeclaration":
|
|
1550
|
-
this.printExportNamedDeclaration(node);
|
|
1551
|
-
break;
|
|
1552
|
-
case "ExportDefaultDeclaration":
|
|
1553
|
-
this.printExportDefaultDeclaration(node);
|
|
1554
|
-
break;
|
|
1555
|
-
case "ExportAllDeclaration":
|
|
1556
|
-
this.printExportAllDeclaration(node);
|
|
1557
|
-
break;
|
|
1558
|
-
case "Decorator":
|
|
1559
|
-
this.out += "@";
|
|
1560
|
-
this.printNode(node.expression, PREC.Member);
|
|
1561
|
-
break;
|
|
1562
|
-
case "TSTypeAliasDeclaration":
|
|
1563
|
-
this.printTSTypeAliasDeclaration(node);
|
|
1564
|
-
break;
|
|
1565
|
-
case "TSInterfaceDeclaration":
|
|
1566
|
-
this.printTSInterfaceDeclaration(node);
|
|
1567
|
-
break;
|
|
1568
|
-
case "TSEnumDeclaration":
|
|
1569
|
-
this.printTSEnumDeclaration(node);
|
|
1570
|
-
break;
|
|
1571
|
-
case "TSModuleDeclaration":
|
|
1572
|
-
this.printTSModuleDeclaration(node);
|
|
1573
|
-
break;
|
|
1574
|
-
case "TSImportEqualsDeclaration":
|
|
1575
|
-
this.printTSImportEqualsDeclaration(node);
|
|
1576
|
-
break;
|
|
1577
|
-
case "TSExportAssignment":
|
|
1578
|
-
this.out += `export = `;
|
|
1579
|
-
this.printNode(node.expression, PREC.Sequence);
|
|
1580
|
-
this.out += ";";
|
|
1581
|
-
break;
|
|
1582
|
-
case "TSNamespaceExportDeclaration":
|
|
1583
|
-
this.out += `export as namespace ${node.id.name};`;
|
|
1584
|
-
break;
|
|
1585
|
-
default: this.printUnclassifiedNode(node, kind);
|
|
1586
|
-
}
|
|
2052
|
+
printJSXMemberExpression(state, obj);
|
|
2053
|
+
state.out += `.${node.property.name}`;
|
|
2054
|
+
}
|
|
2055
|
+
function printJSXAttribute(state, node) {
|
|
2056
|
+
state.out += jsxAttributeNameText(node.name);
|
|
2057
|
+
state.out += jsxAttributeValueClauseText(state, node.value);
|
|
2058
|
+
}
|
|
2059
|
+
function jsxAttributeValueClauseText(state, value) {
|
|
2060
|
+
if (value === null) return "";
|
|
2061
|
+
return `=${jsxAttributeValueText(state, value)}`;
|
|
2062
|
+
}
|
|
2063
|
+
function jsxAttributeValueText(state, value) {
|
|
2064
|
+
switch (value.type) {
|
|
2065
|
+
case "Literal": return capture(state, () => printLiteral(state, value));
|
|
2066
|
+
case "JSXExpressionContainer": return `{${sequenceNodeText(state, value.expression)}}`;
|
|
2067
|
+
case "JSXElement":
|
|
2068
|
+
case "JSXFragment": return sequenceNodeText(state, value);
|
|
1587
2069
|
}
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
2070
|
+
}
|
|
2071
|
+
function printJSXChild(state, child) {
|
|
2072
|
+
switch (child.type) {
|
|
2073
|
+
case "JSXText":
|
|
2074
|
+
state.out += child.value;
|
|
1592
2075
|
return;
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
}
|
|
1596
|
-
printTypeHolderNode(node, kind) {
|
|
1597
|
-
switch (kind) {
|
|
1598
|
-
case "TSTypeAnnotation":
|
|
1599
|
-
this.out += ": ";
|
|
1600
|
-
this.printTSType(node.typeAnnotation);
|
|
1601
|
-
break;
|
|
1602
|
-
case "TSTypeParameterDeclaration":
|
|
1603
|
-
this.printTSTypeParameterDeclaration(node);
|
|
1604
|
-
break;
|
|
1605
|
-
case "TSTypeParameterInstantiation":
|
|
1606
|
-
this.printTSTypeParameterInstantiation(node);
|
|
1607
|
-
break;
|
|
1608
|
-
case "TSTypeParameter":
|
|
1609
|
-
this.printTSTypeParameter(node);
|
|
1610
|
-
break;
|
|
1611
|
-
default: this.out += `/* unknown:${kind} */`;
|
|
1612
|
-
}
|
|
1613
|
-
}
|
|
1614
|
-
printLiteral(node) {
|
|
1615
|
-
this.out += literalText(node);
|
|
1616
|
-
}
|
|
1617
|
-
printIdentifier(node) {
|
|
1618
|
-
this.out += node.name;
|
|
1619
|
-
}
|
|
1620
|
-
printArrayExpression(node) {
|
|
1621
|
-
this.out += `[${node.elements.map((element) => this.arrayElementText(element)).join(", ")}]`;
|
|
1622
|
-
}
|
|
1623
|
-
arrayElementText(element) {
|
|
1624
|
-
switch (element === null) {
|
|
1625
|
-
case true: return "";
|
|
1626
|
-
default: return this.assignmentNodeText(element);
|
|
1627
|
-
}
|
|
1628
|
-
}
|
|
1629
|
-
printObjectExpression(node) {
|
|
1630
|
-
switch (node.properties.length) {
|
|
1631
|
-
case 0:
|
|
1632
|
-
this.out += "{}";
|
|
1633
|
-
break;
|
|
1634
|
-
default: this.out += `{ ${this.nodeListText(node.properties, PREC.Sequence)} }`;
|
|
1635
|
-
}
|
|
1636
|
-
}
|
|
1637
|
-
printProperty(node) {
|
|
1638
|
-
const fields = node;
|
|
1639
|
-
switch (propertyForm(fields)) {
|
|
1640
|
-
case "accessor":
|
|
1641
|
-
this.out += `${fields.kind} `;
|
|
1642
|
-
this.out += this.propertyKeyText(fields.key, fields.computed === true, PREC.Assignment);
|
|
1643
|
-
this.printFunctionTail(fields.value);
|
|
1644
|
-
break;
|
|
1645
|
-
case "method":
|
|
1646
|
-
this.out += `${flagText(fields.async, "async ")}${flagText(fields.generator, "*")}`;
|
|
1647
|
-
this.out += this.propertyKeyText(fields.key, fields.computed === true, PREC.Assignment);
|
|
1648
|
-
this.printFunctionTail(fields.value);
|
|
1649
|
-
break;
|
|
1650
|
-
case "shorthand":
|
|
1651
|
-
this.out += identifierName(fields.key);
|
|
1652
|
-
break;
|
|
1653
|
-
case "shorthandDefault":
|
|
1654
|
-
this.printShorthandDefaultProperty(fields);
|
|
1655
|
-
break;
|
|
1656
|
-
default:
|
|
1657
|
-
this.out += this.propertyKeyText(fields.key, fields.computed === true, PREC.Assignment);
|
|
1658
|
-
this.out += ": ";
|
|
1659
|
-
this.printNode(fields.value, PREC.Assignment);
|
|
1660
|
-
}
|
|
1661
|
-
}
|
|
1662
|
-
printShorthandDefaultProperty(fields) {
|
|
1663
|
-
const right = this.assignmentNodeText(fields.value.right);
|
|
1664
|
-
this.out += `${identifierName(fields.key)} = ${right}`;
|
|
1665
|
-
}
|
|
1666
|
-
propertyKeyText(key, computed, computedPrec) {
|
|
1667
|
-
switch (computed) {
|
|
1668
|
-
case true: return `[${this.capture(() => this.printNode(key, computedPrec))}]`;
|
|
1669
|
-
default: return this.plainPropertyKeyText(key);
|
|
1670
|
-
}
|
|
1671
|
-
}
|
|
1672
|
-
plainPropertyKeyText(key) {
|
|
1673
|
-
switch (key.type) {
|
|
1674
|
-
case "Identifier": return key.name;
|
|
1675
|
-
case "PrivateIdentifier": return `#${key.name}`;
|
|
1676
|
-
case "Literal": return this.capture(() => this.printLiteral(key));
|
|
1677
|
-
default: return this.capture(() => this.printNode(key, PREC.Assignment));
|
|
1678
|
-
}
|
|
1679
|
-
}
|
|
1680
|
-
printPropertyKeyForClass(key, computed) {
|
|
1681
|
-
this.out += this.propertyKeyText(key, computed, PREC.Sequence);
|
|
1682
|
-
}
|
|
1683
|
-
printFunctionTail(fn) {
|
|
1684
|
-
this.out += this.typeParametersText(fn.typeParameters);
|
|
1685
|
-
this.out += `(${this.paramsText(fn.params)})`;
|
|
1686
|
-
this.out += this.typeAnnotationText(fn.returnType);
|
|
1687
|
-
this.out += this.functionBodyText(fn);
|
|
1688
|
-
}
|
|
1689
|
-
functionBodyText(fn) {
|
|
1690
|
-
switch (Boolean(fn.body)) {
|
|
1691
|
-
case true: return ` ${this.capture(() => this.printBlockStatement(fn.body))}`;
|
|
1692
|
-
default: return ";";
|
|
1693
|
-
}
|
|
1694
|
-
}
|
|
1695
|
-
paramsText(params) {
|
|
1696
|
-
return this.capture(() => this.printParams(params));
|
|
1697
|
-
}
|
|
1698
|
-
typeParametersText(params) {
|
|
1699
|
-
switch (Boolean(params)) {
|
|
1700
|
-
case true: return this.capture(() => this.printTSTypeParameterDeclaration(params));
|
|
1701
|
-
default: return "";
|
|
1702
|
-
}
|
|
1703
|
-
}
|
|
1704
|
-
typeArgumentsText(args) {
|
|
1705
|
-
switch (Boolean(args)) {
|
|
1706
|
-
case true: return this.capture(() => this.printTSTypeParameterInstantiation(args));
|
|
1707
|
-
default: return "";
|
|
1708
|
-
}
|
|
1709
|
-
}
|
|
1710
|
-
typeAnnotationText(annotation) {
|
|
1711
|
-
switch (Boolean(annotation)) {
|
|
1712
|
-
case true: return this.capture(() => this.printTSTypeAnnotation(annotation));
|
|
1713
|
-
default: return "";
|
|
1714
|
-
}
|
|
1715
|
-
}
|
|
1716
|
-
printTemplateLiteral(node) {
|
|
1717
|
-
this.out += `\`${node.quasis.map((quasi, index) => this.quasiText(quasi, node.expressions[index])).join("")}\``;
|
|
1718
|
-
}
|
|
1719
|
-
quasiText(quasi, expression) {
|
|
1720
|
-
switch (quasi.tail) {
|
|
1721
|
-
case true: return quasi.value.raw;
|
|
1722
|
-
default: return `${quasi.value.raw}\${${this.sequenceNodeText(expression)}}`;
|
|
1723
|
-
}
|
|
1724
|
-
}
|
|
1725
|
-
printTaggedTemplate(node) {
|
|
1726
|
-
this.printNode(node.tag, PREC.Member);
|
|
1727
|
-
if (node.typeArguments) this.printTSTypeParameterInstantiation(node.typeArguments);
|
|
1728
|
-
this.printTemplateLiteral(node.quasi);
|
|
1729
|
-
}
|
|
1730
|
-
printMemberExpression(node, _prec) {
|
|
1731
|
-
const access = node;
|
|
1732
|
-
this.out += this.wrappedExpressionText(access.object, PREC.Member, MEMBER_OBJECT_WRAPPED_KINDS);
|
|
1733
|
-
this.out += flagText(access.optional, "?.");
|
|
1734
|
-
this.out += this.memberSelectorText(access);
|
|
1735
|
-
}
|
|
1736
|
-
memberSelectorText(access) {
|
|
1737
|
-
switch (access.computed) {
|
|
1738
|
-
case true: return `[${this.sequenceNodeText(access.property)}]`;
|
|
1739
|
-
default: return `${flagText(!access.optional, ".")}${this.memberPropertyText(access.property)}`;
|
|
1740
|
-
}
|
|
1741
|
-
}
|
|
1742
|
-
memberPropertyText(property) {
|
|
1743
|
-
switch (property.type) {
|
|
1744
|
-
case "Identifier": return property.name;
|
|
1745
|
-
case "PrivateIdentifier": return `#${property.name}`;
|
|
1746
|
-
default: return this.sequenceNodeText(property);
|
|
1747
|
-
}
|
|
1748
|
-
}
|
|
1749
|
-
printCallExpression(node, _prec) {
|
|
1750
|
-
this.out += this.wrappedExpressionText(node.callee, PREC.Member, CALLEE_WRAPPED_KINDS);
|
|
1751
|
-
this.out += flagText(node.optional, "?.");
|
|
1752
|
-
this.out += this.typeArgumentsText(node.typeArguments);
|
|
1753
|
-
this.out += `(${this.nodeListText(node.arguments, PREC.Assignment)})`;
|
|
1754
|
-
}
|
|
1755
|
-
printNewExpression(node, _prec) {
|
|
1756
|
-
this.out += "new ";
|
|
1757
|
-
this.out += this.printExpressionToString(node.callee, PREC.Member);
|
|
1758
|
-
this.out += this.typeArgumentsText(node.typeArguments);
|
|
1759
|
-
this.out += `(${this.nodeListText(node.arguments, PREC.Assignment)})`;
|
|
1760
|
-
}
|
|
1761
|
-
printMetaProperty(node) {
|
|
1762
|
-
this.out += `${node.meta.name}.${node.property.name}`;
|
|
1763
|
-
}
|
|
1764
|
-
printV8Intrinsic(node) {
|
|
1765
|
-
this.out += `%${node.name.name}(${this.nodeListText(node.arguments, PREC.Assignment)})`;
|
|
1766
|
-
}
|
|
1767
|
-
printImportExpression(node) {
|
|
1768
|
-
this.out += `import${flagText(node.phase, `.${node.phase}`)}(`;
|
|
1769
|
-
this.out += this.assignmentNodeText(node.source);
|
|
1770
|
-
this.out += flagText(node.options, `, ${this.assignmentNodeText(node.options)}`);
|
|
1771
|
-
this.out += ")";
|
|
1772
|
-
}
|
|
1773
|
-
printUpdateExpression(node, _prec) {
|
|
1774
|
-
const operand = this.wrappedExpressionText(node.argument, PREC.Update, MEMBER_OBJECT_WRAPPED_KINDS);
|
|
1775
|
-
switch (node.prefix) {
|
|
1776
|
-
case true:
|
|
1777
|
-
this.out += `${node.operator}${operand}`;
|
|
1778
|
-
break;
|
|
1779
|
-
default: this.out += `${operand}${node.operator}`;
|
|
1780
|
-
}
|
|
1781
|
-
}
|
|
1782
|
-
printUnaryExpression(node, _prec) {
|
|
1783
|
-
this.out += node.operator;
|
|
1784
|
-
this.out += flagText(UNARY_WORD_OPERATORS[node.operator] === true, " ");
|
|
1785
|
-
this.out += this.wrappedExpressionText(node.argument, PREC.Unary, UNARY_OPERAND_WRAPPED_KINDS);
|
|
1786
|
-
}
|
|
1787
|
-
printBinaryExpression(node, prec) {
|
|
1788
|
-
const myPrec = binaryPrec(node.operator);
|
|
1789
|
-
const leftStr = this.wrapIfNeeded(node.left, precOf(node.left), myPrec, false, node.operator);
|
|
1790
|
-
const rightStr = this.wrapIfNeeded(node.right, precOf(node.right), myPrec, true, node.operator);
|
|
1791
|
-
const whole = `${leftStr} ${node.operator} ${rightStr}`;
|
|
1792
|
-
if (myPrec < prec) this.out += `(${whole})`;
|
|
1793
|
-
else this.out += whole;
|
|
1794
|
-
}
|
|
1795
|
-
printLogicalExpression(node, prec) {
|
|
1796
|
-
const myPrec = logicalPrec(node.operator);
|
|
1797
|
-
const leftStr = this.wrapIfNeeded(node.left, precOf(node.left), myPrec, false, node.operator);
|
|
1798
|
-
const rightStr = this.wrapIfNeeded(node.right, precOf(node.right), myPrec, true, node.operator);
|
|
1799
|
-
const whole = `${leftStr} ${node.operator} ${rightStr}`;
|
|
1800
|
-
if (myPrec < prec) this.out += `(${whole})`;
|
|
1801
|
-
else this.out += whole;
|
|
1802
|
-
}
|
|
1803
|
-
printConditionalExpression(node, prec) {
|
|
1804
|
-
const myPrec = PREC.Conditional;
|
|
1805
|
-
const whole = `${this.wrapIfNeeded(node.test, precOf(node.test), myPrec, false)} ? ${this.printExpressionToString(node.consequent, PREC.Assignment)} : ${this.printExpressionToString(node.alternate, PREC.Assignment)}`;
|
|
1806
|
-
if (myPrec < prec) this.out += `(${whole})`;
|
|
1807
|
-
else this.out += whole;
|
|
1808
|
-
}
|
|
1809
|
-
printAssignmentExpression(node, prec) {
|
|
1810
|
-
const myPrec = PREC.Assignment;
|
|
1811
|
-
const leftStr = this.printExpressionToString(node.left, myPrec);
|
|
1812
|
-
const rightStr = this.printExpressionToString(node.right, myPrec - .1);
|
|
1813
|
-
const whole = `${leftStr} ${node.operator} ${rightStr}`;
|
|
1814
|
-
if (myPrec < prec) this.out += `(${whole})`;
|
|
1815
|
-
else this.out += whole;
|
|
1816
|
-
}
|
|
1817
|
-
printAssignmentPattern(node, prec) {
|
|
1818
|
-
const left = node.left;
|
|
1819
|
-
const leftText = this.printExpressionToString(node.left, PREC.Assignment) + this.typeAnnotationText(left.typeAnnotation);
|
|
1820
|
-
const rightText = this.printExpressionToString(node.right, PREC.Assignment);
|
|
1821
|
-
this.out += parenthesizedIf(PREC.Assignment < prec, `${leftText} = ${rightText}`);
|
|
1822
|
-
}
|
|
1823
|
-
printObjectPattern(node) {
|
|
1824
|
-
switch (node.properties.length) {
|
|
1825
|
-
case 0:
|
|
1826
|
-
this.out += "{}";
|
|
1827
|
-
break;
|
|
1828
|
-
default: this.out += `{ ${this.nodeListText(node.properties, PREC.Sequence)} }`;
|
|
1829
|
-
}
|
|
1830
|
-
}
|
|
1831
|
-
printArrayPattern(node) {
|
|
1832
|
-
this.out += `[${node.elements.map((element) => this.arrayElementText(element)).join(", ")}]`;
|
|
1833
|
-
}
|
|
1834
|
-
printSequenceExpression(node, prec) {
|
|
1835
|
-
const whole = node.expressions.map((expression) => this.printExpressionToString(expression, PREC.Sequence)).join(", ");
|
|
1836
|
-
this.out += parenthesizedIf(PREC.Sequence < prec, whole);
|
|
1837
|
-
}
|
|
1838
|
-
printYieldExpression(node, _prec) {
|
|
1839
|
-
switch (Boolean(node.delegate)) {
|
|
1840
|
-
case true:
|
|
1841
|
-
this.out += "yield*";
|
|
1842
|
-
break;
|
|
1843
|
-
default: this.out += "yield";
|
|
1844
|
-
}
|
|
1845
|
-
this.out += flagText(node.argument, ` ${this.assignmentNodeText(node.argument)}`);
|
|
1846
|
-
}
|
|
1847
|
-
printArrowFunction(node, prec) {
|
|
1848
|
-
const arrow = `${flagText(node.async, "async ")}${this.typeParametersText(node.typeParameters)}${this.arrowParamsText(node)}${this.typeAnnotationText(node.returnType)} => ${this.arrowBodyText(node)}`;
|
|
1849
|
-
this.out += parenthesizedIf(PREC.Assignment < prec, arrow);
|
|
1850
|
-
}
|
|
1851
|
-
arrowParamsText(node) {
|
|
1852
|
-
const bareParam = bareArrowParamName(node);
|
|
1853
|
-
switch (bareParam.length) {
|
|
1854
|
-
case 0: return `(${this.paramsText(node.params)})`;
|
|
1855
|
-
default: return bareParam;
|
|
1856
|
-
}
|
|
1857
|
-
}
|
|
1858
|
-
arrowBodyText(node) {
|
|
1859
|
-
switch (arrowBodyIsBlock(node.body)) {
|
|
1860
|
-
case true: return this.capture(() => this.printBlockStatement(node.body));
|
|
1861
|
-
default: return this.assignmentNodeText(node.body);
|
|
1862
|
-
}
|
|
1863
|
-
}
|
|
1864
|
-
printFunction(node, _prec) {
|
|
1865
|
-
this.out += functionHeaderText(node);
|
|
1866
|
-
this.printFunctionTail(node);
|
|
1867
|
-
}
|
|
1868
|
-
printClass(node, _prec) {
|
|
1869
|
-
this.out += this.capture(() => this.printDecorators(node.decorators));
|
|
1870
|
-
this.out += `${flagText(node.declare, "declare ")}${flagText(node.abstract, "abstract ")}class${namedDeclarationText(node)}`;
|
|
1871
|
-
this.out += this.typeParametersText(node.typeParameters);
|
|
1872
|
-
this.out += this.classHeritageText(node);
|
|
1873
|
-
this.out += this.classImplementsText(node);
|
|
1874
|
-
this.out += " ";
|
|
1875
|
-
this.printClassBody(node.body);
|
|
1876
|
-
}
|
|
1877
|
-
classHeritageText(node) {
|
|
1878
|
-
switch (Boolean(node.superClass)) {
|
|
1879
|
-
case true: return ` extends ${this.assignmentNodeText(node.superClass)}${this.typeArgumentsText(node.superTypeArguments)}`;
|
|
1880
|
-
default: return "";
|
|
1881
|
-
}
|
|
1882
|
-
}
|
|
1883
|
-
classImplementsText(node) {
|
|
1884
|
-
const rendered = (node.implements ?? []).map((heritage) => this.heritageText(heritage)).join(", ");
|
|
1885
|
-
return flagText(rendered, ` implements ${rendered}`);
|
|
1886
|
-
}
|
|
1887
|
-
heritageText(heritage) {
|
|
1888
|
-
return `${this.assignmentNodeText(heritage.expression)}${this.typeArgumentsText(heritage.typeArguments)}`;
|
|
1889
|
-
}
|
|
1890
|
-
printDecorators(decorators) {
|
|
1891
|
-
const rendered = (decorators ?? []).map((decorator) => this.decoratorText(decorator)).join(" ");
|
|
1892
|
-
this.out += flagText(rendered, `${rendered} `);
|
|
1893
|
-
}
|
|
1894
|
-
decoratorText(decorator) {
|
|
1895
|
-
return `@${this.capture(() => this.printNode(decorator.expression, PREC.Member))}`;
|
|
1896
|
-
}
|
|
1897
|
-
printJSXElement(node) {
|
|
1898
|
-
this.printJSXOpeningElement(node.openingElement);
|
|
1899
|
-
node.children.forEach((child) => this.printJSXChild(child));
|
|
1900
|
-
this.printJSXClosingElement(node);
|
|
1901
|
-
}
|
|
1902
|
-
printJSXClosingElement(node) {
|
|
1903
|
-
if (!node.closingElement) return;
|
|
1904
|
-
this.out += `</${this.jsxElementNameText(node.closingElement.name)}>`;
|
|
1905
|
-
}
|
|
1906
|
-
printJSXFragment(node) {
|
|
1907
|
-
this.out += "<>";
|
|
1908
|
-
for (const child of node.children) this.printJSXChild(child);
|
|
1909
|
-
this.out += "</>";
|
|
1910
|
-
}
|
|
1911
|
-
printJSXOpeningElement(node) {
|
|
1912
|
-
this.out += `<${this.jsxElementNameText(node.name)}`;
|
|
1913
|
-
this.out += this.typeArgumentsText(node.typeArguments);
|
|
1914
|
-
this.out += node.attributes.map((attribute) => ` ${this.sequenceNodeText(attribute)}`).join("");
|
|
1915
|
-
switch (node.selfClosing) {
|
|
1916
|
-
case true:
|
|
1917
|
-
this.out += " />";
|
|
1918
|
-
break;
|
|
1919
|
-
default: this.out += ">";
|
|
1920
|
-
}
|
|
1921
|
-
}
|
|
1922
|
-
jsxElementNameText(name) {
|
|
1923
|
-
switch (name.type) {
|
|
1924
|
-
case "JSXIdentifier": return name.name;
|
|
1925
|
-
case "JSXNamespacedName": return `${name.namespace.name}:${name.name.name}`;
|
|
1926
|
-
default: return this.capture(() => this.printJSXMemberExpression(name));
|
|
1927
|
-
}
|
|
1928
|
-
}
|
|
1929
|
-
printJSXMemberExpression(node) {
|
|
1930
|
-
const obj = node.object;
|
|
1931
|
-
if (obj.type === "JSXIdentifier") this.out += `${obj.name}.${node.property.name}`;
|
|
1932
|
-
else {
|
|
1933
|
-
this.printJSXMemberExpression(obj);
|
|
1934
|
-
this.out += `.${node.property.name}`;
|
|
1935
|
-
}
|
|
1936
|
-
}
|
|
1937
|
-
printJSXAttribute(node) {
|
|
1938
|
-
this.out += jsxAttributeNameText(node.name);
|
|
1939
|
-
this.out += this.jsxAttributeValueClauseText(node.value);
|
|
1940
|
-
}
|
|
1941
|
-
jsxAttributeValueClauseText(value) {
|
|
1942
|
-
switch (nodeKind(value)) {
|
|
1943
|
-
case ABSENT_NODE_KIND: return "";
|
|
1944
|
-
default: return `=${this.jsxAttributeValueText(value)}`;
|
|
1945
|
-
}
|
|
1946
|
-
}
|
|
1947
|
-
jsxAttributeValueText(value) {
|
|
1948
|
-
switch (value.type) {
|
|
1949
|
-
case "Literal": return this.capture(() => this.printLiteral(value));
|
|
1950
|
-
case "JSXExpressionContainer": {
|
|
1951
|
-
const container = value;
|
|
1952
|
-
return `{${this.sequenceNodeText(container.expression)}}`;
|
|
1953
|
-
}
|
|
1954
|
-
default: return this.sequenceNodeText(value);
|
|
1955
|
-
}
|
|
1956
|
-
}
|
|
1957
|
-
printJSXChild(child) {
|
|
1958
|
-
switch (child.type) {
|
|
1959
|
-
case "JSXText":
|
|
1960
|
-
this.out += child.value;
|
|
1961
|
-
break;
|
|
1962
|
-
case "JSXElement":
|
|
1963
|
-
this.printJSXElement(child);
|
|
1964
|
-
break;
|
|
1965
|
-
case "JSXFragment":
|
|
1966
|
-
this.printJSXFragment(child);
|
|
1967
|
-
break;
|
|
1968
|
-
case "JSXExpressionContainer":
|
|
1969
|
-
this.out += "{";
|
|
1970
|
-
this.printNode(child.expression, PREC.Sequence);
|
|
1971
|
-
this.out += "}";
|
|
1972
|
-
break;
|
|
1973
|
-
case "JSXSpreadChild":
|
|
1974
|
-
this.out += "{...";
|
|
1975
|
-
this.printNode(child.expression, PREC.Assignment);
|
|
1976
|
-
this.out += "}";
|
|
1977
|
-
break;
|
|
1978
|
-
default: this.printNode(child, PREC.Sequence);
|
|
1979
|
-
}
|
|
1980
|
-
}
|
|
1981
|
-
printTSAsExpression(node, prec) {
|
|
1982
|
-
const myPrec = PREC.Relational;
|
|
1983
|
-
const whole = `${this.printExpressionToString(node.expression, myPrec)} as ${this.printTSTypeToString(node.typeAnnotation)}`;
|
|
1984
|
-
if (myPrec < prec) this.out += `(${whole})`;
|
|
1985
|
-
else this.out += whole;
|
|
1986
|
-
}
|
|
1987
|
-
printTSSatisfiesExpression(node, prec) {
|
|
1988
|
-
const myPrec = PREC.Relational;
|
|
1989
|
-
const whole = `${this.printExpressionToString(node.expression, myPrec)} satisfies ${this.printTSTypeToString(node.typeAnnotation)}`;
|
|
1990
|
-
if (myPrec < prec) this.out += `(${whole})`;
|
|
1991
|
-
else this.out += whole;
|
|
1992
|
-
}
|
|
1993
|
-
printTSTypeAssertion(node, _prec) {
|
|
1994
|
-
this.out += `<${this.printTSTypeToString(node.typeAnnotation)}>`;
|
|
1995
|
-
this.printNode(node.expression, PREC.Unary);
|
|
1996
|
-
}
|
|
1997
|
-
printTSInstantiationExpression(node, _prec) {
|
|
1998
|
-
this.printNode(node.expression, PREC.Member);
|
|
1999
|
-
this.printTSTypeParameterInstantiation(node.typeArguments);
|
|
2000
|
-
}
|
|
2001
|
-
printStatement(node) {
|
|
2002
|
-
const n = node;
|
|
2003
|
-
this.printAttachedComments(n, "leadingComments");
|
|
2004
|
-
switch (n.type) {
|
|
2005
|
-
case "BlockStatement":
|
|
2006
|
-
this.printBlockStatement(n);
|
|
2007
|
-
break;
|
|
2008
|
-
case "VariableDeclaration":
|
|
2009
|
-
this.printVariableDeclaration(n);
|
|
2010
|
-
this.out += ";";
|
|
2011
|
-
break;
|
|
2012
|
-
case "FunctionDeclaration":
|
|
2013
|
-
case "TSDeclareFunction":
|
|
2014
|
-
this.printFunction(n, PREC.Sequence);
|
|
2015
|
-
break;
|
|
2016
|
-
case "ClassDeclaration":
|
|
2017
|
-
this.printClass(n, PREC.Sequence);
|
|
2018
|
-
break;
|
|
2019
|
-
case "ExpressionStatement":
|
|
2020
|
-
this.printExpressionStatement(n);
|
|
2021
|
-
break;
|
|
2022
|
-
case "IfStatement":
|
|
2023
|
-
this.printIfStatement(n);
|
|
2024
|
-
break;
|
|
2025
|
-
case "ForStatement":
|
|
2026
|
-
this.printForStatement(n);
|
|
2027
|
-
break;
|
|
2028
|
-
case "ForInStatement":
|
|
2029
|
-
this.printForInStatement(n);
|
|
2030
|
-
break;
|
|
2031
|
-
case "ForOfStatement":
|
|
2032
|
-
this.printForOfStatement(n);
|
|
2033
|
-
break;
|
|
2034
|
-
case "WhileStatement":
|
|
2035
|
-
this.printWhileStatement(n);
|
|
2036
|
-
break;
|
|
2037
|
-
case "DoWhileStatement":
|
|
2038
|
-
this.printDoWhileStatement(n);
|
|
2039
|
-
break;
|
|
2040
|
-
case "ReturnStatement":
|
|
2041
|
-
this.printReturnStatement(n);
|
|
2042
|
-
break;
|
|
2043
|
-
case "ThrowStatement":
|
|
2044
|
-
this.out += "throw ";
|
|
2045
|
-
this.printNode(n.argument, PREC.Sequence);
|
|
2046
|
-
this.out += ";";
|
|
2047
|
-
break;
|
|
2048
|
-
case "TryStatement":
|
|
2049
|
-
this.printTryStatement(n);
|
|
2050
|
-
break;
|
|
2051
|
-
case "SwitchStatement":
|
|
2052
|
-
this.printSwitchStatement(n);
|
|
2053
|
-
break;
|
|
2054
|
-
case "LabeledStatement":
|
|
2055
|
-
this.printLabeledStatement(n);
|
|
2056
|
-
break;
|
|
2057
|
-
case "BreakStatement":
|
|
2058
|
-
case "ContinueStatement":
|
|
2059
|
-
case "DebuggerStatement":
|
|
2060
|
-
case "EmptyStatement":
|
|
2061
|
-
this.printNode(n, PREC.Sequence);
|
|
2062
|
-
break;
|
|
2063
|
-
case "WithStatement":
|
|
2064
|
-
this.printWithStatement(n);
|
|
2065
|
-
break;
|
|
2066
|
-
case "ImportDeclaration":
|
|
2067
|
-
this.printImportDeclaration(n);
|
|
2068
|
-
break;
|
|
2069
|
-
case "ExportNamedDeclaration":
|
|
2070
|
-
this.printExportNamedDeclaration(n);
|
|
2071
|
-
break;
|
|
2072
|
-
case "ExportDefaultDeclaration":
|
|
2073
|
-
this.printExportDefaultDeclaration(n);
|
|
2074
|
-
break;
|
|
2075
|
-
case "ExportAllDeclaration":
|
|
2076
|
-
this.printExportAllDeclaration(n);
|
|
2077
|
-
break;
|
|
2078
|
-
case "TSTypeAliasDeclaration":
|
|
2079
|
-
this.printTSTypeAliasDeclaration(n);
|
|
2080
|
-
break;
|
|
2081
|
-
case "TSInterfaceDeclaration":
|
|
2082
|
-
this.printTSInterfaceDeclaration(n);
|
|
2083
|
-
break;
|
|
2084
|
-
case "TSEnumDeclaration":
|
|
2085
|
-
this.printTSEnumDeclaration(n);
|
|
2086
|
-
break;
|
|
2087
|
-
case "TSModuleDeclaration":
|
|
2088
|
-
this.printTSModuleDeclaration(n);
|
|
2089
|
-
break;
|
|
2090
|
-
case "TSImportEqualsDeclaration":
|
|
2091
|
-
this.printTSImportEqualsDeclaration(n);
|
|
2092
|
-
break;
|
|
2093
|
-
case "TSExportAssignment":
|
|
2094
|
-
case "TSNamespaceExportDeclaration":
|
|
2095
|
-
this.printNode(n, PREC.Sequence);
|
|
2096
|
-
break;
|
|
2097
|
-
default: this.printUnhandledStatement(n);
|
|
2098
|
-
}
|
|
2099
|
-
this.printAttachedComments(n, "trailingComments");
|
|
2100
|
-
}
|
|
2101
|
-
printUnhandledStatement(node) {
|
|
2102
|
-
if (!isTSTypeNode(node.type)) throw new Error(`Printer: unhandled statement kind ${node.type}`);
|
|
2103
|
-
this.printTSType(node);
|
|
2104
|
-
this.out += ";";
|
|
2105
|
-
}
|
|
2106
|
-
/**
|
|
2107
|
-
* Emits the comments `attachComments` folded into the tree
|
|
2108
|
-
* (`leadingComments` before the statement, `trailingComments` on the
|
|
2109
|
-
* statement's last line). The flat `opts.comments` path only serves direct
|
|
2110
|
-
* `printProgram` calls on freshly parsed trees; instrumented trees carry
|
|
2111
|
-
* their comments attached to nodes.
|
|
2112
|
-
*/
|
|
2113
|
-
printAttachedComments(node, field) {
|
|
2114
|
-
const comments = node[field];
|
|
2115
|
-
if (!Array.isArray(comments)) return;
|
|
2116
|
-
comments.forEach((comment) => this.printAttachedComment(comment, field));
|
|
2117
|
-
}
|
|
2118
|
-
printAttachedComment(comment, field) {
|
|
2119
|
-
switch (field) {
|
|
2120
|
-
case "leadingComments":
|
|
2121
|
-
this.out += `${this.indent()}${commentText(comment)}\n`;
|
|
2122
|
-
break;
|
|
2123
|
-
default: this.out += `${commentText(comment)} `;
|
|
2124
|
-
}
|
|
2125
|
-
}
|
|
2126
|
-
printBlockStatement(node) {
|
|
2127
|
-
switch (node.body.length) {
|
|
2128
|
-
case 0:
|
|
2129
|
-
this.out += "{}";
|
|
2130
|
-
break;
|
|
2131
|
-
default:
|
|
2132
|
-
this.out += "{\n";
|
|
2133
|
-
this.out += this.indentedBodyText(node.body, (statement) => this.printStatement(statement));
|
|
2134
|
-
this.out += `${this.indent()}}`;
|
|
2135
|
-
}
|
|
2136
|
-
}
|
|
2137
|
-
printExpressionStatement(node) {
|
|
2138
|
-
if (this.isDirective(node.directive)) {
|
|
2139
|
-
this.out += JSON.stringify(node.directive) + ";";
|
|
2076
|
+
case "JSXElement":
|
|
2077
|
+
printJSXElement(state, child);
|
|
2140
2078
|
return;
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
}
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
}
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
}
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
}
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
}
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
}
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
}
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
}
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
const n = node;
|
|
2632
|
-
this.printTupleType(n.elementTypes);
|
|
2633
|
-
break;
|
|
2634
|
-
}
|
|
2635
|
-
case "TSConditionalType": {
|
|
2636
|
-
const n = node;
|
|
2637
|
-
this.doPrintTSType(n.checkType);
|
|
2638
|
-
this.out += " extends ";
|
|
2639
|
-
this.doPrintTSType(n.extendsType);
|
|
2640
|
-
this.out += " ? ";
|
|
2641
|
-
this.doPrintTSType(n.trueType);
|
|
2642
|
-
this.out += " : ";
|
|
2643
|
-
this.doPrintTSType(n.falseType);
|
|
2644
|
-
break;
|
|
2645
|
-
}
|
|
2646
|
-
case "TSInferType": {
|
|
2647
|
-
const n = node;
|
|
2648
|
-
this.out += `infer ${n.typeParameter.name.name}`;
|
|
2649
|
-
this.printTypeClause(" extends ", n.typeParameter.constraint);
|
|
2650
|
-
break;
|
|
2651
|
-
}
|
|
2652
|
-
case "TSTypeQuery": {
|
|
2653
|
-
const n = node;
|
|
2654
|
-
this.out += "typeof ";
|
|
2655
|
-
this.printTypeQueryName(n);
|
|
2656
|
-
this.out += this.typeArgumentsText(n.typeArguments);
|
|
2657
|
-
break;
|
|
2658
|
-
}
|
|
2659
|
-
case "TSImportType":
|
|
2660
|
-
this.printTSImportType(node);
|
|
2661
|
-
break;
|
|
2662
|
-
case "TSTypeOperator": {
|
|
2663
|
-
const n = node;
|
|
2664
|
-
this.out += `${n.operator} `;
|
|
2665
|
-
this.doPrintTSType(n.typeAnnotation);
|
|
2666
|
-
break;
|
|
2667
|
-
}
|
|
2668
|
-
case "TSMappedType":
|
|
2669
|
-
this.printMappedType(node);
|
|
2670
|
-
break;
|
|
2671
|
-
case "TSTemplateLiteralType":
|
|
2672
|
-
this.printTSTemplateLiteral(node);
|
|
2673
|
-
break;
|
|
2674
|
-
case "TSFunctionType":
|
|
2675
|
-
this.printTSFunctionType(node);
|
|
2676
|
-
break;
|
|
2677
|
-
case "TSConstructorType":
|
|
2678
|
-
this.printTSConstructorType(node);
|
|
2679
|
-
break;
|
|
2680
|
-
case "TSTypePredicate":
|
|
2681
|
-
this.printTSTypePredicate(node);
|
|
2682
|
-
break;
|
|
2683
|
-
case "TSIndexedAccessType": {
|
|
2684
|
-
const n = node;
|
|
2685
|
-
this.doPrintTSType(n.objectType);
|
|
2686
|
-
this.out += "[";
|
|
2687
|
-
this.doPrintTSType(n.indexType);
|
|
2688
|
-
this.out += "]";
|
|
2689
|
-
break;
|
|
2690
|
-
}
|
|
2691
|
-
case "TSLiteralType":
|
|
2692
|
-
this.printTSLiteralType(node.literal);
|
|
2693
|
-
break;
|
|
2694
|
-
case "TSParenthesizedType": {
|
|
2695
|
-
const n = node;
|
|
2696
|
-
this.out += "(";
|
|
2697
|
-
this.doPrintTSType(n.typeAnnotation);
|
|
2698
|
-
this.out += ")";
|
|
2699
|
-
break;
|
|
2700
|
-
}
|
|
2701
|
-
case "TSJSDocNullableType":
|
|
2702
|
-
this.printJSDocPostfixModifier(node, "?");
|
|
2703
|
-
break;
|
|
2704
|
-
case "TSJSDocNonNullableType":
|
|
2705
|
-
this.printJSDocPostfixModifier(node, "!");
|
|
2706
|
-
break;
|
|
2707
|
-
case "TSJSDocUnknownType":
|
|
2708
|
-
this.out += "?";
|
|
2709
|
-
break;
|
|
2710
|
-
default: this.out += `/* type:${node.type} */`;
|
|
2711
|
-
}
|
|
2712
|
-
}
|
|
2713
|
-
tSTypeListText(types, separator) {
|
|
2714
|
-
return types.map((type) => this.printTSTypeToString(type)).join(separator);
|
|
2715
|
-
}
|
|
2716
|
-
arrayElementTypeText(type) {
|
|
2717
|
-
const printed = this.printTSTypeToString(type);
|
|
2718
|
-
switch (ARRAY_ELEMENT_WRAPPED_KINDS[type.type] === true) {
|
|
2719
|
-
case true: return `(${printed})`;
|
|
2720
|
-
default: return printed;
|
|
2721
|
-
}
|
|
2722
|
-
}
|
|
2723
|
-
printTSTypeLiteral(members) {
|
|
2724
|
-
const rendered = members.map((member) => this.signatureText(member)).join("; ");
|
|
2725
|
-
switch (members.length) {
|
|
2726
|
-
case 0:
|
|
2727
|
-
this.out += "{}";
|
|
2728
|
-
break;
|
|
2729
|
-
default: this.out += `{ ${rendered} }`;
|
|
2730
|
-
}
|
|
2731
|
-
}
|
|
2732
|
-
signatureText(member) {
|
|
2733
|
-
const printed = this.capture(() => this.printTSSignature(member));
|
|
2734
|
-
switch (printed.endsWith(";")) {
|
|
2735
|
-
case true: return printed.slice(0, -1);
|
|
2736
|
-
default: return printed;
|
|
2737
|
-
}
|
|
2738
|
-
}
|
|
2739
|
-
printTupleType(elements) {
|
|
2740
|
-
this.out += `[${elements.map((element) => this.capture(() => this.printTupleElement(element))).join(", ")}]`;
|
|
2741
|
-
}
|
|
2742
|
-
printTupleElement(element) {
|
|
2743
|
-
const tupleElement = element;
|
|
2744
|
-
switch (tupleElement.type) {
|
|
2745
|
-
case "TSRestType":
|
|
2746
|
-
this.out += "...";
|
|
2747
|
-
this.doPrintTSType(tupleElement.typeAnnotation);
|
|
2748
|
-
break;
|
|
2749
|
-
case "TSOptionalType":
|
|
2750
|
-
this.doPrintTSType(tupleElement.typeAnnotation);
|
|
2751
|
-
this.out += "?";
|
|
2752
|
-
break;
|
|
2753
|
-
case "TSNamedTupleMember":
|
|
2754
|
-
this.printNamedTupleMember(tupleElement);
|
|
2755
|
-
break;
|
|
2756
|
-
default: this.doPrintTSType(tupleElement);
|
|
2757
|
-
}
|
|
2758
|
-
}
|
|
2759
|
-
printNamedTupleMember(member) {
|
|
2760
|
-
this.out += `${member.label.name}${flagText(member.optional, "?")}: `;
|
|
2761
|
-
this.printTupleElement(member.elementType);
|
|
2762
|
-
}
|
|
2763
|
-
printTypeClause(keyword, type) {
|
|
2764
|
-
if (!type) return;
|
|
2765
|
-
this.out += keyword;
|
|
2766
|
-
this.doPrintTSType(type);
|
|
2767
|
-
}
|
|
2768
|
-
printTypeQueryName(node) {
|
|
2769
|
-
switch (node.exprName.type) {
|
|
2770
|
-
case "TSImportType":
|
|
2771
|
-
this.doPrintTSType(node.exprName);
|
|
2772
|
-
break;
|
|
2773
|
-
default: this.printTSTypeName(node.exprName);
|
|
2774
|
-
}
|
|
2775
|
-
}
|
|
2776
|
-
printTSImportType(node) {
|
|
2777
|
-
this.printTSImportTypeSource(node);
|
|
2778
|
-
if (node.qualifier) {
|
|
2779
|
-
this.out += ".";
|
|
2780
|
-
this.printTSImportTypeQualifier(node.qualifier);
|
|
2781
|
-
}
|
|
2782
|
-
this.out += this.typeArgumentsText(node.typeArguments);
|
|
2783
|
-
}
|
|
2784
|
-
printTSImportTypeSource(node) {
|
|
2785
|
-
this.out += `import(${JSON.stringify(node.source.value)}`;
|
|
2786
|
-
this.out += flagText(node.options, `, ${this.assignmentNodeText(node.options)}`);
|
|
2787
|
-
this.out += ")";
|
|
2788
|
-
}
|
|
2789
|
-
printMappedType(node) {
|
|
2790
|
-
this.out += "{ ";
|
|
2791
|
-
this.printMappedTypeModifier(node.readonly, "readonly ");
|
|
2792
|
-
this.out += `[${node.key.name} in `;
|
|
2793
|
-
this.doPrintTSType(node.constraint);
|
|
2794
|
-
this.printTypeClause(" as ", node.nameType);
|
|
2795
|
-
this.out += "]";
|
|
2796
|
-
this.printMappedTypeModifier(node.optional, "?");
|
|
2797
|
-
this.printTypeClause(": ", node.typeAnnotation);
|
|
2798
|
-
this.out += " }";
|
|
2799
|
-
}
|
|
2800
|
-
printMappedTypeModifier(modifier, rendered) {
|
|
2801
|
-
switch (modifier) {
|
|
2802
|
-
case true:
|
|
2803
|
-
this.out += rendered;
|
|
2804
|
-
break;
|
|
2805
|
-
case "+":
|
|
2806
|
-
this.out += `+${rendered}`;
|
|
2807
|
-
break;
|
|
2808
|
-
case "-": this.out += `-${rendered}`;
|
|
2809
|
-
}
|
|
2810
|
-
}
|
|
2811
|
-
printTSTemplateLiteral(node) {
|
|
2812
|
-
this.out += `\`${node.quasis.map((quasi, index) => this.templateTypeQuasiText(quasi, node.types[index])).join("")}\``;
|
|
2813
|
-
}
|
|
2814
|
-
templateTypeQuasiText(quasi, type) {
|
|
2815
|
-
switch (quasi.tail) {
|
|
2816
|
-
case true: return quasi.value.raw;
|
|
2817
|
-
default: return `${quasi.value.raw}\${${this.printTSTypeToString(type)}}`;
|
|
2818
|
-
}
|
|
2819
|
-
}
|
|
2820
|
-
printTSFunctionType(node) {
|
|
2821
|
-
this.out += `${this.typeParametersText(node.typeParameters)}(${this.paramsText(node.params)}) => ${this.printTSTypeToString(node.returnType.typeAnnotation)}`;
|
|
2822
|
-
}
|
|
2823
|
-
printTSConstructorType(node) {
|
|
2824
|
-
this.out += `${flagText(node.abstract, "abstract ")}new ${this.typeParametersText(node.typeParameters)}(${this.paramsText(node.params)}) => ${this.printTSTypeToString(node.returnType.typeAnnotation)}`;
|
|
2825
|
-
}
|
|
2826
|
-
printTSTypePredicate(node) {
|
|
2827
|
-
this.out += flagText(node.asserts, "asserts ");
|
|
2828
|
-
this.out += typePredicateParameterText(node.parameterName);
|
|
2829
|
-
this.printPredicateAnnotation(node);
|
|
2830
|
-
}
|
|
2831
|
-
printPredicateAnnotation(node) {
|
|
2832
|
-
if (!node.typeAnnotation) return;
|
|
2833
|
-
this.printTypeClause(" is ", node.typeAnnotation.typeAnnotation);
|
|
2834
|
-
}
|
|
2835
|
-
printTSLiteralType(literal) {
|
|
2836
|
-
switch (nodeKind(literal)) {
|
|
2837
|
-
case "Literal":
|
|
2838
|
-
this.printLiteral(literal);
|
|
2839
|
-
break;
|
|
2840
|
-
case "TemplateLiteral":
|
|
2841
|
-
this.printTemplateLiteral(literal);
|
|
2842
|
-
break;
|
|
2843
|
-
case "UnaryExpression":
|
|
2844
|
-
this.printTSLiteralUnary(literal);
|
|
2845
|
-
break;
|
|
2846
|
-
default: this.printNode(literal, PREC.Sequence);
|
|
2847
|
-
}
|
|
2848
|
-
}
|
|
2849
|
-
printTSLiteralUnary(unary) {
|
|
2850
|
-
this.out += unary.operator;
|
|
2851
|
-
this.printLiteral(unary.argument);
|
|
2852
|
-
}
|
|
2853
|
-
printJSDocPostfixModifier(node, marker) {
|
|
2854
|
-
switch (Boolean(node.postfix)) {
|
|
2855
|
-
case true:
|
|
2856
|
-
this.doPrintTSType(node.typeAnnotation);
|
|
2857
|
-
this.out += marker;
|
|
2858
|
-
break;
|
|
2859
|
-
default:
|
|
2860
|
-
this.out += marker;
|
|
2861
|
-
this.doPrintTSType(node.typeAnnotation);
|
|
2862
|
-
}
|
|
2863
|
-
}
|
|
2864
|
-
printTSTypeName(name) {
|
|
2865
|
-
switch (nodeKind(name)) {
|
|
2866
|
-
case "TSQualifiedName": {
|
|
2867
|
-
const qualified = name;
|
|
2868
|
-
this.printTSTypeName(qualified.left);
|
|
2869
|
-
this.out += `.${qualified.right.name}`;
|
|
2870
|
-
break;
|
|
2871
|
-
}
|
|
2872
|
-
default: this.out += this.tSTypeNameLeafText(name);
|
|
2873
|
-
}
|
|
2874
|
-
}
|
|
2875
|
-
tSTypeNameLeafText(name) {
|
|
2876
|
-
switch (nodeKind(name)) {
|
|
2877
|
-
case "Identifier": return name.name;
|
|
2878
|
-
case "ThisExpression": return "this";
|
|
2879
|
-
default: return this.sequenceNodeText(name);
|
|
2880
|
-
}
|
|
2079
|
+
case "JSXFragment":
|
|
2080
|
+
printJSXFragment(state, child);
|
|
2081
|
+
return;
|
|
2082
|
+
case "JSXExpressionContainer":
|
|
2083
|
+
state.out += "{";
|
|
2084
|
+
printNodePrec(state, child.expression, PREC.Sequence);
|
|
2085
|
+
state.out += "}";
|
|
2086
|
+
return;
|
|
2087
|
+
case "JSXSpreadChild":
|
|
2088
|
+
state.out += "{...";
|
|
2089
|
+
printNodePrec(state, child.expression, PREC.Assignment);
|
|
2090
|
+
state.out += "}";
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
function printTSAsExpression(state, node, prec) {
|
|
2094
|
+
const myPrec = PREC.Relational;
|
|
2095
|
+
const whole = `${printExpressionToString(state, node.expression, myPrec)} as ${printTSTypeToString(state, node.typeAnnotation)}`;
|
|
2096
|
+
if (myPrec < prec) state.out += `(${whole})`;
|
|
2097
|
+
else state.out += whole;
|
|
2098
|
+
}
|
|
2099
|
+
function printTSSatisfiesExpression(state, node, prec) {
|
|
2100
|
+
const myPrec = PREC.Relational;
|
|
2101
|
+
const whole = `${printExpressionToString(state, node.expression, myPrec)} satisfies ${printTSTypeToString(state, node.typeAnnotation)}`;
|
|
2102
|
+
if (myPrec < prec) state.out += `(${whole})`;
|
|
2103
|
+
else state.out += whole;
|
|
2104
|
+
}
|
|
2105
|
+
function printTSTypeAssertion(state, node, _prec) {
|
|
2106
|
+
state.out += `<${printTSTypeToString(state, node.typeAnnotation)}>`;
|
|
2107
|
+
printNodePrec(state, node.expression, PREC.Unary);
|
|
2108
|
+
}
|
|
2109
|
+
function printTSInstantiationExpression(state, node, _prec) {
|
|
2110
|
+
printNodePrec(state, node.expression, PREC.Member);
|
|
2111
|
+
printTSTypeParameterInstantiation(state, node.typeArguments);
|
|
2112
|
+
}
|
|
2113
|
+
function printStatement(state, node) {
|
|
2114
|
+
printAttachedComments(state, node, "leadingComments");
|
|
2115
|
+
printStatementKind(state, node);
|
|
2116
|
+
printAttachedComments(state, node, "trailingComments");
|
|
2117
|
+
}
|
|
2118
|
+
function printStatementKind(state, node) {
|
|
2119
|
+
switch (node.type) {
|
|
2120
|
+
case "BlockStatement":
|
|
2121
|
+
printBlockStatement(state, node);
|
|
2122
|
+
break;
|
|
2123
|
+
case "VariableDeclaration":
|
|
2124
|
+
printVariableDeclaration(state, node);
|
|
2125
|
+
state.out += ";";
|
|
2126
|
+
break;
|
|
2127
|
+
case "FunctionDeclaration":
|
|
2128
|
+
case "FunctionExpression":
|
|
2129
|
+
case "TSDeclareFunction":
|
|
2130
|
+
case "TSEmptyBodyFunctionExpression":
|
|
2131
|
+
printFunction(state, node, PREC.Sequence);
|
|
2132
|
+
break;
|
|
2133
|
+
case "ClassDeclaration":
|
|
2134
|
+
case "ClassExpression":
|
|
2135
|
+
printClass(state, node, PREC.Sequence);
|
|
2136
|
+
break;
|
|
2137
|
+
case "ExpressionStatement":
|
|
2138
|
+
printExpressionStatement(state, node);
|
|
2139
|
+
break;
|
|
2140
|
+
case "IfStatement":
|
|
2141
|
+
printIfStatement(state, node);
|
|
2142
|
+
break;
|
|
2143
|
+
case "ForStatement":
|
|
2144
|
+
printForStatement(state, node);
|
|
2145
|
+
break;
|
|
2146
|
+
case "ForInStatement":
|
|
2147
|
+
printForInStatement(state, node);
|
|
2148
|
+
break;
|
|
2149
|
+
case "ForOfStatement":
|
|
2150
|
+
printForOfStatement(state, node);
|
|
2151
|
+
break;
|
|
2152
|
+
case "WhileStatement":
|
|
2153
|
+
printWhileStatement(state, node);
|
|
2154
|
+
break;
|
|
2155
|
+
case "DoWhileStatement":
|
|
2156
|
+
printDoWhileStatement(state, node);
|
|
2157
|
+
break;
|
|
2158
|
+
case "ReturnStatement":
|
|
2159
|
+
printReturnStatement(state, node);
|
|
2160
|
+
break;
|
|
2161
|
+
case "ThrowStatement":
|
|
2162
|
+
state.out += "throw ";
|
|
2163
|
+
printNodePrec(state, node.argument, PREC.Sequence);
|
|
2164
|
+
state.out += ";";
|
|
2165
|
+
break;
|
|
2166
|
+
case "TryStatement":
|
|
2167
|
+
printTryStatement(state, node);
|
|
2168
|
+
break;
|
|
2169
|
+
case "SwitchStatement":
|
|
2170
|
+
printSwitchStatement(state, node);
|
|
2171
|
+
break;
|
|
2172
|
+
case "LabeledStatement":
|
|
2173
|
+
printLabeledStatement(state, node);
|
|
2174
|
+
break;
|
|
2175
|
+
case "BreakStatement":
|
|
2176
|
+
case "ContinueStatement":
|
|
2177
|
+
case "DebuggerStatement":
|
|
2178
|
+
case "EmptyStatement":
|
|
2179
|
+
printNodePrec(state, node, PREC.Sequence);
|
|
2180
|
+
break;
|
|
2181
|
+
case "WithStatement":
|
|
2182
|
+
printWithStatement(state, node);
|
|
2183
|
+
break;
|
|
2184
|
+
case "ImportDeclaration":
|
|
2185
|
+
printImportDeclaration(state, node);
|
|
2186
|
+
break;
|
|
2187
|
+
case "ExportNamedDeclaration":
|
|
2188
|
+
printExportNamedDeclaration(state, node);
|
|
2189
|
+
break;
|
|
2190
|
+
case "ExportDefaultDeclaration":
|
|
2191
|
+
printExportDefaultDeclaration(state, node);
|
|
2192
|
+
break;
|
|
2193
|
+
case "ExportAllDeclaration":
|
|
2194
|
+
printExportAllDeclaration(state, node);
|
|
2195
|
+
break;
|
|
2196
|
+
case "TSTypeAliasDeclaration":
|
|
2197
|
+
printTSTypeAliasDeclaration(state, node);
|
|
2198
|
+
break;
|
|
2199
|
+
case "TSInterfaceDeclaration":
|
|
2200
|
+
printTSInterfaceDeclaration(state, node);
|
|
2201
|
+
break;
|
|
2202
|
+
case "TSEnumDeclaration":
|
|
2203
|
+
printTSEnumDeclaration(state, node);
|
|
2204
|
+
break;
|
|
2205
|
+
case "TSModuleDeclaration":
|
|
2206
|
+
printTSModuleDeclaration(state, node);
|
|
2207
|
+
break;
|
|
2208
|
+
case "TSImportEqualsDeclaration":
|
|
2209
|
+
printTSImportEqualsDeclaration(state, node);
|
|
2210
|
+
break;
|
|
2211
|
+
case "TSExportAssignment":
|
|
2212
|
+
case "TSNamespaceExportDeclaration": printNodePrec(state, node, PREC.Sequence);
|
|
2213
|
+
}
|
|
2214
|
+
}
|
|
2215
|
+
function printAttachedComments(state, node, field) {
|
|
2216
|
+
const comments = node[field];
|
|
2217
|
+
if (comments === void 0) return;
|
|
2218
|
+
comments.forEach((comment) => printAttachedComment(state, comment, field));
|
|
2219
|
+
}
|
|
2220
|
+
function printAttachedComment(state, comment, field) {
|
|
2221
|
+
if (field === "leadingComments") {
|
|
2222
|
+
state.out += `${indent(state)}${commentText(comment)}\n`;
|
|
2223
|
+
return;
|
|
2224
|
+
}
|
|
2225
|
+
state.out += `${commentText(comment)} `;
|
|
2226
|
+
}
|
|
2227
|
+
function printBlockStatement(state, node) {
|
|
2228
|
+
switch (node.body.length) {
|
|
2229
|
+
case 0:
|
|
2230
|
+
state.out += "{}";
|
|
2231
|
+
break;
|
|
2232
|
+
default:
|
|
2233
|
+
state.out += "{\n";
|
|
2234
|
+
state.out += indentedBodyText(state, node.body, (statement) => printStatement(state, statement));
|
|
2235
|
+
state.out += `${indent(state)}}`;
|
|
2236
|
+
}
|
|
2237
|
+
}
|
|
2238
|
+
function printExpressionStatement(state, node) {
|
|
2239
|
+
if (isDirective(node.directive)) {
|
|
2240
|
+
state.out += JSON.stringify(node.directive) + ";";
|
|
2241
|
+
return;
|
|
2242
|
+
}
|
|
2243
|
+
printNodePrec(state, node.expression, PREC.Sequence);
|
|
2244
|
+
state.out += ";";
|
|
2245
|
+
}
|
|
2246
|
+
function isDirective(directive) {
|
|
2247
|
+
return directive != null && directive !== "";
|
|
2248
|
+
}
|
|
2249
|
+
function printIfStatement(state, node) {
|
|
2250
|
+
state.out += "if (";
|
|
2251
|
+
printNodePrec(state, node.test, PREC.Sequence);
|
|
2252
|
+
state.out += ") ";
|
|
2253
|
+
printStatementOrBlock(state, node.consequent);
|
|
2254
|
+
if (node.alternate !== null) {
|
|
2255
|
+
state.out += " else ";
|
|
2256
|
+
printStatementOrBlock(state, node.alternate);
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2259
|
+
function printStatementOrBlock(state, node) {
|
|
2260
|
+
if (node.type === "BlockStatement") {
|
|
2261
|
+
printBlockStatement(state, node);
|
|
2262
|
+
return;
|
|
2263
|
+
}
|
|
2264
|
+
printStatement(state, node);
|
|
2265
|
+
}
|
|
2266
|
+
function printWhileStatement(state, node) {
|
|
2267
|
+
state.out += "while (";
|
|
2268
|
+
printNodePrec(state, node.test, PREC.Sequence);
|
|
2269
|
+
state.out += ") ";
|
|
2270
|
+
printStatementOrBlock(state, node.body);
|
|
2271
|
+
}
|
|
2272
|
+
function printDoWhileStatement(state, node) {
|
|
2273
|
+
state.out += "do ";
|
|
2274
|
+
printStatementOrBlock(state, node.body);
|
|
2275
|
+
state.out += " while (";
|
|
2276
|
+
printNodePrec(state, node.test, PREC.Sequence);
|
|
2277
|
+
state.out += ");";
|
|
2278
|
+
}
|
|
2279
|
+
function printForStatement(state, node) {
|
|
2280
|
+
state.out += "for (";
|
|
2281
|
+
printDeclarationOrExpression(state, node.init);
|
|
2282
|
+
state.out += "; ";
|
|
2283
|
+
state.out += optionalSequenceText(state, node.test);
|
|
2284
|
+
state.out += "; ";
|
|
2285
|
+
state.out += optionalSequenceText(state, node.update);
|
|
2286
|
+
state.out += ") ";
|
|
2287
|
+
printStatementOrBlock(state, node.body);
|
|
2288
|
+
}
|
|
2289
|
+
function printDeclarationOrExpression(state, node) {
|
|
2290
|
+
if (node == null) return;
|
|
2291
|
+
printDeclarationOrExpressionNode(state, node);
|
|
2292
|
+
}
|
|
2293
|
+
function printDeclarationOrExpressionNode(state, node) {
|
|
2294
|
+
if (node.type === "VariableDeclaration") {
|
|
2295
|
+
printVariableDeclaration(state, node);
|
|
2296
|
+
return;
|
|
2297
|
+
}
|
|
2298
|
+
printNodePrec(state, node, PREC.Sequence);
|
|
2299
|
+
}
|
|
2300
|
+
function optionalSequenceText(state, node) {
|
|
2301
|
+
if (node == null) return "";
|
|
2302
|
+
return sequenceNodeText(state, node);
|
|
2303
|
+
}
|
|
2304
|
+
function printForInStatement(state, node) {
|
|
2305
|
+
state.out += "for (";
|
|
2306
|
+
if (node.left.type === "VariableDeclaration") printVariableDeclaration(state, node.left);
|
|
2307
|
+
else printNodePrec(state, node.left, PREC.Sequence);
|
|
2308
|
+
state.out += " in ";
|
|
2309
|
+
printNodePrec(state, node.right, PREC.Sequence);
|
|
2310
|
+
state.out += ") ";
|
|
2311
|
+
printStatementOrBlock(state, node.body);
|
|
2312
|
+
}
|
|
2313
|
+
function printForOfStatement(state, node) {
|
|
2314
|
+
if (node.await) state.out += "for await (";
|
|
2315
|
+
else state.out += "for (";
|
|
2316
|
+
printDeclarationOrExpression(state, node.left);
|
|
2317
|
+
state.out += " of ";
|
|
2318
|
+
state.out += sequenceNodeText(state, node.right);
|
|
2319
|
+
state.out += ") ";
|
|
2320
|
+
printStatementOrBlock(state, node.body);
|
|
2321
|
+
}
|
|
2322
|
+
function printReturnStatement(state, node) {
|
|
2323
|
+
if (node.argument !== null) {
|
|
2324
|
+
state.out += "return ";
|
|
2325
|
+
printNodePrec(state, node.argument, PREC.Sequence);
|
|
2326
|
+
state.out += ";";
|
|
2327
|
+
return;
|
|
2328
|
+
}
|
|
2329
|
+
state.out += "return;";
|
|
2330
|
+
}
|
|
2331
|
+
function printWithStatement(state, node) {
|
|
2332
|
+
state.out += "with (";
|
|
2333
|
+
printNodePrec(state, node.object, PREC.Sequence);
|
|
2334
|
+
state.out += ") ";
|
|
2335
|
+
printStatementOrBlock(state, node.body);
|
|
2336
|
+
}
|
|
2337
|
+
function printSwitchStatement(state, node) {
|
|
2338
|
+
state.out += `switch (${sequenceNodeText(state, node.discriminant)}) {\n`;
|
|
2339
|
+
state.indentLevel++;
|
|
2340
|
+
state.out += node.cases.map((switchCase) => `${indent(state)}${capture(state, () => printSwitchCase(state, switchCase))}`).join("");
|
|
2341
|
+
state.indentLevel--;
|
|
2342
|
+
state.out += `${indent(state)}}`;
|
|
2343
|
+
}
|
|
2344
|
+
function printSwitchCase(state, node) {
|
|
2345
|
+
state.out += switchCaseHeaderText(state, node);
|
|
2346
|
+
state.out += indentedBodyText(state, node.consequent, (statement) => printStatement(state, statement));
|
|
2347
|
+
}
|
|
2348
|
+
function switchCaseHeaderText(state, node) {
|
|
2349
|
+
if (node.test !== null) return `case ${sequenceNodeText(state, node.test)}:\n`;
|
|
2350
|
+
return "default:\n";
|
|
2351
|
+
}
|
|
2352
|
+
function printLabeledStatement(state, node) {
|
|
2353
|
+
state.out += `${node.label.name}: `;
|
|
2354
|
+
printStatement(state, node.body);
|
|
2355
|
+
}
|
|
2356
|
+
function printTryStatement(state, node) {
|
|
2357
|
+
state.out += "try ";
|
|
2358
|
+
printBlockStatement(state, node.block);
|
|
2359
|
+
printCatchClause(state, node.handler);
|
|
2360
|
+
printFinallyClause(state, node.finalizer);
|
|
2361
|
+
}
|
|
2362
|
+
function printCatchClause(state, handler) {
|
|
2363
|
+
if (handler == null) return;
|
|
2364
|
+
state.out += ` catch${catchParamText(state, handler.param)} `;
|
|
2365
|
+
printBlockStatement(state, handler.body);
|
|
2366
|
+
}
|
|
2367
|
+
function catchParamText(state, param) {
|
|
2368
|
+
if (param == null) return "";
|
|
2369
|
+
return ` (${catchParamBodyText(state, param)})`;
|
|
2370
|
+
}
|
|
2371
|
+
function catchParamBodyText(state, param) {
|
|
2372
|
+
if (param.type === "Identifier") return identifierWithOptionalText(state, param);
|
|
2373
|
+
return sequenceNodeText(state, param);
|
|
2374
|
+
}
|
|
2375
|
+
function printFinallyClause(state, finalizer) {
|
|
2376
|
+
if (finalizer == null) return;
|
|
2377
|
+
state.out += " finally ";
|
|
2378
|
+
printBlockStatement(state, finalizer);
|
|
2379
|
+
}
|
|
2380
|
+
function printVariableDeclaration(state, node) {
|
|
2381
|
+
state.out += `${flagText(node.declare, "declare ")}${node.kind} `;
|
|
2382
|
+
state.out += node.declarations.map((declaration) => variableDeclaratorText(state, declaration)).join(", ");
|
|
2383
|
+
}
|
|
2384
|
+
function variableDeclaratorText(state, node) {
|
|
2385
|
+
return capture(state, () => printVariableDeclarator(state, node));
|
|
2386
|
+
}
|
|
2387
|
+
function printVariableDeclarator(state, node) {
|
|
2388
|
+
state.out += bindingTargetText(state, node.id);
|
|
2389
|
+
state.out += flagText(node.definite, "!");
|
|
2390
|
+
state.out += typeAnnotationText(state, bindingTypeAnnotation(node.id));
|
|
2391
|
+
state.out += initializerText(state, node.init);
|
|
2392
|
+
}
|
|
2393
|
+
function bindingTargetText(state, id) {
|
|
2394
|
+
if (id.type === "Identifier") return `${bindingNameText(id)}${flagText(id.optional, "?")}`;
|
|
2395
|
+
return sequenceNodeText(state, id);
|
|
2396
|
+
}
|
|
2397
|
+
function identifierWithOptionalText(state, node) {
|
|
2398
|
+
return `${bindingNameText(node)}${flagText(node.optional, "?")}${typeAnnotationText(state, node.typeAnnotation)}`;
|
|
2399
|
+
}
|
|
2400
|
+
function printParams(state, params) {
|
|
2401
|
+
state.out += params.map((param) => paramText(state, param)).join(", ");
|
|
2402
|
+
}
|
|
2403
|
+
function paramText(state, param) {
|
|
2404
|
+
switch (param.type) {
|
|
2405
|
+
case "RestElement": return restParamText(state, param);
|
|
2406
|
+
case "TSParameterProperty": return parameterPropertyText(state, param);
|
|
2407
|
+
case "Identifier":
|
|
2408
|
+
case "ObjectPattern":
|
|
2409
|
+
case "ArrayPattern":
|
|
2410
|
+
case "AssignmentPattern": return formalParameterText(state, param);
|
|
2411
|
+
}
|
|
2412
|
+
}
|
|
2413
|
+
function restParamText(state, param) {
|
|
2414
|
+
return `...${assignmentNodeText(state, param.argument)}${typeAnnotationText(state, param.typeAnnotation)}`;
|
|
2415
|
+
}
|
|
2416
|
+
function parameterPropertyText(state, param) {
|
|
2417
|
+
return `${capture(state, () => printDecorators(state, param.decorators))}${parameterPropertyModifiers(param)}${parameterPropertyTargetText(state, param.parameter)}`;
|
|
2418
|
+
}
|
|
2419
|
+
function parameterPropertyTargetText(state, parameter) {
|
|
2420
|
+
if (parameter.type === "Identifier") return identifierWithOptionalText(state, parameter);
|
|
2421
|
+
return sequenceNodeText(state, parameter);
|
|
2422
|
+
}
|
|
2423
|
+
function formalParameterText(state, param) {
|
|
2424
|
+
return `${capture(state, () => printDecorators(state, param.decorators))}${formalParameterBodyText(state, param)}`;
|
|
2425
|
+
}
|
|
2426
|
+
function formalParameterBodyText(state, param) {
|
|
2427
|
+
if (param.type === "Identifier") return identifierWithOptionalText(state, param);
|
|
2428
|
+
return `${assignmentNodeText(state, param)}${typeAnnotationText(state, bindingTypeAnnotation(param))}`;
|
|
2429
|
+
}
|
|
2430
|
+
function printClassBody(state, node) {
|
|
2431
|
+
switch (node.body.length) {
|
|
2432
|
+
case 0:
|
|
2433
|
+
state.out += "{}";
|
|
2434
|
+
break;
|
|
2435
|
+
default:
|
|
2436
|
+
state.out += "{\n";
|
|
2437
|
+
state.out += indentedBodyText(state, node.body, (element) => printNodePrec(state, element, PREC.Sequence));
|
|
2438
|
+
state.out += `${indent(state)}}`;
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
function indentedBodyText(state, items, print) {
|
|
2442
|
+
state.indentLevel++;
|
|
2443
|
+
const body = items.map((item) => `${indent(state)}${capture(state, () => print(item))}\n`).join("");
|
|
2444
|
+
state.indentLevel--;
|
|
2445
|
+
return body;
|
|
2446
|
+
}
|
|
2447
|
+
function printMethodDefinition(state, node) {
|
|
2448
|
+
const fn = node.value;
|
|
2449
|
+
state.out += capture(state, () => printDecorators(state, node.decorators));
|
|
2450
|
+
state.out += methodDefinitionPrefix(node, fn);
|
|
2451
|
+
state.out += propertyKeyText(state, node.key, node.computed === true, PREC.Sequence);
|
|
2452
|
+
state.out += flagText(node.optional, "?");
|
|
2453
|
+
printFunctionTail(state, fn);
|
|
2454
|
+
}
|
|
2455
|
+
function printPropertyDefinition(state, node) {
|
|
2456
|
+
state.out += capture(state, () => printDecorators(state, node.decorators));
|
|
2457
|
+
state.out += propertyDefinitionModifiers(node);
|
|
2458
|
+
state.out += propertyKeyText(state, node.key, node.computed === true, PREC.Sequence);
|
|
2459
|
+
state.out += flagText(node.optional, "?");
|
|
2460
|
+
state.out += flagText(node.definite, "!");
|
|
2461
|
+
state.out += typeAnnotationText(state, node.typeAnnotation);
|
|
2462
|
+
state.out += initializerText(state, node.value);
|
|
2463
|
+
state.out += ";";
|
|
2464
|
+
}
|
|
2465
|
+
function printAccessorProperty(state, node) {
|
|
2466
|
+
state.out += capture(state, () => printDecorators(state, node.decorators));
|
|
2467
|
+
state.out += flagText(node.accessibility, `${node.accessibility} `);
|
|
2468
|
+
state.out += flagText(node.static, "static ");
|
|
2469
|
+
state.out += flagText(node.override, "override ");
|
|
2470
|
+
state.out += "accessor ";
|
|
2471
|
+
state.out += propertyKeyText(state, node.key, node.computed === true, PREC.Sequence);
|
|
2472
|
+
state.out += flagText(node.definite, "!");
|
|
2473
|
+
state.out += typeAnnotationText(state, node.typeAnnotation);
|
|
2474
|
+
state.out += initializerText(state, node.value);
|
|
2475
|
+
state.out += ";";
|
|
2476
|
+
}
|
|
2477
|
+
function initializerText(state, value) {
|
|
2478
|
+
return flagText(value, ` = ${assignmentNodeText(state, value)}`);
|
|
2479
|
+
}
|
|
2480
|
+
function printStaticBlock(state, node) {
|
|
2481
|
+
state.out += "static {\n";
|
|
2482
|
+
state.indentLevel++;
|
|
2483
|
+
for (const stmt of node.body) {
|
|
2484
|
+
state.out += indent(state);
|
|
2485
|
+
printStatement(state, stmt);
|
|
2486
|
+
state.out += "\n";
|
|
2487
|
+
}
|
|
2488
|
+
state.indentLevel--;
|
|
2489
|
+
state.out += `${indent(state)}}`;
|
|
2490
|
+
}
|
|
2491
|
+
function printImportDeclaration(state, node) {
|
|
2492
|
+
const source = printImportSource(node.source, node.attributes);
|
|
2493
|
+
state.out += `import ${importKindText(node)}${importClauseText(node, source)};`;
|
|
2494
|
+
}
|
|
2495
|
+
function importClauseText(node, source) {
|
|
2496
|
+
if (node.specifiers.length === 0) return source;
|
|
2497
|
+
return `${importBindingsText(node.specifiers)} from ${source}`;
|
|
2498
|
+
}
|
|
2499
|
+
function printImportSource(source, attrs) {
|
|
2500
|
+
return `${source.raw ?? JSON.stringify(source.value)}${importAttributesText(attrs)}`;
|
|
2501
|
+
}
|
|
2502
|
+
function printExportNamedDeclaration(state, node) {
|
|
2503
|
+
const declaration = node.declaration;
|
|
2504
|
+
if (declaration !== null) {
|
|
2505
|
+
state.out += `export ${capture(state, () => printStatement(state, declaration))}`;
|
|
2506
|
+
return;
|
|
2507
|
+
}
|
|
2508
|
+
state.out += `export ${flagText(node.exportKind === "type", "type ")}{ ${node.specifiers.map((specifier) => exportSpecifierText(specifier)).join(", ")} }${exportSourceClauseText(node)};`;
|
|
2509
|
+
}
|
|
2510
|
+
function exportSourceClauseText(node) {
|
|
2511
|
+
if (node.source === null) return "";
|
|
2512
|
+
return ` from ${JSON.stringify(node.source.value)}${importAttributesText(node.attributes)}`;
|
|
2513
|
+
}
|
|
2514
|
+
function printExportDefaultDeclaration(state, node) {
|
|
2515
|
+
state.out += "export default ";
|
|
2516
|
+
printExportDefaultDeclarationBody(state, node.declaration);
|
|
2517
|
+
}
|
|
2518
|
+
function printExportDefaultDeclarationBody(state, declaration) {
|
|
2519
|
+
if (isBareDefaultExport(declaration)) {
|
|
2520
|
+
printStatement(state, declaration);
|
|
2521
|
+
return;
|
|
2522
|
+
}
|
|
2523
|
+
printNodePrec(state, declaration, PREC.Assignment);
|
|
2524
|
+
state.out += ";";
|
|
2525
|
+
}
|
|
2526
|
+
function printExportAllDeclaration(state, node) {
|
|
2527
|
+
state.out += `export ${flagText(node.exportKind === "type", "type ")}*${exportedNameClauseText(node.exported)}`;
|
|
2528
|
+
state.out += ` from ${JSON.stringify(node.source.value)}${importAttributesText(node.attributes)};`;
|
|
2529
|
+
}
|
|
2530
|
+
function printTSTypeAliasDeclaration(state, node) {
|
|
2531
|
+
state.out += `${flagText(node.declare, "declare ")}type ${node.id.name}${typeParametersText(state, node.typeParameters)} = ${printTSTypeToString(state, node.typeAnnotation)};`;
|
|
2532
|
+
}
|
|
2533
|
+
function printTSInterfaceDeclaration(state, node) {
|
|
2534
|
+
state.out += `${flagText(node.declare, "declare ")}interface ${node.id.name}${typeParametersText(state, node.typeParameters)}`;
|
|
2535
|
+
state.out += interfaceExtendsText(state, node.extends);
|
|
2536
|
+
state.out += " ";
|
|
2537
|
+
printTSInterfaceBody(state, node.body);
|
|
2538
|
+
}
|
|
2539
|
+
function interfaceExtendsText(state, extensions) {
|
|
2540
|
+
const rendered = extensions.map((heritage) => heritageText(state, heritage)).join(", ");
|
|
2541
|
+
return flagText(rendered, ` extends ${rendered}`);
|
|
2542
|
+
}
|
|
2543
|
+
function printTSInterfaceBody(state, node) {
|
|
2544
|
+
switch (node.body.length) {
|
|
2545
|
+
case 0:
|
|
2546
|
+
state.out += "{}";
|
|
2547
|
+
break;
|
|
2548
|
+
default:
|
|
2549
|
+
state.out += "{\n";
|
|
2550
|
+
state.out += indentedBodyText(state, node.body, (member) => printTSSignature(state, member));
|
|
2551
|
+
state.out += `${indent(state)}}`;
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
function printTSSignature(state, sig) {
|
|
2555
|
+
switch (sig.type) {
|
|
2556
|
+
case "TSPropertySignature":
|
|
2557
|
+
printTSPropertySignature(state, sig);
|
|
2558
|
+
return;
|
|
2559
|
+
case "TSIndexSignature":
|
|
2560
|
+
printTSIndexSignature(state, sig);
|
|
2561
|
+
return;
|
|
2562
|
+
case "TSCallSignatureDeclaration":
|
|
2563
|
+
printTSCallSignature(state, sig);
|
|
2564
|
+
return;
|
|
2565
|
+
case "TSConstructSignatureDeclaration":
|
|
2566
|
+
printTSConstructSignature(state, sig);
|
|
2567
|
+
return;
|
|
2568
|
+
case "TSMethodSignature": printTSMethodSignature(state, sig);
|
|
2881
2569
|
}
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2570
|
+
}
|
|
2571
|
+
function printTSPropertySignature(state, node) {
|
|
2572
|
+
state.out += `${flagText(node.readonly, "readonly ")}${propertyKeyText(state, node.key, node.computed === true, PREC.Sequence)}${flagText(node.optional, "?")}${typeAnnotationText(state, node.typeAnnotation)};`;
|
|
2573
|
+
}
|
|
2574
|
+
function printTSIndexSignature(state, node) {
|
|
2575
|
+
const parameters = node.parameters.map((parameter) => indexParameterText(state, parameter)).join(", ");
|
|
2576
|
+
state.out += `${flagText(node.readonly, "readonly ")}${flagText(node.static, "static ")}[${parameters}]${typeAnnotationText(state, node.typeAnnotation)};`;
|
|
2577
|
+
}
|
|
2578
|
+
function indexParameterText(state, parameter) {
|
|
2579
|
+
return `${parameter.name}: ${printTSTypeToString(state, parameter.typeAnnotation.typeAnnotation)}`;
|
|
2580
|
+
}
|
|
2581
|
+
function printTSCallSignature(state, node) {
|
|
2582
|
+
state.out += `${typeParametersText(state, node.typeParameters)}(${paramsText(state, node.params)})${typeAnnotationText(state, node.returnType)};`;
|
|
2583
|
+
}
|
|
2584
|
+
function printTSConstructSignature(state, node) {
|
|
2585
|
+
state.out += `new ${typeParametersText(state, node.typeParameters)}(${paramsText(state, node.params)})${typeAnnotationText(state, node.returnType)};`;
|
|
2586
|
+
}
|
|
2587
|
+
function printTSMethodSignature(state, node) {
|
|
2588
|
+
state.out += `${methodKindText(node.kind)}${propertyKeyText(state, node.key, node.computed === true, PREC.Sequence)}${flagText(node.optional, "?")}${typeParametersText(state, node.typeParameters)}(${paramsText(state, node.params)})${typeAnnotationText(state, node.returnType)};`;
|
|
2589
|
+
}
|
|
2590
|
+
function printTSEnumDeclaration(state, node) {
|
|
2591
|
+
state.out += `${flagText(node.declare, "declare ")}${flagText(node.const, "const ")}enum ${node.id.name} {\n`;
|
|
2592
|
+
state.out += indentedBodyText(state, node.body.members, (member) => printEnumMember(state, member));
|
|
2593
|
+
state.out += `${indent(state)}}`;
|
|
2594
|
+
}
|
|
2595
|
+
function printEnumMember(state, member) {
|
|
2596
|
+
state.out += `${identifierOrLiteralNameText(state, member.id)}${initializerText(state, member.initializer)},`;
|
|
2597
|
+
}
|
|
2598
|
+
function identifierOrLiteralNameText(state, id) {
|
|
2599
|
+
switch (nodeKind(id)) {
|
|
2600
|
+
case "Identifier": return identifierNameText(id);
|
|
2601
|
+
case "Literal": return literalCapture(state, id);
|
|
2602
|
+
default: return sequenceNodeText(state, id);
|
|
2894
2603
|
}
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2604
|
+
}
|
|
2605
|
+
function printTSModuleDeclaration(state, node) {
|
|
2606
|
+
state.out += `${flagText(node.declare, "declare ")}${moduleHeaderText(state, node)}${moduleBodyText(state, node)}`;
|
|
2607
|
+
}
|
|
2608
|
+
function moduleHeaderText(state, node) {
|
|
2609
|
+
if (node.global) return "global ";
|
|
2610
|
+
return `${node.kind} ${identifierOrLiteralNameText(state, node.id)}`;
|
|
2611
|
+
}
|
|
2612
|
+
function moduleBodyText(state, node) {
|
|
2613
|
+
const body = node.body;
|
|
2614
|
+
if (body !== null) return ` ${capture(state, () => printTSModuleBlock(state, body))}`;
|
|
2615
|
+
return ";";
|
|
2616
|
+
}
|
|
2617
|
+
function printTSModuleBlock(state, node) {
|
|
2618
|
+
state.out += "{\n";
|
|
2619
|
+
state.out += indentedBodyText(state, node.body, (statement) => printStatement(state, statement));
|
|
2620
|
+
state.out += `${indent(state)}}`;
|
|
2621
|
+
}
|
|
2622
|
+
function printTSImportEqualsDeclaration(state, node) {
|
|
2623
|
+
state.out += `import ${flagText(node.importKind === "type", "type ")}${node.id.name} = ${moduleReferenceText(state, node.moduleReference)};`;
|
|
2624
|
+
}
|
|
2625
|
+
function moduleReferenceText(state, reference) {
|
|
2626
|
+
if (reference.type === "TSExternalModuleReference") return `require(${externalModuleArgumentText(reference.expression.value)})`;
|
|
2627
|
+
return sequenceNodeText(state, reference);
|
|
2628
|
+
}
|
|
2629
|
+
function printTSType(state, node) {
|
|
2630
|
+
state.out += printTSTypeToString(state, node);
|
|
2631
|
+
}
|
|
2632
|
+
function printTSTypeToString(state, node) {
|
|
2633
|
+
const saved = state.out;
|
|
2634
|
+
state.out = "";
|
|
2635
|
+
doPrintTSType(state, node);
|
|
2636
|
+
const result = state.out;
|
|
2637
|
+
state.out = saved;
|
|
2638
|
+
return result;
|
|
2639
|
+
}
|
|
2640
|
+
function doPrintTSType(state, node) {
|
|
2641
|
+
switch (node.type) {
|
|
2642
|
+
case "TSAnyKeyword":
|
|
2643
|
+
state.out += "any";
|
|
2644
|
+
break;
|
|
2645
|
+
case "TSStringKeyword":
|
|
2646
|
+
state.out += "string";
|
|
2647
|
+
break;
|
|
2648
|
+
case "TSBooleanKeyword":
|
|
2649
|
+
state.out += "boolean";
|
|
2650
|
+
break;
|
|
2651
|
+
case "TSNumberKeyword":
|
|
2652
|
+
state.out += "number";
|
|
2653
|
+
break;
|
|
2654
|
+
case "TSBigIntKeyword":
|
|
2655
|
+
state.out += "bigint";
|
|
2656
|
+
break;
|
|
2657
|
+
case "TSSymbolKeyword":
|
|
2658
|
+
state.out += "symbol";
|
|
2659
|
+
break;
|
|
2660
|
+
case "TSVoidKeyword":
|
|
2661
|
+
state.out += "void";
|
|
2662
|
+
break;
|
|
2663
|
+
case "TSUndefinedKeyword":
|
|
2664
|
+
state.out += "undefined";
|
|
2665
|
+
break;
|
|
2666
|
+
case "TSNullKeyword":
|
|
2667
|
+
state.out += "null";
|
|
2668
|
+
break;
|
|
2669
|
+
case "TSNeverKeyword":
|
|
2670
|
+
state.out += "never";
|
|
2671
|
+
break;
|
|
2672
|
+
case "TSUnknownKeyword":
|
|
2673
|
+
state.out += "unknown";
|
|
2674
|
+
break;
|
|
2675
|
+
case "TSObjectKeyword":
|
|
2676
|
+
state.out += "object";
|
|
2677
|
+
break;
|
|
2678
|
+
case "TSIntrinsicKeyword":
|
|
2679
|
+
state.out += "intrinsic";
|
|
2680
|
+
break;
|
|
2681
|
+
case "TSThisType":
|
|
2682
|
+
state.out += "this";
|
|
2683
|
+
break;
|
|
2684
|
+
case "TSTypeReference":
|
|
2685
|
+
printTSTypeName(state, node.typeName);
|
|
2686
|
+
state.out += typeArgumentsText(state, node.typeArguments);
|
|
2687
|
+
break;
|
|
2688
|
+
case "TSUnionType":
|
|
2689
|
+
state.out += tSTypeListText(state, node.types, " | ");
|
|
2690
|
+
break;
|
|
2691
|
+
case "TSIntersectionType":
|
|
2692
|
+
state.out += tSTypeListText(state, node.types, " & ");
|
|
2693
|
+
break;
|
|
2694
|
+
case "TSArrayType":
|
|
2695
|
+
state.out += `${arrayElementTypeText(state, node.elementType)}[]`;
|
|
2696
|
+
break;
|
|
2697
|
+
case "TSTypeLiteral":
|
|
2698
|
+
printTSTypeLiteral(state, node.members);
|
|
2699
|
+
break;
|
|
2700
|
+
case "TSTupleType":
|
|
2701
|
+
printTupleType(state, node.elementTypes);
|
|
2702
|
+
break;
|
|
2703
|
+
case "TSConditionalType":
|
|
2704
|
+
doPrintTSType(state, node.checkType);
|
|
2705
|
+
state.out += " extends ";
|
|
2706
|
+
doPrintTSType(state, node.extendsType);
|
|
2707
|
+
state.out += " ? ";
|
|
2708
|
+
doPrintTSType(state, node.trueType);
|
|
2709
|
+
state.out += " : ";
|
|
2710
|
+
doPrintTSType(state, node.falseType);
|
|
2711
|
+
break;
|
|
2712
|
+
case "TSInferType":
|
|
2713
|
+
state.out += `infer ${node.typeParameter.name.name}`;
|
|
2714
|
+
printTypeClause(state, " extends ", node.typeParameter.constraint);
|
|
2715
|
+
break;
|
|
2716
|
+
case "TSTypeQuery":
|
|
2717
|
+
state.out += "typeof ";
|
|
2718
|
+
printTypeQueryName(state, node);
|
|
2719
|
+
state.out += typeArgumentsText(state, node.typeArguments);
|
|
2720
|
+
break;
|
|
2721
|
+
case "TSImportType":
|
|
2722
|
+
printTSImportType(state, node);
|
|
2723
|
+
break;
|
|
2724
|
+
case "TSTypeOperator":
|
|
2725
|
+
state.out += `${node.operator} `;
|
|
2726
|
+
doPrintTSType(state, node.typeAnnotation);
|
|
2727
|
+
break;
|
|
2728
|
+
case "TSMappedType":
|
|
2729
|
+
printMappedType(state, node);
|
|
2730
|
+
break;
|
|
2731
|
+
case "TSTemplateLiteralType":
|
|
2732
|
+
printTSTemplateLiteral(state, node);
|
|
2733
|
+
break;
|
|
2734
|
+
case "TSFunctionType":
|
|
2735
|
+
printTSFunctionType(state, node);
|
|
2736
|
+
break;
|
|
2737
|
+
case "TSConstructorType":
|
|
2738
|
+
printTSConstructorType(state, node);
|
|
2739
|
+
break;
|
|
2740
|
+
case "TSTypePredicate":
|
|
2741
|
+
printTSTypePredicate(state, node);
|
|
2742
|
+
break;
|
|
2743
|
+
case "TSIndexedAccessType":
|
|
2744
|
+
doPrintTSType(state, node.objectType);
|
|
2745
|
+
state.out += "[";
|
|
2746
|
+
doPrintTSType(state, node.indexType);
|
|
2747
|
+
state.out += "]";
|
|
2748
|
+
break;
|
|
2749
|
+
case "TSNamedTupleMember":
|
|
2750
|
+
printNamedTupleMember(state, node);
|
|
2751
|
+
break;
|
|
2752
|
+
case "TSLiteralType":
|
|
2753
|
+
printTSLiteralType(state, node.literal);
|
|
2754
|
+
break;
|
|
2755
|
+
case "TSParenthesizedType":
|
|
2756
|
+
state.out += "(";
|
|
2757
|
+
doPrintTSType(state, node.typeAnnotation);
|
|
2758
|
+
state.out += ")";
|
|
2759
|
+
break;
|
|
2760
|
+
case "TSJSDocNullableType":
|
|
2761
|
+
printJSDocPostfixModifier(state, node, "?");
|
|
2762
|
+
break;
|
|
2763
|
+
case "TSJSDocNonNullableType":
|
|
2764
|
+
printJSDocPostfixModifier(state, node, "!");
|
|
2765
|
+
break;
|
|
2766
|
+
case "TSJSDocUnknownType": state.out += "?";
|
|
2767
|
+
}
|
|
2768
|
+
}
|
|
2769
|
+
function tSTypeListText(state, types, separator) {
|
|
2770
|
+
return types.map((type) => printTSTypeToString(state, type)).join(separator);
|
|
2771
|
+
}
|
|
2772
|
+
function arrayElementTypeText(state, type) {
|
|
2773
|
+
const printed = printTSTypeToString(state, type);
|
|
2774
|
+
if (ARRAY_ELEMENT_WRAPPED_KINDS[type.type] === true) return `(${printed})`;
|
|
2775
|
+
return printed;
|
|
2776
|
+
}
|
|
2777
|
+
function printTSTypeLiteral(state, members) {
|
|
2778
|
+
const rendered = members.map((member) => signatureText(state, member)).join("; ");
|
|
2779
|
+
switch (members.length) {
|
|
2780
|
+
case 0:
|
|
2781
|
+
state.out += "{}";
|
|
2782
|
+
break;
|
|
2783
|
+
default: state.out += `{ ${rendered} }`;
|
|
2784
|
+
}
|
|
2785
|
+
}
|
|
2786
|
+
function signatureText(state, member) {
|
|
2787
|
+
const printed = capture(state, () => printTSSignature(state, member));
|
|
2788
|
+
if (printed.endsWith(";")) return printed.slice(0, -1);
|
|
2789
|
+
return printed;
|
|
2790
|
+
}
|
|
2791
|
+
function printTupleType(state, elements) {
|
|
2792
|
+
state.out += `[${elements.map((element) => capture(state, () => printTupleElement(state, element))).join(", ")}]`;
|
|
2793
|
+
}
|
|
2794
|
+
function printTupleElement(state, element) {
|
|
2795
|
+
switch (nodeKind(element)) {
|
|
2796
|
+
case "TSRestType":
|
|
2797
|
+
printRestTupleElement(state, element);
|
|
2798
|
+
break;
|
|
2799
|
+
case "TSOptionalType":
|
|
2800
|
+
printOptionalTupleElement(state, element);
|
|
2801
|
+
break;
|
|
2802
|
+
case "TSNamedTupleMember":
|
|
2803
|
+
printNamedTupleElement(state, element);
|
|
2804
|
+
break;
|
|
2805
|
+
default: printTupleElementType(state, element);
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2808
|
+
function printRestTupleElement(state, element) {
|
|
2809
|
+
if (isNodeOfKind(element, "TSRestType")) {
|
|
2810
|
+
state.out += "...";
|
|
2811
|
+
doPrintTSType(state, element.typeAnnotation);
|
|
2812
|
+
}
|
|
2813
|
+
}
|
|
2814
|
+
function printOptionalTupleElement(state, element) {
|
|
2815
|
+
if (isNodeOfKind(element, "TSOptionalType")) {
|
|
2816
|
+
doPrintTSType(state, element.typeAnnotation);
|
|
2817
|
+
state.out += "?";
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
function printNamedTupleElement(state, element) {
|
|
2821
|
+
if (isNodeOfKind(element, "TSNamedTupleMember")) printNamedTupleMember(state, element);
|
|
2822
|
+
}
|
|
2823
|
+
function printTupleElementType(state, element) {
|
|
2824
|
+
if (isTSType(element)) doPrintTSType(state, element);
|
|
2825
|
+
}
|
|
2826
|
+
function printNamedTupleMember(state, member) {
|
|
2827
|
+
state.out += `${member.label.name}${flagText(member.optional, "?")}: `;
|
|
2828
|
+
printTupleElement(state, member.elementType);
|
|
2829
|
+
}
|
|
2830
|
+
function printTypeClause(state, keyword, type) {
|
|
2831
|
+
if (type == null) return;
|
|
2832
|
+
state.out += keyword;
|
|
2833
|
+
doPrintTSType(state, type);
|
|
2834
|
+
}
|
|
2835
|
+
function printTypeQueryName(state, node) {
|
|
2836
|
+
const exprName = node.exprName;
|
|
2837
|
+
if (exprName.type === "TSImportType") {
|
|
2838
|
+
doPrintTSType(state, exprName);
|
|
2839
|
+
return;
|
|
2840
|
+
}
|
|
2841
|
+
printTSTypeName(state, exprName);
|
|
2842
|
+
}
|
|
2843
|
+
function printTSTypeName(state, name) {
|
|
2844
|
+
if (name.type === "TSQualifiedName") {
|
|
2845
|
+
printTSTypeName(state, name.left);
|
|
2846
|
+
state.out += `.${name.right.name}`;
|
|
2847
|
+
return;
|
|
2848
|
+
}
|
|
2849
|
+
state.out += tSTypeNameLeafText(state, name);
|
|
2850
|
+
}
|
|
2851
|
+
function tSTypeNameLeafText(state, name) {
|
|
2852
|
+
switch (name.type) {
|
|
2853
|
+
case "Identifier": return name.name;
|
|
2854
|
+
case "ThisExpression": return "this";
|
|
2855
|
+
case "TSQualifiedName": return sequenceNodeText(state, name);
|
|
2856
|
+
}
|
|
2857
|
+
}
|
|
2858
|
+
function printTSImportTypeQualifier(state, qualifier) {
|
|
2859
|
+
if (qualifier === null) return;
|
|
2860
|
+
printTSImportTypeQualifierNode(state, qualifier);
|
|
2861
|
+
}
|
|
2862
|
+
function printTSImportTypeQualifierNode(state, qualifier) {
|
|
2863
|
+
if (qualifier.type === "Identifier") {
|
|
2864
|
+
state.out += qualifier.name;
|
|
2865
|
+
return;
|
|
2866
|
+
}
|
|
2867
|
+
printTSImportTypeQualifier(state, qualifier.left);
|
|
2868
|
+
state.out += `.${qualifier.right.name}`;
|
|
2869
|
+
}
|
|
2870
|
+
function printTSImportType(state, node) {
|
|
2871
|
+
printTSImportTypeSource(state, node);
|
|
2872
|
+
if (node.qualifier !== null) {
|
|
2873
|
+
state.out += ".";
|
|
2874
|
+
printTSImportTypeQualifier(state, node.qualifier);
|
|
2875
|
+
}
|
|
2876
|
+
state.out += typeArgumentsText(state, node.typeArguments);
|
|
2877
|
+
}
|
|
2878
|
+
function printTSImportTypeSource(state, node) {
|
|
2879
|
+
state.out += `import(${JSON.stringify(node.source.value)}`;
|
|
2880
|
+
state.out += flagText(node.options, `, ${assignmentNodeText(state, node.options)}`);
|
|
2881
|
+
state.out += ")";
|
|
2882
|
+
}
|
|
2883
|
+
function printMappedType(state, node) {
|
|
2884
|
+
state.out += "{ ";
|
|
2885
|
+
printMappedTypeModifier(state, node.readonly, "readonly ");
|
|
2886
|
+
state.out += `[${node.key.name} in `;
|
|
2887
|
+
doPrintTSType(state, node.constraint);
|
|
2888
|
+
printTypeClause(state, " as ", node.nameType);
|
|
2889
|
+
state.out += "]";
|
|
2890
|
+
printMappedTypeModifier(state, node.optional, "?");
|
|
2891
|
+
printTypeClause(state, ": ", node.typeAnnotation);
|
|
2892
|
+
state.out += " }";
|
|
2893
|
+
}
|
|
2894
|
+
function printMappedTypeModifier(state, modifier, rendered) {
|
|
2895
|
+
switch (modifier) {
|
|
2896
|
+
case true:
|
|
2897
|
+
state.out += rendered;
|
|
2898
|
+
break;
|
|
2899
|
+
case "+":
|
|
2900
|
+
state.out += `+${rendered}`;
|
|
2901
|
+
break;
|
|
2902
|
+
case "-": state.out += `-${rendered}`;
|
|
2898
2903
|
}
|
|
2899
|
-
|
|
2900
|
-
|
|
2904
|
+
}
|
|
2905
|
+
function printTSTemplateLiteral(state, node) {
|
|
2906
|
+
state.out += `\`${node.quasis.map((quasi, index) => templateTypeQuasiText(state, quasi, node.types[index])).join("")}\``;
|
|
2907
|
+
}
|
|
2908
|
+
function templateTypeQuasiText(state, quasi, type) {
|
|
2909
|
+
switch (quasi.tail) {
|
|
2910
|
+
case true: return quasi.value.raw;
|
|
2911
|
+
case false: return templateTypeText(state, quasi, type);
|
|
2901
2912
|
}
|
|
2902
|
-
|
|
2903
|
-
|
|
2913
|
+
}
|
|
2914
|
+
function templateTypeText(state, quasi, type) {
|
|
2915
|
+
if (type === void 0) throw new Error("Printer: template literal type has no type for its quasi");
|
|
2916
|
+
return `${quasi.value.raw}\${${printTSTypeToString(state, type)}}`;
|
|
2917
|
+
}
|
|
2918
|
+
function printTSFunctionType(state, node) {
|
|
2919
|
+
state.out += `${typeParametersText(state, node.typeParameters)}(${paramsText(state, node.params)}) => ${printTSTypeToString(state, node.returnType.typeAnnotation)}`;
|
|
2920
|
+
}
|
|
2921
|
+
function printTSConstructorType(state, node) {
|
|
2922
|
+
state.out += `${flagText(node.abstract, "abstract ")}new ${typeParametersText(state, node.typeParameters)}(${paramsText(state, node.params)}) => ${printTSTypeToString(state, node.returnType.typeAnnotation)}`;
|
|
2923
|
+
}
|
|
2924
|
+
function printTSTypePredicate(state, node) {
|
|
2925
|
+
state.out += flagText(node.asserts, "asserts ");
|
|
2926
|
+
state.out += typePredicateParameterText(node.parameterName);
|
|
2927
|
+
printPredicateAnnotation(state, node);
|
|
2928
|
+
}
|
|
2929
|
+
function printPredicateAnnotation(state, node) {
|
|
2930
|
+
if (node.typeAnnotation === null) return;
|
|
2931
|
+
printTypeClause(state, " is ", node.typeAnnotation.typeAnnotation);
|
|
2932
|
+
}
|
|
2933
|
+
function printTSLiteralType(state, literal) {
|
|
2934
|
+
switch (literal.type) {
|
|
2935
|
+
case "Literal":
|
|
2936
|
+
printLiteral(state, literal);
|
|
2937
|
+
return;
|
|
2938
|
+
case "TemplateLiteral":
|
|
2939
|
+
printTemplateLiteral(state, literal);
|
|
2940
|
+
return;
|
|
2941
|
+
case "UnaryExpression": printTSLiteralUnary(state, literal);
|
|
2904
2942
|
}
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2943
|
+
}
|
|
2944
|
+
function printTSLiteralUnary(state, unary) {
|
|
2945
|
+
state.out += unary.operator;
|
|
2946
|
+
if (isLiteralNode(unary.argument)) printLiteral(state, unary.argument);
|
|
2947
|
+
}
|
|
2948
|
+
function printJSDocPostfixModifier(state, node, marker) {
|
|
2949
|
+
if (node.postfix) {
|
|
2950
|
+
doPrintTSType(state, node.typeAnnotation);
|
|
2951
|
+
state.out += marker;
|
|
2952
|
+
return;
|
|
2910
2953
|
}
|
|
2911
|
-
|
|
2954
|
+
state.out += marker;
|
|
2955
|
+
doPrintTSType(state, node.typeAnnotation);
|
|
2956
|
+
}
|
|
2957
|
+
function printTSTypeAnnotation(state, node) {
|
|
2958
|
+
state.out += ": ";
|
|
2959
|
+
doPrintTSType(state, node.typeAnnotation);
|
|
2960
|
+
}
|
|
2961
|
+
function printTSTypeParameterDeclaration(state, node) {
|
|
2962
|
+
state.out += `<${node.params.map((param) => capture(state, () => printTSTypeParameter(state, param))).join(", ")}>`;
|
|
2963
|
+
}
|
|
2964
|
+
function printTSTypeParameterInstantiation(state, node) {
|
|
2965
|
+
state.out += `<${node.params.map((param) => printTSTypeToString(state, param)).join(", ")}>`;
|
|
2966
|
+
}
|
|
2967
|
+
function printTSTypeParameter(state, node) {
|
|
2968
|
+
state.out += typeParameterModifiersText(node);
|
|
2969
|
+
state.out += node.name.name;
|
|
2970
|
+
printTypeClause(state, " extends ", node.constraint);
|
|
2971
|
+
printTypeClause(state, " = ", node.default);
|
|
2972
|
+
}
|
|
2912
2973
|
const TS_TYPE_NODE_KINDS = {
|
|
2913
2974
|
TSAnyKeyword: true,
|
|
2914
2975
|
TSStringKeyword: true,
|
|
@@ -2953,13 +3014,65 @@ const TS_TYPE_NODE_KINDS = {
|
|
|
2953
3014
|
function isTSTypeNode(kind) {
|
|
2954
3015
|
return TS_TYPE_NODE_KINDS[kind] === true;
|
|
2955
3016
|
}
|
|
3017
|
+
function isTSType(node) {
|
|
3018
|
+
return isTSTypeNode(node.type);
|
|
3019
|
+
}
|
|
3020
|
+
function isNodeOfKind(node, kind) {
|
|
3021
|
+
return node.type === kind;
|
|
3022
|
+
}
|
|
3023
|
+
const FUNCTION_KINDS = {
|
|
3024
|
+
FunctionDeclaration: true,
|
|
3025
|
+
FunctionExpression: true,
|
|
3026
|
+
TSDeclareFunction: true,
|
|
3027
|
+
TSEmptyBodyFunctionExpression: true
|
|
3028
|
+
};
|
|
3029
|
+
function isFunctionNode(node) {
|
|
3030
|
+
return FUNCTION_KINDS[node.type] === true;
|
|
3031
|
+
}
|
|
3032
|
+
function isAssignmentPattern(node) {
|
|
3033
|
+
return node.type === "AssignmentPattern";
|
|
3034
|
+
}
|
|
3035
|
+
function isLiteralNode(node) {
|
|
3036
|
+
return node.type === "Literal";
|
|
3037
|
+
}
|
|
3038
|
+
const ABSENT_NODE_KIND = "\0absent";
|
|
3039
|
+
function nodeKind(node) {
|
|
3040
|
+
if (node == null) return ABSENT_NODE_KIND;
|
|
3041
|
+
return node.type;
|
|
3042
|
+
}
|
|
3043
|
+
function isIdentifierNode(node) {
|
|
3044
|
+
if (node == null) return false;
|
|
3045
|
+
return node.type === "Identifier";
|
|
3046
|
+
}
|
|
3047
|
+
function isPrivateIdentifierNode(node) {
|
|
3048
|
+
if (node == null) return false;
|
|
3049
|
+
return node.type === "PrivateIdentifier";
|
|
3050
|
+
}
|
|
3051
|
+
function isAssignmentPatternNode(node) {
|
|
3052
|
+
if (node == null) return false;
|
|
3053
|
+
return node.type === "AssignmentPattern";
|
|
3054
|
+
}
|
|
3055
|
+
function identifierName(node) {
|
|
3056
|
+
if (isIdentifierNode(node)) return node.name;
|
|
3057
|
+
}
|
|
3058
|
+
function identifierNameText(node) {
|
|
3059
|
+
return identifierName(node) ?? "";
|
|
3060
|
+
}
|
|
3061
|
+
function privateIdentifierText(node) {
|
|
3062
|
+
if (isPrivateIdentifierNode(node)) return `#${node.name}`;
|
|
3063
|
+
return "";
|
|
3064
|
+
}
|
|
3065
|
+
function literalCapture(state, node) {
|
|
3066
|
+
if (isLiteralNode(node)) return capture(state, () => printLiteral(state, node));
|
|
3067
|
+
return capture(state, () => printNodePrec(state, node, PREC.Assignment));
|
|
3068
|
+
}
|
|
2956
3069
|
function precOf(node) {
|
|
2957
|
-
switch (node
|
|
3070
|
+
switch (nodeKind(node)) {
|
|
2958
3071
|
case "SequenceExpression": return PREC.Sequence;
|
|
2959
3072
|
case "AssignmentExpression": return PREC.Assignment;
|
|
2960
3073
|
case "ConditionalExpression": return PREC.Conditional;
|
|
2961
|
-
case "LogicalExpression": return
|
|
2962
|
-
case "BinaryExpression": return
|
|
3074
|
+
case "LogicalExpression": return logicalPrecOf(node);
|
|
3075
|
+
case "BinaryExpression": return binaryPrecOf(node);
|
|
2963
3076
|
case "UnaryExpression":
|
|
2964
3077
|
case "AwaitExpression":
|
|
2965
3078
|
case "YieldExpression": return PREC.Unary;
|
|
@@ -2973,6 +3086,14 @@ function precOf(node) {
|
|
|
2973
3086
|
default: return PREC.Primary;
|
|
2974
3087
|
}
|
|
2975
3088
|
}
|
|
3089
|
+
function logicalPrecOf(node) {
|
|
3090
|
+
if (node.type === "LogicalExpression") return logicalPrec(node.operator);
|
|
3091
|
+
return PREC.Primary;
|
|
3092
|
+
}
|
|
3093
|
+
function binaryPrecOf(node) {
|
|
3094
|
+
if (node.type === "BinaryExpression") return binaryPrec(node.operator);
|
|
3095
|
+
return PREC.Primary;
|
|
3096
|
+
}
|
|
2976
3097
|
const EVERY_COMMENT_POSITION = Number.POSITIVE_INFINITY;
|
|
2977
3098
|
const END_OF_COMMENTS = {
|
|
2978
3099
|
type: "Line",
|
|
@@ -2984,52 +3105,9 @@ function sortedCommentsWithoutHashbang(comments, hashbang) {
|
|
|
2984
3105
|
return [...withoutHashbangComment(comments ?? [], hashbang)].sort((a, b) => a.start - b.start);
|
|
2985
3106
|
}
|
|
2986
3107
|
function withoutHashbangComment(comments, hashbang) {
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
const { start } = hashbang;
|
|
2991
|
-
return comments.filter((comment) => !(comment.type === "Line" && comment.start === start));
|
|
2992
|
-
}
|
|
2993
|
-
}
|
|
2994
|
-
}
|
|
2995
|
-
const ABSENT_NODE_KIND = "\0absent";
|
|
2996
|
-
const ABSENT_NODE = { type: ABSENT_NODE_KIND };
|
|
2997
|
-
function nodeKind(node) {
|
|
2998
|
-
return (node ?? ABSENT_NODE).type;
|
|
2999
|
-
}
|
|
3000
|
-
function propertyForm(fields) {
|
|
3001
|
-
switch (true) {
|
|
3002
|
-
case fields.kind === "get":
|
|
3003
|
-
case fields.kind === "set": return "accessor";
|
|
3004
|
-
case fields.method === true: return "method";
|
|
3005
|
-
case isShorthandMatch(fields): return "shorthand";
|
|
3006
|
-
case isShorthandDefaultMatch(fields): return "shorthandDefault";
|
|
3007
|
-
default: return "verbose";
|
|
3008
|
-
}
|
|
3009
|
-
}
|
|
3010
|
-
function isShorthandMatch(fields) {
|
|
3011
|
-
return fields.shorthand === true && namesMatch(identifierName(fields.key), identifierName(fields.value));
|
|
3012
|
-
}
|
|
3013
|
-
function isShorthandDefaultMatch(fields) {
|
|
3014
|
-
return fields.shorthand === true && namesMatch(identifierName(fields.key), defaultTargetName(fields.value));
|
|
3015
|
-
}
|
|
3016
|
-
function identifierName(node) {
|
|
3017
|
-
switch (nodeKind(node)) {
|
|
3018
|
-
case "Identifier": return node.name;
|
|
3019
|
-
default: return;
|
|
3020
|
-
}
|
|
3021
|
-
}
|
|
3022
|
-
function defaultTargetName(node) {
|
|
3023
|
-
switch (nodeKind(node)) {
|
|
3024
|
-
case "AssignmentPattern": return identifierName(node.left);
|
|
3025
|
-
default: return;
|
|
3026
|
-
}
|
|
3027
|
-
}
|
|
3028
|
-
function namesMatch(key, value) {
|
|
3029
|
-
switch (value) {
|
|
3030
|
-
case void 0: return false;
|
|
3031
|
-
default: return key === value;
|
|
3032
|
-
}
|
|
3108
|
+
if (hashbang === null) return comments;
|
|
3109
|
+
const { start } = hashbang;
|
|
3110
|
+
return comments.filter((comment) => !(comment.type === "Line" && comment.start === start));
|
|
3033
3111
|
}
|
|
3034
3112
|
const MEMBER_OBJECT_WRAPPED_KINDS = {
|
|
3035
3113
|
SequenceExpression: true,
|
|
@@ -3057,41 +3135,64 @@ const UNARY_WORD_OPERATORS = {
|
|
|
3057
3135
|
void: true,
|
|
3058
3136
|
delete: true
|
|
3059
3137
|
};
|
|
3138
|
+
const ARRAY_ELEMENT_WRAPPED_KINDS = {
|
|
3139
|
+
TSUnionType: true,
|
|
3140
|
+
TSIntersectionType: true
|
|
3141
|
+
};
|
|
3060
3142
|
function parenthesizedIf(wrap, text) {
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
default: return text;
|
|
3064
|
-
}
|
|
3143
|
+
if (wrap) return `(${text})`;
|
|
3144
|
+
return text;
|
|
3065
3145
|
}
|
|
3066
3146
|
function jsxAttributeNameText(name) {
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
default: return `${name.namespace.name}:${name.name.name}`;
|
|
3070
|
-
}
|
|
3147
|
+
if (name.type === "JSXIdentifier") return name.name;
|
|
3148
|
+
return `${name.namespace.name}:${name.name.name}`;
|
|
3071
3149
|
}
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3150
|
+
function propertyForm(fields) {
|
|
3151
|
+
if (isAccessorKind(fields)) return "accessor";
|
|
3152
|
+
return propertyFormWithoutAccessor(fields);
|
|
3153
|
+
}
|
|
3154
|
+
function isAccessorKind(fields) {
|
|
3155
|
+
return fields.kind === "get" || fields.kind === "set";
|
|
3156
|
+
}
|
|
3157
|
+
function propertyFormWithoutAccessor(fields) {
|
|
3158
|
+
if (fields.method === true) return "method";
|
|
3159
|
+
return propertyFormShorthand(fields);
|
|
3160
|
+
}
|
|
3161
|
+
function propertyFormShorthand(fields) {
|
|
3162
|
+
if (isShorthandMatch(fields)) return "shorthand";
|
|
3163
|
+
return propertyFormDefault(fields);
|
|
3164
|
+
}
|
|
3165
|
+
function propertyFormDefault(fields) {
|
|
3166
|
+
if (isShorthandDefaultMatch(fields)) return "shorthandDefault";
|
|
3167
|
+
return "verbose";
|
|
3168
|
+
}
|
|
3169
|
+
function isShorthandMatch(fields) {
|
|
3170
|
+
return fields.shorthand === true && namesMatch(identifierName(fields.key), identifierName(fields.value));
|
|
3171
|
+
}
|
|
3172
|
+
function isShorthandDefaultMatch(fields) {
|
|
3173
|
+
return fields.shorthand === true && namesMatch(identifierName(fields.key), defaultTargetName(fields.value));
|
|
3174
|
+
}
|
|
3175
|
+
function defaultTargetName(node) {
|
|
3176
|
+
if (isAssignmentPatternNode(node)) return identifierName(node.left);
|
|
3177
|
+
}
|
|
3178
|
+
function namesMatch(key, value) {
|
|
3179
|
+
if (value === void 0) return false;
|
|
3180
|
+
return key === value;
|
|
3181
|
+
}
|
|
3182
|
+
const BINDING_TYPE_ANNOTATION_KINDS = {
|
|
3183
|
+
Identifier: true,
|
|
3184
|
+
ObjectPattern: true,
|
|
3185
|
+
ArrayPattern: true
|
|
3080
3186
|
};
|
|
3081
|
-
function
|
|
3082
|
-
|
|
3187
|
+
function bindingTypeAnnotation(node) {
|
|
3188
|
+
if (isBindingTypeAnnotationCarrier(node)) return node.typeAnnotation;
|
|
3083
3189
|
}
|
|
3084
|
-
function
|
|
3085
|
-
|
|
3086
|
-
case "TSThisType": return "this";
|
|
3087
|
-
default: return parameterName.name;
|
|
3088
|
-
}
|
|
3190
|
+
function isBindingTypeAnnotationCarrier(node) {
|
|
3191
|
+
return BINDING_TYPE_ANNOTATION_KINDS[node.type] === true;
|
|
3089
3192
|
}
|
|
3090
|
-
function
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
default: return "\"\"";
|
|
3094
|
-
}
|
|
3193
|
+
function bindingNameText(node) {
|
|
3194
|
+
if (node.name === void 0) return "";
|
|
3195
|
+
return node.name;
|
|
3095
3196
|
}
|
|
3096
3197
|
const EXPORT_NAME_TEXTS = {
|
|
3097
3198
|
Identifier: (name) => name.name ?? "",
|
|
@@ -3126,32 +3227,31 @@ function namedSpecifierText(specifier) {
|
|
|
3126
3227
|
return `${flagText(specifier.importKind === "type", "type ")}${alias}`;
|
|
3127
3228
|
}
|
|
3128
3229
|
function importLocalName(specifier) {
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
default: return specifier.local.name;
|
|
3132
|
-
}
|
|
3230
|
+
if (specifier === void 0) return "";
|
|
3231
|
+
return specifier.local.name;
|
|
3133
3232
|
}
|
|
3134
3233
|
function importedNameText(imported) {
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3234
|
+
if (imported === void 0) return "";
|
|
3235
|
+
return importedNameOf(imported);
|
|
3236
|
+
}
|
|
3237
|
+
function importedNameOf(imported) {
|
|
3238
|
+
if (imported.type === "Identifier") return nameOrEmpty(imported.name);
|
|
3239
|
+
return nameOrEmpty(imported.value);
|
|
3240
|
+
}
|
|
3241
|
+
function nameOrEmpty(value) {
|
|
3242
|
+
return value ?? "";
|
|
3139
3243
|
}
|
|
3140
3244
|
function exportAliasText(localName, exportedName) {
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
default: return `${localName} as ${exportedName}`;
|
|
3144
|
-
}
|
|
3245
|
+
if (localName === exportedName) return localName;
|
|
3246
|
+
return `${localName} as ${exportedName}`;
|
|
3145
3247
|
}
|
|
3146
3248
|
function exportSpecifierText(specifier) {
|
|
3147
3249
|
const alias = exportAliasText(exportNameToString(specifier.local), exportNameToString(specifier.exported));
|
|
3148
3250
|
return `${flagText(specifier.exportKind === "type", "type ")}${alias}`;
|
|
3149
3251
|
}
|
|
3150
3252
|
function exportedNameClauseText(exported) {
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
default: return ` as ${exportNameToString(exported)}`;
|
|
3154
|
-
}
|
|
3253
|
+
if (exported == null) return "";
|
|
3254
|
+
return ` as ${exportNameToString(exported)}`;
|
|
3155
3255
|
}
|
|
3156
3256
|
function importAttributesText(attrs) {
|
|
3157
3257
|
const rendered = attrs.map((attribute) => importAttributeText(attribute)).join(", ");
|
|
@@ -3161,17 +3261,13 @@ function importAttributeText(attribute) {
|
|
|
3161
3261
|
return `${importAttrKeyText(attribute.key)}: ${JSON.stringify(attribute.value.value)}`;
|
|
3162
3262
|
}
|
|
3163
3263
|
function importAttrKeyText(key) {
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
default: return JSON.stringify(key.value);
|
|
3167
|
-
}
|
|
3264
|
+
if (key.type === "Identifier") return key.name;
|
|
3265
|
+
return JSON.stringify(key.value);
|
|
3168
3266
|
}
|
|
3169
3267
|
function bareArrowParamName(node) {
|
|
3170
3268
|
const name = singleParamName(node);
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
default: return flagText(node.returnType == null, name);
|
|
3174
|
-
}
|
|
3269
|
+
if (name === "") return "";
|
|
3270
|
+
return flagText(node.returnType == null, name);
|
|
3175
3271
|
}
|
|
3176
3272
|
function singleParamName(node) {
|
|
3177
3273
|
switch (node.params.length) {
|
|
@@ -3180,49 +3276,33 @@ function singleParamName(node) {
|
|
|
3180
3276
|
}
|
|
3181
3277
|
}
|
|
3182
3278
|
function bareParameterName(param) {
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3279
|
+
if (param === void 0) return "";
|
|
3280
|
+
return bareParameterNameOf(param);
|
|
3281
|
+
}
|
|
3282
|
+
function bareParameterNameOf(param) {
|
|
3283
|
+
if (!isUnannotatedIdentifier(param)) return "";
|
|
3284
|
+
return param.name;
|
|
3285
|
+
}
|
|
3286
|
+
function isUnannotatedIdentifier(param) {
|
|
3287
|
+
if (param.type !== "Identifier") return false;
|
|
3288
|
+
return param.typeAnnotation == null;
|
|
3191
3289
|
}
|
|
3192
3290
|
function arrowBodyIsBlock(body) {
|
|
3193
|
-
return
|
|
3291
|
+
return body.type === "BlockStatement";
|
|
3194
3292
|
}
|
|
3195
3293
|
function functionHeaderText(node) {
|
|
3196
3294
|
return `${flagText(node.declare, "declare ")}${flagText(node.async, "async ")}function${flagText(node.generator, "*")}${namedDeclarationText(node)}`;
|
|
3197
3295
|
}
|
|
3198
3296
|
function namedDeclarationText(node) {
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
default: return "";
|
|
3202
|
-
}
|
|
3203
|
-
}
|
|
3204
|
-
function bindingNameText(node) {
|
|
3205
|
-
switch (node.name) {
|
|
3206
|
-
case void 0: return "";
|
|
3207
|
-
default: return node.name;
|
|
3208
|
-
}
|
|
3209
|
-
}
|
|
3210
|
-
function parameterForm(param) {
|
|
3211
|
-
switch (true) {
|
|
3212
|
-
case param["type"] === "RestElement": return "rest";
|
|
3213
|
-
case param["type"] === "TSParameterProperty": return "property";
|
|
3214
|
-
default: return "formal";
|
|
3215
|
-
}
|
|
3297
|
+
if (node.id == null) return "";
|
|
3298
|
+
return ` ${node.id.name}`;
|
|
3216
3299
|
}
|
|
3217
3300
|
function parameterPropertyModifiers(param) {
|
|
3218
|
-
|
|
3219
|
-
return `${flagText(accessibility, `${accessibility} `)}${flagText(param["readonly"], "readonly ")}${flagText(param["override"], "override ")}${flagText(param["static"], "static ")}`;
|
|
3301
|
+
return `${flagText(param.accessibility, `${param.accessibility} `)}${flagText(param.readonly, "readonly ")}${flagText(param.override, "override ")}${flagText(param.static, "static ")}`;
|
|
3220
3302
|
}
|
|
3221
3303
|
function commentText(comment) {
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
default: return `//${comment.value}`;
|
|
3225
|
-
}
|
|
3304
|
+
if (comment.type === "Block") return `/*${comment.value}*/`;
|
|
3305
|
+
return `//${comment.value}`;
|
|
3226
3306
|
}
|
|
3227
3307
|
function methodDefinitionPrefix(node, fn) {
|
|
3228
3308
|
return `${flagText(node.accessibility, `${node.accessibility} `)}${flagText(node.static, "static ")}${flagText(node.override, "override ")}${flagText(fn.async, "async ")}${flagText(fn.generator, "*")}${methodKindText(node.kind)}`;
|
|
@@ -3238,28 +3318,56 @@ function propertyDefinitionModifiers(node) {
|
|
|
3238
3318
|
return `${flagText(node.declare, "declare ")}${flagText(node.accessibility, `${node.accessibility} `)}${flagText(node.static, "static ")}${flagText(node.readonly, "readonly ")}${flagText(node.override, "override ")}`;
|
|
3239
3319
|
}
|
|
3240
3320
|
function literalText(node) {
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3321
|
+
if (node.raw != null) return node.raw;
|
|
3322
|
+
return literalWithoutRaw(node);
|
|
3323
|
+
}
|
|
3324
|
+
function literalWithoutRaw(node) {
|
|
3325
|
+
if (node.regex != null) return `/${node.regex.pattern}/${node.regex.flags}`;
|
|
3326
|
+
return literalWithoutRegex(node);
|
|
3327
|
+
}
|
|
3328
|
+
function literalWithoutRegex(node) {
|
|
3329
|
+
if (node.bigint != null) return node.bigint;
|
|
3330
|
+
return valueLiteralText(node.value);
|
|
3247
3331
|
}
|
|
3248
3332
|
function valueLiteralText(value) {
|
|
3249
3333
|
switch (typeof value) {
|
|
3250
3334
|
case "string": return JSON.stringify(value);
|
|
3251
|
-
case "number":
|
|
3335
|
+
case "number": return String(value);
|
|
3252
3336
|
case "boolean": return String(value);
|
|
3253
3337
|
case "bigint": return `${value}n`;
|
|
3254
|
-
|
|
3338
|
+
case "symbol":
|
|
3339
|
+
case "undefined":
|
|
3340
|
+
case "object":
|
|
3341
|
+
case "function": return "null";
|
|
3255
3342
|
}
|
|
3256
3343
|
}
|
|
3257
3344
|
function flagText(present, text) {
|
|
3258
3345
|
switch (Boolean(present)) {
|
|
3259
3346
|
case true: return text;
|
|
3260
|
-
|
|
3347
|
+
case false: return "";
|
|
3348
|
+
}
|
|
3349
|
+
}
|
|
3350
|
+
function typeParameterModifiersText(node) {
|
|
3351
|
+
return `${flagText(node.in, "in ")}${flagText(node.out, "out ")}${flagText(node.const, "const ")}`;
|
|
3352
|
+
}
|
|
3353
|
+
function typePredicateParameterText(parameterName) {
|
|
3354
|
+
if (parameterName.type === "TSThisType") return "this";
|
|
3355
|
+
return parameterName.name;
|
|
3356
|
+
}
|
|
3357
|
+
function externalModuleArgumentText(value) {
|
|
3358
|
+
switch (Boolean(value)) {
|
|
3359
|
+
case true: return JSON.stringify(value);
|
|
3360
|
+
case false: return "\"\"";
|
|
3261
3361
|
}
|
|
3262
3362
|
}
|
|
3363
|
+
const BARE_DEFAULT_EXPORT_KINDS = {
|
|
3364
|
+
FunctionDeclaration: true,
|
|
3365
|
+
ClassDeclaration: true,
|
|
3366
|
+
TSInterfaceDeclaration: true
|
|
3367
|
+
};
|
|
3368
|
+
function isBareDefaultExport(node) {
|
|
3369
|
+
return BARE_DEFAULT_EXPORT_KINDS[node.type] === true;
|
|
3370
|
+
}
|
|
3263
3371
|
//#endregion
|
|
3264
3372
|
//#region src/Printer.ts
|
|
3265
3373
|
/**
|
|
@@ -3342,6 +3450,76 @@ function appendStatement(state, script, rawContent, context) {
|
|
|
3342
3450
|
};
|
|
3343
3451
|
}
|
|
3344
3452
|
//#endregion
|
|
3453
|
+
//#region src/Mutant.ts
|
|
3454
|
+
const isMutant = (value) => S.is(Mutant)(value);
|
|
3455
|
+
const INSTRUMENTER_CONSTANTS = Object.freeze({
|
|
3456
|
+
NAMESPACE: "__stryker__",
|
|
3457
|
+
MUTATION_COVERAGE_OBJECT: "mutantCoverage",
|
|
3458
|
+
ACTIVE_MUTANT: "activeMutant",
|
|
3459
|
+
CURRENT_TEST_ID: "currentTestId",
|
|
3460
|
+
HIT_COUNT: "hitCount",
|
|
3461
|
+
HIT_LIMIT: "hitLimit",
|
|
3462
|
+
ACTIVE_MUTANT_ENV_VARIABLE: "__STRYKER_ACTIVE_MUTANT__"
|
|
3463
|
+
});
|
|
3464
|
+
function normalizeFileName(fileName) {
|
|
3465
|
+
return fileName.replace(/\\/g, "/");
|
|
3466
|
+
}
|
|
3467
|
+
const hasText = (value) => Predicate.isString(value) && value.length > 0;
|
|
3468
|
+
const textIfNonEmpty = (value) => Option.getOrUndefined(Option.filter(Option.fromUndefinedOr(value), hasText));
|
|
3469
|
+
const fieldOf = (value, key) => Match.value(key in value).pipe(Match.when(true, () => {
|
|
3470
|
+
return Reflect.get(value, key);
|
|
3471
|
+
}), Match.orElse(() => void 0));
|
|
3472
|
+
const hasStringCode = (error) => Match.value(fieldOf(error, "code")).pipe(Match.when(Match.string, () => true), Match.orElse(() => false));
|
|
3473
|
+
function isErrnoException(error) {
|
|
3474
|
+
return Match.value(error).pipe(Match.when(Match.instanceOf(Error), hasStringCode), Match.orElse(() => false));
|
|
3475
|
+
}
|
|
3476
|
+
const isEmptyNumber = (value) => Match.value(value).pipe(Match.when(0, () => true), Match.orElse(Number.isNaN));
|
|
3477
|
+
const isEmptyError = (error) => Match.value(error).pipe(Match.when(Match.undefined, () => true), Match.when(Match.null, () => true), Match.when(Match.string, (text) => text.length === 0), Match.when(Match.number, isEmptyNumber), Match.when(Match.boolean, (value) => !value), Match.orElse(() => false));
|
|
3478
|
+
const formatErrnoException = (error) => Match.value(error.stack).pipe(Match.when(hasText, (stack) => `${error.name}: ${error.code} (${error.syscall}) ${stack}`), Match.orElse(() => `${error.name}: ${error.code} (${error.syscall})`));
|
|
3479
|
+
const formatError = (error) => Match.value(error.stack).pipe(Match.when(hasText, (stack) => `${error.name}: ${error.message}\n${stack}`), Match.orElse(() => `${error.name}: ${error.message}`));
|
|
3480
|
+
const isJsonPrimitive = (value) => Match.value(value).pipe(Match.when(Match.number, () => true), Match.when(Match.boolean, () => true), Match.when(Match.bigint, () => true), Match.orElse(() => false));
|
|
3481
|
+
const jsonText = (error) => {
|
|
3482
|
+
try {
|
|
3483
|
+
return textIfNonEmpty(JSON.stringify(error));
|
|
3484
|
+
} catch {
|
|
3485
|
+
return;
|
|
3486
|
+
}
|
|
3487
|
+
};
|
|
3488
|
+
const isNonPlaceholderText = (text) => Match.value({
|
|
3489
|
+
hasLength: text.length > 0,
|
|
3490
|
+
isPlaceholder: text === "[object Object]"
|
|
3491
|
+
}).pipe(Match.when({
|
|
3492
|
+
hasLength: true,
|
|
3493
|
+
isPlaceholder: false
|
|
3494
|
+
}, () => true), Match.orElse(() => false));
|
|
3495
|
+
const isUsableText = (value) => Match.value(value).pipe(Match.when(Match.string, isNonPlaceholderText), Match.orElse(() => false));
|
|
3496
|
+
const usableText = (value) => Match.value(value).pipe(Match.when(isUsableText, (text) => text), Match.orElse(() => ""));
|
|
3497
|
+
const objectToStringText = (value) => Match.value(fieldOf(value, "toString")).pipe(Match.when(Match.instanceOf(Function), (callable) => {
|
|
3498
|
+
try {
|
|
3499
|
+
return usableText(Reflect.apply(callable, value, []));
|
|
3500
|
+
} catch {
|
|
3501
|
+
return "";
|
|
3502
|
+
}
|
|
3503
|
+
}), Match.orElse(() => ""));
|
|
3504
|
+
const isObjectType = (cause) => typeof cause === "object";
|
|
3505
|
+
const toStringText = (error) => Match.value(error).pipe(Match.when(Match.null, () => ""), Match.when(isObjectType, (value) => objectToStringText(value)), Match.orElse(() => ""));
|
|
3506
|
+
const stringifyRest = (error) => Match.value(jsonText(error)).pipe(Match.when(hasText, (json) => json), Match.orElse(() => toStringText(error)));
|
|
3507
|
+
const stringifyNonError = (error) => Match.value(error).pipe(Match.when(Match.string, (text) => text), Match.when(isJsonPrimitive, (primitive) => JSON.stringify(primitive)), Match.orElse(() => stringifyRest(error)));
|
|
3508
|
+
const errorText = (error) => Match.value(error).pipe(Match.when(isErrnoException, formatErrnoException), Match.orElse(() => formatError(error)));
|
|
3509
|
+
function errorToString(error) {
|
|
3510
|
+
return Match.value(error).pipe(Match.when(isEmptyError, () => ""), Match.when(Match.instanceOf(Error), errorText), Match.orElse(() => stringifyNonError(error)));
|
|
3511
|
+
}
|
|
3512
|
+
const ERROR_CODES = Object.freeze({ NoSuchFileOrDirectory: "ENOENT" });
|
|
3513
|
+
const errorNameOf = (value) => Match.value(value).pipe(Match.when(Match.instanceOf(Error), (error) => textIfNonEmpty(error.name)), Match.orElse(() => void 0));
|
|
3514
|
+
const tagOf = (value) => Match.value(textIfNonEmpty(fieldOf(value, "_tag"))).pipe(Match.when(hasText, (tag) => tag), Match.orElse(() => errorNameOf(value)));
|
|
3515
|
+
const textWithNested = (own, nested) => Match.value(own).pipe(Match.when(hasText, (text) => appendNested(text, nested)), Match.orElse(() => nested));
|
|
3516
|
+
const appendNested = (own, nested) => Match.value(nested).pipe(Match.when(hasText, (text) => `${own}: ${text}`), Match.orElse(() => own));
|
|
3517
|
+
const errorMessage = (error) => Match.value(error.message.length > 0).pipe(Match.when(true, () => error.message), Match.orElse(() => tagOf(error)));
|
|
3518
|
+
const errorMessageOrTag = (value) => Match.value(value).pipe(Match.when(Match.instanceOf(Error), errorMessage), Match.orElse(() => tagOf(value)));
|
|
3519
|
+
const messageText = (value) => Match.value(textIfNonEmpty(fieldOf(value, "message"))).pipe(Match.when(hasText, (message) => message), Match.orElse(() => errorMessageOrTag(value)));
|
|
3520
|
+
const ownCauseText = (value) => Match.value(textIfNonEmpty(fieldOf(value, "reason"))).pipe(Match.when(hasText, (reason) => reason), Match.orElse(() => messageText(value)));
|
|
3521
|
+
const causeText = (cause, depth) => Match.value(cause).pipe(Match.when(() => depth > 4, () => void 0), Match.when(Match.undefined, () => void 0), Match.when(Match.null, () => void 0), Match.when(Match.string, textIfNonEmpty), Match.when(isObjectType, (value) => textWithNested(ownCauseText(value), causeText(fieldOf(value, "cause"), depth + 1))), Match.orElse(() => void 0));
|
|
3522
|
+
//#endregion
|
|
3345
3523
|
//#region src/Mutator.ts
|
|
3346
3524
|
/**
|
|
3347
3525
|
* Mutator — every mutation operator and its registry.
|
|
@@ -4062,7 +4240,9 @@ function regexFlags(parent) {
|
|
|
4062
4240
|
const PLACEHOLDER = "Stryker was here!";
|
|
4063
4241
|
const stringLiteralMutator = (node, context) => Match.value(node).pipe(Match.when(isTemplateLiteral, (template) => templateMutants(template)), Match.when(isStringLiteral, (literal) => mutantsWhen(isValidParent(literal, context), () => [stringLiteral(replacementText(literal.value.length === 0))])), Match.orElse(() => NO_MUTANTS));
|
|
4064
4242
|
function templateMutants(template) {
|
|
4065
|
-
|
|
4243
|
+
const first = template.quasis[0];
|
|
4244
|
+
if (first === void 0) return NO_MUTANTS;
|
|
4245
|
+
return [emptyOrPlaceholderTemplate(template, first)];
|
|
4066
4246
|
}
|
|
4067
4247
|
function emptyOrPlaceholderTemplate(template, first) {
|
|
4068
4248
|
return templateLiteral([templateElement(replacementText([template.quasis.length === 1, first.value.raw.length === 0].every(Boolean)))], []);
|
|
@@ -4252,7 +4432,13 @@ function processStrykerDirectives(rule, node, allMutatorNames, originFileName) {
|
|
|
4252
4432
|
};
|
|
4253
4433
|
}
|
|
4254
4434
|
function attachedComments(node) {
|
|
4255
|
-
return node
|
|
4435
|
+
return leadingCommentsOn(node) ?? NO_COMMENTS;
|
|
4436
|
+
}
|
|
4437
|
+
function leadingCommentsOn(value) {
|
|
4438
|
+
if (isCommentBearing(value)) return value.leadingComments;
|
|
4439
|
+
}
|
|
4440
|
+
function isCommentBearing(value) {
|
|
4441
|
+
return Predicate.hasProperty(value, "leadingComments");
|
|
4256
4442
|
}
|
|
4257
4443
|
/** A comment that matched the directive grammar, decoded into the fields a rule needs. */
|
|
4258
4444
|
function parseStrykerDirective(comment) {
|
|
@@ -4368,16 +4554,35 @@ function mutationCoverageSequenceExpression(mutants, targetExpression) {
|
|
|
4368
4554
|
return sequenceExpression(sequence);
|
|
4369
4555
|
}
|
|
4370
4556
|
function nodeOfKind(mutant, node, isKind, kind) {
|
|
4371
|
-
|
|
4372
|
-
|
|
4557
|
+
return narrowNode(node, isKind, `Cannot place mutant ${mutant.id}: expected ${kind}, got ${node.type}`);
|
|
4558
|
+
}
|
|
4559
|
+
function narrowNode(node, isKind, message) {
|
|
4560
|
+
if (isKind(node)) return node;
|
|
4561
|
+
throw new Error(message);
|
|
4562
|
+
}
|
|
4563
|
+
function expressionOf(node) {
|
|
4564
|
+
return narrowNode(node, isExpressionKind, `Expected an expression, got ${node.type}`);
|
|
4565
|
+
}
|
|
4566
|
+
function statementOf(node) {
|
|
4567
|
+
return narrowNode(node, isStatementKind, `Expected a statement, got ${node.type}`);
|
|
4568
|
+
}
|
|
4569
|
+
function isSwitchCase(node) {
|
|
4570
|
+
return nodeType(node) === "SwitchCase";
|
|
4571
|
+
}
|
|
4572
|
+
function switchCaseOf(node) {
|
|
4573
|
+
return narrowNode(node, isSwitchCase, `Expected a switch case, got ${node.type}`);
|
|
4373
4574
|
}
|
|
4374
4575
|
function throwPlacementError(error, nodePath, placer, mutants, fileName, lineTable, basePath) {
|
|
4375
4576
|
const message = `${placer.name} could not place mutants with type(s): "${placementListFormat.format(mutants.map((mutant) => mutant.mutatorName))}"`;
|
|
4376
4577
|
const errorMessage = `${placementLocation(nodePath.node, fileName, lineTable, basePath)} ${message}. Either remove this file from the list of files to be mutated, or exclude the mutator (using \`mutator.excludedMutations\`). Original error: ${error.stack}`;
|
|
4377
4578
|
throw new Error(errorMessage);
|
|
4378
4579
|
}
|
|
4580
|
+
const fileNameWithin = (basePath, fileName) => {
|
|
4581
|
+
if (basePath === void 0) return fileName;
|
|
4582
|
+
return relativeTo(basePath, fileName);
|
|
4583
|
+
};
|
|
4379
4584
|
function placementLocation(node, fileName, lineTable, basePath) {
|
|
4380
|
-
const relativeFile =
|
|
4585
|
+
const relativeFile = fileNameWithin(basePath, fileName);
|
|
4381
4586
|
const position = Option.map(Option.fromNullishOr(spanOf(node)), (span) => positionFromLineTable(span.start, lineTable));
|
|
4382
4587
|
return Option.match(position, {
|
|
4383
4588
|
onNone: () => `${relativeFile}:undefined:undefined`,
|
|
@@ -4388,12 +4593,14 @@ const placementListFormat = new Intl.ListFormat("en");
|
|
|
4388
4593
|
const normalizeSeparators = (value) => value.replace(/\\/g, "/");
|
|
4389
4594
|
const withTrailingSlash = (basePath) => {
|
|
4390
4595
|
const normalized = normalizeSeparators(basePath);
|
|
4391
|
-
|
|
4596
|
+
if (normalized.endsWith("/")) return normalized;
|
|
4597
|
+
return `${normalized}/`;
|
|
4392
4598
|
};
|
|
4393
4599
|
const relativeTo = (basePath, fileName) => {
|
|
4394
4600
|
const prefix = withTrailingSlash(basePath);
|
|
4395
4601
|
const normalizedFile = normalizeSeparators(fileName);
|
|
4396
|
-
|
|
4602
|
+
if (!normalizedFile.startsWith(prefix)) return fileName;
|
|
4603
|
+
return normalizedFile.slice(prefix.length);
|
|
4397
4604
|
};
|
|
4398
4605
|
function classOrFunctionExpressionNamedIfNeeded(path) {
|
|
4399
4606
|
return Match.value(path.node).pipe(Match.when(isAnonymousFunctionOrClass, (node) => nameFromParent(path, node)), Match.orElse(() => void 0));
|
|
@@ -4453,7 +4660,7 @@ function nameIfAnonymous(path) {
|
|
|
4453
4660
|
return classOrFunctionExpressionNamedIfNeeded(path) ?? arrowNameOrNode(path);
|
|
4454
4661
|
}
|
|
4455
4662
|
function arrowNameOrNode(path) {
|
|
4456
|
-
return arrowFunctionExpressionNamedIfNeeded(path) ?? path.node;
|
|
4663
|
+
return arrowFunctionExpressionNamedIfNeeded(path) ?? expressionOf(path.node);
|
|
4457
4664
|
}
|
|
4458
4665
|
function isChainLink(node) {
|
|
4459
4666
|
return [
|
|
@@ -4555,7 +4762,7 @@ const statementMutantPlacer = {
|
|
|
4555
4762
|
function statementsOf(path) {
|
|
4556
4763
|
const node = path.node;
|
|
4557
4764
|
if (node.type === "BlockStatement") return node.body;
|
|
4558
|
-
return [node];
|
|
4765
|
+
return [statementOf(node)];
|
|
4559
4766
|
}
|
|
4560
4767
|
function guardedStatement(statement, entry) {
|
|
4561
4768
|
return ifStatement(mutantTestExpression(entry[0].id), blockStatement([nodeOfKind(entry[0], entry[1], isStatementKind, "a statement")]), statement);
|
|
@@ -4572,10 +4779,10 @@ const allMutantPlacers = Object.freeze([
|
|
|
4572
4779
|
return nodeType(path.node) === "SwitchCase";
|
|
4573
4780
|
},
|
|
4574
4781
|
place(path, appliedMutants) {
|
|
4575
|
-
const currentCase = path.node;
|
|
4782
|
+
const currentCase = switchCaseOf(path.node);
|
|
4576
4783
|
let consequence = blockStatement([expressionStatement(mutationCoverageSequenceExpression(appliedMutants.keys())), ...currentCase.consequent]);
|
|
4577
4784
|
for (const [mutant, appliedMutant] of appliedMutants) {
|
|
4578
|
-
const appliedCase = nodeOfKind(mutant, appliedMutant,
|
|
4785
|
+
const appliedCase = nodeOfKind(mutant, appliedMutant, isSwitchCase, "a switch case");
|
|
4579
4786
|
consequence = ifStatement(mutantTestExpression(mutant.id), blockStatement(appliedCase.consequent), consequence);
|
|
4580
4787
|
}
|
|
4581
4788
|
path.replaceWith(switchCase(currentCase.test, [consequence]));
|
|
@@ -4652,12 +4859,11 @@ const headerFor = (root) => Effect.map(instrumentationHeader, (header) => Option
|
|
|
4652
4859
|
onSome: (leadingComments) => [commentedHeader(leadingComments, header), ...header.slice(1)]
|
|
4653
4860
|
}));
|
|
4654
4861
|
function leadingCommentsOf(root) {
|
|
4655
|
-
|
|
4656
|
-
return Option.filter(Option.fromNullishOr(firstStatement?.leadingComments), isCommentArray);
|
|
4862
|
+
return Option.filter(Option.some(leadingCommentsOn(root.body[0])), isCommentArray);
|
|
4657
4863
|
}
|
|
4658
4864
|
function commentedHeader(leadingComments, header) {
|
|
4659
4865
|
const cloned = cloneNode(Option.getOrThrowWith(Option.fromNullishOr(header[0]), () => /* @__PURE__ */ new Error("Instrumentation header is empty")));
|
|
4660
|
-
cloned
|
|
4866
|
+
Object.assign(cloned, { leadingComments });
|
|
4661
4867
|
return cloned;
|
|
4662
4868
|
}
|
|
4663
4869
|
function deepFreeze(value) {
|
|
@@ -5126,4 +5332,4 @@ const instrument = (files, options, basePath) => Effect.gen(function* () {
|
|
|
5126
5332
|
});
|
|
5127
5333
|
});
|
|
5128
5334
|
//#endregion
|
|
5129
|
-
export { disableTypeChecks, instrument };
|
|
5335
|
+
export { ERROR_CODES, INSTRUMENTER_CONSTANTS, InstrumenterOptionsSchema, LocationSchema, Mutant, MutantActivationSchema, MutantRunOptionsSchema, MutantStatusSchema, OpenEndLocationSchema, PositionSchema, RunOptionsFields, causeText, disableTypeChecks, errorToString, instrument, isErrnoException, isMutant, normalizeFileName };
|