esrap 2.2.12 → 2.2.13
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/package.json +1 -1
- package/src/languages/ts/index.js +186 -24
package/package.json
CHANGED
|
@@ -653,12 +653,25 @@ export default (options = {}) => {
|
|
|
653
653
|
|
|
654
654
|
if (node.id) {
|
|
655
655
|
context.visit(node.id);
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
if (node.typeParameters) {
|
|
659
|
+
context.visit(node.typeParameters);
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
if (node.id || node.typeParameters) {
|
|
656
663
|
context.write(' ');
|
|
657
664
|
}
|
|
658
665
|
|
|
659
666
|
if (node.superClass) {
|
|
660
667
|
context.write('extends ');
|
|
668
|
+
// the `extends` clause is a LeftHandSideExpression; anything lower (a
|
|
669
|
+
// logical/binary/conditional/etc.) must be parenthesized
|
|
670
|
+
const wrap_super =
|
|
671
|
+
EXPRESSIONS_PRECEDENCE[node.superClass.type] < EXPRESSIONS_PRECEDENCE.NewExpression;
|
|
672
|
+
if (wrap_super) context.write('(');
|
|
661
673
|
context.visit(node.superClass);
|
|
674
|
+
if (wrap_super) context.write(')');
|
|
662
675
|
|
|
663
676
|
// @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
|
|
664
677
|
var type_arguments = node.superTypeParameters ?? node.superTypeArguments;
|
|
@@ -795,6 +808,12 @@ export default (options = {}) => {
|
|
|
795
808
|
context.visit(node.key);
|
|
796
809
|
if (node.computed) context.write(']');
|
|
797
810
|
|
|
811
|
+
// optional method (`m?()`)
|
|
812
|
+
if (node.optional) context.write('?');
|
|
813
|
+
|
|
814
|
+
// @ts-expect-error `typeParameters` lives on the method node, not its value
|
|
815
|
+
if (node.typeParameters) context.visit(node.typeParameters);
|
|
816
|
+
|
|
798
817
|
context.write('(');
|
|
799
818
|
sequence(
|
|
800
819
|
context,
|
|
@@ -827,6 +846,8 @@ export default (options = {}) => {
|
|
|
827
846
|
|
|
828
847
|
const kw = create_keyword_write(context, node, field_modifiers_keywords_map_ok);
|
|
829
848
|
|
|
849
|
+
if (node.declare) kw('declare ');
|
|
850
|
+
|
|
830
851
|
if (node.accessibility) {
|
|
831
852
|
kw(node.accessibility + ' ');
|
|
832
853
|
}
|
|
@@ -844,6 +865,10 @@ export default (options = {}) => {
|
|
|
844
865
|
kw('static ');
|
|
845
866
|
}
|
|
846
867
|
|
|
868
|
+
if (node.override) kw('override ');
|
|
869
|
+
|
|
870
|
+
if (node.readonly) kw('readonly ');
|
|
871
|
+
|
|
847
872
|
if (
|
|
848
873
|
// @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
|
|
849
874
|
node.accessor ||
|
|
@@ -861,6 +886,10 @@ export default (options = {}) => {
|
|
|
861
886
|
context.visit(node.key);
|
|
862
887
|
}
|
|
863
888
|
|
|
889
|
+
// `x?: T` (optional) / `x!: T` (definite assignment)
|
|
890
|
+
if (node.optional) context.write('?');
|
|
891
|
+
else if (node.definite) context.write('!');
|
|
892
|
+
|
|
864
893
|
if (node.typeAnnotation) {
|
|
865
894
|
if (node.type === 'AccessorProperty' || node.type === 'TSAbstractAccessorProperty') {
|
|
866
895
|
context.visit(node.typeAnnotation);
|
|
@@ -1101,7 +1130,14 @@ export default (options = {}) => {
|
|
|
1101
1130
|
|
|
1102
1131
|
Decorator(node, context) {
|
|
1103
1132
|
context.write('@');
|
|
1133
|
+
// a decorator must be an identifier/member/call (or parenthesized); anything
|
|
1134
|
+
// else (ternary, logical, assignment, unary, `as`, optional chain…) needs wrapping
|
|
1135
|
+
const wrap =
|
|
1136
|
+
/** @type {string} */ (node.expression.type) === 'ChainExpression' ||
|
|
1137
|
+
EXPRESSIONS_PRECEDENCE[node.expression.type] < EXPRESSIONS_PRECEDENCE.CallExpression;
|
|
1138
|
+
if (wrap) context.write('(');
|
|
1104
1139
|
context.visit(node.expression);
|
|
1140
|
+
if (wrap) context.write(')');
|
|
1105
1141
|
context.newline();
|
|
1106
1142
|
},
|
|
1107
1143
|
|
|
@@ -1211,12 +1247,8 @@ export default (options = {}) => {
|
|
|
1211
1247
|
},
|
|
1212
1248
|
|
|
1213
1249
|
ExpressionStatement(node, context) {
|
|
1214
|
-
//
|
|
1215
|
-
const wrap =
|
|
1216
|
-
node.expression.type === 'ObjectExpression' ||
|
|
1217
|
-
(node.expression.type === 'AssignmentExpression' &&
|
|
1218
|
-
node.expression.left.type === 'ObjectPattern') ||
|
|
1219
|
-
node.expression.type === 'FunctionExpression';
|
|
1250
|
+
// would otherwise be parsed as a block / function / class declaration
|
|
1251
|
+
const wrap = leads_with_curly_or_keyword(node.expression);
|
|
1220
1252
|
maybe_wrap(context, node.expression, wrap);
|
|
1221
1253
|
context.write(';');
|
|
1222
1254
|
},
|
|
@@ -1253,7 +1285,9 @@ export default (options = {}) => {
|
|
|
1253
1285
|
let name = node.name;
|
|
1254
1286
|
context.write(name, node);
|
|
1255
1287
|
|
|
1288
|
+
// optional parameters (`a?: T`) carry `optional` on the identifier
|
|
1256
1289
|
if (node.optional) context.write('?');
|
|
1290
|
+
|
|
1257
1291
|
if (node.typeAnnotation) context.visit(node.typeAnnotation);
|
|
1258
1292
|
},
|
|
1259
1293
|
|
|
@@ -1594,7 +1628,12 @@ export default (options = {}) => {
|
|
|
1594
1628
|
},
|
|
1595
1629
|
|
|
1596
1630
|
TaggedTemplateExpression(node, context) {
|
|
1597
|
-
|
|
1631
|
+
// the tag is a LeftHandSideExpression; a lower-precedence tag (logical,
|
|
1632
|
+
// conditional, arrow, `as`, unary…) or an optional chain must be wrapped
|
|
1633
|
+
const wrap =
|
|
1634
|
+
/** @type {string} */ (node.tag.type) === 'ChainExpression' ||
|
|
1635
|
+
EXPRESSIONS_PRECEDENCE[node.tag.type] < EXPRESSIONS_PRECEDENCE.CallExpression;
|
|
1636
|
+
maybe_wrap(context, node.tag, wrap);
|
|
1598
1637
|
context.visit(node.quasi);
|
|
1599
1638
|
},
|
|
1600
1639
|
|
|
@@ -1847,7 +1886,9 @@ export default (options = {}) => {
|
|
|
1847
1886
|
},
|
|
1848
1887
|
|
|
1849
1888
|
TSPropertySignature(node, context) {
|
|
1889
|
+
if (node.computed) context.write('[');
|
|
1850
1890
|
context.visit(node.key);
|
|
1891
|
+
if (node.computed) context.write(']');
|
|
1851
1892
|
if (node.optional) context.write('?');
|
|
1852
1893
|
if (node.typeAnnotation) context.visit(node.typeAnnotation);
|
|
1853
1894
|
},
|
|
@@ -1939,6 +1980,11 @@ export default (options = {}) => {
|
|
|
1939
1980
|
},
|
|
1940
1981
|
|
|
1941
1982
|
TSTypeParameter(node, context) {
|
|
1983
|
+
// modifiers: `const T`, `in T` / `out T` (variance)
|
|
1984
|
+
if (node.const) context.write('const ');
|
|
1985
|
+
if (node.in) context.write('in ');
|
|
1986
|
+
if (node.out) context.write('out ');
|
|
1987
|
+
|
|
1942
1988
|
if (node.name && node.name.type) context.visit(node.name);
|
|
1943
1989
|
// @ts-expect-error type mismatch TSESTree and acorn-typescript?
|
|
1944
1990
|
else context.write(node.name, node);
|
|
@@ -1955,19 +2001,14 @@ export default (options = {}) => {
|
|
|
1955
2001
|
},
|
|
1956
2002
|
|
|
1957
2003
|
TSTypePredicate(node, context) {
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
context.visit(node.typeAnnotation);
|
|
1962
|
-
}
|
|
2004
|
+
// `asserts` precedes the parameter name; `is <type>` follows it. Forms:
|
|
2005
|
+
// `x is T`, `asserts x is T`, `asserts x`
|
|
2006
|
+
if (node.asserts) context.write('asserts ');
|
|
1963
2007
|
|
|
1964
|
-
if (node.
|
|
1965
|
-
context.write(' asserts ');
|
|
1966
|
-
} else {
|
|
1967
|
-
context.write(' is ');
|
|
1968
|
-
}
|
|
2008
|
+
if (node.parameterName) context.visit(node.parameterName);
|
|
1969
2009
|
|
|
1970
2010
|
if (node.typeAnnotation) {
|
|
2011
|
+
context.write(' is ');
|
|
1971
2012
|
context.visit(node.typeAnnotation.typeAnnotation);
|
|
1972
2013
|
}
|
|
1973
2014
|
},
|
|
@@ -2005,7 +2046,16 @@ export default (options = {}) => {
|
|
|
2005
2046
|
},
|
|
2006
2047
|
|
|
2007
2048
|
TSMappedType(node, context) {
|
|
2008
|
-
context.write('{
|
|
2049
|
+
context.write('{');
|
|
2050
|
+
|
|
2051
|
+
// `readonly` / `+readonly` / `-readonly` modifier
|
|
2052
|
+
if (node.readonly) {
|
|
2053
|
+
context.write(
|
|
2054
|
+
node.readonly === '-' ? '-readonly ' : node.readonly === '+' ? '+readonly ' : 'readonly '
|
|
2055
|
+
);
|
|
2056
|
+
}
|
|
2057
|
+
|
|
2058
|
+
context.write('[');
|
|
2009
2059
|
|
|
2010
2060
|
const legacy_type_parameter = node.typeParameter;
|
|
2011
2061
|
const key = node.key ?? legacy_type_parameter?.name;
|
|
@@ -2022,8 +2072,19 @@ export default (options = {}) => {
|
|
|
2022
2072
|
context.visit(constraint);
|
|
2023
2073
|
}
|
|
2024
2074
|
|
|
2075
|
+
// `as` key remapping
|
|
2076
|
+
if (node.nameType) {
|
|
2077
|
+
context.write(' as ');
|
|
2078
|
+
context.visit(node.nameType);
|
|
2079
|
+
}
|
|
2080
|
+
|
|
2025
2081
|
context.write(']');
|
|
2026
2082
|
|
|
2083
|
+
// `?` / `+?` / `-?` optionality modifier
|
|
2084
|
+
if (node.optional) {
|
|
2085
|
+
context.write(node.optional === '-' ? '-?' : node.optional === '+' ? '+?' : '?');
|
|
2086
|
+
}
|
|
2087
|
+
|
|
2027
2088
|
if (node.typeAnnotation) {
|
|
2028
2089
|
context.write(': ');
|
|
2029
2090
|
context.visit(node.typeAnnotation);
|
|
@@ -2033,7 +2094,9 @@ export default (options = {}) => {
|
|
|
2033
2094
|
},
|
|
2034
2095
|
|
|
2035
2096
|
TSMethodSignature(node, context) {
|
|
2097
|
+
if (node.computed) context.write('[');
|
|
2036
2098
|
context.visit(node.key);
|
|
2099
|
+
if (node.computed) context.write(']');
|
|
2037
2100
|
|
|
2038
2101
|
context.write('(');
|
|
2039
2102
|
sequence(
|
|
@@ -2191,8 +2254,17 @@ export default (options = {}) => {
|
|
|
2191
2254
|
context.visit(node.id);
|
|
2192
2255
|
}
|
|
2193
2256
|
|
|
2194
|
-
|
|
2195
|
-
|
|
2257
|
+
// a qualified name (`namespace A.B.C`) is represented as nested
|
|
2258
|
+
// `TSModuleDeclaration`s whose body is the next name part, not a block
|
|
2259
|
+
let body = /** @type {any} */ (node.body);
|
|
2260
|
+
while (body && body.type === 'TSModuleDeclaration') {
|
|
2261
|
+
context.write('.');
|
|
2262
|
+
context.visit(body.id);
|
|
2263
|
+
body = body.body;
|
|
2264
|
+
}
|
|
2265
|
+
|
|
2266
|
+
if (!body) return;
|
|
2267
|
+
context.visit(body);
|
|
2196
2268
|
},
|
|
2197
2269
|
|
|
2198
2270
|
TSNonNullExpression(node, context) {
|
|
@@ -2320,19 +2392,20 @@ function operand_needs_wrap(node, parent, is_right) {
|
|
|
2320
2392
|
return true;
|
|
2321
2393
|
}
|
|
2322
2394
|
|
|
2323
|
-
// `**` can't take a unary/await left operand: `-2 ** 2`, `await x ** 2
|
|
2395
|
+
// `**` can't take a unary/await/assertion left operand: `-2 ** 2`, `await x ** 2`,
|
|
2396
|
+
// `<T>x ** 2` are syntax errors
|
|
2324
2397
|
const unary_base_of_pow =
|
|
2325
2398
|
!is_right &&
|
|
2326
2399
|
parent.operator === '**' &&
|
|
2327
|
-
(node.type === 'UnaryExpression' ||
|
|
2400
|
+
(node.type === 'UnaryExpression' ||
|
|
2401
|
+
node.type === 'AwaitExpression' ||
|
|
2402
|
+
node.type === 'TSTypeAssertion');
|
|
2328
2403
|
if (unary_base_of_pow) return true;
|
|
2329
2404
|
|
|
2330
2405
|
const precedence = EXPRESSIONS_PRECEDENCE[node.type];
|
|
2331
2406
|
const parent_precedence = EXPRESSIONS_PRECEDENCE[parent.type];
|
|
2332
2407
|
if (precedence !== parent_precedence) return precedence < parent_precedence;
|
|
2333
|
-
|
|
2334
2408
|
const operator = /** @type {TSESTree.BinaryExpression} */ (node).operator;
|
|
2335
|
-
|
|
2336
2409
|
if (operator === '**' && parent.operator === '**') {
|
|
2337
2410
|
// exponentiation is right-associative
|
|
2338
2411
|
return !is_right;
|
|
@@ -2375,6 +2448,95 @@ function has_call_expression(node) {
|
|
|
2375
2448
|
return false;
|
|
2376
2449
|
}
|
|
2377
2450
|
|
|
2451
|
+
/**
|
|
2452
|
+
* True when printing `node` as an expression statement would begin with `{`,
|
|
2453
|
+
* `function`, or `class` — which the parser would misread as a block, function
|
|
2454
|
+
* declaration, or class declaration. Walks the left spine following the same
|
|
2455
|
+
* parenthesization the visitors apply, so it stops as soon as a child position
|
|
2456
|
+
* would already be wrapped.
|
|
2457
|
+
* @param {TSESTree.Node} node
|
|
2458
|
+
* @returns {boolean}
|
|
2459
|
+
*/
|
|
2460
|
+
function leads_with_curly_or_keyword(node) {
|
|
2461
|
+
while (node) {
|
|
2462
|
+
switch (node.type) {
|
|
2463
|
+
case 'ObjectExpression':
|
|
2464
|
+
case 'ObjectPattern':
|
|
2465
|
+
case 'FunctionExpression':
|
|
2466
|
+
case 'ClassExpression':
|
|
2467
|
+
return true;
|
|
2468
|
+
|
|
2469
|
+
case 'BinaryExpression':
|
|
2470
|
+
case 'LogicalExpression':
|
|
2471
|
+
if (operand_needs_wrap(node.left, node, false)) return false;
|
|
2472
|
+
node = node.left;
|
|
2473
|
+
continue;
|
|
2474
|
+
|
|
2475
|
+
case 'AssignmentExpression':
|
|
2476
|
+
node = node.left;
|
|
2477
|
+
continue;
|
|
2478
|
+
|
|
2479
|
+
case 'ConditionalExpression':
|
|
2480
|
+
if (
|
|
2481
|
+
EXPRESSIONS_PRECEDENCE[node.test.type] <= EXPRESSIONS_PRECEDENCE.ConditionalExpression
|
|
2482
|
+
) {
|
|
2483
|
+
return false;
|
|
2484
|
+
}
|
|
2485
|
+
node = node.test;
|
|
2486
|
+
continue;
|
|
2487
|
+
|
|
2488
|
+
case 'MemberExpression':
|
|
2489
|
+
if (
|
|
2490
|
+
/** @type {string} */ (node.object.type) === 'ChainExpression' ||
|
|
2491
|
+
EXPRESSIONS_PRECEDENCE[node.object.type] < EXPRESSIONS_PRECEDENCE.MemberExpression
|
|
2492
|
+
) {
|
|
2493
|
+
return false;
|
|
2494
|
+
}
|
|
2495
|
+
node = node.object;
|
|
2496
|
+
continue;
|
|
2497
|
+
|
|
2498
|
+
case 'CallExpression':
|
|
2499
|
+
if (
|
|
2500
|
+
/** @type {string} */ (node.callee.type) === 'ChainExpression' ||
|
|
2501
|
+
EXPRESSIONS_PRECEDENCE[node.callee.type] < EXPRESSIONS_PRECEDENCE.CallExpression
|
|
2502
|
+
) {
|
|
2503
|
+
return false;
|
|
2504
|
+
}
|
|
2505
|
+
node = node.callee;
|
|
2506
|
+
continue;
|
|
2507
|
+
|
|
2508
|
+
case 'TaggedTemplateExpression':
|
|
2509
|
+
if (
|
|
2510
|
+
/** @type {string} */ (node.tag.type) === 'ChainExpression' ||
|
|
2511
|
+
EXPRESSIONS_PRECEDENCE[node.tag.type] < EXPRESSIONS_PRECEDENCE.CallExpression
|
|
2512
|
+
) {
|
|
2513
|
+
return false;
|
|
2514
|
+
}
|
|
2515
|
+
node = node.tag;
|
|
2516
|
+
continue;
|
|
2517
|
+
|
|
2518
|
+
case 'UpdateExpression':
|
|
2519
|
+
if (node.prefix) return false;
|
|
2520
|
+
node = node.argument;
|
|
2521
|
+
continue;
|
|
2522
|
+
|
|
2523
|
+
case 'TSAsExpression':
|
|
2524
|
+
case 'TSSatisfiesExpression':
|
|
2525
|
+
case 'TSNonNullExpression':
|
|
2526
|
+
node = node.expression;
|
|
2527
|
+
continue;
|
|
2528
|
+
|
|
2529
|
+
// a sequence expression always prints its own wrapping parens
|
|
2530
|
+
case 'SequenceExpression':
|
|
2531
|
+
return false;
|
|
2532
|
+
|
|
2533
|
+
default:
|
|
2534
|
+
return false;
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
return false;
|
|
2538
|
+
}
|
|
2539
|
+
|
|
2378
2540
|
/**
|
|
2379
2541
|
* @param {TSESTree.VariableDeclaration} node
|
|
2380
2542
|
* @param {Context} context
|