espolar 0.3.0 → 0.4.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/dist/index.d.ts +9 -1
- package/dist/index.js +73 -34
- package/package.json +1 -1
- package/src/api.ts +9 -0
- package/src/printer.ts +9 -23
- package/src/printers.ts +113 -51
package/dist/index.d.ts
CHANGED
|
@@ -94,7 +94,15 @@ interface PrinterContext<Data = any> {
|
|
|
94
94
|
writeNode(node: AST.Node | null | undefined): void;
|
|
95
95
|
writeNodeList(nodes: readonly (AST.Node | null)[], separator: string): void;
|
|
96
96
|
writeExpressionListWithCommaSep(nodes: readonly (AST.Expression | AST.SpreadElement | null)[]): void;
|
|
97
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Write `nodes` with "newline" separator, but if the node is ranged and either:
|
|
99
|
+
* - it is the first node with `lastRangeEnd` provided, or
|
|
100
|
+
* - the previous adjacent node is ranged too,
|
|
101
|
+
* Then the source text ranging between the two adjacent nodes will be preserved instead of printing a newline character.
|
|
102
|
+
* @param nodes
|
|
103
|
+
* @param lastRangeEnd
|
|
104
|
+
*/
|
|
105
|
+
writeNodeListWithNewLineSep(nodes: readonly (AST.ProgramStatement | AST.ClassElement)[], lastRangeEnd?: number): void;
|
|
98
106
|
writeSource(start: number, end: number, data?: Data): void;
|
|
99
107
|
writePreservedNode(node: AST.Node): void;
|
|
100
108
|
appendMapping(sourceRange: SourceRange, generatedStart: number, generatedEnd: number, data?: Data): void;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
//#region src/printers.ts
|
|
2
|
+
/**
|
|
3
|
+
* Precedence table for expressions.
|
|
4
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#table
|
|
5
|
+
*/
|
|
2
6
|
const EXPRESSIONS_PRECEDENCE = {
|
|
3
7
|
ArrayPattern: 20,
|
|
4
8
|
ObjectPattern: 20,
|
|
@@ -109,13 +113,13 @@ function operandOfBinaryExprNeedsParens(node, parent, where) {
|
|
|
109
113
|
* which not contains a CallExpression
|
|
110
114
|
*/
|
|
111
115
|
function validUnparenthesizedNewOperand(node) {
|
|
116
|
+
if (node.type === "ChainExpression" || node.type === "ImportExpression") return false;
|
|
112
117
|
let cur = node;
|
|
113
118
|
while (true) if (cur.type === "CallExpression") return false;
|
|
114
119
|
else if (cur.type === "TSNonNullExpression") cur = cur.expression;
|
|
115
120
|
else if (cur.type === "MemberExpression") cur = cur.object;
|
|
116
121
|
else if (cur.type === "TaggedTemplateExpression") cur = cur.tag;
|
|
117
|
-
else
|
|
118
|
-
else return cur !== node;
|
|
122
|
+
else return true;
|
|
119
123
|
}
|
|
120
124
|
function operandOfUnaryExprNeedsParens(node) {
|
|
121
125
|
return EXPRESSIONS_PRECEDENCE[node.type] < EXPRESSIONS_PRECEDENCE.UnaryExpression;
|
|
@@ -130,19 +134,6 @@ function commentNeedsNewline(comment) {
|
|
|
130
134
|
if (comment.type === "Line") return true;
|
|
131
135
|
return comment.value.includes("\n");
|
|
132
136
|
}
|
|
133
|
-
function arrowConciseBodyNeedsWrap(body) {
|
|
134
|
-
if (body.type === "BlockStatement") return false;
|
|
135
|
-
switch (body.type) {
|
|
136
|
-
case "ObjectExpression": return true;
|
|
137
|
-
case "AssignmentExpression": return body.left.type === "ObjectPattern";
|
|
138
|
-
case "LogicalExpression": return body.left.type === "ObjectExpression";
|
|
139
|
-
case "ConditionalExpression": return body.test.type === "ObjectExpression";
|
|
140
|
-
case "TSAsExpression":
|
|
141
|
-
case "TSSatisfiesExpression":
|
|
142
|
-
case "TSNonNullExpression": return body.expression ? arrowConciseBodyNeedsWrap(body.expression) : false;
|
|
143
|
-
default: return false;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
137
|
const defaultPrinters = {
|
|
147
138
|
Program: printProgram,
|
|
148
139
|
Identifier: printIdentifier,
|
|
@@ -287,7 +278,7 @@ const defaultPrinters = {
|
|
|
287
278
|
TSIntrinsicKeyword: printKeywordType
|
|
288
279
|
};
|
|
289
280
|
function printProgram(program, context) {
|
|
290
|
-
context.writeNodeListWithNewLineSep(program.body);
|
|
281
|
+
context.writeNodeListWithNewLineSep(program.body, program.range?.[0]);
|
|
291
282
|
}
|
|
292
283
|
function canStartExpressionStatement(node) {
|
|
293
284
|
let lhs;
|
|
@@ -312,6 +303,7 @@ function canStartExpressionStatement(node) {
|
|
|
312
303
|
break;
|
|
313
304
|
case "MemberExpression":
|
|
314
305
|
lhs = node.object;
|
|
306
|
+
if (node.computed && lhs.type === "Identifier" && lhs.name === "let") return false;
|
|
315
307
|
break;
|
|
316
308
|
case "TaggedTemplateExpression":
|
|
317
309
|
lhs = node.tag;
|
|
@@ -347,8 +339,11 @@ function printVariableDeclaration(declaration, context) {
|
|
|
347
339
|
context.write(";");
|
|
348
340
|
}
|
|
349
341
|
function printVariableDeclarator(declarator, context) {
|
|
350
|
-
|
|
351
|
-
|
|
342
|
+
if (declarator.definite === true) {
|
|
343
|
+
context.write(String(declarator.id.name));
|
|
344
|
+
context.write("!");
|
|
345
|
+
writeOptionalTypeAnnotation(declarator.id, context);
|
|
346
|
+
} else context.writeNode(declarator.id);
|
|
352
347
|
if (declarator.init) {
|
|
353
348
|
context.write(" = ");
|
|
354
349
|
if (expectAssignmentExprNeedsParen(declarator.init)) {
|
|
@@ -362,8 +357,10 @@ function printBlockStatement(block, context) {
|
|
|
362
357
|
const body = block.body;
|
|
363
358
|
context.write("{");
|
|
364
359
|
if (body.length > 0) {
|
|
365
|
-
|
|
366
|
-
|
|
360
|
+
let lastRangeEnd;
|
|
361
|
+
if (block.range) lastRangeEnd = block.range[0] + 1;
|
|
362
|
+
else context.write("\n");
|
|
363
|
+
context.writeNodeListWithNewLineSep(body, lastRangeEnd);
|
|
367
364
|
context.write("\n");
|
|
368
365
|
}
|
|
369
366
|
context.write("}");
|
|
@@ -686,7 +683,7 @@ function printProperty(property, context) {
|
|
|
686
683
|
context.writeNode(value);
|
|
687
684
|
return;
|
|
688
685
|
}
|
|
689
|
-
if (value.type === "FunctionExpression") {
|
|
686
|
+
if (value.type === "FunctionExpression" && (property.method || property.kind !== "init")) {
|
|
690
687
|
if (property.kind !== "init") context.write(property.kind + " ");
|
|
691
688
|
if (value.async === true) context.write("async ");
|
|
692
689
|
if (value.generator === true) context.write("*");
|
|
@@ -708,7 +705,6 @@ function printProperty(property, context) {
|
|
|
708
705
|
context.writeNode(property.key);
|
|
709
706
|
context.write("]: ");
|
|
710
707
|
} else {
|
|
711
|
-
if (property.kind === "get" || property.kind === "set") context.write(property.kind + " ");
|
|
712
708
|
context.writeNode(property.key);
|
|
713
709
|
context.write(": ");
|
|
714
710
|
}
|
|
@@ -794,6 +790,44 @@ function printFunction(fn, context) {
|
|
|
794
790
|
context.writeNode(fn.body);
|
|
795
791
|
}
|
|
796
792
|
}
|
|
793
|
+
function canStartConciseBody(body) {
|
|
794
|
+
if (body.type === "BlockStatement" || body.type === "PrivateIdentifier") return true;
|
|
795
|
+
if (expectAssignmentExprNeedsParen(body)) return false;
|
|
796
|
+
let lhs;
|
|
797
|
+
switch (body.type) {
|
|
798
|
+
default: return true;
|
|
799
|
+
case "ObjectExpression":
|
|
800
|
+
case "FunctionExpression":
|
|
801
|
+
case "ClassExpression":
|
|
802
|
+
case "ObjectPattern": return false;
|
|
803
|
+
case "AssignmentExpression":
|
|
804
|
+
case "LogicalExpression":
|
|
805
|
+
case "BinaryExpression":
|
|
806
|
+
lhs = body.left;
|
|
807
|
+
break;
|
|
808
|
+
case "TSAsExpression":
|
|
809
|
+
case "TSSatisfiesExpression":
|
|
810
|
+
case "TSNonNullExpression":
|
|
811
|
+
lhs = body.expression;
|
|
812
|
+
break;
|
|
813
|
+
case "CallExpression":
|
|
814
|
+
lhs = body.callee;
|
|
815
|
+
break;
|
|
816
|
+
case "MemberExpression":
|
|
817
|
+
lhs = body.object;
|
|
818
|
+
if (body.computed && lhs.type === "Identifier" && lhs.name === "let") return false;
|
|
819
|
+
break;
|
|
820
|
+
case "TaggedTemplateExpression":
|
|
821
|
+
lhs = body.tag;
|
|
822
|
+
break;
|
|
823
|
+
case "ConditionalExpression":
|
|
824
|
+
lhs = body.test;
|
|
825
|
+
break;
|
|
826
|
+
case "UpdateExpression": return canStartConciseBody(body.argument);
|
|
827
|
+
case "ChainExpression": return canStartConciseBody(body.expression);
|
|
828
|
+
}
|
|
829
|
+
return operandOfBinaryExprNeedsParens(lhs, body, "left") || canStartConciseBody(lhs);
|
|
830
|
+
}
|
|
797
831
|
function printArrowFunctionExpression(fn, context) {
|
|
798
832
|
if (fn.async === true) context.write("async ");
|
|
799
833
|
if (fn.typeParameters) context.writeNode(fn.typeParameters);
|
|
@@ -803,7 +837,7 @@ function printArrowFunctionExpression(fn, context) {
|
|
|
803
837
|
writeReturnType(fn, context);
|
|
804
838
|
context.write(" => ");
|
|
805
839
|
const body = fn.body;
|
|
806
|
-
if (
|
|
840
|
+
if (!canStartConciseBody(body)) {
|
|
807
841
|
context.write("(");
|
|
808
842
|
context.writeNode(body);
|
|
809
843
|
context.write(")");
|
|
@@ -845,8 +879,10 @@ function printClassBody(node, context) {
|
|
|
845
879
|
context.write("{");
|
|
846
880
|
const body = node.body;
|
|
847
881
|
if (body.length > 0) {
|
|
848
|
-
|
|
849
|
-
|
|
882
|
+
let lastRangeEnd;
|
|
883
|
+
if (node.range) lastRangeEnd = node.range[0] + 1;
|
|
884
|
+
else context.write("\n");
|
|
885
|
+
context.writeNodeListWithNewLineSep(body, lastRangeEnd);
|
|
850
886
|
context.write("\n");
|
|
851
887
|
}
|
|
852
888
|
context.write("}");
|
|
@@ -855,8 +891,10 @@ function printStaticBlock(node, context) {
|
|
|
855
891
|
context.write("static {");
|
|
856
892
|
const body = node.body;
|
|
857
893
|
if (body.length > 0) {
|
|
858
|
-
|
|
859
|
-
|
|
894
|
+
let lastRangeEnd;
|
|
895
|
+
if (node.range) lastRangeEnd = node.range[0] + 1;
|
|
896
|
+
else context.write("\n");
|
|
897
|
+
context.writeNodeListWithNewLineSep(body, lastRangeEnd);
|
|
860
898
|
context.write("\n");
|
|
861
899
|
}
|
|
862
900
|
context.write("}");
|
|
@@ -1400,8 +1438,11 @@ function printTSModuleDeclaration(node, context) {
|
|
|
1400
1438
|
}
|
|
1401
1439
|
}
|
|
1402
1440
|
function printTSModuleBlock(node, context) {
|
|
1403
|
-
context.write("{
|
|
1404
|
-
|
|
1441
|
+
context.write("{");
|
|
1442
|
+
let lastRangeEnd;
|
|
1443
|
+
if (node.range) lastRangeEnd = node.range[0] + 1;
|
|
1444
|
+
else context.write("\n");
|
|
1445
|
+
context.writeNodeListWithNewLineSep(node.body, lastRangeEnd);
|
|
1405
1446
|
context.write("\n}");
|
|
1406
1447
|
}
|
|
1407
1448
|
function printTSDeclareFunction(node, context) {
|
|
@@ -1614,14 +1655,12 @@ function createPrinterContext(options) {
|
|
|
1614
1655
|
needsSeparator = true;
|
|
1615
1656
|
}
|
|
1616
1657
|
},
|
|
1617
|
-
writeNodeListWithNewLineSep(nodes) {
|
|
1618
|
-
let lastRangeEnd;
|
|
1658
|
+
writeNodeListWithNewLineSep(nodes, lastRangeEnd) {
|
|
1619
1659
|
let wroteNode = false;
|
|
1620
1660
|
for (const node of nodes) {
|
|
1621
|
-
if (!node) continue;
|
|
1622
1661
|
const range = getNodeRange(node);
|
|
1623
|
-
if (
|
|
1624
|
-
else context.write("\n");
|
|
1662
|
+
if (lastRangeEnd !== void 0 && range && range.start >= lastRangeEnd) context.writeSource(lastRangeEnd, range.start, getMappingData(null));
|
|
1663
|
+
else if (wroteNode) context.write("\n");
|
|
1625
1664
|
context.writeNode(node);
|
|
1626
1665
|
wroteNode = true;
|
|
1627
1666
|
if (range) lastRangeEnd = range.end;
|
package/package.json
CHANGED
package/src/api.ts
CHANGED
|
@@ -57,8 +57,17 @@ export interface PrinterContext<Data = any> {
|
|
|
57
57
|
writeExpressionListWithCommaSep(
|
|
58
58
|
nodes: readonly (AST.Expression | AST.SpreadElement | null)[],
|
|
59
59
|
): void;
|
|
60
|
+
/**
|
|
61
|
+
* Write `nodes` with "newline" separator, but if the node is ranged and either:
|
|
62
|
+
* - it is the first node with `lastRangeEnd` provided, or
|
|
63
|
+
* - the previous adjacent node is ranged too,
|
|
64
|
+
* Then the source text ranging between the two adjacent nodes will be preserved instead of printing a newline character.
|
|
65
|
+
* @param nodes
|
|
66
|
+
* @param lastRangeEnd
|
|
67
|
+
*/
|
|
60
68
|
writeNodeListWithNewLineSep(
|
|
61
69
|
nodes: readonly (AST.ProgramStatement | AST.ClassElement)[],
|
|
70
|
+
lastRangeEnd?: number,
|
|
62
71
|
): void;
|
|
63
72
|
writeSource(start: number, end: number, data?: Data): void;
|
|
64
73
|
writePreservedNode(node: AST.Node): void;
|
package/src/printer.ts
CHANGED
|
@@ -220,35 +220,21 @@ function createPrinterContext<Data>(
|
|
|
220
220
|
needsSeparator = true;
|
|
221
221
|
}
|
|
222
222
|
},
|
|
223
|
-
writeNodeListWithNewLineSep(nodes) {
|
|
224
|
-
let lastRangeEnd: number | undefined;
|
|
223
|
+
writeNodeListWithNewLineSep(nodes, lastRangeEnd) {
|
|
225
224
|
let wroteNode = false;
|
|
226
|
-
|
|
227
225
|
for (const node of nodes) {
|
|
228
|
-
if (!node) {
|
|
229
|
-
continue;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
226
|
const range = getNodeRange(node);
|
|
233
|
-
if (
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
)
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
range.start,
|
|
242
|
-
getMappingData(null),
|
|
243
|
-
);
|
|
244
|
-
} else {
|
|
245
|
-
context.write("\n");
|
|
246
|
-
}
|
|
227
|
+
if (
|
|
228
|
+
lastRangeEnd !== undefined &&
|
|
229
|
+
range &&
|
|
230
|
+
range.start >= lastRangeEnd
|
|
231
|
+
) {
|
|
232
|
+
context.writeSource(lastRangeEnd, range.start, getMappingData(null));
|
|
233
|
+
} else if (wroteNode) {
|
|
234
|
+
context.write("\n");
|
|
247
235
|
}
|
|
248
|
-
|
|
249
236
|
context.writeNode(node);
|
|
250
237
|
wroteNode = true;
|
|
251
|
-
|
|
252
238
|
if (range) {
|
|
253
239
|
lastRangeEnd = range.end;
|
|
254
240
|
} else {
|
package/src/printers.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { PrinterContext, Printers } from "./api.ts";
|
|
2
2
|
import type { AST, AST_NODE_TYPES, Comment } from "./types.ts";
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Precedence table for expressions.
|
|
6
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#table
|
|
7
|
+
*/
|
|
4
8
|
const EXPRESSIONS_PRECEDENCE = {
|
|
5
9
|
// LHS of =, must NOT parenthesized
|
|
6
10
|
ArrayPattern: 20,
|
|
@@ -48,7 +52,9 @@ const EXPRESSIONS_PRECEDENCE = {
|
|
|
48
52
|
|
|
49
53
|
// ranges from 13-5 depending on operator
|
|
50
54
|
BinaryExpression: 13,
|
|
51
|
-
// as/satisfies have same precedence as relational operators
|
|
55
|
+
// as/satisfies have same precedence as relational operators, e.g.
|
|
56
|
+
// `1 < 2 as number` is `(1 < 2) as number`, but
|
|
57
|
+
// `1 === 2 as number` is `1 === (2 as number)`
|
|
52
58
|
TSAsExpression: 9,
|
|
53
59
|
TSSatisfiesExpression: 9,
|
|
54
60
|
// ranges from 4-3 depending on operator
|
|
@@ -225,6 +231,9 @@ function operandOfBinaryExprNeedsParens(
|
|
|
225
231
|
* which not contains a CallExpression
|
|
226
232
|
*/
|
|
227
233
|
function validUnparenthesizedNewOperand(node: MemberLikeExpression): boolean {
|
|
234
|
+
if (node.type === "ChainExpression" || node.type === "ImportExpression") {
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
228
237
|
let cur: AST.Expression = node;
|
|
229
238
|
while (true) {
|
|
230
239
|
if (cur.type === "CallExpression") {
|
|
@@ -235,18 +244,8 @@ function validUnparenthesizedNewOperand(node: MemberLikeExpression): boolean {
|
|
|
235
244
|
cur = cur.object;
|
|
236
245
|
} else if (cur.type === "TaggedTemplateExpression") {
|
|
237
246
|
cur = cur.tag;
|
|
238
|
-
} else if (
|
|
239
|
-
cur.type === "MetaProperty" ||
|
|
240
|
-
cur.type === "NewExpression" ||
|
|
241
|
-
cur.type === "ImportExpression"
|
|
242
|
-
) {
|
|
243
|
-
return true;
|
|
244
247
|
} else {
|
|
245
|
-
|
|
246
|
-
// - an expression with higher precedence, no need to check further
|
|
247
|
-
// - an expression with lower precedence, will be inner-parenthesized later
|
|
248
|
-
// - a ChainExpression, will be inner-parenthesized later
|
|
249
|
-
return cur !== node;
|
|
248
|
+
return true;
|
|
250
249
|
}
|
|
251
250
|
}
|
|
252
251
|
}
|
|
@@ -279,30 +278,6 @@ function commentNeedsNewline(comment: Comment): boolean {
|
|
|
279
278
|
return comment.value.includes("\n");
|
|
280
279
|
}
|
|
281
280
|
|
|
282
|
-
function arrowConciseBodyNeedsWrap(
|
|
283
|
-
body: AST.BlockStatement | AST.Expression,
|
|
284
|
-
): boolean {
|
|
285
|
-
if (body.type === "BlockStatement") return false;
|
|
286
|
-
switch (body.type) {
|
|
287
|
-
case "ObjectExpression":
|
|
288
|
-
return true;
|
|
289
|
-
case "AssignmentExpression":
|
|
290
|
-
return body.left.type === "ObjectPattern";
|
|
291
|
-
case "LogicalExpression":
|
|
292
|
-
return body.left.type === "ObjectExpression";
|
|
293
|
-
case "ConditionalExpression":
|
|
294
|
-
return body.test.type === "ObjectExpression";
|
|
295
|
-
case "TSAsExpression":
|
|
296
|
-
case "TSSatisfiesExpression":
|
|
297
|
-
case "TSNonNullExpression":
|
|
298
|
-
return body.expression
|
|
299
|
-
? arrowConciseBodyNeedsWrap(body.expression)
|
|
300
|
-
: false;
|
|
301
|
-
default:
|
|
302
|
-
return false;
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
281
|
// Printers
|
|
307
282
|
export const defaultPrinters = {
|
|
308
283
|
Program: printProgram,
|
|
@@ -457,7 +432,7 @@ export const defaultPrinters = {
|
|
|
457
432
|
// JS – Statements
|
|
458
433
|
|
|
459
434
|
function printProgram(program: AST.Program, context: PrinterContext): void {
|
|
460
|
-
context.writeNodeListWithNewLineSep(program.body);
|
|
435
|
+
context.writeNodeListWithNewLineSep(program.body, program.range?.[0]);
|
|
461
436
|
}
|
|
462
437
|
|
|
463
438
|
function canStartExpressionStatement(
|
|
@@ -487,6 +462,9 @@ function canStartExpressionStatement(
|
|
|
487
462
|
break;
|
|
488
463
|
case "MemberExpression":
|
|
489
464
|
lhs = node.object;
|
|
465
|
+
if (node.computed && lhs.type === "Identifier" && lhs.name === "let") {
|
|
466
|
+
return false;
|
|
467
|
+
}
|
|
490
468
|
break;
|
|
491
469
|
case "TaggedTemplateExpression":
|
|
492
470
|
lhs = node.tag;
|
|
@@ -546,9 +524,18 @@ function printVariableDeclarator(
|
|
|
546
524
|
declarator: AST.VariableDeclarator,
|
|
547
525
|
context: PrinterContext,
|
|
548
526
|
): void {
|
|
549
|
-
context.writeNode(declarator.id);
|
|
550
527
|
if (declarator.definite === true) {
|
|
528
|
+
context.write(String((declarator.id as AST.Identifier).name));
|
|
551
529
|
context.write("!");
|
|
530
|
+
writeOptionalTypeAnnotation(
|
|
531
|
+
declarator.id as unknown as {
|
|
532
|
+
optional?: boolean;
|
|
533
|
+
typeAnnotation?: AST.Node | null;
|
|
534
|
+
},
|
|
535
|
+
context,
|
|
536
|
+
);
|
|
537
|
+
} else {
|
|
538
|
+
context.writeNode(declarator.id);
|
|
552
539
|
}
|
|
553
540
|
if (declarator.init) {
|
|
554
541
|
context.write(" = ");
|
|
@@ -570,8 +557,13 @@ function printBlockStatement(
|
|
|
570
557
|
const body = block.body;
|
|
571
558
|
context.write("{");
|
|
572
559
|
if (body.length > 0) {
|
|
573
|
-
|
|
574
|
-
|
|
560
|
+
let lastRangeEnd: number | undefined;
|
|
561
|
+
if (block.range) {
|
|
562
|
+
lastRangeEnd = block.range[0] + 1;
|
|
563
|
+
} else {
|
|
564
|
+
context.write("\n");
|
|
565
|
+
}
|
|
566
|
+
context.writeNodeListWithNewLineSep(body, lastRangeEnd);
|
|
575
567
|
context.write("\n");
|
|
576
568
|
}
|
|
577
569
|
context.write("}");
|
|
@@ -1161,7 +1153,10 @@ function printProperty(
|
|
|
1161
1153
|
}
|
|
1162
1154
|
|
|
1163
1155
|
// shorthand method
|
|
1164
|
-
if (
|
|
1156
|
+
if (
|
|
1157
|
+
value.type === "FunctionExpression" &&
|
|
1158
|
+
(property.method || property.kind !== "init")
|
|
1159
|
+
) {
|
|
1165
1160
|
if (property.kind !== "init") {
|
|
1166
1161
|
context.write(property.kind + " ");
|
|
1167
1162
|
}
|
|
@@ -1192,9 +1187,6 @@ function printProperty(
|
|
|
1192
1187
|
context.writeNode(property.key);
|
|
1193
1188
|
context.write("]: ");
|
|
1194
1189
|
} else {
|
|
1195
|
-
if (property.kind === "get" || property.kind === "set") {
|
|
1196
|
-
context.write(property.kind + " ");
|
|
1197
|
-
}
|
|
1198
1190
|
context.writeNode(property.key);
|
|
1199
1191
|
context.write(": ");
|
|
1200
1192
|
}
|
|
@@ -1342,6 +1334,60 @@ function printFunction(
|
|
|
1342
1334
|
}
|
|
1343
1335
|
}
|
|
1344
1336
|
|
|
1337
|
+
function canStartConciseBody(
|
|
1338
|
+
body: AST.BlockStatement | AST.Expression | AST.PrivateIdentifier,
|
|
1339
|
+
): boolean {
|
|
1340
|
+
if (body.type === "BlockStatement" || body.type === "PrivateIdentifier") {
|
|
1341
|
+
return true;
|
|
1342
|
+
}
|
|
1343
|
+
if (expectAssignmentExprNeedsParen(body)) {
|
|
1344
|
+
return false;
|
|
1345
|
+
}
|
|
1346
|
+
let lhs: AST.Expression | AST.PrivateIdentifier;
|
|
1347
|
+
switch (body.type) {
|
|
1348
|
+
default:
|
|
1349
|
+
return true;
|
|
1350
|
+
case "ObjectExpression":
|
|
1351
|
+
case "FunctionExpression":
|
|
1352
|
+
case "ClassExpression":
|
|
1353
|
+
case "ObjectPattern":
|
|
1354
|
+
return false;
|
|
1355
|
+
case "AssignmentExpression":
|
|
1356
|
+
case "LogicalExpression":
|
|
1357
|
+
case "BinaryExpression":
|
|
1358
|
+
lhs = body.left;
|
|
1359
|
+
break;
|
|
1360
|
+
case "TSAsExpression":
|
|
1361
|
+
case "TSSatisfiesExpression":
|
|
1362
|
+
case "TSNonNullExpression":
|
|
1363
|
+
lhs = body.expression;
|
|
1364
|
+
break;
|
|
1365
|
+
case "CallExpression":
|
|
1366
|
+
lhs = body.callee;
|
|
1367
|
+
break;
|
|
1368
|
+
case "MemberExpression":
|
|
1369
|
+
lhs = body.object;
|
|
1370
|
+
if (body.computed && lhs.type === "Identifier" && lhs.name === "let") {
|
|
1371
|
+
return false;
|
|
1372
|
+
}
|
|
1373
|
+
break;
|
|
1374
|
+
case "TaggedTemplateExpression":
|
|
1375
|
+
lhs = body.tag;
|
|
1376
|
+
break;
|
|
1377
|
+
case "ConditionalExpression":
|
|
1378
|
+
lhs = body.test;
|
|
1379
|
+
break;
|
|
1380
|
+
case "UpdateExpression":
|
|
1381
|
+
return canStartConciseBody(body.argument);
|
|
1382
|
+
case "ChainExpression":
|
|
1383
|
+
return canStartConciseBody(body.expression);
|
|
1384
|
+
}
|
|
1385
|
+
return (
|
|
1386
|
+
operandOfBinaryExprNeedsParens(lhs, body, "left") ||
|
|
1387
|
+
canStartConciseBody(lhs)
|
|
1388
|
+
);
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1345
1391
|
function printArrowFunctionExpression(
|
|
1346
1392
|
fn: AST.ArrowFunctionExpression,
|
|
1347
1393
|
context: PrinterContext,
|
|
@@ -1358,7 +1404,7 @@ function printArrowFunctionExpression(
|
|
|
1358
1404
|
writeReturnType(fn, context);
|
|
1359
1405
|
context.write(" => ");
|
|
1360
1406
|
const body = fn.body;
|
|
1361
|
-
if (
|
|
1407
|
+
if (!canStartConciseBody(body)) {
|
|
1362
1408
|
context.write("(");
|
|
1363
1409
|
context.writeNode(body);
|
|
1364
1410
|
context.write(")");
|
|
@@ -1431,8 +1477,13 @@ function printClassBody(node: AST.ClassBody, context: PrinterContext): void {
|
|
|
1431
1477
|
context.write("{");
|
|
1432
1478
|
const body = node.body;
|
|
1433
1479
|
if (body.length > 0) {
|
|
1434
|
-
|
|
1435
|
-
|
|
1480
|
+
let lastRangeEnd: number | undefined;
|
|
1481
|
+
if (node.range) {
|
|
1482
|
+
lastRangeEnd = node.range[0] + 1;
|
|
1483
|
+
} else {
|
|
1484
|
+
context.write("\n");
|
|
1485
|
+
}
|
|
1486
|
+
context.writeNodeListWithNewLineSep(body, lastRangeEnd);
|
|
1436
1487
|
context.write("\n");
|
|
1437
1488
|
}
|
|
1438
1489
|
context.write("}");
|
|
@@ -1445,8 +1496,13 @@ function printStaticBlock(
|
|
|
1445
1496
|
context.write("static {");
|
|
1446
1497
|
const body = node.body;
|
|
1447
1498
|
if (body.length > 0) {
|
|
1448
|
-
|
|
1449
|
-
|
|
1499
|
+
let lastRangeEnd: number | undefined;
|
|
1500
|
+
if (node.range) {
|
|
1501
|
+
lastRangeEnd = node.range[0] + 1;
|
|
1502
|
+
} else {
|
|
1503
|
+
context.write("\n");
|
|
1504
|
+
}
|
|
1505
|
+
context.writeNodeListWithNewLineSep(body, lastRangeEnd);
|
|
1450
1506
|
context.write("\n");
|
|
1451
1507
|
}
|
|
1452
1508
|
context.write("}");
|
|
@@ -2486,8 +2542,14 @@ function printTSModuleBlock(
|
|
|
2486
2542
|
node: AST.TSModuleBlock,
|
|
2487
2543
|
context: PrinterContext,
|
|
2488
2544
|
): void {
|
|
2489
|
-
context.write("{
|
|
2490
|
-
|
|
2545
|
+
context.write("{");
|
|
2546
|
+
let lastRangeEnd: number | undefined;
|
|
2547
|
+
if (node.range) {
|
|
2548
|
+
lastRangeEnd = node.range[0] + 1;
|
|
2549
|
+
} else {
|
|
2550
|
+
context.write("\n");
|
|
2551
|
+
}
|
|
2552
|
+
context.writeNodeListWithNewLineSep(node.body, lastRangeEnd);
|
|
2491
2553
|
context.write("\n}");
|
|
2492
2554
|
}
|
|
2493
2555
|
|