@herb-tools/core 0.1.1 → 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.
@@ -1,12 +1,5 @@
1
1
  'use strict';
2
2
 
3
- class ASTNode {
4
- errors;
5
- constructor() {
6
- this.errors = [];
7
- }
8
- }
9
-
10
3
  const expectedFunctions = [
11
4
  "parse",
12
5
  "lex",
@@ -736,7 +729,7 @@ class RubyParseError extends HerbError {
736
729
  }
737
730
 
738
731
  var name = "@herb-tools/core";
739
- var version = "0.1.1";
732
+ var version = "0.2.0";
740
733
  var packageJSON = {
741
734
  name: name,
742
735
  version: version};
@@ -947,6 +940,7 @@ function fromSerializedNode(node) {
947
940
  case "AST_ERB_BLOCK_NODE": return ERBBlockNode.from(node);
948
941
  case "AST_ERB_WHEN_NODE": return ERBWhenNode.from(node);
949
942
  case "AST_ERB_CASE_NODE": return ERBCaseNode.from(node);
943
+ case "AST_ERB_CASE_MATCH_NODE": return ERBCaseMatchNode.from(node);
950
944
  case "AST_ERB_WHILE_NODE": return ERBWhileNode.from(node);
951
945
  case "AST_ERB_UNTIL_NODE": return ERBUntilNode.from(node);
952
946
  case "AST_ERB_FOR_NODE": return ERBForNode.from(node);
@@ -954,6 +948,8 @@ function fromSerializedNode(node) {
954
948
  case "AST_ERB_ENSURE_NODE": return ERBEnsureNode.from(node);
955
949
  case "AST_ERB_BEGIN_NODE": return ERBBeginNode.from(node);
956
950
  case "AST_ERB_UNLESS_NODE": return ERBUnlessNode.from(node);
951
+ case "AST_ERB_YIELD_NODE": return ERBYieldNode.from(node);
952
+ case "AST_ERB_IN_NODE": return ERBInNode.from(node);
957
953
  default:
958
954
  throw new Error(`Unknown node type: ${node.type}`);
959
955
  }
@@ -972,10 +968,16 @@ class DocumentNode extends Node {
972
968
  super(props.type, props.location, props.errors);
973
969
  this.children = props.children;
974
970
  }
971
+ accept(visitor) {
972
+ visitor.visitDocumentNode(this);
973
+ }
975
974
  childNodes() {
976
975
  return [
977
976
  ...this.children,
978
- ].filter(node => node !== null && node !== undefined);
977
+ ];
978
+ }
979
+ compactChildNodes() {
980
+ return this.childNodes().filter(node => node !== null && node !== undefined);
979
981
  }
980
982
  recursiveErrors() {
981
983
  return [
@@ -1013,8 +1015,14 @@ class LiteralNode extends Node {
1013
1015
  super(props.type, props.location, props.errors);
1014
1016
  this.content = convertToUTF8(props.content);
1015
1017
  }
1018
+ accept(visitor) {
1019
+ visitor.visitLiteralNode(this);
1020
+ }
1016
1021
  childNodes() {
1017
- return [].filter(node => node !== null && node !== undefined);
1022
+ return [];
1023
+ }
1024
+ compactChildNodes() {
1025
+ return this.childNodes().filter(node => node !== null && node !== undefined);
1018
1026
  }
1019
1027
  recursiveErrors() {
1020
1028
  return [
@@ -1063,10 +1071,16 @@ class HTMLOpenTagNode extends Node {
1063
1071
  this.children = props.children;
1064
1072
  this.is_void = props.is_void;
1065
1073
  }
1074
+ accept(visitor) {
1075
+ visitor.visitHTMLOpenTagNode(this);
1076
+ }
1066
1077
  childNodes() {
1067
1078
  return [
1068
1079
  ...this.children,
1069
- ].filter(node => node !== null && node !== undefined);
1080
+ ];
1081
+ }
1082
+ compactChildNodes() {
1083
+ return this.childNodes().filter(node => node !== null && node !== undefined);
1070
1084
  }
1071
1085
  recursiveErrors() {
1072
1086
  return [
@@ -1118,8 +1132,14 @@ class HTMLCloseTagNode extends Node {
1118
1132
  this.tag_name = props.tag_name;
1119
1133
  this.tag_closing = props.tag_closing;
1120
1134
  }
1135
+ accept(visitor) {
1136
+ visitor.visitHTMLCloseTagNode(this);
1137
+ }
1121
1138
  childNodes() {
1122
- return [].filter(node => node !== null && node !== undefined);
1139
+ return [];
1140
+ }
1141
+ compactChildNodes() {
1142
+ return this.childNodes().filter(node => node !== null && node !== undefined);
1123
1143
  }
1124
1144
  recursiveErrors() {
1125
1145
  return [
@@ -1172,10 +1192,16 @@ class HTMLSelfCloseTagNode extends Node {
1172
1192
  this.tag_closing = props.tag_closing;
1173
1193
  this.is_void = props.is_void;
1174
1194
  }
1195
+ accept(visitor) {
1196
+ visitor.visitHTMLSelfCloseTagNode(this);
1197
+ }
1175
1198
  childNodes() {
1176
1199
  return [
1177
1200
  ...this.attributes,
1178
- ].filter(node => node !== null && node !== undefined);
1201
+ ];
1202
+ }
1203
+ compactChildNodes() {
1204
+ return this.childNodes().filter(node => node !== null && node !== undefined);
1179
1205
  }
1180
1206
  recursiveErrors() {
1181
1207
  return [
@@ -1233,12 +1259,18 @@ class HTMLElementNode extends Node {
1233
1259
  this.close_tag = props.close_tag;
1234
1260
  this.is_void = props.is_void;
1235
1261
  }
1262
+ accept(visitor) {
1263
+ visitor.visitHTMLElementNode(this);
1264
+ }
1236
1265
  childNodes() {
1237
1266
  return [
1238
1267
  this.open_tag,
1239
1268
  ...this.body,
1240
1269
  this.close_tag,
1241
- ].filter(node => node !== null && node !== undefined);
1270
+ ];
1271
+ }
1272
+ compactChildNodes() {
1273
+ return this.childNodes().filter(node => node !== null && node !== undefined);
1242
1274
  }
1243
1275
  recursiveErrors() {
1244
1276
  return [
@@ -1295,10 +1327,16 @@ class HTMLAttributeValueNode extends Node {
1295
1327
  this.close_quote = props.close_quote;
1296
1328
  this.quoted = props.quoted;
1297
1329
  }
1330
+ accept(visitor) {
1331
+ visitor.visitHTMLAttributeValueNode(this);
1332
+ }
1298
1333
  childNodes() {
1299
1334
  return [
1300
1335
  ...this.children,
1301
- ].filter(node => node !== null && node !== undefined);
1336
+ ];
1337
+ }
1338
+ compactChildNodes() {
1339
+ return this.childNodes().filter(node => node !== null && node !== undefined);
1302
1340
  }
1303
1341
  recursiveErrors() {
1304
1342
  return [
@@ -1342,8 +1380,14 @@ class HTMLAttributeNameNode extends Node {
1342
1380
  super(props.type, props.location, props.errors);
1343
1381
  this.name = props.name;
1344
1382
  }
1383
+ accept(visitor) {
1384
+ visitor.visitHTMLAttributeNameNode(this);
1385
+ }
1345
1386
  childNodes() {
1346
- return [].filter(node => node !== null && node !== undefined);
1387
+ return [];
1388
+ }
1389
+ compactChildNodes() {
1390
+ return this.childNodes().filter(node => node !== null && node !== undefined);
1347
1391
  }
1348
1392
  recursiveErrors() {
1349
1393
  return [
@@ -1386,11 +1430,17 @@ class HTMLAttributeNode extends Node {
1386
1430
  this.equals = props.equals;
1387
1431
  this.value = props.value;
1388
1432
  }
1433
+ accept(visitor) {
1434
+ visitor.visitHTMLAttributeNode(this);
1435
+ }
1389
1436
  childNodes() {
1390
1437
  return [
1391
1438
  this.name,
1392
1439
  this.value,
1393
- ].filter(node => node !== null && node !== undefined);
1440
+ ];
1441
+ }
1442
+ compactChildNodes() {
1443
+ return this.childNodes().filter(node => node !== null && node !== undefined);
1394
1444
  }
1395
1445
  recursiveErrors() {
1396
1446
  return [
@@ -1433,8 +1483,14 @@ class HTMLTextNode extends Node {
1433
1483
  super(props.type, props.location, props.errors);
1434
1484
  this.content = convertToUTF8(props.content);
1435
1485
  }
1486
+ accept(visitor) {
1487
+ visitor.visitHTMLTextNode(this);
1488
+ }
1436
1489
  childNodes() {
1437
- return [].filter(node => node !== null && node !== undefined);
1490
+ return [];
1491
+ }
1492
+ compactChildNodes() {
1493
+ return this.childNodes().filter(node => node !== null && node !== undefined);
1438
1494
  }
1439
1495
  recursiveErrors() {
1440
1496
  return [
@@ -1477,10 +1533,16 @@ class HTMLCommentNode extends Node {
1477
1533
  this.children = props.children;
1478
1534
  this.comment_end = props.comment_end;
1479
1535
  }
1536
+ accept(visitor) {
1537
+ visitor.visitHTMLCommentNode(this);
1538
+ }
1480
1539
  childNodes() {
1481
1540
  return [
1482
1541
  ...this.children,
1483
- ].filter(node => node !== null && node !== undefined);
1542
+ ];
1543
+ }
1544
+ compactChildNodes() {
1545
+ return this.childNodes().filter(node => node !== null && node !== undefined);
1484
1546
  }
1485
1547
  recursiveErrors() {
1486
1548
  return [
@@ -1528,10 +1590,16 @@ class HTMLDoctypeNode extends Node {
1528
1590
  this.children = props.children;
1529
1591
  this.tag_closing = props.tag_closing;
1530
1592
  }
1593
+ accept(visitor) {
1594
+ visitor.visitHTMLDoctypeNode(this);
1595
+ }
1531
1596
  childNodes() {
1532
1597
  return [
1533
1598
  ...this.children,
1534
- ].filter(node => node !== null && node !== undefined);
1599
+ ];
1600
+ }
1601
+ compactChildNodes() {
1602
+ return this.childNodes().filter(node => node !== null && node !== undefined);
1535
1603
  }
1536
1604
  recursiveErrors() {
1537
1605
  return [
@@ -1573,8 +1641,14 @@ class WhitespaceNode extends Node {
1573
1641
  super(props.type, props.location, props.errors);
1574
1642
  this.value = props.value;
1575
1643
  }
1644
+ accept(visitor) {
1645
+ visitor.visitWhitespaceNode(this);
1646
+ }
1576
1647
  childNodes() {
1577
- return [].filter(node => node !== null && node !== undefined);
1648
+ return [];
1649
+ }
1650
+ compactChildNodes() {
1651
+ return this.childNodes().filter(node => node !== null && node !== undefined);
1578
1652
  }
1579
1653
  recursiveErrors() {
1580
1654
  return [
@@ -1626,8 +1700,14 @@ class ERBContentNode extends Node {
1626
1700
  this.parsed = props.parsed;
1627
1701
  this.valid = props.valid;
1628
1702
  }
1703
+ accept(visitor) {
1704
+ visitor.visitERBContentNode(this);
1705
+ }
1629
1706
  childNodes() {
1630
- return [].filter(node => node !== null && node !== undefined);
1707
+ return [];
1708
+ }
1709
+ compactChildNodes() {
1710
+ return this.childNodes().filter(node => node !== null && node !== undefined);
1631
1711
  }
1632
1712
  recursiveErrors() {
1633
1713
  return [
@@ -1680,8 +1760,14 @@ class ERBEndNode extends Node {
1680
1760
  this.content = props.content;
1681
1761
  this.tag_closing = props.tag_closing;
1682
1762
  }
1763
+ accept(visitor) {
1764
+ visitor.visitERBEndNode(this);
1765
+ }
1683
1766
  childNodes() {
1684
- return [].filter(node => node !== null && node !== undefined);
1767
+ return [];
1768
+ }
1769
+ compactChildNodes() {
1770
+ return this.childNodes().filter(node => node !== null && node !== undefined);
1685
1771
  }
1686
1772
  recursiveErrors() {
1687
1773
  return [
@@ -1731,10 +1817,16 @@ class ERBElseNode extends Node {
1731
1817
  this.tag_closing = props.tag_closing;
1732
1818
  this.statements = props.statements;
1733
1819
  }
1820
+ accept(visitor) {
1821
+ visitor.visitERBElseNode(this);
1822
+ }
1734
1823
  childNodes() {
1735
1824
  return [
1736
1825
  ...this.statements,
1737
- ].filter(node => node !== null && node !== undefined);
1826
+ ];
1827
+ }
1828
+ compactChildNodes() {
1829
+ return this.childNodes().filter(node => node !== null && node !== undefined);
1738
1830
  }
1739
1831
  recursiveErrors() {
1740
1832
  return [
@@ -1793,12 +1885,18 @@ class ERBIfNode extends Node {
1793
1885
  this.subsequent = props.subsequent;
1794
1886
  this.end_node = props.end_node;
1795
1887
  }
1888
+ accept(visitor) {
1889
+ visitor.visitERBIfNode(this);
1890
+ }
1796
1891
  childNodes() {
1797
1892
  return [
1798
1893
  ...this.statements,
1799
1894
  this.subsequent,
1800
1895
  this.end_node,
1801
- ].filter(node => node !== null && node !== undefined);
1896
+ ];
1897
+ }
1898
+ compactChildNodes() {
1899
+ return this.childNodes().filter(node => node !== null && node !== undefined);
1802
1900
  }
1803
1901
  recursiveErrors() {
1804
1902
  return [
@@ -1860,11 +1958,17 @@ class ERBBlockNode extends Node {
1860
1958
  this.body = props.body;
1861
1959
  this.end_node = props.end_node;
1862
1960
  }
1961
+ accept(visitor) {
1962
+ visitor.visitERBBlockNode(this);
1963
+ }
1863
1964
  childNodes() {
1864
1965
  return [
1865
1966
  ...this.body,
1866
1967
  this.end_node,
1867
- ].filter(node => node !== null && node !== undefined);
1968
+ ];
1969
+ }
1970
+ compactChildNodes() {
1971
+ return this.childNodes().filter(node => node !== null && node !== undefined);
1868
1972
  }
1869
1973
  recursiveErrors() {
1870
1974
  return [
@@ -1920,10 +2024,16 @@ class ERBWhenNode extends Node {
1920
2024
  this.tag_closing = props.tag_closing;
1921
2025
  this.statements = props.statements;
1922
2026
  }
2027
+ accept(visitor) {
2028
+ visitor.visitERBWhenNode(this);
2029
+ }
1923
2030
  childNodes() {
1924
2031
  return [
1925
2032
  ...this.statements,
1926
- ].filter(node => node !== null && node !== undefined);
2033
+ ];
2034
+ }
2035
+ compactChildNodes() {
2036
+ return this.childNodes().filter(node => node !== null && node !== undefined);
1927
2037
  }
1928
2038
  recursiveErrors() {
1929
2039
  return [
@@ -1985,13 +2095,19 @@ class ERBCaseNode extends Node {
1985
2095
  this.else_clause = props.else_clause;
1986
2096
  this.end_node = props.end_node;
1987
2097
  }
2098
+ accept(visitor) {
2099
+ visitor.visitERBCaseNode(this);
2100
+ }
1988
2101
  childNodes() {
1989
2102
  return [
1990
2103
  ...this.children,
1991
2104
  ...this.conditions,
1992
2105
  this.else_clause,
1993
2106
  this.end_node,
1994
- ].filter(node => node !== null && node !== undefined);
2107
+ ];
2108
+ }
2109
+ compactChildNodes() {
2110
+ return this.childNodes().filter(node => node !== null && node !== undefined);
1995
2111
  }
1996
2112
  recursiveErrors() {
1997
2113
  return [
@@ -2030,6 +2146,89 @@ class ERBCaseNode extends Node {
2030
2146
  return output;
2031
2147
  }
2032
2148
  }
2149
+ class ERBCaseMatchNode extends Node {
2150
+ tag_opening;
2151
+ content;
2152
+ tag_closing;
2153
+ children;
2154
+ conditions;
2155
+ else_clause;
2156
+ end_node;
2157
+ static from(data) {
2158
+ return new ERBCaseMatchNode({
2159
+ type: data.type,
2160
+ location: Location.from(data.location),
2161
+ errors: (data.errors || []).map(error => HerbError.from(error)),
2162
+ tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
2163
+ content: data.content ? Token.from(data.content) : null,
2164
+ tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2165
+ children: (data.children || []).map(node => fromSerializedNode(node)),
2166
+ conditions: (data.conditions || []).map(node => fromSerializedNode(node)),
2167
+ else_clause: data.else_clause ? fromSerializedNode(data.else_clause) : null,
2168
+ end_node: data.end_node ? fromSerializedNode(data.end_node) : null,
2169
+ });
2170
+ }
2171
+ constructor(props) {
2172
+ super(props.type, props.location, props.errors);
2173
+ this.tag_opening = props.tag_opening;
2174
+ this.content = props.content;
2175
+ this.tag_closing = props.tag_closing;
2176
+ this.children = props.children;
2177
+ this.conditions = props.conditions;
2178
+ this.else_clause = props.else_clause;
2179
+ this.end_node = props.end_node;
2180
+ }
2181
+ accept(visitor) {
2182
+ visitor.visitERBCaseMatchNode(this);
2183
+ }
2184
+ childNodes() {
2185
+ return [
2186
+ ...this.children,
2187
+ ...this.conditions,
2188
+ this.else_clause,
2189
+ this.end_node,
2190
+ ];
2191
+ }
2192
+ compactChildNodes() {
2193
+ return this.childNodes().filter(node => node !== null && node !== undefined);
2194
+ }
2195
+ recursiveErrors() {
2196
+ return [
2197
+ ...this.errors,
2198
+ ...this.children.map(node => node.recursiveErrors()),
2199
+ ...this.conditions.map(node => node.recursiveErrors()),
2200
+ this.else_clause ? this.else_clause.recursiveErrors() : [],
2201
+ this.end_node ? this.end_node.recursiveErrors() : [],
2202
+ ].flat();
2203
+ }
2204
+ toJSON() {
2205
+ return {
2206
+ ...super.toJSON(),
2207
+ type: "AST_ERB_CASE_MATCH_NODE",
2208
+ tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
2209
+ content: this.content ? this.content.toJSON() : null,
2210
+ tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
2211
+ children: this.children.map(node => node.toJSON()),
2212
+ conditions: this.conditions.map(node => node.toJSON()),
2213
+ else_clause: this.else_clause ? this.else_clause.toJSON() : null,
2214
+ end_node: this.end_node ? this.end_node.toJSON() : null,
2215
+ };
2216
+ }
2217
+ treeInspect() {
2218
+ let output = "";
2219
+ output += `@ ERBCaseMatchNode ${this.location.treeInspectWithLabel()}\n`;
2220
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
2221
+ output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
2222
+ output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
2223
+ output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
2224
+ output += `├── children: ${this.inspectArray(this.children, "│ ")}`;
2225
+ output += `├── conditions: ${this.inspectArray(this.conditions, "│ ")}`;
2226
+ output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
2227
+ output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
2228
+ // output += "\n";
2229
+ return output;
2230
+ }
2231
+ }
2033
2232
  class ERBWhileNode extends Node {
2034
2233
  tag_opening;
2035
2234
  content;
@@ -2056,11 +2255,17 @@ class ERBWhileNode extends Node {
2056
2255
  this.statements = props.statements;
2057
2256
  this.end_node = props.end_node;
2058
2257
  }
2258
+ accept(visitor) {
2259
+ visitor.visitERBWhileNode(this);
2260
+ }
2059
2261
  childNodes() {
2060
2262
  return [
2061
2263
  ...this.statements,
2062
2264
  this.end_node,
2063
- ].filter(node => node !== null && node !== undefined);
2265
+ ];
2266
+ }
2267
+ compactChildNodes() {
2268
+ return this.childNodes().filter(node => node !== null && node !== undefined);
2064
2269
  }
2065
2270
  recursiveErrors() {
2066
2271
  return [
@@ -2119,11 +2324,17 @@ class ERBUntilNode extends Node {
2119
2324
  this.statements = props.statements;
2120
2325
  this.end_node = props.end_node;
2121
2326
  }
2327
+ accept(visitor) {
2328
+ visitor.visitERBUntilNode(this);
2329
+ }
2122
2330
  childNodes() {
2123
2331
  return [
2124
2332
  ...this.statements,
2125
2333
  this.end_node,
2126
- ].filter(node => node !== null && node !== undefined);
2334
+ ];
2335
+ }
2336
+ compactChildNodes() {
2337
+ return this.childNodes().filter(node => node !== null && node !== undefined);
2127
2338
  }
2128
2339
  recursiveErrors() {
2129
2340
  return [
@@ -2182,11 +2393,17 @@ class ERBForNode extends Node {
2182
2393
  this.statements = props.statements;
2183
2394
  this.end_node = props.end_node;
2184
2395
  }
2396
+ accept(visitor) {
2397
+ visitor.visitERBForNode(this);
2398
+ }
2185
2399
  childNodes() {
2186
2400
  return [
2187
2401
  ...this.statements,
2188
2402
  this.end_node,
2189
- ].filter(node => node !== null && node !== undefined);
2403
+ ];
2404
+ }
2405
+ compactChildNodes() {
2406
+ return this.childNodes().filter(node => node !== null && node !== undefined);
2190
2407
  }
2191
2408
  recursiveErrors() {
2192
2409
  return [
@@ -2245,11 +2462,17 @@ class ERBRescueNode extends Node {
2245
2462
  this.statements = props.statements;
2246
2463
  this.subsequent = props.subsequent;
2247
2464
  }
2465
+ accept(visitor) {
2466
+ visitor.visitERBRescueNode(this);
2467
+ }
2248
2468
  childNodes() {
2249
2469
  return [
2250
2470
  ...this.statements,
2251
2471
  this.subsequent,
2252
- ].filter(node => node !== null && node !== undefined);
2472
+ ];
2473
+ }
2474
+ compactChildNodes() {
2475
+ return this.childNodes().filter(node => node !== null && node !== undefined);
2253
2476
  }
2254
2477
  recursiveErrors() {
2255
2478
  return [
@@ -2305,10 +2528,16 @@ class ERBEnsureNode extends Node {
2305
2528
  this.tag_closing = props.tag_closing;
2306
2529
  this.statements = props.statements;
2307
2530
  }
2531
+ accept(visitor) {
2532
+ visitor.visitERBEnsureNode(this);
2533
+ }
2308
2534
  childNodes() {
2309
2535
  return [
2310
2536
  ...this.statements,
2311
- ].filter(node => node !== null && node !== undefined);
2537
+ ];
2538
+ }
2539
+ compactChildNodes() {
2540
+ return this.childNodes().filter(node => node !== null && node !== undefined);
2312
2541
  }
2313
2542
  recursiveErrors() {
2314
2543
  return [
@@ -2373,6 +2602,9 @@ class ERBBeginNode extends Node {
2373
2602
  this.ensure_clause = props.ensure_clause;
2374
2603
  this.end_node = props.end_node;
2375
2604
  }
2605
+ accept(visitor) {
2606
+ visitor.visitERBBeginNode(this);
2607
+ }
2376
2608
  childNodes() {
2377
2609
  return [
2378
2610
  ...this.statements,
@@ -2380,7 +2612,10 @@ class ERBBeginNode extends Node {
2380
2612
  this.else_clause,
2381
2613
  this.ensure_clause,
2382
2614
  this.end_node,
2383
- ].filter(node => node !== null && node !== undefined);
2615
+ ];
2616
+ }
2617
+ compactChildNodes() {
2618
+ return this.childNodes().filter(node => node !== null && node !== undefined);
2384
2619
  }
2385
2620
  recursiveErrors() {
2386
2621
  return [
@@ -2451,12 +2686,18 @@ class ERBUnlessNode extends Node {
2451
2686
  this.else_clause = props.else_clause;
2452
2687
  this.end_node = props.end_node;
2453
2688
  }
2689
+ accept(visitor) {
2690
+ visitor.visitERBUnlessNode(this);
2691
+ }
2454
2692
  childNodes() {
2455
2693
  return [
2456
2694
  ...this.statements,
2457
2695
  this.else_clause,
2458
2696
  this.end_node,
2459
- ].filter(node => node !== null && node !== undefined);
2697
+ ];
2698
+ }
2699
+ compactChildNodes() {
2700
+ return this.childNodes().filter(node => node !== null && node !== undefined);
2460
2701
  }
2461
2702
  recursiveErrors() {
2462
2703
  return [
@@ -2492,6 +2733,122 @@ class ERBUnlessNode extends Node {
2492
2733
  return output;
2493
2734
  }
2494
2735
  }
2736
+ class ERBYieldNode extends Node {
2737
+ tag_opening;
2738
+ content;
2739
+ tag_closing;
2740
+ static from(data) {
2741
+ return new ERBYieldNode({
2742
+ type: data.type,
2743
+ location: Location.from(data.location),
2744
+ errors: (data.errors || []).map(error => HerbError.from(error)),
2745
+ tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
2746
+ content: data.content ? Token.from(data.content) : null,
2747
+ tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2748
+ });
2749
+ }
2750
+ constructor(props) {
2751
+ super(props.type, props.location, props.errors);
2752
+ this.tag_opening = props.tag_opening;
2753
+ this.content = props.content;
2754
+ this.tag_closing = props.tag_closing;
2755
+ }
2756
+ accept(visitor) {
2757
+ visitor.visitERBYieldNode(this);
2758
+ }
2759
+ childNodes() {
2760
+ return [];
2761
+ }
2762
+ compactChildNodes() {
2763
+ return this.childNodes().filter(node => node !== null && node !== undefined);
2764
+ }
2765
+ recursiveErrors() {
2766
+ return [
2767
+ ...this.errors,
2768
+ ].flat();
2769
+ }
2770
+ toJSON() {
2771
+ return {
2772
+ ...super.toJSON(),
2773
+ type: "AST_ERB_YIELD_NODE",
2774
+ tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
2775
+ content: this.content ? this.content.toJSON() : null,
2776
+ tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
2777
+ };
2778
+ }
2779
+ treeInspect() {
2780
+ let output = "";
2781
+ output += `@ ERBYieldNode ${this.location.treeInspectWithLabel()}\n`;
2782
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
2783
+ output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
2784
+ output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
2785
+ output += `└── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
2786
+ // output += "\n";
2787
+ return output;
2788
+ }
2789
+ }
2790
+ class ERBInNode extends Node {
2791
+ tag_opening;
2792
+ content;
2793
+ tag_closing;
2794
+ statements;
2795
+ static from(data) {
2796
+ return new ERBInNode({
2797
+ type: data.type,
2798
+ location: Location.from(data.location),
2799
+ errors: (data.errors || []).map(error => HerbError.from(error)),
2800
+ tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
2801
+ content: data.content ? Token.from(data.content) : null,
2802
+ tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2803
+ statements: (data.statements || []).map(node => fromSerializedNode(node)),
2804
+ });
2805
+ }
2806
+ constructor(props) {
2807
+ super(props.type, props.location, props.errors);
2808
+ this.tag_opening = props.tag_opening;
2809
+ this.content = props.content;
2810
+ this.tag_closing = props.tag_closing;
2811
+ this.statements = props.statements;
2812
+ }
2813
+ accept(visitor) {
2814
+ visitor.visitERBInNode(this);
2815
+ }
2816
+ childNodes() {
2817
+ return [
2818
+ ...this.statements,
2819
+ ];
2820
+ }
2821
+ compactChildNodes() {
2822
+ return this.childNodes().filter(node => node !== null && node !== undefined);
2823
+ }
2824
+ recursiveErrors() {
2825
+ return [
2826
+ ...this.errors,
2827
+ ...this.statements.map(node => node.recursiveErrors()),
2828
+ ].flat();
2829
+ }
2830
+ toJSON() {
2831
+ return {
2832
+ ...super.toJSON(),
2833
+ type: "AST_ERB_IN_NODE",
2834
+ tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
2835
+ content: this.content ? this.content.toJSON() : null,
2836
+ tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
2837
+ statements: this.statements.map(node => node.toJSON()),
2838
+ };
2839
+ }
2840
+ treeInspect() {
2841
+ let output = "";
2842
+ output += `@ ERBInNode ${this.location.treeInspectWithLabel()}\n`;
2843
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
2844
+ output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
2845
+ output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
2846
+ output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
2847
+ output += `└── statements: ${this.inspectArray(this.statements, " ")}`;
2848
+ // output += "\n";
2849
+ return output;
2850
+ }
2851
+ }
2495
2852
 
2496
2853
  class HerbWarning {
2497
2854
  message;
@@ -2689,23 +3046,116 @@ class HerbBackend {
2689
3046
  }
2690
3047
  }
2691
3048
 
2692
- /**
2693
- * Represents a visitor that can traverse nodes.
2694
- */
3049
+ // NOTE: This file is generated by the templates/template.rb script and should not
3050
+ // be modified manually. See /Users/marcoroth/Development/herb-release/templates/javascript/packages/core/src/visitor.ts.erb
2695
3051
  class Visitor {
2696
- /**
2697
- * Visits a node and performs an action.
2698
- * @param node - The node to visit.
2699
- */
2700
3052
  visit(node) {
2701
- console.log("Node", node); // TODO: implement
3053
+ if (!node)
3054
+ return;
3055
+ node.accept(this);
3056
+ }
3057
+ visitAll(nodes) {
3058
+ nodes.forEach(node => node?.accept(this));
3059
+ }
3060
+ visitChildNodes(node) {
3061
+ node.compactChildNodes().forEach(node => node.accept(this));
3062
+ }
3063
+ visitDocumentNode(node) {
3064
+ this.visitChildNodes(node);
3065
+ }
3066
+ visitLiteralNode(node) {
3067
+ this.visitChildNodes(node);
3068
+ }
3069
+ visitHTMLOpenTagNode(node) {
3070
+ this.visitChildNodes(node);
3071
+ }
3072
+ visitHTMLCloseTagNode(node) {
3073
+ this.visitChildNodes(node);
3074
+ }
3075
+ visitHTMLSelfCloseTagNode(node) {
3076
+ this.visitChildNodes(node);
3077
+ }
3078
+ visitHTMLElementNode(node) {
3079
+ this.visitChildNodes(node);
3080
+ }
3081
+ visitHTMLAttributeValueNode(node) {
3082
+ this.visitChildNodes(node);
3083
+ }
3084
+ visitHTMLAttributeNameNode(node) {
3085
+ this.visitChildNodes(node);
3086
+ }
3087
+ visitHTMLAttributeNode(node) {
3088
+ this.visitChildNodes(node);
3089
+ }
3090
+ visitHTMLTextNode(node) {
3091
+ this.visitChildNodes(node);
3092
+ }
3093
+ visitHTMLCommentNode(node) {
3094
+ this.visitChildNodes(node);
3095
+ }
3096
+ visitHTMLDoctypeNode(node) {
3097
+ this.visitChildNodes(node);
3098
+ }
3099
+ visitWhitespaceNode(node) {
3100
+ this.visitChildNodes(node);
3101
+ }
3102
+ visitERBContentNode(node) {
3103
+ this.visitChildNodes(node);
3104
+ }
3105
+ visitERBEndNode(node) {
3106
+ this.visitChildNodes(node);
3107
+ }
3108
+ visitERBElseNode(node) {
3109
+ this.visitChildNodes(node);
3110
+ }
3111
+ visitERBIfNode(node) {
3112
+ this.visitChildNodes(node);
3113
+ }
3114
+ visitERBBlockNode(node) {
3115
+ this.visitChildNodes(node);
3116
+ }
3117
+ visitERBWhenNode(node) {
3118
+ this.visitChildNodes(node);
3119
+ }
3120
+ visitERBCaseNode(node) {
3121
+ this.visitChildNodes(node);
3122
+ }
3123
+ visitERBCaseMatchNode(node) {
3124
+ this.visitChildNodes(node);
3125
+ }
3126
+ visitERBWhileNode(node) {
3127
+ this.visitChildNodes(node);
3128
+ }
3129
+ visitERBUntilNode(node) {
3130
+ this.visitChildNodes(node);
3131
+ }
3132
+ visitERBForNode(node) {
3133
+ this.visitChildNodes(node);
3134
+ }
3135
+ visitERBRescueNode(node) {
3136
+ this.visitChildNodes(node);
3137
+ }
3138
+ visitERBEnsureNode(node) {
3139
+ this.visitChildNodes(node);
3140
+ }
3141
+ visitERBBeginNode(node) {
3142
+ this.visitChildNodes(node);
3143
+ }
3144
+ visitERBUnlessNode(node) {
3145
+ this.visitChildNodes(node);
3146
+ }
3147
+ visitERBYieldNode(node) {
3148
+ this.visitChildNodes(node);
3149
+ }
3150
+ visitERBInNode(node) {
3151
+ this.visitChildNodes(node);
2702
3152
  }
2703
3153
  }
2704
3154
 
2705
- exports.ASTNode = ASTNode;
2706
3155
  exports.DocumentNode = DocumentNode;
2707
3156
  exports.ERBBeginNode = ERBBeginNode;
2708
3157
  exports.ERBBlockNode = ERBBlockNode;
3158
+ exports.ERBCaseMatchNode = ERBCaseMatchNode;
2709
3159
  exports.ERBCaseNode = ERBCaseNode;
2710
3160
  exports.ERBContentNode = ERBContentNode;
2711
3161
  exports.ERBElseNode = ERBElseNode;
@@ -2713,11 +3163,13 @@ exports.ERBEndNode = ERBEndNode;
2713
3163
  exports.ERBEnsureNode = ERBEnsureNode;
2714
3164
  exports.ERBForNode = ERBForNode;
2715
3165
  exports.ERBIfNode = ERBIfNode;
3166
+ exports.ERBInNode = ERBInNode;
2716
3167
  exports.ERBRescueNode = ERBRescueNode;
2717
3168
  exports.ERBUnlessNode = ERBUnlessNode;
2718
3169
  exports.ERBUntilNode = ERBUntilNode;
2719
3170
  exports.ERBWhenNode = ERBWhenNode;
2720
3171
  exports.ERBWhileNode = ERBWhileNode;
3172
+ exports.ERBYieldNode = ERBYieldNode;
2721
3173
  exports.HTMLAttributeNameNode = HTMLAttributeNameNode;
2722
3174
  exports.HTMLAttributeNode = HTMLAttributeNode;
2723
3175
  exports.HTMLAttributeValueNode = HTMLAttributeValueNode;
@@ -2734,6 +3186,7 @@ exports.LiteralNode = LiteralNode;
2734
3186
  exports.Location = Location;
2735
3187
  exports.MissingClosingTagError = MissingClosingTagError;
2736
3188
  exports.MissingOpeningTagError = MissingOpeningTagError;
3189
+ exports.Node = Node;
2737
3190
  exports.ParseResult = ParseResult;
2738
3191
  exports.Position = Position;
2739
3192
  exports.QuotesMismatchError = QuotesMismatchError;