liquidsoap-prettier 1.7.4 → 1.8.1

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/src/index.js CHANGED
@@ -1,21 +1,9 @@
1
1
  import prettierDoc from "prettier/doc";
2
2
  import * as liquidsoap from "../dist/liquidsoap.cjs";
3
+ import { remapOffsets } from "./remap_offsets.js";
3
4
 
4
5
  const {
5
- builders: {
6
- group,
7
- trim,
8
- indent,
9
- dedent,
10
- join,
11
- hardline,
12
- line,
13
- litteralline,
14
- softline,
15
- ifBreak,
16
- lineSuffix,
17
- fill,
18
- },
6
+ builders: { group, trim, indent, join, hardline, line, softline, ifBreak, fill },
19
7
  } = prettierDoc;
20
8
 
21
9
  export const languages = [
@@ -27,15 +15,42 @@ export const languages = [
27
15
  },
28
16
  ];
29
17
 
18
+
30
19
  export const parsers = {
31
20
  liquidsoap: {
32
- parse: liquidsoap.default.lang.parse,
21
+ parse: (text) => {
22
+ const result = liquidsoap.default.lang.parse(text);
23
+ remapOffsets(result, text);
24
+ result.ast.comments = result.comments;
25
+ return result.ast;
26
+ },
33
27
  astFormat: "liquidsoap",
34
- locStart: () => 0,
35
- locEnd: () => 0,
28
+ locStart: (node) => node.position?.[0]?.cnum ?? node.start ?? 0,
29
+ locEnd: (node) => node.position?.[1]?.cnum ?? node.end ?? 0,
36
30
  },
37
31
  };
38
32
 
33
+ const printStmts = (stmts, printed) => {
34
+ if (!stmts || stmts.length === 0) return "";
35
+ const result = [];
36
+ for (let i = 0; i < printed.length; i++) {
37
+ if (i > 0) {
38
+ result.push(hardline);
39
+ const prev = stmts[i - 1];
40
+ const cur = stmts[i];
41
+ if (
42
+ prev.position?.[1]?.lnum &&
43
+ cur.position?.[0]?.lnum &&
44
+ cur.position[0].lnum - prev.position[1].lnum > 1
45
+ ) {
46
+ result.push(hardline);
47
+ }
48
+ }
49
+ result.push(printed[i]);
50
+ }
51
+ return result;
52
+ };
53
+
39
54
  const printString = (str) => {
40
55
  if (/(?<!\\)\n/.test(str)) return str;
41
56
  if (!/\s/.test(str)) return str;
@@ -51,11 +66,17 @@ const printString = (str) => {
51
66
  const print = (path, options, print) => {
52
67
  const node = path.getValue();
53
68
 
69
+ const printStatements = (field) =>
70
+ printStmts(node[field], path.map(print, field));
71
+
54
72
  const printIfDef = (...ifdef) => [
55
73
  group([trim, ...ifdef, hardline]),
56
- group([print("then")]),
57
- ...(node.else
58
- ? [group([hardline, trim, "%else", hardline]), group([print("else")])]
74
+ group([path.call(print, "then_block")]),
75
+ ...(node.else_block
76
+ ? [
77
+ group([hardline, trim, "%else", hardline]),
78
+ group([path.call(print, "else_block")]),
79
+ ]
59
80
  : []),
60
81
  group([hardline, trim, "%endif"]),
61
82
  ];
@@ -72,113 +93,19 @@ const print = (path, options, print) => {
72
93
  ]);
73
94
  };
74
95
 
75
- const newLine = (pos1, pos2) => {
76
- const posBefore = pos1?.[1]?.lnum;
77
- const posAfter = pos2?.[0]?.lnum;
78
- return posBefore && posAfter && posAfter - posBefore > 1 ? [hardline] : [];
79
- };
80
-
81
96
  const printEllipsis = (p) => {
82
- node.ast_comments = node.value.ast_comments;
83
- node.position = node.value.position;
84
- delete node.value.ast_comments;
85
97
  return group(["...", print(p)]);
86
98
  };
87
99
 
88
- const printComments = (node, content) => {
89
- if (!node.ast_comments) return [node.position, content];
90
-
91
- const beforeComments = node.ast_comments.before;
92
- const afterComments = node.ast_comments.after;
93
-
94
- delete node.ast_comments;
95
-
96
- const [contentWithBeforeComments, beforePosition] = beforeComments
97
- .reverse()
98
- .reduce(
99
- ([content, position], comment) => [
100
- [
101
- join(hardline, comment.value),
102
- hardline,
103
- ...(position === node.position
104
- ? newLine(comment.position, position)
105
- : [hardline]),
106
- ...content,
107
- ],
108
- comment.position,
109
- ],
110
- [[content], node.position],
111
- );
112
-
113
- const [contentWithAfterComments, afterPosition] = afterComments.reduce(
114
- ([content, position], comment) => [
115
- [
116
- ...content,
117
- ...(position === node.position
118
- ? [hardline, ...newLine(position, comment.position)]
119
- : [hardline, hardline]),
120
- lineSuffix(join(hardline, comment.value)),
121
- ],
122
- comment.position,
123
- ],
124
- [contentWithBeforeComments, node.position],
125
- );
126
-
127
- return [[beforePosition[0], afterPosition[1]], contentWithAfterComments];
128
- };
129
-
130
100
  const printSeq = (pos1, content1, pos2, content2) => {
131
- return [content1, hardline, ...newLine(pos1, pos2), content2];
101
+ const posBefore = pos1?.[1]?.lnum;
102
+ const posAfter = pos2?.[0]?.lnum;
103
+ const blank =
104
+ posBefore && posAfter && posAfter - posBefore > 1 ? [hardline] : [];
105
+ return [content1, hardline, ...blank, content2];
132
106
  };
133
107
 
134
- const printDef = (pos1, node1) =>
135
- node.body.type === "eof"
136
- ? node1
137
- : printSeq(pos1, node1, node.body.position, print("body"));
138
-
139
- const joinWithComments = (join, p) => {
140
- const nodes = node[p].map((node) => {
141
- if (node.type === "term") {
142
- node.ast_comments = node.value.ast_comments;
143
- node.position = node.value.position;
144
- delete node.value.ast_comments;
145
- }
146
-
147
- const { ast_comments, position } = node;
148
-
149
- delete node.ast_comments;
150
-
151
- return { ast_comments, position };
152
- });
153
-
154
- const content = path.map(print, p);
155
-
156
- return content.reduce(
157
- ([position, result], c, idx) => {
158
- const isLast = idx === content.length - 1;
159
- const joinedContent = isLast ? c : [c, join];
160
-
161
- if (!nodes[idx].position)
162
- return [position, [result, joinedContent, ...(isLast ? [] : [line])]];
163
-
164
- const [nextPosition, contentWithComments] = printComments(
165
- nodes[idx],
166
- joinedContent,
167
- );
168
-
169
- return [
170
- [position[0], nextPosition[1]],
171
- [
172
- ...result,
173
- ...newLine(position, nextPosition),
174
- contentWithComments,
175
- ...(isLast ? [] : [line]),
176
- ],
177
- ];
178
- },
179
- [node.position, []],
180
- )[1];
181
- };
108
+ const joinArgs = (p) => join([",", line], path.map(print, p));
182
109
 
183
110
  const printOptTyp = (name) => [
184
111
  ...(node.typ ? ["(", softline] : []),
@@ -252,7 +179,7 @@ const print = (path, options, print) => {
252
179
  return [
253
180
  group([
254
181
  "(",
255
- indent([softline, joinWithComments([",", line], "args")]),
182
+ indent([softline, joinArgs("args")]),
256
183
  softline,
257
184
  ")",
258
185
  ]),
@@ -274,7 +201,7 @@ const print = (path, options, print) => {
274
201
  return group([
275
202
  "{",
276
203
  group([
277
- indent([softline, joinWithComments([","], "value")]),
204
+ indent([softline, joinArgs("value")]),
278
205
  softline,
279
206
  ]),
280
207
  "}",
@@ -284,7 +211,7 @@ const print = (path, options, print) => {
284
211
  print("base"),
285
212
  ".",
286
213
  "{",
287
- group([indent([line, joinWithComments([","], "value")]), line]),
214
+ group([indent([line, joinArgs("value")]), line]),
288
215
  "}",
289
216
  ];
290
217
  case "invoke":
@@ -317,7 +244,7 @@ const print = (path, options, print) => {
317
244
  : [
318
245
  group([
319
246
  "(",
320
- indent([softline, joinWithComments([","], "params")]),
247
+ indent([softline, joinArgs("params")]),
321
248
  softline,
322
249
  ")",
323
250
  ]),
@@ -332,15 +259,21 @@ const print = (path, options, print) => {
332
259
 
333
260
  const printValue = () => {
334
261
  switch (node.type) {
335
- case "while":
336
- return group([
337
- "while",
338
- group([indent([line, print("condition")]), line]),
339
- "do",
340
- group([indent([line, print("loop")]), line]),
341
- "end",
342
- ]);
343
- case "for":
262
+ case "program":
263
+ return printStatements("body");
264
+ case "while": {
265
+ const [whileHeader, whileBody] = path.map(print, "parts");
266
+ return group([whileHeader, whileBody, line, "end"]);
267
+ }
268
+ case "while_header":
269
+ return ["while", group([indent([line, print("condition")]), line])];
270
+ case "while_body":
271
+ return ["do", group([indent([line, printStatements("body")]), line])];
272
+ case "for": {
273
+ const [forHeader, forBody] = path.map(print, "parts");
274
+ return group([forHeader, forBody, line, "end"]);
275
+ }
276
+ case "for_header":
344
277
  return group([
345
278
  "for",
346
279
  " ",
@@ -348,29 +281,27 @@ const print = (path, options, print) => {
348
281
  "to",
349
282
  indent([line, print("to")]),
350
283
  line,
351
- "do",
352
- indent([line, print("loop")]),
353
- line,
354
- "end",
355
284
  ]);
356
- case "iterable_for":
285
+ case "for_body":
286
+ return ["do", indent([line, printStatements("body")]), line];
287
+ case "iterable_for": {
288
+ const [iterHeader, iterBody] = path.map(print, "parts");
289
+ return group([iterHeader, iterBody, line, "end"]);
290
+ }
291
+ case "iterable_for_header":
357
292
  return group([
358
293
  "for",
359
- line,
294
+ " ",
360
295
  node.variable,
361
- line,
296
+ " ",
362
297
  "=",
298
+ indent([line, print("iterator")]),
363
299
  line,
364
- print("iterator"),
365
- line,
366
- "do",
367
- print("do"),
368
- indent([line, print("loop")]),
369
- line,
370
- "end",
371
300
  ]);
301
+ case "iterable_for_body":
302
+ return ["do", indent([line, printStatements("body")]), line];
372
303
  case "open":
373
- return ["open", " ", print("left"), hardline, print("right")];
304
+ return ["open", " ", print("left")];
374
305
  case "if_def":
375
306
  return printIfDef(
376
307
  node.negative ? "%ifndef" : "%ifdef",
@@ -386,6 +317,8 @@ const print = (path, options, print) => {
386
317
  );
387
318
  case "if_version":
388
319
  return printIfDef("%ifversion", " ", node.opt, " ", node.version);
320
+ case "ifdef_block":
321
+ return printStmts(node.body, path.map(print, "body"));
389
322
  case "negative":
390
323
  return group(["-", print("value")]);
391
324
  case "append":
@@ -434,7 +367,7 @@ const print = (path, options, print) => {
434
367
  return group([
435
368
  "(",
436
369
  group([
437
- indent([softline, joinWithComments([","], "value")]),
370
+ indent([softline, joinArgs("value")]),
438
371
  softline,
439
372
  ]),
440
373
  ")",
@@ -442,14 +375,14 @@ const print = (path, options, print) => {
442
375
  case "list":
443
376
  return group([
444
377
  "[",
445
- indent(group([softline, joinWithComments([","], "value")])),
378
+ indent(group([softline, joinArgs("value")])),
446
379
  softline,
447
380
  "]",
448
381
  ]);
449
382
  case "pmeth":
450
383
  return group([
451
384
  "{",
452
- indent([softline, joinWithComments([","], "value")]),
385
+ indent([softline, joinArgs("value")]),
453
386
  softline,
454
387
  "}",
455
388
  ]);
@@ -489,7 +422,7 @@ const print = (path, options, print) => {
489
422
  case "parenthesis":
490
423
  return group(["(", indent([softline, print("value")]), softline, ")"]);
491
424
  case "block":
492
- return group(["begin", indent([line, print("value")]), line, "end"]);
425
+ return group(["begin", indent([line, printStatements("body")]), line, "end"]);
493
426
  case "cast":
494
427
  return group([
495
428
  "(",
@@ -504,36 +437,31 @@ const print = (path, options, print) => {
504
437
  " ",
505
438
  group([
506
439
  "(",
507
- indent([softline, joinWithComments([","], "arguments")]),
440
+ indent([softline, joinArgs("arguments")]),
508
441
  softline,
509
442
  ")",
510
443
  " ",
511
444
  "->",
512
445
  ]),
513
- indent([line, print("body")]),
446
+ indent([line, printStatements("body")]),
514
447
  ]);
515
448
  case "fun_arg":
516
449
  return printFunArg();
517
450
  case "app_arg":
518
451
  return printAppArg();
519
- case "app":
452
+ case "app": {
520
453
  if (node.args.length === 0) {
521
454
  return group([print("op"), "(", ")"]);
522
455
  }
523
-
524
- // Print all arguments
525
456
  const printedArgs = path.map(print, "args");
526
-
527
- // Try to format on a single line first
528
- const singleLine = join(", ", printedArgs);
529
-
530
- // Format with line breaks
531
- const multiLine = [
532
- indent([line, join([",", line], printedArgs)]),
533
- line,
534
- ];
535
-
536
- return group([print("op"), "(", ifBreak(multiLine, singleLine), ")"]);
457
+ return group([
458
+ print("op"),
459
+ "(",
460
+ indent([softline, join([",", line], printedArgs)]),
461
+ softline,
462
+ ")",
463
+ ]);
464
+ }
537
465
  case "eof":
538
466
  return "";
539
467
  case "seq":
@@ -545,89 +473,87 @@ const print = (path, options, print) => {
545
473
  print("right"),
546
474
  );
547
475
  case "def":
548
- return printDef(
549
- ...printComments(
550
- node,
551
- group([
552
- "def",
553
- " ",
554
- ...(node.decoration ? [print("decoration"), " "] : []),
555
- printPat(),
556
- ...(node.arglist
557
- ? [
558
- "(",
559
- group([
560
- indent([softline, joinWithComments([","], "arglist")]),
561
- softline,
562
- ]),
563
- ")",
564
- ]
565
- : []),
566
- " ",
567
- "=",
568
- group([indent([hardline, print("definition")]), hardline, "end"]),
569
- ]),
570
- ),
571
- );
476
+ return group([
477
+ "def",
478
+ " ",
479
+ ...(node.decoration ? [print("decoration"), " "] : []),
480
+ printPat(),
481
+ ...(node.arglist
482
+ ? [
483
+ "(",
484
+ group([
485
+ indent([softline, joinArgs("arglist")]),
486
+ softline,
487
+ ]),
488
+ ")",
489
+ ]
490
+ : []),
491
+ " ",
492
+ "=",
493
+ group([
494
+ indent([hardline, printStatements("body")]),
495
+ hardline,
496
+ "end",
497
+ ]),
498
+ ]);
572
499
  case "let":
573
- return printDef(
574
- ...printComments(
575
- node,
576
- group([
577
- "let",
578
- " ",
579
- ...(node.decoration ? [print("decoration"), " "] : []),
580
- printPat(),
581
- " ",
582
- "=",
583
- group([indent([line, print("definition")])]),
584
- ]),
585
- ),
586
- );
500
+ return group([
501
+ "let",
502
+ " ",
503
+ ...(node.decoration ? [print("decoration"), " "] : []),
504
+ printPat(),
505
+ " ",
506
+ "=",
507
+ group([indent([line, print("definition")])]),
508
+ ]);
587
509
  case "binding":
588
- return printDef(
589
- ...printComments(
590
- node,
591
- group([
592
- printPat(),
593
- " ",
594
- "=",
595
- group([indent([line, print("definition")])]),
596
- ]),
597
- ),
598
- );
599
- case "simple_fun":
600
- return group(["{", indent([softline, print("value")]), softline, "}"]);
601
- case "if":
602
510
  return group([
511
+ printPat(),
512
+ " ",
513
+ "=",
514
+ group([indent([line, print("definition")])]),
515
+ ]);
516
+ case "simple_fun":
517
+ return group(["{", indent([softline, printStatements("body")]), softline, "}"]);
518
+ case "if": {
519
+ const parts = [
603
520
  "if",
604
- indent([line, group(print("condition"))]),
521
+ indent([line, print("condition")]),
605
522
  line,
523
+ path.call(print, "then_block"),
524
+ ];
525
+ for (let i = 0; i < node.elsif.length; i++) {
526
+ parts.push(line, path.call(print, "elsif", i));
527
+ }
528
+ if (node.else_block) {
529
+ parts.push(line, path.call(print, "else_block"));
530
+ }
531
+ parts.push(line, "end");
532
+ return group(parts);
533
+ }
534
+ case "then_block":
535
+ return [
606
536
  "then",
607
- indent([line, print("then")]),
608
- ...(node.elsif.length !== 0
609
- ? [line, join(line, path.map(print, "elsif"))]
610
- : []),
611
- ...(node.else ? [line, "else", indent([line, print("else")])] : []),
612
- line,
613
- "end",
614
- ]);
615
- case "elsif":
616
- return group([
537
+ indent([line, printStmts(node.body, path.map(print, "body"))]),
538
+ ];
539
+ case "else_block":
540
+ return [
541
+ "else",
542
+ indent([line, printStmts(node.body, path.map(print, "body"))]),
543
+ ];
544
+ case "elsif": {
545
+ return [
617
546
  "elsif",
618
547
  indent([line, print("condition")]),
619
548
  line,
620
549
  "then",
621
- indent([line, print("then")]),
622
- ]);
550
+ indent([line, printStmts(node.body, path.map(print, "body"))]),
551
+ ];
552
+ }
623
553
  case "inline_if":
624
554
  return group([
625
555
  print("condition"),
626
- line,
627
- "?",
628
- group([indent([line, print("then")]), line]),
629
- ":",
630
- group([indent([line, print("else")]), line]),
556
+ indent([line, "? ", print("then"), line, ": ", print("else")]),
631
557
  ]);
632
558
  case "infix":
633
559
  return group([
@@ -637,26 +563,15 @@ const print = (path, options, print) => {
637
563
  indent([line, print("right")]),
638
564
  ]);
639
565
  case "bool":
640
- return group(
641
- join(
642
- [dedent(line), node.op, line],
643
- path.map(
644
- (v) => group([indent([softline, print(v)]), softline]),
645
- "value",
646
- ),
647
- ),
648
- );
566
+ return group(join([line, node.op, " "], path.map(print, "value")));
649
567
  case "string_interpolation":
650
- return group(path.map(print, "value"));
568
+ return path.map(print, "value");
651
569
  case "interpolated_string":
652
570
  return printString(node.value);
653
571
  case "interpolated_term":
654
572
  return group(["#{", indent([softline, print("value")]), softline, "}"]);
655
573
  case "coalesce":
656
- return group([
657
- print("left"),
658
- indent([line, "??", indent([line, print("right")])]),
659
- ]);
574
+ return group([print("left"), indent([line, "?? ", print("right")])]);
660
575
  case "assoc":
661
576
  return group([
662
577
  print("left"),
@@ -689,7 +604,7 @@ const print = (path, options, print) => {
689
604
  : [
690
605
  group([
691
606
  "(",
692
- indent([softline, joinWithComments([","], "params")]),
607
+ indent([softline, joinArgs("params")]),
693
608
  softline,
694
609
  ")",
695
610
  ]),
@@ -702,43 +617,48 @@ const print = (path, options, print) => {
702
617
  ...(node.base ? [print("base"), "."] : []),
703
618
  group([
704
619
  "{",
705
- indent([softline, joinWithComments([","], "methods")]),
620
+ indent([softline, joinArgs("methods")]),
706
621
  softline,
707
622
  "}",
708
623
  ]),
709
624
  ];
710
625
  case "method":
711
- return group([node.name, "=", indent([softline, print("value")])]);
626
+ return group([node.name, " ", "=", indent([line, print("value")])]);
712
627
  case "try":
713
- return group([
628
+ return group([...path.map(print, "parts"), line, "end"]);
629
+ case "try_body":
630
+ return [
714
631
  "try",
715
- indent(group([line, print("body")], { shouldBreak: true })),
716
- ...(node.handler
717
- ? [
718
- line,
719
- group([
720
- "catch",
721
- line,
722
- node.variable,
723
- ...(node.errors_list
724
- ? [group([line, ":", line, print("errors_list")])]
725
- : []),
726
- line,
727
- "do",
728
- ]),
729
- indent(group([line, print("handler")], { shouldBreak: true })),
730
- ]
731
- : []),
732
- ...(node.finally
733
- ? [
734
- line,
735
- group(["finally", line]),
736
- indent(group([line, print("finally")], { shouldBreak: true })),
737
- ]
738
- : []),
632
+ indent(group([line, printStatements("body")], { shouldBreak: true })),
633
+ ];
634
+ case "try_catch":
635
+ return [
739
636
  line,
740
- "end",
741
- ]);
637
+ group([
638
+ "catch",
639
+ line,
640
+ node.variable,
641
+ ...(node.errors_list
642
+ ? [
643
+ group([
644
+ line,
645
+ ":",
646
+ line,
647
+ print("errors_list"),
648
+ ]),
649
+ ]
650
+ : []),
651
+ line,
652
+ "do",
653
+ ]),
654
+ indent(group([line, printStatements("body")], { shouldBreak: true })),
655
+ ];
656
+ case "try_finally":
657
+ return [
658
+ line,
659
+ "finally",
660
+ indent(group([line, printStatements("body")], { shouldBreak: true })),
661
+ ];
742
662
  case "null":
743
663
  return "null";
744
664
  default:
@@ -746,15 +666,56 @@ const print = (path, options, print) => {
746
666
  }
747
667
  };
748
668
 
749
- return [
750
- printComments(node, printValue())[1],
751
- ...(path.stack.length == 1 ? ["\n"] : []),
752
- ];
669
+ return [printValue(), ...(path.stack.length == 1 ? [hardline] : [])];
753
670
  };
754
671
 
755
672
  export const printers = {
756
673
  liquidsoap: {
757
674
  print,
675
+ canAttachComment: (node) => node.position != null && node.type !== "eof",
676
+ isBlockComment: () => false,
677
+ printComment: (path) => {
678
+ const value = path.getValue().value;
679
+ const lines = value.split("\n");
680
+ return lines.length === 1 ? value : join(hardline, lines);
681
+ },
682
+ handleComments: {},
683
+ getCommentChildNodes: (node) => {
684
+ if (
685
+ [
686
+ "program", "def", "fun", "rfun", "simple_fun", "block",
687
+ "while_body", "for_body", "iterable_for_body",
688
+ "try_body", "try_finally",
689
+ ].includes(node.type)
690
+ )
691
+ return node.body;
692
+ if (node.type === "if")
693
+ return [
694
+ node.condition,
695
+ node.then_block,
696
+ ...node.elsif,
697
+ ...(node.else_block ? [node.else_block] : []),
698
+ ];
699
+ if (node.type === "then_block" || node.type === "else_block")
700
+ return node.body;
701
+ if (node.type === "elsif")
702
+ return [node.condition, ...node.body];
703
+ if (["while", "for", "iterable_for", "try"].includes(node.type))
704
+ return node.parts;
705
+ if (node.type === "while_header") return [node.condition];
706
+ if (node.type === "for_header") return [node.from, node.to];
707
+ if (node.type === "iterable_for_header") return [node.iterator];
708
+ if (node.type === "try_catch")
709
+ return [
710
+ ...(node.errors_list ? [node.errors_list] : []),
711
+ ...node.body,
712
+ ];
713
+ if (["if_def", "if_version", "if_encoder"].includes(node.type))
714
+ return [node.then_block, ...(node.else_block ? [node.else_block] : [])];
715
+ if (node.type === "ifdef_block") return node.body;
716
+ if (node.type === "app") return [node.op, ...node.args];
717
+ return null;
718
+ },
758
719
  },
759
720
  };
760
721