@herb-tools/core 0.1.0 → 0.2.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/src/nodes.ts CHANGED
@@ -2,11 +2,12 @@
2
2
  // be modified manually. See /Users/marcoroth/Development/herb-release/templates/javascript/packages/core/src/nodes.ts.erb
3
3
 
4
4
  import { Node } from "./node.js"
5
- import { Location, SerializedLocation } from "./location.js"
5
+ import { Location } from "./location.js"
6
6
  import { Token, SerializedToken } from "./token.js"
7
- import { HerbError, SerializedHerbError } from "./error.js"
7
+ import { HerbError } from "./error.js"
8
8
  import { convertToUTF8 } from "./util.js"
9
9
 
10
+ import type { Visitor } from "./visitor.js"
10
11
  import type { SerializedNode, BaseNodeProps } from "./node.js"
11
12
 
12
13
  export function fromSerializedNode(node: SerializedNode): Node {
@@ -31,6 +32,7 @@ export function fromSerializedNode(node: SerializedNode): Node {
31
32
  case "AST_ERB_BLOCK_NODE": return ERBBlockNode.from(node as SerializedERBBlockNode);
32
33
  case "AST_ERB_WHEN_NODE": return ERBWhenNode.from(node as SerializedERBWhenNode);
33
34
  case "AST_ERB_CASE_NODE": return ERBCaseNode.from(node as SerializedERBCaseNode);
35
+ case "AST_ERB_CASE_MATCH_NODE": return ERBCaseMatchNode.from(node as SerializedERBCaseMatchNode);
34
36
  case "AST_ERB_WHILE_NODE": return ERBWhileNode.from(node as SerializedERBWhileNode);
35
37
  case "AST_ERB_UNTIL_NODE": return ERBUntilNode.from(node as SerializedERBUntilNode);
36
38
  case "AST_ERB_FOR_NODE": return ERBForNode.from(node as SerializedERBForNode);
@@ -38,6 +40,8 @@ export function fromSerializedNode(node: SerializedNode): Node {
38
40
  case "AST_ERB_ENSURE_NODE": return ERBEnsureNode.from(node as SerializedERBEnsureNode);
39
41
  case "AST_ERB_BEGIN_NODE": return ERBBeginNode.from(node as SerializedERBBeginNode);
40
42
  case "AST_ERB_UNLESS_NODE": return ERBUnlessNode.from(node as SerializedERBUnlessNode);
43
+ case "AST_ERB_YIELD_NODE": return ERBYieldNode.from(node as SerializedERBYieldNode);
44
+ case "AST_ERB_IN_NODE": return ERBInNode.from(node as SerializedERBInNode);
41
45
 
42
46
  default:
43
47
  throw new Error(`Unknown node type: ${node.type}`);
@@ -66,6 +70,7 @@ export type NodeType =
66
70
  | "AST_ERB_BLOCK_NODE"
67
71
  | "AST_ERB_WHEN_NODE"
68
72
  | "AST_ERB_CASE_NODE"
73
+ | "AST_ERB_CASE_MATCH_NODE"
69
74
  | "AST_ERB_WHILE_NODE"
70
75
  | "AST_ERB_UNTIL_NODE"
71
76
  | "AST_ERB_FOR_NODE"
@@ -73,6 +78,8 @@ export type NodeType =
73
78
  | "AST_ERB_ENSURE_NODE"
74
79
  | "AST_ERB_BEGIN_NODE"
75
80
  | "AST_ERB_UNLESS_NODE"
81
+ | "AST_ERB_YIELD_NODE"
82
+ | "AST_ERB_IN_NODE"
76
83
 
77
84
  export interface SerializedDocumentNode extends SerializedNode {
78
85
  type: "AST_DOCUMENT_NODE";
@@ -100,10 +107,18 @@ export class DocumentNode extends Node {
100
107
  this.children = props.children;
101
108
  }
102
109
 
103
- childNodes(): Node[] {
110
+ accept(visitor: Visitor): void {
111
+ visitor.visitDocumentNode(this)
112
+ }
113
+
114
+ childNodes(): (Node | null | undefined)[] {
104
115
  return [
105
116
  ...this.children,
106
- ].filter(node => node !== null && node !== undefined) as Node[];
117
+ ];
118
+ }
119
+
120
+ compactChildNodes(): Node[] {
121
+ return this.childNodes().filter(node => node !== null && node !== undefined)
107
122
  }
108
123
 
109
124
  recursiveErrors(): HerbError[] {
@@ -160,9 +175,17 @@ export class LiteralNode extends Node {
160
175
  this.content = convertToUTF8(props.content);
161
176
  }
162
177
 
163
- childNodes(): Node[] {
178
+ accept(visitor: Visitor): void {
179
+ visitor.visitLiteralNode(this)
180
+ }
181
+
182
+ childNodes(): (Node | null | undefined)[] {
164
183
  return [
165
- ].filter(node => node !== null && node !== undefined) as Node[];
184
+ ];
185
+ }
186
+
187
+ compactChildNodes(): Node[] {
188
+ return this.childNodes().filter(node => node !== null && node !== undefined)
166
189
  }
167
190
 
168
191
  recursiveErrors(): HerbError[] {
@@ -238,10 +261,18 @@ export class HTMLOpenTagNode extends Node {
238
261
  this.is_void = props.is_void;
239
262
  }
240
263
 
241
- childNodes(): Node[] {
264
+ accept(visitor: Visitor): void {
265
+ visitor.visitHTMLOpenTagNode(this)
266
+ }
267
+
268
+ childNodes(): (Node | null | undefined)[] {
242
269
  return [
243
270
  ...this.children,
244
- ].filter(node => node !== null && node !== undefined) as Node[];
271
+ ];
272
+ }
273
+
274
+ compactChildNodes(): Node[] {
275
+ return this.childNodes().filter(node => node !== null && node !== undefined)
245
276
  }
246
277
 
247
278
  recursiveErrors(): HerbError[] {
@@ -316,9 +347,17 @@ export class HTMLCloseTagNode extends Node {
316
347
  this.tag_closing = props.tag_closing;
317
348
  }
318
349
 
319
- childNodes(): Node[] {
350
+ accept(visitor: Visitor): void {
351
+ visitor.visitHTMLCloseTagNode(this)
352
+ }
353
+
354
+ childNodes(): (Node | null | undefined)[] {
320
355
  return [
321
- ].filter(node => node !== null && node !== undefined) as Node[];
356
+ ];
357
+ }
358
+
359
+ compactChildNodes(): Node[] {
360
+ return this.childNodes().filter(node => node !== null && node !== undefined)
322
361
  }
323
362
 
324
363
  recursiveErrors(): HerbError[] {
@@ -364,7 +403,7 @@ export interface SerializedHTMLSelfCloseTagNode extends SerializedNode {
364
403
  export interface HTMLSelfCloseTagNodeProps extends BaseNodeProps {
365
404
  tag_opening: Token | null;
366
405
  tag_name: Token | null;
367
- attributes: Node[];
406
+ attributes: any[];
368
407
  tag_closing: Token | null;
369
408
  is_void: boolean;
370
409
  }
@@ -372,7 +411,7 @@ export interface HTMLSelfCloseTagNodeProps extends BaseNodeProps {
372
411
  export class HTMLSelfCloseTagNode extends Node {
373
412
  readonly tag_opening: Token | null;
374
413
  readonly tag_name: Token | null;
375
- readonly attributes: Node[];
414
+ readonly attributes: any[];
376
415
  readonly tag_closing: Token | null;
377
416
  readonly is_void: boolean;
378
417
 
@@ -398,10 +437,18 @@ export class HTMLSelfCloseTagNode extends Node {
398
437
  this.is_void = props.is_void;
399
438
  }
400
439
 
401
- childNodes(): Node[] {
440
+ accept(visitor: Visitor): void {
441
+ visitor.visitHTMLSelfCloseTagNode(this)
442
+ }
443
+
444
+ childNodes(): (Node | null | undefined)[] {
402
445
  return [
403
446
  ...this.attributes,
404
- ].filter(node => node !== null && node !== undefined) as Node[];
447
+ ];
448
+ }
449
+
450
+ compactChildNodes(): Node[] {
451
+ return this.childNodes().filter(node => node !== null && node !== undefined)
405
452
  }
406
453
 
407
454
  recursiveErrors(): HerbError[] {
@@ -486,12 +533,20 @@ export class HTMLElementNode extends Node {
486
533
  this.is_void = props.is_void;
487
534
  }
488
535
 
489
- childNodes(): Node[] {
536
+ accept(visitor: Visitor): void {
537
+ visitor.visitHTMLElementNode(this)
538
+ }
539
+
540
+ childNodes(): (Node | null | undefined)[] {
490
541
  return [
491
542
  this.open_tag,
492
543
  ...this.body,
493
544
  this.close_tag,
494
- ].filter(node => node !== null && node !== undefined) as Node[];
545
+ ];
546
+ }
547
+
548
+ compactChildNodes(): Node[] {
549
+ return this.childNodes().filter(node => node !== null && node !== undefined)
495
550
  }
496
551
 
497
552
  recursiveErrors(): HerbError[] {
@@ -573,10 +628,18 @@ export class HTMLAttributeValueNode extends Node {
573
628
  this.quoted = props.quoted;
574
629
  }
575
630
 
576
- childNodes(): Node[] {
631
+ accept(visitor: Visitor): void {
632
+ visitor.visitHTMLAttributeValueNode(this)
633
+ }
634
+
635
+ childNodes(): (Node | null | undefined)[] {
577
636
  return [
578
637
  ...this.children,
579
- ].filter(node => node !== null && node !== undefined) as Node[];
638
+ ];
639
+ }
640
+
641
+ compactChildNodes(): Node[] {
642
+ return this.childNodes().filter(node => node !== null && node !== undefined)
580
643
  }
581
644
 
582
645
  recursiveErrors(): HerbError[] {
@@ -639,9 +702,17 @@ export class HTMLAttributeNameNode extends Node {
639
702
  this.name = props.name;
640
703
  }
641
704
 
642
- childNodes(): Node[] {
705
+ accept(visitor: Visitor): void {
706
+ visitor.visitHTMLAttributeNameNode(this)
707
+ }
708
+
709
+ childNodes(): (Node | null | undefined)[] {
643
710
  return [
644
- ].filter(node => node !== null && node !== undefined) as Node[];
711
+ ];
712
+ }
713
+
714
+ compactChildNodes(): Node[] {
715
+ return this.childNodes().filter(node => node !== null && node !== undefined)
645
716
  }
646
717
 
647
718
  recursiveErrors(): HerbError[] {
@@ -707,11 +778,19 @@ export class HTMLAttributeNode extends Node {
707
778
  this.value = props.value;
708
779
  }
709
780
 
710
- childNodes(): Node[] {
781
+ accept(visitor: Visitor): void {
782
+ visitor.visitHTMLAttributeNode(this)
783
+ }
784
+
785
+ childNodes(): (Node | null | undefined)[] {
711
786
  return [
712
787
  this.name,
713
788
  this.value,
714
- ].filter(node => node !== null && node !== undefined) as Node[];
789
+ ];
790
+ }
791
+
792
+ compactChildNodes(): Node[] {
793
+ return this.childNodes().filter(node => node !== null && node !== undefined)
715
794
  }
716
795
 
717
796
  recursiveErrors(): HerbError[] {
@@ -773,9 +852,17 @@ export class HTMLTextNode extends Node {
773
852
  this.content = convertToUTF8(props.content);
774
853
  }
775
854
 
776
- childNodes(): Node[] {
855
+ accept(visitor: Visitor): void {
856
+ visitor.visitHTMLTextNode(this)
857
+ }
858
+
859
+ childNodes(): (Node | null | undefined)[] {
777
860
  return [
778
- ].filter(node => node !== null && node !== undefined) as Node[];
861
+ ];
862
+ }
863
+
864
+ compactChildNodes(): Node[] {
865
+ return this.childNodes().filter(node => node !== null && node !== undefined)
779
866
  }
780
867
 
781
868
  recursiveErrors(): HerbError[] {
@@ -841,10 +928,18 @@ export class HTMLCommentNode extends Node {
841
928
  this.comment_end = props.comment_end;
842
929
  }
843
930
 
844
- childNodes(): Node[] {
931
+ accept(visitor: Visitor): void {
932
+ visitor.visitHTMLCommentNode(this)
933
+ }
934
+
935
+ childNodes(): (Node | null | undefined)[] {
845
936
  return [
846
937
  ...this.children,
847
- ].filter(node => node !== null && node !== undefined) as Node[];
938
+ ];
939
+ }
940
+
941
+ compactChildNodes(): Node[] {
942
+ return this.childNodes().filter(node => node !== null && node !== undefined)
848
943
  }
849
944
 
850
945
  recursiveErrors(): HerbError[] {
@@ -915,10 +1010,18 @@ export class HTMLDoctypeNode extends Node {
915
1010
  this.tag_closing = props.tag_closing;
916
1011
  }
917
1012
 
918
- childNodes(): Node[] {
1013
+ accept(visitor: Visitor): void {
1014
+ visitor.visitHTMLDoctypeNode(this)
1015
+ }
1016
+
1017
+ childNodes(): (Node | null | undefined)[] {
919
1018
  return [
920
1019
  ...this.children,
921
- ].filter(node => node !== null && node !== undefined) as Node[];
1020
+ ];
1021
+ }
1022
+
1023
+ compactChildNodes(): Node[] {
1024
+ return this.childNodes().filter(node => node !== null && node !== undefined)
922
1025
  }
923
1026
 
924
1027
  recursiveErrors(): HerbError[] {
@@ -979,9 +1082,17 @@ export class WhitespaceNode extends Node {
979
1082
  this.value = props.value;
980
1083
  }
981
1084
 
982
- childNodes(): Node[] {
1085
+ accept(visitor: Visitor): void {
1086
+ visitor.visitWhitespaceNode(this)
1087
+ }
1088
+
1089
+ childNodes(): (Node | null | undefined)[] {
983
1090
  return [
984
- ].filter(node => node !== null && node !== undefined) as Node[];
1091
+ ];
1092
+ }
1093
+
1094
+ compactChildNodes(): Node[] {
1095
+ return this.childNodes().filter(node => node !== null && node !== undefined)
985
1096
  }
986
1097
 
987
1098
  recursiveErrors(): HerbError[] {
@@ -1062,9 +1173,17 @@ export class ERBContentNode extends Node {
1062
1173
  this.valid = props.valid;
1063
1174
  }
1064
1175
 
1065
- childNodes(): Node[] {
1176
+ accept(visitor: Visitor): void {
1177
+ visitor.visitERBContentNode(this)
1178
+ }
1179
+
1180
+ childNodes(): (Node | null | undefined)[] {
1066
1181
  return [
1067
- ].filter(node => node !== null && node !== undefined) as Node[];
1182
+ ];
1183
+ }
1184
+
1185
+ compactChildNodes(): Node[] {
1186
+ return this.childNodes().filter(node => node !== null && node !== undefined)
1068
1187
  }
1069
1188
 
1070
1189
  recursiveErrors(): HerbError[] {
@@ -1140,9 +1259,17 @@ export class ERBEndNode extends Node {
1140
1259
  this.tag_closing = props.tag_closing;
1141
1260
  }
1142
1261
 
1143
- childNodes(): Node[] {
1262
+ accept(visitor: Visitor): void {
1263
+ visitor.visitERBEndNode(this)
1264
+ }
1265
+
1266
+ childNodes(): (Node | null | undefined)[] {
1144
1267
  return [
1145
- ].filter(node => node !== null && node !== undefined) as Node[];
1268
+ ];
1269
+ }
1270
+
1271
+ compactChildNodes(): Node[] {
1272
+ return this.childNodes().filter(node => node !== null && node !== undefined)
1146
1273
  }
1147
1274
 
1148
1275
  recursiveErrors(): HerbError[] {
@@ -1217,10 +1344,18 @@ export class ERBElseNode extends Node {
1217
1344
  this.statements = props.statements;
1218
1345
  }
1219
1346
 
1220
- childNodes(): Node[] {
1347
+ accept(visitor: Visitor): void {
1348
+ visitor.visitERBElseNode(this)
1349
+ }
1350
+
1351
+ childNodes(): (Node | null | undefined)[] {
1221
1352
  return [
1222
1353
  ...this.statements,
1223
- ].filter(node => node !== null && node !== undefined) as Node[];
1354
+ ];
1355
+ }
1356
+
1357
+ compactChildNodes(): Node[] {
1358
+ return this.childNodes().filter(node => node !== null && node !== undefined)
1224
1359
  }
1225
1360
 
1226
1361
  recursiveErrors(): HerbError[] {
@@ -1308,12 +1443,20 @@ export class ERBIfNode extends Node {
1308
1443
  this.end_node = props.end_node;
1309
1444
  }
1310
1445
 
1311
- childNodes(): Node[] {
1446
+ accept(visitor: Visitor): void {
1447
+ visitor.visitERBIfNode(this)
1448
+ }
1449
+
1450
+ childNodes(): (Node | null | undefined)[] {
1312
1451
  return [
1313
1452
  ...this.statements,
1314
1453
  this.subsequent,
1315
1454
  this.end_node,
1316
- ].filter(node => node !== null && node !== undefined) as Node[];
1455
+ ];
1456
+ }
1457
+
1458
+ compactChildNodes(): Node[] {
1459
+ return this.childNodes().filter(node => node !== null && node !== undefined)
1317
1460
  }
1318
1461
 
1319
1462
  recursiveErrors(): HerbError[] {
@@ -1402,11 +1545,19 @@ export class ERBBlockNode extends Node {
1402
1545
  this.end_node = props.end_node;
1403
1546
  }
1404
1547
 
1405
- childNodes(): Node[] {
1548
+ accept(visitor: Visitor): void {
1549
+ visitor.visitERBBlockNode(this)
1550
+ }
1551
+
1552
+ childNodes(): (Node | null | undefined)[] {
1406
1553
  return [
1407
1554
  ...this.body,
1408
1555
  this.end_node,
1409
- ].filter(node => node !== null && node !== undefined) as Node[];
1556
+ ];
1557
+ }
1558
+
1559
+ compactChildNodes(): Node[] {
1560
+ return this.childNodes().filter(node => node !== null && node !== undefined)
1410
1561
  }
1411
1562
 
1412
1563
  recursiveErrors(): HerbError[] {
@@ -1487,10 +1638,18 @@ export class ERBWhenNode extends Node {
1487
1638
  this.statements = props.statements;
1488
1639
  }
1489
1640
 
1490
- childNodes(): Node[] {
1641
+ accept(visitor: Visitor): void {
1642
+ visitor.visitERBWhenNode(this)
1643
+ }
1644
+
1645
+ childNodes(): (Node | null | undefined)[] {
1491
1646
  return [
1492
1647
  ...this.statements,
1493
- ].filter(node => node !== null && node !== undefined) as Node[];
1648
+ ];
1649
+ }
1650
+
1651
+ compactChildNodes(): Node[] {
1652
+ return this.childNodes().filter(node => node !== null && node !== undefined)
1494
1653
  }
1495
1654
 
1496
1655
  recursiveErrors(): HerbError[] {
@@ -1543,7 +1702,7 @@ export interface ERBCaseNodeProps extends BaseNodeProps {
1543
1702
  content: Token | null;
1544
1703
  tag_closing: Token | null;
1545
1704
  children: Node[];
1546
- conditions: Node[];
1705
+ conditions: any[];
1547
1706
  else_clause: Node | null;
1548
1707
  end_node: Node | null;
1549
1708
  }
@@ -1553,7 +1712,7 @@ export class ERBCaseNode extends Node {
1553
1712
  readonly content: Token | null;
1554
1713
  readonly tag_closing: Token | null;
1555
1714
  readonly children: Node[];
1556
- readonly conditions: Node[];
1715
+ readonly conditions: any[];
1557
1716
  readonly else_clause: Node | null;
1558
1717
  readonly end_node: Node | null;
1559
1718
 
@@ -1583,13 +1742,21 @@ export class ERBCaseNode extends Node {
1583
1742
  this.end_node = props.end_node;
1584
1743
  }
1585
1744
 
1586
- childNodes(): Node[] {
1745
+ accept(visitor: Visitor): void {
1746
+ visitor.visitERBCaseNode(this)
1747
+ }
1748
+
1749
+ childNodes(): (Node | null | undefined)[] {
1587
1750
  return [
1588
1751
  ...this.children,
1589
1752
  ...this.conditions,
1590
1753
  this.else_clause,
1591
1754
  this.end_node,
1592
- ].filter(node => node !== null && node !== undefined) as Node[];
1755
+ ];
1756
+ }
1757
+
1758
+ compactChildNodes(): Node[] {
1759
+ return this.childNodes().filter(node => node !== null && node !== undefined)
1593
1760
  }
1594
1761
 
1595
1762
  recursiveErrors(): HerbError[] {
@@ -1635,6 +1802,122 @@ export class ERBCaseNode extends Node {
1635
1802
  }
1636
1803
  }
1637
1804
 
1805
+ export interface SerializedERBCaseMatchNode extends SerializedNode {
1806
+ type: "AST_ERB_CASE_MATCH_NODE";
1807
+ tag_opening: SerializedToken | null;
1808
+ content: SerializedToken | null;
1809
+ tag_closing: SerializedToken | null;
1810
+ children: SerializedNode[];
1811
+ conditions: SerializedNode[];
1812
+ else_clause: SerializedNode | null;
1813
+ end_node: SerializedNode | null;
1814
+ }
1815
+
1816
+ export interface ERBCaseMatchNodeProps extends BaseNodeProps {
1817
+ tag_opening: Token | null;
1818
+ content: Token | null;
1819
+ tag_closing: Token | null;
1820
+ children: Node[];
1821
+ conditions: any[];
1822
+ else_clause: Node | null;
1823
+ end_node: Node | null;
1824
+ }
1825
+
1826
+ export class ERBCaseMatchNode extends Node {
1827
+ readonly tag_opening: Token | null;
1828
+ readonly content: Token | null;
1829
+ readonly tag_closing: Token | null;
1830
+ readonly children: Node[];
1831
+ readonly conditions: any[];
1832
+ readonly else_clause: Node | null;
1833
+ readonly end_node: Node | null;
1834
+
1835
+ static from(data: SerializedERBCaseMatchNode): ERBCaseMatchNode {
1836
+ return new ERBCaseMatchNode({
1837
+ type: data.type,
1838
+ location: Location.from(data.location),
1839
+ errors: (data.errors || []).map(error => HerbError.from(error)),
1840
+ tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
1841
+ content: data.content ? Token.from(data.content) : null,
1842
+ tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
1843
+ children: (data.children || []).map(node => fromSerializedNode(node)),
1844
+ conditions: (data.conditions || []).map(node => fromSerializedNode(node)),
1845
+ else_clause: data.else_clause ? fromSerializedNode((data.else_clause as any)) : null,
1846
+ end_node: data.end_node ? fromSerializedNode((data.end_node as any)) : null,
1847
+ })
1848
+ }
1849
+
1850
+ constructor(props: ERBCaseMatchNodeProps) {
1851
+ super(props.type, props.location, props.errors);
1852
+ this.tag_opening = props.tag_opening;
1853
+ this.content = props.content;
1854
+ this.tag_closing = props.tag_closing;
1855
+ this.children = props.children;
1856
+ this.conditions = props.conditions;
1857
+ this.else_clause = props.else_clause;
1858
+ this.end_node = props.end_node;
1859
+ }
1860
+
1861
+ accept(visitor: Visitor): void {
1862
+ visitor.visitERBCaseMatchNode(this)
1863
+ }
1864
+
1865
+ childNodes(): (Node | null | undefined)[] {
1866
+ return [
1867
+ ...this.children,
1868
+ ...this.conditions,
1869
+ this.else_clause,
1870
+ this.end_node,
1871
+ ];
1872
+ }
1873
+
1874
+ compactChildNodes(): Node[] {
1875
+ return this.childNodes().filter(node => node !== null && node !== undefined)
1876
+ }
1877
+
1878
+ recursiveErrors(): HerbError[] {
1879
+ return [
1880
+ ...this.errors,
1881
+ ...this.children.map(node => node.recursiveErrors()),
1882
+ ...this.conditions.map(node => node.recursiveErrors()),
1883
+ this.else_clause ? this.else_clause.recursiveErrors() : [],
1884
+ this.end_node ? this.end_node.recursiveErrors() : [],
1885
+ ].flat();
1886
+ }
1887
+
1888
+ toJSON(): SerializedERBCaseMatchNode {
1889
+ return {
1890
+ ...super.toJSON(),
1891
+ type: "AST_ERB_CASE_MATCH_NODE",
1892
+ tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
1893
+ content: this.content ? this.content.toJSON() : null,
1894
+ tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
1895
+ children: this.children.map(node => node.toJSON()),
1896
+ conditions: this.conditions.map(node => node.toJSON()),
1897
+ else_clause: this.else_clause ? this.else_clause.toJSON() : null,
1898
+ end_node: this.end_node ? this.end_node.toJSON() : null,
1899
+ };
1900
+ }
1901
+
1902
+ treeInspect(): string {
1903
+ let output = "";
1904
+
1905
+ output += `@ ERBCaseMatchNode ${this.location.treeInspectWithLabel()}\n`;
1906
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
1907
+ output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
1908
+ output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
1909
+ output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
1910
+ output += `├── children: ${this.inspectArray(this.children, "│ ")}`;
1911
+ output += `├── conditions: ${this.inspectArray(this.conditions, "│ ")}`;
1912
+ output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
1913
+ output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
1914
+
1915
+ // output += "\n";
1916
+
1917
+ return output
1918
+ }
1919
+ }
1920
+
1638
1921
  export interface SerializedERBWhileNode extends SerializedNode {
1639
1922
  type: "AST_ERB_WHILE_NODE";
1640
1923
  tag_opening: SerializedToken | null;
@@ -1681,11 +1964,19 @@ export class ERBWhileNode extends Node {
1681
1964
  this.end_node = props.end_node;
1682
1965
  }
1683
1966
 
1684
- childNodes(): Node[] {
1967
+ accept(visitor: Visitor): void {
1968
+ visitor.visitERBWhileNode(this)
1969
+ }
1970
+
1971
+ childNodes(): (Node | null | undefined)[] {
1685
1972
  return [
1686
1973
  ...this.statements,
1687
1974
  this.end_node,
1688
- ].filter(node => node !== null && node !== undefined) as Node[];
1975
+ ];
1976
+ }
1977
+
1978
+ compactChildNodes(): Node[] {
1979
+ return this.childNodes().filter(node => node !== null && node !== undefined)
1689
1980
  }
1690
1981
 
1691
1982
  recursiveErrors(): HerbError[] {
@@ -1771,11 +2062,19 @@ export class ERBUntilNode extends Node {
1771
2062
  this.end_node = props.end_node;
1772
2063
  }
1773
2064
 
1774
- childNodes(): Node[] {
2065
+ accept(visitor: Visitor): void {
2066
+ visitor.visitERBUntilNode(this)
2067
+ }
2068
+
2069
+ childNodes(): (Node | null | undefined)[] {
1775
2070
  return [
1776
2071
  ...this.statements,
1777
2072
  this.end_node,
1778
- ].filter(node => node !== null && node !== undefined) as Node[];
2073
+ ];
2074
+ }
2075
+
2076
+ compactChildNodes(): Node[] {
2077
+ return this.childNodes().filter(node => node !== null && node !== undefined)
1779
2078
  }
1780
2079
 
1781
2080
  recursiveErrors(): HerbError[] {
@@ -1861,11 +2160,19 @@ export class ERBForNode extends Node {
1861
2160
  this.end_node = props.end_node;
1862
2161
  }
1863
2162
 
1864
- childNodes(): Node[] {
2163
+ accept(visitor: Visitor): void {
2164
+ visitor.visitERBForNode(this)
2165
+ }
2166
+
2167
+ childNodes(): (Node | null | undefined)[] {
1865
2168
  return [
1866
2169
  ...this.statements,
1867
2170
  this.end_node,
1868
- ].filter(node => node !== null && node !== undefined) as Node[];
2171
+ ];
2172
+ }
2173
+
2174
+ compactChildNodes(): Node[] {
2175
+ return this.childNodes().filter(node => node !== null && node !== undefined)
1869
2176
  }
1870
2177
 
1871
2178
  recursiveErrors(): HerbError[] {
@@ -1951,11 +2258,19 @@ export class ERBRescueNode extends Node {
1951
2258
  this.subsequent = props.subsequent;
1952
2259
  }
1953
2260
 
1954
- childNodes(): Node[] {
2261
+ accept(visitor: Visitor): void {
2262
+ visitor.visitERBRescueNode(this)
2263
+ }
2264
+
2265
+ childNodes(): (Node | null | undefined)[] {
1955
2266
  return [
1956
2267
  ...this.statements,
1957
2268
  this.subsequent,
1958
- ].filter(node => node !== null && node !== undefined) as Node[];
2269
+ ];
2270
+ }
2271
+
2272
+ compactChildNodes(): Node[] {
2273
+ return this.childNodes().filter(node => node !== null && node !== undefined)
1959
2274
  }
1960
2275
 
1961
2276
  recursiveErrors(): HerbError[] {
@@ -2036,10 +2351,18 @@ export class ERBEnsureNode extends Node {
2036
2351
  this.statements = props.statements;
2037
2352
  }
2038
2353
 
2039
- childNodes(): Node[] {
2354
+ accept(visitor: Visitor): void {
2355
+ visitor.visitERBEnsureNode(this)
2356
+ }
2357
+
2358
+ childNodes(): (Node | null | undefined)[] {
2040
2359
  return [
2041
2360
  ...this.statements,
2042
- ].filter(node => node !== null && node !== undefined) as Node[];
2361
+ ];
2362
+ }
2363
+
2364
+ compactChildNodes(): Node[] {
2365
+ return this.childNodes().filter(node => node !== null && node !== undefined)
2043
2366
  }
2044
2367
 
2045
2368
  recursiveErrors(): HerbError[] {
@@ -2137,14 +2460,22 @@ export class ERBBeginNode extends Node {
2137
2460
  this.end_node = props.end_node;
2138
2461
  }
2139
2462
 
2140
- childNodes(): Node[] {
2463
+ accept(visitor: Visitor): void {
2464
+ visitor.visitERBBeginNode(this)
2465
+ }
2466
+
2467
+ childNodes(): (Node | null | undefined)[] {
2141
2468
  return [
2142
2469
  ...this.statements,
2143
2470
  this.rescue_clause,
2144
2471
  this.else_clause,
2145
2472
  this.ensure_clause,
2146
2473
  this.end_node,
2147
- ].filter(node => node !== null && node !== undefined) as Node[];
2474
+ ];
2475
+ }
2476
+
2477
+ compactChildNodes(): Node[] {
2478
+ return this.childNodes().filter(node => node !== null && node !== undefined)
2148
2479
  }
2149
2480
 
2150
2481
  recursiveErrors(): HerbError[] {
@@ -2244,12 +2575,20 @@ export class ERBUnlessNode extends Node {
2244
2575
  this.end_node = props.end_node;
2245
2576
  }
2246
2577
 
2247
- childNodes(): Node[] {
2578
+ accept(visitor: Visitor): void {
2579
+ visitor.visitERBUnlessNode(this)
2580
+ }
2581
+
2582
+ childNodes(): (Node | null | undefined)[] {
2248
2583
  return [
2249
2584
  ...this.statements,
2250
2585
  this.else_clause,
2251
2586
  this.end_node,
2252
- ].filter(node => node !== null && node !== undefined) as Node[];
2587
+ ];
2588
+ }
2589
+
2590
+ compactChildNodes(): Node[] {
2591
+ return this.childNodes().filter(node => node !== null && node !== undefined)
2253
2592
  }
2254
2593
 
2255
2594
  recursiveErrors(): HerbError[] {
@@ -2292,3 +2631,172 @@ export class ERBUnlessNode extends Node {
2292
2631
  }
2293
2632
  }
2294
2633
 
2634
+ export interface SerializedERBYieldNode extends SerializedNode {
2635
+ type: "AST_ERB_YIELD_NODE";
2636
+ tag_opening: SerializedToken | null;
2637
+ content: SerializedToken | null;
2638
+ tag_closing: SerializedToken | null;
2639
+ }
2640
+
2641
+ export interface ERBYieldNodeProps extends BaseNodeProps {
2642
+ tag_opening: Token | null;
2643
+ content: Token | null;
2644
+ tag_closing: Token | null;
2645
+ }
2646
+
2647
+ export class ERBYieldNode extends Node {
2648
+ readonly tag_opening: Token | null;
2649
+ readonly content: Token | null;
2650
+ readonly tag_closing: Token | null;
2651
+
2652
+ static from(data: SerializedERBYieldNode): ERBYieldNode {
2653
+ return new ERBYieldNode({
2654
+ type: data.type,
2655
+ location: Location.from(data.location),
2656
+ errors: (data.errors || []).map(error => HerbError.from(error)),
2657
+ tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
2658
+ content: data.content ? Token.from(data.content) : null,
2659
+ tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2660
+ })
2661
+ }
2662
+
2663
+ constructor(props: ERBYieldNodeProps) {
2664
+ super(props.type, props.location, props.errors);
2665
+ this.tag_opening = props.tag_opening;
2666
+ this.content = props.content;
2667
+ this.tag_closing = props.tag_closing;
2668
+ }
2669
+
2670
+ accept(visitor: Visitor): void {
2671
+ visitor.visitERBYieldNode(this)
2672
+ }
2673
+
2674
+ childNodes(): (Node | null | undefined)[] {
2675
+ return [
2676
+ ];
2677
+ }
2678
+
2679
+ compactChildNodes(): Node[] {
2680
+ return this.childNodes().filter(node => node !== null && node !== undefined)
2681
+ }
2682
+
2683
+ recursiveErrors(): HerbError[] {
2684
+ return [
2685
+ ...this.errors,
2686
+ ].flat();
2687
+ }
2688
+
2689
+ toJSON(): SerializedERBYieldNode {
2690
+ return {
2691
+ ...super.toJSON(),
2692
+ type: "AST_ERB_YIELD_NODE",
2693
+ tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
2694
+ content: this.content ? this.content.toJSON() : null,
2695
+ tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
2696
+ };
2697
+ }
2698
+
2699
+ treeInspect(): string {
2700
+ let output = "";
2701
+
2702
+ output += `@ ERBYieldNode ${this.location.treeInspectWithLabel()}\n`;
2703
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
2704
+ output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
2705
+ output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
2706
+ output += `└── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
2707
+
2708
+ // output += "\n";
2709
+
2710
+ return output
2711
+ }
2712
+ }
2713
+
2714
+ export interface SerializedERBInNode extends SerializedNode {
2715
+ type: "AST_ERB_IN_NODE";
2716
+ tag_opening: SerializedToken | null;
2717
+ content: SerializedToken | null;
2718
+ tag_closing: SerializedToken | null;
2719
+ statements: SerializedNode[];
2720
+ }
2721
+
2722
+ export interface ERBInNodeProps extends BaseNodeProps {
2723
+ tag_opening: Token | null;
2724
+ content: Token | null;
2725
+ tag_closing: Token | null;
2726
+ statements: Node[];
2727
+ }
2728
+
2729
+ export class ERBInNode extends Node {
2730
+ readonly tag_opening: Token | null;
2731
+ readonly content: Token | null;
2732
+ readonly tag_closing: Token | null;
2733
+ readonly statements: Node[];
2734
+
2735
+ static from(data: SerializedERBInNode): ERBInNode {
2736
+ return new ERBInNode({
2737
+ type: data.type,
2738
+ location: Location.from(data.location),
2739
+ errors: (data.errors || []).map(error => HerbError.from(error)),
2740
+ tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
2741
+ content: data.content ? Token.from(data.content) : null,
2742
+ tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2743
+ statements: (data.statements || []).map(node => fromSerializedNode(node)),
2744
+ })
2745
+ }
2746
+
2747
+ constructor(props: ERBInNodeProps) {
2748
+ super(props.type, props.location, props.errors);
2749
+ this.tag_opening = props.tag_opening;
2750
+ this.content = props.content;
2751
+ this.tag_closing = props.tag_closing;
2752
+ this.statements = props.statements;
2753
+ }
2754
+
2755
+ accept(visitor: Visitor): void {
2756
+ visitor.visitERBInNode(this)
2757
+ }
2758
+
2759
+ childNodes(): (Node | null | undefined)[] {
2760
+ return [
2761
+ ...this.statements,
2762
+ ];
2763
+ }
2764
+
2765
+ compactChildNodes(): Node[] {
2766
+ return this.childNodes().filter(node => node !== null && node !== undefined)
2767
+ }
2768
+
2769
+ recursiveErrors(): HerbError[] {
2770
+ return [
2771
+ ...this.errors,
2772
+ ...this.statements.map(node => node.recursiveErrors()),
2773
+ ].flat();
2774
+ }
2775
+
2776
+ toJSON(): SerializedERBInNode {
2777
+ return {
2778
+ ...super.toJSON(),
2779
+ type: "AST_ERB_IN_NODE",
2780
+ tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
2781
+ content: this.content ? this.content.toJSON() : null,
2782
+ tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
2783
+ statements: this.statements.map(node => node.toJSON()),
2784
+ };
2785
+ }
2786
+
2787
+ treeInspect(): string {
2788
+ let output = "";
2789
+
2790
+ output += `@ ERBInNode ${this.location.treeInspectWithLabel()}\n`;
2791
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
2792
+ output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
2793
+ output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
2794
+ output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
2795
+ output += `└── statements: ${this.inspectArray(this.statements, " ")}`;
2796
+
2797
+ // output += "\n";
2798
+
2799
+ return output
2800
+ }
2801
+ }
2802
+