@herb-tools/rewriter 0.9.2 → 0.9.4

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.
@@ -170,6 +170,9 @@ class Token {
170
170
  static from(token) {
171
171
  return new Token(token.value, Range.from(token.range), Location.from(token.location), token.type);
172
172
  }
173
+ static synthetic(value, type = "SYNTETHIC") {
174
+ return new Token(value, Range.zero, Location.zero, type);
175
+ }
173
176
  constructor(value, range, location, type) {
174
177
  this.value = value;
175
178
  this.range = range;
@@ -204,7 +207,7 @@ class Token {
204
207
  }
205
208
 
206
209
  // NOTE: This file is generated by the templates/template.rb script and should not
207
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.2/templates/javascript/packages/core/src/errors.ts.erb
210
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.4/templates/javascript/packages/core/src/errors.ts.erb
208
211
  class HerbError {
209
212
  type;
210
213
  message;
@@ -1478,6 +1481,284 @@ class RenderLayoutWithoutBlockError extends HerbError {
1478
1481
  return output;
1479
1482
  }
1480
1483
  }
1484
+ class StrictLocalsPositionalArgumentError extends HerbError {
1485
+ name;
1486
+ static from(data) {
1487
+ return new StrictLocalsPositionalArgumentError({
1488
+ type: data.type,
1489
+ message: data.message,
1490
+ location: Location.from(data.location),
1491
+ name: data.name,
1492
+ });
1493
+ }
1494
+ constructor(props) {
1495
+ super(props.type, props.message, props.location);
1496
+ this.name = props.name;
1497
+ }
1498
+ toJSON() {
1499
+ return {
1500
+ ...super.toJSON(),
1501
+ type: "STRICT_LOCALS_POSITIONAL_ARGUMENT_ERROR",
1502
+ name: this.name,
1503
+ };
1504
+ }
1505
+ toMonacoDiagnostic() {
1506
+ return {
1507
+ line: this.location.start.line,
1508
+ column: this.location.start.column,
1509
+ endLine: this.location.end.line,
1510
+ endColumn: this.location.end.column,
1511
+ message: this.message,
1512
+ severity: 'error'
1513
+ };
1514
+ }
1515
+ treeInspect() {
1516
+ let output = "";
1517
+ output += `@ StrictLocalsPositionalArgumentError ${this.location.treeInspectWithLabel()}\n`;
1518
+ output += `├── message: "${this.message}"\n`;
1519
+ output += `└── name: ${JSON.stringify(this.name)}\n`;
1520
+ return output;
1521
+ }
1522
+ }
1523
+ class StrictLocalsBlockArgumentError extends HerbError {
1524
+ name;
1525
+ static from(data) {
1526
+ return new StrictLocalsBlockArgumentError({
1527
+ type: data.type,
1528
+ message: data.message,
1529
+ location: Location.from(data.location),
1530
+ name: data.name,
1531
+ });
1532
+ }
1533
+ constructor(props) {
1534
+ super(props.type, props.message, props.location);
1535
+ this.name = props.name;
1536
+ }
1537
+ toJSON() {
1538
+ return {
1539
+ ...super.toJSON(),
1540
+ type: "STRICT_LOCALS_BLOCK_ARGUMENT_ERROR",
1541
+ name: this.name,
1542
+ };
1543
+ }
1544
+ toMonacoDiagnostic() {
1545
+ return {
1546
+ line: this.location.start.line,
1547
+ column: this.location.start.column,
1548
+ endLine: this.location.end.line,
1549
+ endColumn: this.location.end.column,
1550
+ message: this.message,
1551
+ severity: 'error'
1552
+ };
1553
+ }
1554
+ treeInspect() {
1555
+ let output = "";
1556
+ output += `@ StrictLocalsBlockArgumentError ${this.location.treeInspectWithLabel()}\n`;
1557
+ output += `├── message: "${this.message}"\n`;
1558
+ output += `└── name: ${JSON.stringify(this.name)}\n`;
1559
+ return output;
1560
+ }
1561
+ }
1562
+ class StrictLocalsSplatArgumentError extends HerbError {
1563
+ name;
1564
+ static from(data) {
1565
+ return new StrictLocalsSplatArgumentError({
1566
+ type: data.type,
1567
+ message: data.message,
1568
+ location: Location.from(data.location),
1569
+ name: data.name,
1570
+ });
1571
+ }
1572
+ constructor(props) {
1573
+ super(props.type, props.message, props.location);
1574
+ this.name = props.name;
1575
+ }
1576
+ toJSON() {
1577
+ return {
1578
+ ...super.toJSON(),
1579
+ type: "STRICT_LOCALS_SPLAT_ARGUMENT_ERROR",
1580
+ name: this.name,
1581
+ };
1582
+ }
1583
+ toMonacoDiagnostic() {
1584
+ return {
1585
+ line: this.location.start.line,
1586
+ column: this.location.start.column,
1587
+ endLine: this.location.end.line,
1588
+ endColumn: this.location.end.column,
1589
+ message: this.message,
1590
+ severity: 'error'
1591
+ };
1592
+ }
1593
+ treeInspect() {
1594
+ let output = "";
1595
+ output += `@ StrictLocalsSplatArgumentError ${this.location.treeInspectWithLabel()}\n`;
1596
+ output += `├── message: "${this.message}"\n`;
1597
+ output += `└── name: ${JSON.stringify(this.name)}\n`;
1598
+ return output;
1599
+ }
1600
+ }
1601
+ class StrictLocalsMissingParenthesisError extends HerbError {
1602
+ rest;
1603
+ static from(data) {
1604
+ return new StrictLocalsMissingParenthesisError({
1605
+ type: data.type,
1606
+ message: data.message,
1607
+ location: Location.from(data.location),
1608
+ rest: data.rest,
1609
+ });
1610
+ }
1611
+ constructor(props) {
1612
+ super(props.type, props.message, props.location);
1613
+ this.rest = props.rest;
1614
+ }
1615
+ toJSON() {
1616
+ return {
1617
+ ...super.toJSON(),
1618
+ type: "STRICT_LOCALS_MISSING_PARENTHESIS_ERROR",
1619
+ rest: this.rest,
1620
+ };
1621
+ }
1622
+ toMonacoDiagnostic() {
1623
+ return {
1624
+ line: this.location.start.line,
1625
+ column: this.location.start.column,
1626
+ endLine: this.location.end.line,
1627
+ endColumn: this.location.end.column,
1628
+ message: this.message,
1629
+ severity: 'error'
1630
+ };
1631
+ }
1632
+ treeInspect() {
1633
+ let output = "";
1634
+ output += `@ StrictLocalsMissingParenthesisError ${this.location.treeInspectWithLabel()}\n`;
1635
+ output += `├── message: "${this.message}"\n`;
1636
+ output += `└── rest: ${JSON.stringify(this.rest)}\n`;
1637
+ return output;
1638
+ }
1639
+ }
1640
+ class StrictLocalsDuplicateDeclarationError extends HerbError {
1641
+ static from(data) {
1642
+ return new StrictLocalsDuplicateDeclarationError({
1643
+ type: data.type,
1644
+ message: data.message,
1645
+ location: Location.from(data.location),
1646
+ });
1647
+ }
1648
+ constructor(props) {
1649
+ super(props.type, props.message, props.location);
1650
+ }
1651
+ toJSON() {
1652
+ return {
1653
+ ...super.toJSON(),
1654
+ type: "STRICT_LOCALS_DUPLICATE_DECLARATION_ERROR",
1655
+ };
1656
+ }
1657
+ toMonacoDiagnostic() {
1658
+ return {
1659
+ line: this.location.start.line,
1660
+ column: this.location.start.column,
1661
+ endLine: this.location.end.line,
1662
+ endColumn: this.location.end.column,
1663
+ message: this.message,
1664
+ severity: 'error'
1665
+ };
1666
+ }
1667
+ treeInspect() {
1668
+ let output = "";
1669
+ output += `@ StrictLocalsDuplicateDeclarationError ${this.location.treeInspectWithLabel()}\n`;
1670
+ output += `└── message: "${this.message}"\n`;
1671
+ return output;
1672
+ }
1673
+ }
1674
+ class VoidElementContentError extends HerbError {
1675
+ tag_name;
1676
+ helper_name;
1677
+ content_type;
1678
+ static from(data) {
1679
+ return new VoidElementContentError({
1680
+ type: data.type,
1681
+ message: data.message,
1682
+ location: Location.from(data.location),
1683
+ tag_name: data.tag_name ? Token.from(data.tag_name) : null,
1684
+ helper_name: data.helper_name,
1685
+ content_type: data.content_type,
1686
+ });
1687
+ }
1688
+ constructor(props) {
1689
+ super(props.type, props.message, props.location);
1690
+ this.tag_name = props.tag_name;
1691
+ this.helper_name = props.helper_name;
1692
+ this.content_type = props.content_type;
1693
+ }
1694
+ toJSON() {
1695
+ return {
1696
+ ...super.toJSON(),
1697
+ type: "VOID_ELEMENT_CONTENT_ERROR",
1698
+ tag_name: this.tag_name ? this.tag_name.toJSON() : null,
1699
+ helper_name: this.helper_name,
1700
+ content_type: this.content_type,
1701
+ };
1702
+ }
1703
+ toMonacoDiagnostic() {
1704
+ return {
1705
+ line: this.location.start.line,
1706
+ column: this.location.start.column,
1707
+ endLine: this.location.end.line,
1708
+ endColumn: this.location.end.column,
1709
+ message: this.message,
1710
+ severity: 'error'
1711
+ };
1712
+ }
1713
+ treeInspect() {
1714
+ let output = "";
1715
+ output += `@ VoidElementContentError ${this.location.treeInspectWithLabel()}\n`;
1716
+ output += `├── message: "${this.message}"\n`;
1717
+ output += `├── tag_name: ${this.tag_name ? this.tag_name.treeInspect() : "∅"}\n`;
1718
+ output += `├── helper_name: ${JSON.stringify(this.helper_name)}\n`;
1719
+ output += `└── content_type: ${JSON.stringify(this.content_type)}\n`;
1720
+ return output;
1721
+ }
1722
+ }
1723
+ class DotNotationCasingError extends HerbError {
1724
+ segment;
1725
+ static from(data) {
1726
+ return new DotNotationCasingError({
1727
+ type: data.type,
1728
+ message: data.message,
1729
+ location: Location.from(data.location),
1730
+ segment: data.segment ? Token.from(data.segment) : null,
1731
+ });
1732
+ }
1733
+ constructor(props) {
1734
+ super(props.type, props.message, props.location);
1735
+ this.segment = props.segment;
1736
+ }
1737
+ toJSON() {
1738
+ return {
1739
+ ...super.toJSON(),
1740
+ type: "DOT_NOTATION_CASING_ERROR",
1741
+ segment: this.segment ? this.segment.toJSON() : null,
1742
+ };
1743
+ }
1744
+ toMonacoDiagnostic() {
1745
+ return {
1746
+ line: this.location.start.line,
1747
+ column: this.location.start.column,
1748
+ endLine: this.location.end.line,
1749
+ endColumn: this.location.end.column,
1750
+ message: this.message,
1751
+ severity: 'error'
1752
+ };
1753
+ }
1754
+ treeInspect() {
1755
+ let output = "";
1756
+ output += `@ DotNotationCasingError ${this.location.treeInspectWithLabel()}\n`;
1757
+ output += `├── message: "${this.message}"\n`;
1758
+ output += `└── segment: ${this.segment ? this.segment.treeInspect() : "∅"}\n`;
1759
+ return output;
1760
+ }
1761
+ }
1481
1762
  function fromSerializedError(error) {
1482
1763
  switch (error.type) {
1483
1764
  case "UNEXPECTED_ERROR": return UnexpectedError.from(error);
@@ -1510,6 +1791,13 @@ function fromSerializedError(error) {
1510
1791
  case "RENDER_INVALID_AS_OPTION_ERROR": return RenderInvalidAsOptionError.from(error);
1511
1792
  case "RENDER_OBJECT_AND_COLLECTION_ERROR": return RenderObjectAndCollectionError.from(error);
1512
1793
  case "RENDER_LAYOUT_WITHOUT_BLOCK_ERROR": return RenderLayoutWithoutBlockError.from(error);
1794
+ case "STRICT_LOCALS_POSITIONAL_ARGUMENT_ERROR": return StrictLocalsPositionalArgumentError.from(error);
1795
+ case "STRICT_LOCALS_BLOCK_ARGUMENT_ERROR": return StrictLocalsBlockArgumentError.from(error);
1796
+ case "STRICT_LOCALS_SPLAT_ARGUMENT_ERROR": return StrictLocalsSplatArgumentError.from(error);
1797
+ case "STRICT_LOCALS_MISSING_PARENTHESIS_ERROR": return StrictLocalsMissingParenthesisError.from(error);
1798
+ case "STRICT_LOCALS_DUPLICATE_DECLARATION_ERROR": return StrictLocalsDuplicateDeclarationError.from(error);
1799
+ case "VOID_ELEMENT_CONTENT_ERROR": return VoidElementContentError.from(error);
1800
+ case "DOT_NOTATION_CASING_ERROR": return DotNotationCasingError.from(error);
1513
1801
  default:
1514
1802
  throw new Error(`Unknown node type: ${error.type}`);
1515
1803
  }
@@ -20098,7 +20386,7 @@ function deserializePrismNode(bytes, source) {
20098
20386
  }
20099
20387
 
20100
20388
  // NOTE: This file is generated by the templates/template.rb script and should not
20101
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.2/templates/javascript/packages/core/src/nodes.ts.erb
20389
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.4/templates/javascript/packages/core/src/nodes.ts.erb
20102
20390
  class Node {
20103
20391
  type;
20104
20392
  location;
@@ -21719,6 +22007,9 @@ class ERBBlockNode extends Node {
21719
22007
  tag_closing;
21720
22008
  prism_node;
21721
22009
  body;
22010
+ rescue_clause;
22011
+ else_clause;
22012
+ ensure_clause;
21722
22013
  end_node;
21723
22014
  static get type() {
21724
22015
  return "AST_ERB_BLOCK_NODE";
@@ -21733,6 +22024,9 @@ class ERBBlockNode extends Node {
21733
22024
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
21734
22025
  prism_node: data.prism_node ? new Uint8Array(data.prism_node) : null,
21735
22026
  body: (data.body || []).map(node => fromSerializedNode(node)),
22027
+ rescue_clause: data.rescue_clause ? fromSerializedNode((data.rescue_clause)) : null,
22028
+ else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
22029
+ ensure_clause: data.ensure_clause ? fromSerializedNode((data.ensure_clause)) : null,
21736
22030
  end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
21737
22031
  });
21738
22032
  }
@@ -21743,6 +22037,9 @@ class ERBBlockNode extends Node {
21743
22037
  this.tag_closing = props.tag_closing;
21744
22038
  this.prism_node = props.prism_node;
21745
22039
  this.body = props.body;
22040
+ this.rescue_clause = props.rescue_clause;
22041
+ this.else_clause = props.else_clause;
22042
+ this.ensure_clause = props.ensure_clause;
21746
22043
  this.end_node = props.end_node;
21747
22044
  }
21748
22045
  accept(visitor) {
@@ -21751,6 +22048,9 @@ class ERBBlockNode extends Node {
21751
22048
  childNodes() {
21752
22049
  return [
21753
22050
  ...this.body,
22051
+ this.rescue_clause,
22052
+ this.else_clause,
22053
+ this.ensure_clause,
21754
22054
  this.end_node,
21755
22055
  ];
21756
22056
  }
@@ -21766,6 +22066,9 @@ class ERBBlockNode extends Node {
21766
22066
  return [
21767
22067
  ...this.errors,
21768
22068
  ...this.body.map(node => node.recursiveErrors()),
22069
+ this.rescue_clause ? this.rescue_clause.recursiveErrors() : [],
22070
+ this.else_clause ? this.else_clause.recursiveErrors() : [],
22071
+ this.ensure_clause ? this.ensure_clause.recursiveErrors() : [],
21769
22072
  this.end_node ? this.end_node.recursiveErrors() : [],
21770
22073
  ].flat();
21771
22074
  }
@@ -21778,6 +22081,9 @@ class ERBBlockNode extends Node {
21778
22081
  tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
21779
22082
  prism_node: this.prism_node ? Array.from(this.prism_node) : null,
21780
22083
  body: this.body.map(node => node.toJSON()),
22084
+ rescue_clause: this.rescue_clause ? this.rescue_clause.toJSON() : null,
22085
+ else_clause: this.else_clause ? this.else_clause.toJSON() : null,
22086
+ ensure_clause: this.ensure_clause ? this.ensure_clause.toJSON() : null,
21781
22087
  end_node: this.end_node ? this.end_node.toJSON() : null,
21782
22088
  };
21783
22089
  }
@@ -21792,6 +22098,9 @@ class ERBBlockNode extends Node {
21792
22098
  output += `├── prism_node: ${this.source ? inspectPrismSerialized(this.prism_node, this.source, "│ ") : `(${this.prism_node.length} bytes)`}\n`;
21793
22099
  }
21794
22100
  output += `├── body: ${this.inspectArray(this.body, "│ ")}`;
22101
+ output += `├── rescue_clause: ${this.inspectNode(this.rescue_clause, "│ ")}`;
22102
+ output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
22103
+ output += `├── ensure_clause: ${this.inspectNode(this.ensure_clause, "│ ")}`;
21795
22104
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
21796
22105
  return output;
21797
22106
  }
@@ -22861,6 +23170,150 @@ class ERBRenderNode extends Node {
22861
23170
  return output;
22862
23171
  }
22863
23172
  }
23173
+ class RubyStrictLocalNode extends Node {
23174
+ name;
23175
+ default_value;
23176
+ required;
23177
+ double_splat;
23178
+ static get type() {
23179
+ return "AST_RUBY_STRICT_LOCAL_NODE";
23180
+ }
23181
+ static from(data) {
23182
+ return new RubyStrictLocalNode({
23183
+ type: data.type,
23184
+ location: Location.from(data.location),
23185
+ errors: (data.errors || []).map(error => HerbError.from(error)),
23186
+ name: data.name ? Token.from(data.name) : null,
23187
+ default_value: data.default_value ? fromSerializedNode((data.default_value)) : null,
23188
+ required: data.required,
23189
+ double_splat: data.double_splat,
23190
+ });
23191
+ }
23192
+ constructor(props) {
23193
+ super(props.type, props.location, props.errors);
23194
+ this.name = props.name;
23195
+ this.default_value = props.default_value;
23196
+ this.required = props.required;
23197
+ this.double_splat = props.double_splat;
23198
+ }
23199
+ accept(visitor) {
23200
+ visitor.visitRubyStrictLocalNode(this);
23201
+ }
23202
+ childNodes() {
23203
+ return [
23204
+ this.default_value,
23205
+ ];
23206
+ }
23207
+ compactChildNodes() {
23208
+ return this.childNodes().filter(node => node !== null && node !== undefined);
23209
+ }
23210
+ recursiveErrors() {
23211
+ return [
23212
+ ...this.errors,
23213
+ this.default_value ? this.default_value.recursiveErrors() : [],
23214
+ ].flat();
23215
+ }
23216
+ toJSON() {
23217
+ return {
23218
+ ...super.toJSON(),
23219
+ type: "AST_RUBY_STRICT_LOCAL_NODE",
23220
+ name: this.name ? this.name.toJSON() : null,
23221
+ default_value: this.default_value ? this.default_value.toJSON() : null,
23222
+ required: this.required,
23223
+ double_splat: this.double_splat,
23224
+ };
23225
+ }
23226
+ treeInspect() {
23227
+ let output = "";
23228
+ output += `@ RubyStrictLocalNode ${this.location.treeInspectWithLabel()}\n`;
23229
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
23230
+ output += `├── name: ${this.name ? this.name.treeInspect() : "∅"}\n`;
23231
+ output += `├── default_value: ${this.inspectNode(this.default_value, "│ ")}`;
23232
+ output += `├── required: ${typeof this.required === 'boolean' ? String(this.required) : "∅"}\n`;
23233
+ output += `└── double_splat: ${typeof this.double_splat === 'boolean' ? String(this.double_splat) : "∅"}\n`;
23234
+ return output;
23235
+ }
23236
+ }
23237
+ class ERBStrictLocalsNode extends Node {
23238
+ tag_opening;
23239
+ content;
23240
+ tag_closing;
23241
+ // no-op for analyzed_ruby
23242
+ prism_node;
23243
+ locals;
23244
+ static get type() {
23245
+ return "AST_ERB_STRICT_LOCALS_NODE";
23246
+ }
23247
+ static from(data) {
23248
+ return new ERBStrictLocalsNode({
23249
+ type: data.type,
23250
+ location: Location.from(data.location),
23251
+ errors: (data.errors || []).map(error => HerbError.from(error)),
23252
+ tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
23253
+ content: data.content ? Token.from(data.content) : null,
23254
+ tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
23255
+ // no-op for analyzed_ruby
23256
+ prism_node: data.prism_node ? new Uint8Array(data.prism_node) : null,
23257
+ locals: (data.locals || []).map(node => fromSerializedNode(node)),
23258
+ });
23259
+ }
23260
+ constructor(props) {
23261
+ super(props.type, props.location, props.errors);
23262
+ this.tag_opening = props.tag_opening;
23263
+ this.content = props.content;
23264
+ this.tag_closing = props.tag_closing;
23265
+ // no-op for analyzed_ruby
23266
+ this.prism_node = props.prism_node;
23267
+ this.locals = props.locals;
23268
+ }
23269
+ accept(visitor) {
23270
+ visitor.visitERBStrictLocalsNode(this);
23271
+ }
23272
+ childNodes() {
23273
+ return [
23274
+ ...this.locals,
23275
+ ];
23276
+ }
23277
+ compactChildNodes() {
23278
+ return this.childNodes().filter(node => node !== null && node !== undefined);
23279
+ }
23280
+ get prismNode() {
23281
+ if (!this.prism_node || !this.source)
23282
+ return null;
23283
+ return deserializePrismNode(this.prism_node, this.source);
23284
+ }
23285
+ recursiveErrors() {
23286
+ return [
23287
+ ...this.errors,
23288
+ ...this.locals.map(node => node.recursiveErrors()),
23289
+ ].flat();
23290
+ }
23291
+ toJSON() {
23292
+ return {
23293
+ ...super.toJSON(),
23294
+ type: "AST_ERB_STRICT_LOCALS_NODE",
23295
+ tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
23296
+ content: this.content ? this.content.toJSON() : null,
23297
+ tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
23298
+ // no-op for analyzed_ruby
23299
+ prism_node: this.prism_node ? Array.from(this.prism_node) : null,
23300
+ locals: this.locals.map(node => node.toJSON()),
23301
+ };
23302
+ }
23303
+ treeInspect() {
23304
+ let output = "";
23305
+ output += `@ ERBStrictLocalsNode ${this.location.treeInspectWithLabel()}\n`;
23306
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
23307
+ output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
23308
+ output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
23309
+ output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
23310
+ if (this.prism_node) {
23311
+ output += `├── prism_node: ${this.source ? inspectPrismSerialized(this.prism_node, this.source, "│ ") : `(${this.prism_node.length} bytes)`}\n`;
23312
+ }
23313
+ output += `└── locals: ${this.inspectArray(this.locals, " ")}`;
23314
+ return output;
23315
+ }
23316
+ }
22864
23317
  class ERBYieldNode extends Node {
22865
23318
  tag_opening;
22866
23319
  content;
@@ -23026,6 +23479,8 @@ function fromSerializedNode(node) {
23026
23479
  case "AST_ERB_UNLESS_NODE": return ERBUnlessNode.from(node);
23027
23480
  case "AST_RUBY_RENDER_LOCAL_NODE": return RubyRenderLocalNode.from(node);
23028
23481
  case "AST_ERB_RENDER_NODE": return ERBRenderNode.from(node);
23482
+ case "AST_RUBY_STRICT_LOCAL_NODE": return RubyStrictLocalNode.from(node);
23483
+ case "AST_ERB_STRICT_LOCALS_NODE": return ERBStrictLocalsNode.from(node);
23029
23484
  case "AST_ERB_YIELD_NODE": return ERBYieldNode.from(node);
23030
23485
  case "AST_ERB_IN_NODE": return ERBInNode.from(node);
23031
23486
  default:
@@ -23076,9 +23531,12 @@ const DEFAULT_PARSER_OPTIONS = {
23076
23531
  strict: true,
23077
23532
  action_view_helpers: false,
23078
23533
  render_nodes: false,
23534
+ strict_locals: false,
23079
23535
  prism_nodes: false,
23080
23536
  prism_nodes_deep: false,
23081
23537
  prism_program: false,
23538
+ dot_notation_tags: false,
23539
+ html: true,
23082
23540
  };
23083
23541
  /**
23084
23542
  * Represents the parser options used during parsing.
@@ -23094,12 +23552,18 @@ class ParserOptions {
23094
23552
  action_view_helpers;
23095
23553
  /** Whether ActionView render call detection was enabled during parsing. */
23096
23554
  render_nodes;
23555
+ /** Whether strict locals analysis was enabled during parsing. */
23556
+ strict_locals;
23097
23557
  /** Whether Prism node serialization was enabled during parsing. */
23098
23558
  prism_nodes;
23099
23559
  /** Whether deep Prism node serialization was enabled during parsing. */
23100
23560
  prism_nodes_deep;
23101
23561
  /** Whether the full Prism ProgramNode was serialized on the DocumentNode. */
23102
23562
  prism_program;
23563
+ /** Whether dot-notation component tags (e.g. Dialog.Button) are parsed as HTML elements. */
23564
+ dot_notation_tags;
23565
+ /** Whether HTML tag parsing is enabled during parsing. When false, HTML-like content is treated as literal text. */
23566
+ html;
23103
23567
  static from(options) {
23104
23568
  return new ParserOptions(options);
23105
23569
  }
@@ -23109,9 +23573,12 @@ class ParserOptions {
23109
23573
  this.analyze = options.analyze ?? DEFAULT_PARSER_OPTIONS.analyze;
23110
23574
  this.action_view_helpers = options.action_view_helpers ?? DEFAULT_PARSER_OPTIONS.action_view_helpers;
23111
23575
  this.render_nodes = options.render_nodes ?? DEFAULT_PARSER_OPTIONS.render_nodes;
23576
+ this.strict_locals = options.strict_locals ?? DEFAULT_PARSER_OPTIONS.strict_locals;
23112
23577
  this.prism_nodes = options.prism_nodes ?? DEFAULT_PARSER_OPTIONS.prism_nodes;
23113
23578
  this.prism_nodes_deep = options.prism_nodes_deep ?? DEFAULT_PARSER_OPTIONS.prism_nodes_deep;
23114
23579
  this.prism_program = options.prism_program ?? DEFAULT_PARSER_OPTIONS.prism_program;
23580
+ this.dot_notation_tags = options.dot_notation_tags ?? DEFAULT_PARSER_OPTIONS.dot_notation_tags;
23581
+ this.html = options.html ?? DEFAULT_PARSER_OPTIONS.html;
23115
23582
  }
23116
23583
  }
23117
23584
 
@@ -23188,7 +23655,7 @@ class ParseResult extends Result {
23188
23655
  }
23189
23656
 
23190
23657
  // NOTE: This file is generated by the templates/template.rb script and should not
23191
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.2/templates/javascript/packages/core/src/node-type-guards.ts.erb
23658
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.4/templates/javascript/packages/core/src/node-type-guards.ts.erb
23192
23659
  /**
23193
23660
  * Type guard functions for AST nodes.
23194
23661
  * These functions provide type checking by combining both instanceof
@@ -23499,6 +23966,22 @@ function isERBRenderNode(node) {
23499
23966
  return false;
23500
23967
  return node instanceof ERBRenderNode || node.type === "AST_ERB_RENDER_NODE" || node.constructor.type === "AST_ERB_RENDER_NODE";
23501
23968
  }
23969
+ /**
23970
+ * Checks if a node is a RubyStrictLocalNode
23971
+ */
23972
+ function isRubyStrictLocalNode(node) {
23973
+ if (!node)
23974
+ return false;
23975
+ return node instanceof RubyStrictLocalNode || node.type === "AST_RUBY_STRICT_LOCAL_NODE" || node.constructor.type === "AST_RUBY_STRICT_LOCAL_NODE";
23976
+ }
23977
+ /**
23978
+ * Checks if a node is a ERBStrictLocalsNode
23979
+ */
23980
+ function isERBStrictLocalsNode(node) {
23981
+ if (!node)
23982
+ return false;
23983
+ return node instanceof ERBStrictLocalsNode || node.type === "AST_ERB_STRICT_LOCALS_NODE" || node.constructor.type === "AST_ERB_STRICT_LOCALS_NODE";
23984
+ }
23502
23985
  /**
23503
23986
  * Checks if a node is a ERBYieldNode
23504
23987
  */
@@ -23515,6 +23998,31 @@ function isERBInNode(node) {
23515
23998
  return false;
23516
23999
  return node instanceof ERBInNode || node.type === "AST_ERB_IN_NODE" || node.constructor.type === "AST_ERB_IN_NODE";
23517
24000
  }
24001
+ /**
24002
+ * Checks if a node is any ERB node type
24003
+ */
24004
+ function isERBNode(node) {
24005
+ return isERBOpenTagNode(node) ||
24006
+ isERBContentNode(node) ||
24007
+ isERBEndNode(node) ||
24008
+ isERBElseNode(node) ||
24009
+ isERBIfNode(node) ||
24010
+ isERBBlockNode(node) ||
24011
+ isERBWhenNode(node) ||
24012
+ isERBCaseNode(node) ||
24013
+ isERBCaseMatchNode(node) ||
24014
+ isERBWhileNode(node) ||
24015
+ isERBUntilNode(node) ||
24016
+ isERBForNode(node) ||
24017
+ isERBRescueNode(node) ||
24018
+ isERBEnsureNode(node) ||
24019
+ isERBBeginNode(node) ||
24020
+ isERBUnlessNode(node) ||
24021
+ isERBRenderNode(node) ||
24022
+ isERBStrictLocalsNode(node) ||
24023
+ isERBYieldNode(node) ||
24024
+ isERBInNode(node);
24025
+ }
23518
24026
  /**
23519
24027
  * Map of node classes to their corresponding type guard functions
23520
24028
  *
@@ -23564,6 +24072,8 @@ const NODE_TYPE_GUARDS = new Map([
23564
24072
  [ERBUnlessNode, isERBUnlessNode],
23565
24073
  [RubyRenderLocalNode, isRubyRenderLocalNode],
23566
24074
  [ERBRenderNode, isERBRenderNode],
24075
+ [RubyStrictLocalNode, isRubyStrictLocalNode],
24076
+ [ERBStrictLocalsNode, isERBStrictLocalsNode],
23567
24077
  [ERBYieldNode, isERBYieldNode],
23568
24078
  [ERBInNode, isERBInNode],
23569
24079
  ]);
@@ -23616,6 +24126,8 @@ const AST_TYPE_GUARDS = new Map([
23616
24126
  ["AST_ERB_UNLESS_NODE", isERBUnlessNode],
23617
24127
  ["AST_RUBY_RENDER_LOCAL_NODE", isRubyRenderLocalNode],
23618
24128
  ["AST_ERB_RENDER_NODE", isERBRenderNode],
24129
+ ["AST_RUBY_STRICT_LOCAL_NODE", isRubyStrictLocalNode],
24130
+ ["AST_ERB_STRICT_LOCALS_NODE", isERBStrictLocalsNode],
23619
24131
  ["AST_ERB_YIELD_NODE", isERBYieldNode],
23620
24132
  ["AST_ERB_IN_NODE", isERBInNode],
23621
24133
  ]);
@@ -23673,6 +24185,17 @@ function isToken(object) {
23673
24185
  function isParseResult(object) {
23674
24186
  return (object instanceof ParseResult) || (object?.constructor?.name === "ParseResult" && "value" in object);
23675
24187
  }
24188
+
24189
+ /**
24190
+ * Checks if a node is an ERB output node (generates content: <%= %> or <%== %>)
24191
+ */
24192
+ function isERBOutputNode(node) {
24193
+ if (!isERBNode(node))
24194
+ return false;
24195
+ if (!node.tag_opening?.value)
24196
+ return false;
24197
+ return ["<%=", "<%=="].includes(node.tag_opening?.value);
24198
+ }
23676
24199
  /**
23677
24200
  * Extracts a static string from an array of literal nodes
23678
24201
  * Returns null if any node is not a literal node
@@ -23837,12 +24360,88 @@ function getNodesBeforePosition(nodes, position, inclusive = false) {
23837
24360
  function getNodesAfterPosition(nodes, position, inclusive = true) {
23838
24361
  return nodes.filter(node => node.location && isPositionAfter(node.location.start, position, inclusive));
23839
24362
  }
24363
+ // --- AST Mutation Utilities ---
24364
+ const CHILD_ARRAY_PROPS = ["children", "body", "statements", "conditions"];
24365
+ const LINKED_NODE_PROPS = ["subsequent", "else_clause"];
24366
+ /**
24367
+ * Finds the array containing a target node in the AST, along with its index.
24368
+ * Traverses child arrays and linked node properties (e.g., `subsequent`, `else_clause`).
24369
+ *
24370
+ * Useful for autofix operations that need to splice nodes in/out of their parent array.
24371
+ *
24372
+ * @param root - The root node to search from
24373
+ * @param target - The node to find
24374
+ * @returns The containing array and the target's index, or null if not found
24375
+ */
24376
+ function findParentArray(root, target) {
24377
+ const search = (node) => {
24378
+ const record = node;
24379
+ for (const prop of CHILD_ARRAY_PROPS) {
24380
+ const array = record[prop];
24381
+ if (Array.isArray(array)) {
24382
+ const index = array.indexOf(target);
24383
+ if (index !== -1) {
24384
+ return { array, index };
24385
+ }
24386
+ }
24387
+ }
24388
+ for (const prop of CHILD_ARRAY_PROPS) {
24389
+ const array = record[prop];
24390
+ if (Array.isArray(array)) {
24391
+ for (const child of array) {
24392
+ if (child && typeof child === 'object' && 'type' in child) {
24393
+ const result = search(child);
24394
+ if (result) {
24395
+ return result;
24396
+ }
24397
+ }
24398
+ }
24399
+ }
24400
+ }
24401
+ for (const prop of LINKED_NODE_PROPS) {
24402
+ const value = record[prop];
24403
+ if (value && typeof value === 'object' && 'type' in value) {
24404
+ const result = search(value);
24405
+ if (result) {
24406
+ return result;
24407
+ }
24408
+ }
24409
+ }
24410
+ return null;
24411
+ };
24412
+ return search(root);
24413
+ }
24414
+ /**
24415
+ * Creates a synthetic LiteralNode with the given content and zero location.
24416
+ * Useful for inserting whitespace or newlines during AST mutations.
24417
+ */
24418
+ function createLiteral(content) {
24419
+ return new LiteralNode({
24420
+ type: "AST_LITERAL_NODE",
24421
+ content,
24422
+ location: Location.zero,
24423
+ errors: [],
24424
+ });
24425
+ }
23840
24426
  function createSyntheticToken(value, type = "TOKEN_SYNTHETIC") {
23841
24427
  return new Token(value, Range.zero, Location.zero, type);
23842
24428
  }
24429
+ function createERBOutputNode(expression, tagOpening = "<%=", tagClosing = "%>") {
24430
+ return new ERBContentNode({
24431
+ type: "AST_ERB_CONTENT_NODE",
24432
+ tag_opening: createSyntheticToken(tagOpening),
24433
+ content: createSyntheticToken(expression),
24434
+ tag_closing: createSyntheticToken(tagClosing),
24435
+ parsed: false,
24436
+ valid: true,
24437
+ prism_node: null,
24438
+ location: Location.zero,
24439
+ errors: [],
24440
+ });
24441
+ }
23843
24442
 
23844
24443
  // NOTE: This file is generated by the templates/template.rb script and should not
23845
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.2/templates/javascript/packages/core/src/visitor.ts.erb
24444
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.4/templates/javascript/packages/core/src/visitor.ts.erb
23846
24445
  class Visitor {
23847
24446
  visit(node) {
23848
24447
  if (!node)
@@ -24030,6 +24629,15 @@ class Visitor {
24030
24629
  this.visitERBNode(node);
24031
24630
  this.visitChildNodes(node);
24032
24631
  }
24632
+ visitRubyStrictLocalNode(node) {
24633
+ this.visitNode(node);
24634
+ this.visitChildNodes(node);
24635
+ }
24636
+ visitERBStrictLocalsNode(node) {
24637
+ this.visitNode(node);
24638
+ this.visitERBNode(node);
24639
+ this.visitChildNodes(node);
24640
+ }
24033
24641
  visitERBYieldNode(node) {
24034
24642
  this.visitNode(node);
24035
24643
  this.visitERBNode(node);
@@ -24062,6 +24670,34 @@ function createWhitespaceNode() {
24062
24670
  });
24063
24671
  }
24064
24672
  class ActionViewTagHelperToHTMLVisitor extends Visitor {
24673
+ shallow;
24674
+ includeBody;
24675
+ constructor(options = {}) {
24676
+ super();
24677
+ this.shallow = options.shallow ?? false;
24678
+ this.includeBody = options.includeBody ?? true;
24679
+ }
24680
+ visitHTMLOpenTagNode(node) {
24681
+ const newChildren = [];
24682
+ for (let index = 0; index < node.children.length; index++) {
24683
+ const child = node.children[index];
24684
+ if (isHTMLAttributeNode(child)) {
24685
+ if (child.equals && child.equals.value !== "=") {
24686
+ asMutable(child).equals = createSyntheticToken("=");
24687
+ }
24688
+ if (child.value) {
24689
+ this.transformAttributeValue(child.value);
24690
+ }
24691
+ const previous = index > 0 ? node.children[index - 1] : null;
24692
+ if (!previous || !isWhitespaceNode(previous)) {
24693
+ newChildren.push(createWhitespaceNode());
24694
+ }
24695
+ }
24696
+ newChildren.push(child);
24697
+ }
24698
+ asMutable(node).children = newChildren;
24699
+ this.visitChildNodes(node);
24700
+ }
24065
24701
  visitHTMLElementNode(node) {
24066
24702
  if (!node.element_source) {
24067
24703
  this.visitChildNodes(node);
@@ -24132,7 +24768,10 @@ class ActionViewTagHelperToHTMLVisitor extends Visitor {
24132
24768
  asMutable(node).close_tag = htmlCloseTag;
24133
24769
  }
24134
24770
  asMutable(node).element_source = "HTML";
24135
- if (node.body) {
24771
+ if (!this.includeBody) {
24772
+ asMutable(node).body = [];
24773
+ }
24774
+ else if (node.body) {
24136
24775
  asMutable(node).body = node.body.map(child => {
24137
24776
  if (isRubyLiteralNode(child)) {
24138
24777
  return new ERBContentNode({
@@ -24147,7 +24786,9 @@ class ActionViewTagHelperToHTMLVisitor extends Visitor {
24147
24786
  prism_node: null
24148
24787
  });
24149
24788
  }
24150
- this.visit(child);
24789
+ if (!this.shallow) {
24790
+ this.visit(child);
24791
+ }
24151
24792
  return child;
24152
24793
  });
24153
24794
  }
@@ -24173,11 +24814,11 @@ class ActionViewTagHelperToHTMLVisitor extends Visitor {
24173
24814
  return child;
24174
24815
  });
24175
24816
  mutableValue.children = newChildren;
24176
- if (!value.quoted) {
24177
- mutableValue.quoted = true;
24178
- mutableValue.open_quote = createSyntheticToken('"');
24179
- mutableValue.close_quote = createSyntheticToken('"');
24180
- }
24817
+ }
24818
+ if (!value.quoted) {
24819
+ mutableValue.quoted = true;
24820
+ mutableValue.open_quote = createSyntheticToken('"');
24821
+ mutableValue.close_quote = createSyntheticToken('"');
24181
24822
  }
24182
24823
  }
24183
24824
  }
@@ -24188,11 +24829,132 @@ class ActionViewTagHelperToHTMLRewriter extends ASTRewriter {
24188
24829
  get description() {
24189
24830
  return "Converts ActionView tag helpers to raw HTML elements";
24190
24831
  }
24832
+ rewrite(node, context) {
24833
+ const visitor = new ActionViewTagHelperToHTMLVisitor({ shallow: context.shallow, includeBody: context.includeBody });
24834
+ visitor.visit(node);
24835
+ return node;
24836
+ }
24837
+ }
24838
+
24839
+ const STRING_NODE_TYPE = "StringNode";
24840
+ const INTERPOLATED_STRING_NODE_TYPE = "InterpolatedStringNode";
24841
+ const EMBEDDED_STATEMENTS_NODE_TYPE = "EmbeddedStatementsNode";
24842
+ class ERBStringToDirectOutputVisitor extends Visitor {
24843
+ root;
24844
+ constructor(root) {
24845
+ super();
24846
+ this.root = root;
24847
+ }
24848
+ visitERBContentNode(node) {
24849
+ if (!isERBOutputNode(node)) {
24850
+ this.visitChildNodes(node);
24851
+ return;
24852
+ }
24853
+ const prismNode = node.prismNode;
24854
+ if (!prismNode) {
24855
+ this.visitChildNodes(node);
24856
+ return;
24857
+ }
24858
+ const source = node.source;
24859
+ if (!source) {
24860
+ this.visitChildNodes(node);
24861
+ return;
24862
+ }
24863
+ if (!ERBStringToDirectOutputRewriter.isStringOutputNode(prismNode)) {
24864
+ this.visitChildNodes(node);
24865
+ return;
24866
+ }
24867
+ const replacementParts = ERBStringToDirectOutputRewriter.extractReplacementParts(prismNode, source);
24868
+ if (!replacementParts) {
24869
+ this.visitChildNodes(node);
24870
+ return;
24871
+ }
24872
+ const tagOpening = node.tag_opening?.value ?? "<%=";
24873
+ const tagClosing = node.tag_closing?.value ?? "%>";
24874
+ const parentInfo = findParentArray(this.root, node);
24875
+ if (!parentInfo) {
24876
+ this.visitChildNodes(node);
24877
+ return;
24878
+ }
24879
+ const { array: parentArray, index: nodeIndex } = parentInfo;
24880
+ const replacementNodes = [];
24881
+ for (const part of replacementParts) {
24882
+ if (part.type === "text") {
24883
+ replacementNodes.push(createLiteral(part.content));
24884
+ }
24885
+ else {
24886
+ replacementNodes.push(createERBOutputNode(` ${part.expression.trim()} `, tagOpening, tagClosing));
24887
+ }
24888
+ }
24889
+ parentArray.splice(nodeIndex, 1, ...replacementNodes);
24890
+ }
24891
+ }
24892
+ class ERBStringToDirectOutputRewriter extends ASTRewriter {
24893
+ get name() {
24894
+ return "erb-string-to-direct-output";
24895
+ }
24896
+ get description() {
24897
+ return "Replaces ERB string output with direct text and expression tags";
24898
+ }
24191
24899
  rewrite(node, _context) {
24192
- const visitor = new ActionViewTagHelperToHTMLVisitor();
24900
+ const visitor = new ERBStringToDirectOutputVisitor(node);
24193
24901
  visitor.visit(node);
24194
24902
  return node;
24195
24903
  }
24904
+ static isStringOutputNode(prismNode) {
24905
+ const nodeType = prismNode.constructor.name;
24906
+ return nodeType === STRING_NODE_TYPE || nodeType === INTERPOLATED_STRING_NODE_TYPE;
24907
+ }
24908
+ static extractStringContent(stringNode, source) {
24909
+ const unescapedValue = stringNode.unescaped?.value;
24910
+ if (typeof unescapedValue === "string") {
24911
+ return unescapedValue;
24912
+ }
24913
+ const location = stringNode.contentLoc;
24914
+ if (location) {
24915
+ return source.substring(location.startOffset, location.startOffset + location.length);
24916
+ }
24917
+ return "";
24918
+ }
24919
+ static extractExpressionSource(embeddedNode, source) {
24920
+ const openingLocation = embeddedNode.openingLoc;
24921
+ const closingLocation = embeddedNode.closingLoc;
24922
+ if (!openingLocation || !closingLocation)
24923
+ return null;
24924
+ const expressionStart = openingLocation.startOffset + openingLocation.length;
24925
+ const expressionEnd = closingLocation.startOffset;
24926
+ return source.substring(expressionStart, expressionEnd);
24927
+ }
24928
+ static extractReplacementParts(prismNode, source) {
24929
+ const nodeType = prismNode.constructor.name;
24930
+ if (nodeType === STRING_NODE_TYPE) {
24931
+ const textContent = this.extractStringContent(prismNode, source);
24932
+ return [{ type: "text", content: textContent }];
24933
+ }
24934
+ if (nodeType === INTERPOLATED_STRING_NODE_TYPE) {
24935
+ const parts = prismNode.parts;
24936
+ if (!parts || parts.length === 0)
24937
+ return null;
24938
+ const replacementParts = [];
24939
+ for (const part of parts) {
24940
+ const partType = part.constructor.name;
24941
+ if (partType === STRING_NODE_TYPE) {
24942
+ const textContent = this.extractStringContent(part, source);
24943
+ if (textContent) {
24944
+ replacementParts.push({ type: "text", content: textContent });
24945
+ }
24946
+ }
24947
+ else if (partType === EMBEDDED_STATEMENTS_NODE_TYPE) {
24948
+ const expression = this.extractExpressionSource(part, source);
24949
+ if (expression) {
24950
+ replacementParts.push({ type: "expression", expression });
24951
+ }
24952
+ }
24953
+ }
24954
+ return replacementParts.length > 0 ? replacementParts : null;
24955
+ }
24956
+ return null;
24957
+ }
24196
24958
  }
24197
24959
 
24198
24960
  function serializeAttributeValue(value) {
@@ -24282,9 +25044,10 @@ class HTMLToActionViewTagHelperVisitor extends Visitor {
24282
25044
  const isAnchor = tagName.value === "a";
24283
25045
  const isTurboFrame = tagName.value === "turbo-frame";
24284
25046
  const isScript = tagName.value === "script";
25047
+ const isImg = tagName.value === "img";
24285
25048
  const attributes = openTag.children.filter(child => !isWhitespaceNode(child));
24286
- const hasSrcAttribute = isScript && attributes.some(child => isHTMLAttributeNode(child) && getStaticAttributeName(child.name) === "src");
24287
- const { attributes: attributesString, href, id, src } = serializeAttributes(attributes, { extractHref: isAnchor, extractId: isTurboFrame, extractSrc: isScript });
25049
+ const hasSrcAttribute = (isScript || isImg) && attributes.some(child => isHTMLAttributeNode(child) && getStaticAttributeName(child.name) === "src");
25050
+ const { attributes: attributesString, href, id, src } = serializeAttributes(attributes, { extractHref: isAnchor, extractId: isTurboFrame, extractSrc: isScript || isImg });
24288
25051
  const hasBody = node.body && node.body.length > 0 && !node.is_void;
24289
25052
  const isInlineContent = hasBody && isTextOnlyBody(node.body);
24290
25053
  let content;
@@ -24305,6 +25068,10 @@ class HTMLToActionViewTagHelperVisitor extends Visitor {
24305
25068
  content = this.buildJavascriptTagContent(node, attributesString, isInlineContent);
24306
25069
  elementSource = "ActionView::Helpers::JavaScriptHelper#javascript_tag";
24307
25070
  }
25071
+ else if (isImg) {
25072
+ content = this.buildImageTagContent(attributesString, src);
25073
+ elementSource = "ActionView::Helpers::AssetTagHelper#image_tag";
25074
+ }
24308
25075
  else {
24309
25076
  content = this.buildTagContent(tagName.value, node, attributesString, isInlineContent);
24310
25077
  elementSource = "ActionView::Helpers::TagHelper#tag";
@@ -24322,7 +25089,7 @@ class HTMLToActionViewTagHelperVisitor extends Visitor {
24322
25089
  asMutable(node).open_tag = erbOpenTag;
24323
25090
  asMutable(node).element_source = elementSource;
24324
25091
  const isInlineLiteralContent = isScript && hasBody && node.body.length === 1 && isLiteralNode(node.body[0]) && !node.body[0].content.includes("\n");
24325
- const isInlineForm = isInlineContent || isInlineLiteralContent || (isTurboFrame && !hasBody) || (isScript && hasSrcAttribute);
25092
+ const isInlineForm = isInlineContent || isInlineLiteralContent || (isTurboFrame && !hasBody) || (isScript && hasSrcAttribute) || isImg;
24326
25093
  if (node.is_void) {
24327
25094
  asMutable(node).close_tag = null;
24328
25095
  }
@@ -24406,6 +25173,15 @@ class HTMLToActionViewTagHelperVisitor extends Visitor {
24406
25173
  const argString = args.join(", ");
24407
25174
  return argString ? ` javascript_include_tag ${argString} ` : ` javascript_include_tag `;
24408
25175
  }
25176
+ buildImageTagContent(attributes, source) {
25177
+ const args = [];
25178
+ if (source)
25179
+ args.push(source);
25180
+ if (attributes)
25181
+ args.push(attributes);
25182
+ const argString = args.join(", ");
25183
+ return argString ? ` image_tag ${argString} ` : ` image_tag `;
25184
+ }
24409
25185
  buildLinkToContent(node, attribute, href, isInlineContent) {
24410
25186
  const args = [];
24411
25187
  if (isInlineContent && isHTMLTextNode(node.body[0])) {
@@ -24429,7 +25205,7 @@ class HTMLToActionViewTagHelperRewriter extends ASTRewriter {
24429
25205
  return "html-to-action-view-tag-helper";
24430
25206
  }
24431
25207
  get description() {
24432
- return "Converts raw HTML elements to ActionView tag helpers (tag.*, turbo_frame_tag, javascript_tag, javascript_include_tag)";
25208
+ return "Converts raw HTML elements to ActionView tag helpers (tag.*, turbo_frame_tag, javascript_tag, javascript_include_tag, image_tag)";
24433
25209
  }
24434
25210
  rewrite(node, _context) {
24435
25211
  const visitor = new HTMLToActionViewTagHelperVisitor();
@@ -24856,6 +25632,15 @@ class IdentityPrinter extends Printer {
24856
25632
  if (node.body) {
24857
25633
  node.body.forEach(child => this.visit(child));
24858
25634
  }
25635
+ if (node.rescue_clause) {
25636
+ this.visit(node.rescue_clause);
25637
+ }
25638
+ if (node.else_clause) {
25639
+ this.visit(node.else_clause);
25640
+ }
25641
+ if (node.ensure_clause) {
25642
+ this.visit(node.ensure_clause);
25643
+ }
24859
25644
  if (node.end_node) {
24860
25645
  this.visit(node.end_node);
24861
25646
  }
@@ -24959,6 +25744,12 @@ class IdentityPrinter extends Printer {
24959
25744
  visitRubyRenderLocalNode(_node) {
24960
25745
  // extracted metadata, nothing to print
24961
25746
  }
25747
+ visitERBStrictLocalsNode(node) {
25748
+ this.printERBNode(node);
25749
+ }
25750
+ visitRubyStrictLocalNode(_node) {
25751
+ // extracted metadata, nothing to print
25752
+ }
24962
25753
  visitERBYieldNode(node) {
24963
25754
  this.printERBNode(node);
24964
25755
  }
@@ -25507,6 +26298,7 @@ class TailwindClassSorterRewriter extends ASTRewriter {
25507
26298
  */
25508
26299
  const builtinRewriters = [
25509
26300
  ActionViewTagHelperToHTMLRewriter,
26301
+ ERBStringToDirectOutputRewriter,
25510
26302
  HTMLToActionViewTagHelperRewriter,
25511
26303
  TailwindClassSorterRewriter
25512
26304
  ];
@@ -25555,5 +26347,5 @@ async function tailwindClassSorter(options = {}) {
25555
26347
  return rewriter;
25556
26348
  }
25557
26349
 
25558
- export { ASTRewriter, ActionViewTagHelperToHTMLRewriter, CustomRewriterLoader, HTMLToActionViewTagHelperRewriter, StringRewriter, TailwindClassSorterRewriter, asMutable, builtinRewriters, getBuiltinRewriter, getBuiltinRewriterNames, isASTRewriterClass, isRewriterClass, isStringRewriterClass, rewrite, rewriteString, tailwindClassSorter };
26350
+ export { ASTRewriter, ActionViewTagHelperToHTMLRewriter, CustomRewriterLoader, ERBStringToDirectOutputRewriter, HTMLToActionViewTagHelperRewriter, StringRewriter, TailwindClassSorterRewriter, asMutable, builtinRewriters, getBuiltinRewriter, getBuiltinRewriterNames, isASTRewriterClass, isRewriterClass, isStringRewriterClass, rewrite, rewriteString, tailwindClassSorter };
25559
26351
  //# sourceMappingURL=loader.esm.js.map