esrap 2.2.8 → 2.2.10
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 +54 -14
package/package.json
CHANGED
|
@@ -25,7 +25,6 @@ export const EXPRESSIONS_PRECEDENCE = {
|
|
|
25
25
|
ImportExpression: 19,
|
|
26
26
|
NewExpression: 19,
|
|
27
27
|
Literal: 18,
|
|
28
|
-
TSSatisfiesExpression: 18,
|
|
29
28
|
TSInstantiationExpression: 18,
|
|
30
29
|
TSNonNullExpression: 18,
|
|
31
30
|
TSTypeAssertion: 18,
|
|
@@ -33,11 +32,13 @@ export const EXPRESSIONS_PRECEDENCE = {
|
|
|
33
32
|
ClassExpression: 17,
|
|
34
33
|
FunctionExpression: 17,
|
|
35
34
|
ObjectExpression: 17,
|
|
36
|
-
TSAsExpression: 16,
|
|
37
35
|
UpdateExpression: 16,
|
|
38
36
|
UnaryExpression: 15,
|
|
39
37
|
BinaryExpression: 14,
|
|
40
|
-
|
|
38
|
+
// `as`/`satisfies` sit between binary and logical operators
|
|
39
|
+
TSAsExpression: 13,
|
|
40
|
+
TSSatisfiesExpression: 13,
|
|
41
|
+
LogicalExpression: 12,
|
|
41
42
|
ConditionalExpression: 4,
|
|
42
43
|
ArrowFunctionExpression: 3,
|
|
43
44
|
AssignmentExpression: 3,
|
|
@@ -360,7 +361,7 @@ export default (options = {}) => {
|
|
|
360
361
|
* @param {{ line: number, column: number }} until
|
|
361
362
|
* @param {boolean} pad
|
|
362
363
|
*/
|
|
363
|
-
function sequence(context, nodes, until, pad, separator = ',') {
|
|
364
|
+
function sequence(context, nodes, until, pad, separator = ',', trailing_newline = true) {
|
|
364
365
|
let multiline = false;
|
|
365
366
|
let length = -1;
|
|
366
367
|
|
|
@@ -426,7 +427,7 @@ export default (options = {}) => {
|
|
|
426
427
|
|
|
427
428
|
if (multiline) {
|
|
428
429
|
context.dedent();
|
|
429
|
-
context.newline();
|
|
430
|
+
if (trailing_newline) context.newline();
|
|
430
431
|
} else if (pad && length > 0) {
|
|
431
432
|
context.write(' ');
|
|
432
433
|
}
|
|
@@ -1010,12 +1011,7 @@ export default (options = {}) => {
|
|
|
1010
1011
|
|
|
1011
1012
|
context.write(' => ');
|
|
1012
1013
|
|
|
1013
|
-
if (
|
|
1014
|
-
node.body.type === 'ObjectExpression' ||
|
|
1015
|
-
(node.body.type === 'AssignmentExpression' && node.body.left.type === 'ObjectPattern') ||
|
|
1016
|
-
(node.body.type === 'LogicalExpression' && node.body.left.type === 'ObjectExpression') ||
|
|
1017
|
-
(node.body.type === 'ConditionalExpression' && node.body.test.type === 'ObjectExpression')
|
|
1018
|
-
) {
|
|
1014
|
+
if (arrow_concise_body_needs_wrap(node.body)) {
|
|
1019
1015
|
context.write('(');
|
|
1020
1016
|
context.visit(node.body);
|
|
1021
1017
|
context.write(')');
|
|
@@ -2111,11 +2107,13 @@ export default (options = {}) => {
|
|
|
2111
2107
|
},
|
|
2112
2108
|
|
|
2113
2109
|
TSUnionType(node, context) {
|
|
2114
|
-
|
|
2110
|
+
// no trailing newline, so a following `=>` stays on the same line
|
|
2111
|
+
sequence(context, node.types, node.loc?.end ?? null, false, ' |', false);
|
|
2115
2112
|
},
|
|
2116
2113
|
|
|
2117
2114
|
TSIntersectionType(node, context) {
|
|
2118
|
-
|
|
2115
|
+
// no trailing newline, so a following `=>` stays on the same line
|
|
2116
|
+
sequence(context, node.types, node.loc?.end ?? null, false, ' &', false);
|
|
2119
2117
|
},
|
|
2120
2118
|
|
|
2121
2119
|
TSInferType(node, context) {
|
|
@@ -2246,7 +2244,16 @@ export default (options = {}) => {
|
|
|
2246
2244
|
},
|
|
2247
2245
|
|
|
2248
2246
|
TSNonNullExpression(node, context) {
|
|
2249
|
-
|
|
2247
|
+
// operator expressions can't take a postfix `!` directly: `(0 as number)!`, `(await x)!`
|
|
2248
|
+
if (
|
|
2249
|
+
EXPRESSIONS_PRECEDENCE[node.expression.type] < EXPRESSIONS_PRECEDENCE.TSNonNullExpression
|
|
2250
|
+
) {
|
|
2251
|
+
context.write('(');
|
|
2252
|
+
context.visit(node.expression);
|
|
2253
|
+
context.write(')');
|
|
2254
|
+
} else {
|
|
2255
|
+
context.visit(node.expression);
|
|
2256
|
+
}
|
|
2250
2257
|
context.write('!');
|
|
2251
2258
|
},
|
|
2252
2259
|
|
|
@@ -2322,6 +2329,34 @@ export default (options = {}) => {
|
|
|
2322
2329
|
|
|
2323
2330
|
/** @satisfies {Visitors} */
|
|
2324
2331
|
|
|
2332
|
+
/**
|
|
2333
|
+
* Arrow functions with a concise body must wrap certain expressions in parentheses,
|
|
2334
|
+
* otherwise `{` can start a block statement instead of an object literal (`as` /
|
|
2335
|
+
* `satisfies` / `!` do not change that (e.g. `() => { x } as const`).
|
|
2336
|
+
* @param {TSESTree.BlockStatement | TSESTree.Expression} body
|
|
2337
|
+
* @returns {boolean}
|
|
2338
|
+
*/
|
|
2339
|
+
function arrow_concise_body_needs_wrap(body) {
|
|
2340
|
+
if (body.type === 'BlockStatement') return false;
|
|
2341
|
+
|
|
2342
|
+
switch (body.type) {
|
|
2343
|
+
case 'ObjectExpression':
|
|
2344
|
+
return true;
|
|
2345
|
+
case 'AssignmentExpression':
|
|
2346
|
+
return body.left.type === 'ObjectPattern';
|
|
2347
|
+
case 'LogicalExpression':
|
|
2348
|
+
return body.left.type === 'ObjectExpression';
|
|
2349
|
+
case 'ConditionalExpression':
|
|
2350
|
+
return body.test.type === 'ObjectExpression';
|
|
2351
|
+
case 'TSAsExpression':
|
|
2352
|
+
case 'TSSatisfiesExpression':
|
|
2353
|
+
case 'TSNonNullExpression':
|
|
2354
|
+
return body.expression ? arrow_concise_body_needs_wrap(body.expression) : false;
|
|
2355
|
+
default:
|
|
2356
|
+
return false;
|
|
2357
|
+
}
|
|
2358
|
+
}
|
|
2359
|
+
|
|
2325
2360
|
/**
|
|
2326
2361
|
*
|
|
2327
2362
|
* @param {TSESTree.Expression | TSESTree.PrivateIdentifier} node
|
|
@@ -2332,6 +2367,11 @@ export default (options = {}) => {
|
|
|
2332
2367
|
function needs_parens(node, parent, is_right) {
|
|
2333
2368
|
if (node.type === 'PrivateIdentifier') return false;
|
|
2334
2369
|
|
|
2370
|
+
if (!is_right && (node.type === 'TSAsExpression' || node.type === 'TSSatisfiesExpression')) {
|
|
2371
|
+
// `**` would be invalid, `&`/`|` would be swallowed into the trailing type
|
|
2372
|
+
return parent.operator === '**' || parent.operator === '&' || parent.operator === '|';
|
|
2373
|
+
}
|
|
2374
|
+
|
|
2335
2375
|
// special case where logical expressions and coalesce expressions cannot be mixed,
|
|
2336
2376
|
// either of them need to be wrapped with parentheses
|
|
2337
2377
|
if (
|