@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.
package/dist/index.esm.js CHANGED
@@ -166,6 +166,9 @@ class Token {
166
166
  static from(token) {
167
167
  return new Token(token.value, Range.from(token.range), Location.from(token.location), token.type);
168
168
  }
169
+ static synthetic(value, type = "SYNTETHIC") {
170
+ return new Token(value, Range.zero, Location.zero, type);
171
+ }
169
172
  constructor(value, range, location, type) {
170
173
  this.value = value;
171
174
  this.range = range;
@@ -200,7 +203,7 @@ class Token {
200
203
  }
201
204
 
202
205
  // NOTE: This file is generated by the templates/template.rb script and should not
203
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.2/templates/javascript/packages/core/src/errors.ts.erb
206
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.4/templates/javascript/packages/core/src/errors.ts.erb
204
207
  class HerbError {
205
208
  type;
206
209
  message;
@@ -1474,6 +1477,284 @@ class RenderLayoutWithoutBlockError extends HerbError {
1474
1477
  return output;
1475
1478
  }
1476
1479
  }
1480
+ class StrictLocalsPositionalArgumentError extends HerbError {
1481
+ name;
1482
+ static from(data) {
1483
+ return new StrictLocalsPositionalArgumentError({
1484
+ type: data.type,
1485
+ message: data.message,
1486
+ location: Location.from(data.location),
1487
+ name: data.name,
1488
+ });
1489
+ }
1490
+ constructor(props) {
1491
+ super(props.type, props.message, props.location);
1492
+ this.name = props.name;
1493
+ }
1494
+ toJSON() {
1495
+ return {
1496
+ ...super.toJSON(),
1497
+ type: "STRICT_LOCALS_POSITIONAL_ARGUMENT_ERROR",
1498
+ name: this.name,
1499
+ };
1500
+ }
1501
+ toMonacoDiagnostic() {
1502
+ return {
1503
+ line: this.location.start.line,
1504
+ column: this.location.start.column,
1505
+ endLine: this.location.end.line,
1506
+ endColumn: this.location.end.column,
1507
+ message: this.message,
1508
+ severity: 'error'
1509
+ };
1510
+ }
1511
+ treeInspect() {
1512
+ let output = "";
1513
+ output += `@ StrictLocalsPositionalArgumentError ${this.location.treeInspectWithLabel()}\n`;
1514
+ output += `├── message: "${this.message}"\n`;
1515
+ output += `└── name: ${JSON.stringify(this.name)}\n`;
1516
+ return output;
1517
+ }
1518
+ }
1519
+ class StrictLocalsBlockArgumentError extends HerbError {
1520
+ name;
1521
+ static from(data) {
1522
+ return new StrictLocalsBlockArgumentError({
1523
+ type: data.type,
1524
+ message: data.message,
1525
+ location: Location.from(data.location),
1526
+ name: data.name,
1527
+ });
1528
+ }
1529
+ constructor(props) {
1530
+ super(props.type, props.message, props.location);
1531
+ this.name = props.name;
1532
+ }
1533
+ toJSON() {
1534
+ return {
1535
+ ...super.toJSON(),
1536
+ type: "STRICT_LOCALS_BLOCK_ARGUMENT_ERROR",
1537
+ name: this.name,
1538
+ };
1539
+ }
1540
+ toMonacoDiagnostic() {
1541
+ return {
1542
+ line: this.location.start.line,
1543
+ column: this.location.start.column,
1544
+ endLine: this.location.end.line,
1545
+ endColumn: this.location.end.column,
1546
+ message: this.message,
1547
+ severity: 'error'
1548
+ };
1549
+ }
1550
+ treeInspect() {
1551
+ let output = "";
1552
+ output += `@ StrictLocalsBlockArgumentError ${this.location.treeInspectWithLabel()}\n`;
1553
+ output += `├── message: "${this.message}"\n`;
1554
+ output += `└── name: ${JSON.stringify(this.name)}\n`;
1555
+ return output;
1556
+ }
1557
+ }
1558
+ class StrictLocalsSplatArgumentError extends HerbError {
1559
+ name;
1560
+ static from(data) {
1561
+ return new StrictLocalsSplatArgumentError({
1562
+ type: data.type,
1563
+ message: data.message,
1564
+ location: Location.from(data.location),
1565
+ name: data.name,
1566
+ });
1567
+ }
1568
+ constructor(props) {
1569
+ super(props.type, props.message, props.location);
1570
+ this.name = props.name;
1571
+ }
1572
+ toJSON() {
1573
+ return {
1574
+ ...super.toJSON(),
1575
+ type: "STRICT_LOCALS_SPLAT_ARGUMENT_ERROR",
1576
+ name: this.name,
1577
+ };
1578
+ }
1579
+ toMonacoDiagnostic() {
1580
+ return {
1581
+ line: this.location.start.line,
1582
+ column: this.location.start.column,
1583
+ endLine: this.location.end.line,
1584
+ endColumn: this.location.end.column,
1585
+ message: this.message,
1586
+ severity: 'error'
1587
+ };
1588
+ }
1589
+ treeInspect() {
1590
+ let output = "";
1591
+ output += `@ StrictLocalsSplatArgumentError ${this.location.treeInspectWithLabel()}\n`;
1592
+ output += `├── message: "${this.message}"\n`;
1593
+ output += `└── name: ${JSON.stringify(this.name)}\n`;
1594
+ return output;
1595
+ }
1596
+ }
1597
+ class StrictLocalsMissingParenthesisError extends HerbError {
1598
+ rest;
1599
+ static from(data) {
1600
+ return new StrictLocalsMissingParenthesisError({
1601
+ type: data.type,
1602
+ message: data.message,
1603
+ location: Location.from(data.location),
1604
+ rest: data.rest,
1605
+ });
1606
+ }
1607
+ constructor(props) {
1608
+ super(props.type, props.message, props.location);
1609
+ this.rest = props.rest;
1610
+ }
1611
+ toJSON() {
1612
+ return {
1613
+ ...super.toJSON(),
1614
+ type: "STRICT_LOCALS_MISSING_PARENTHESIS_ERROR",
1615
+ rest: this.rest,
1616
+ };
1617
+ }
1618
+ toMonacoDiagnostic() {
1619
+ return {
1620
+ line: this.location.start.line,
1621
+ column: this.location.start.column,
1622
+ endLine: this.location.end.line,
1623
+ endColumn: this.location.end.column,
1624
+ message: this.message,
1625
+ severity: 'error'
1626
+ };
1627
+ }
1628
+ treeInspect() {
1629
+ let output = "";
1630
+ output += `@ StrictLocalsMissingParenthesisError ${this.location.treeInspectWithLabel()}\n`;
1631
+ output += `├── message: "${this.message}"\n`;
1632
+ output += `└── rest: ${JSON.stringify(this.rest)}\n`;
1633
+ return output;
1634
+ }
1635
+ }
1636
+ class StrictLocalsDuplicateDeclarationError extends HerbError {
1637
+ static from(data) {
1638
+ return new StrictLocalsDuplicateDeclarationError({
1639
+ type: data.type,
1640
+ message: data.message,
1641
+ location: Location.from(data.location),
1642
+ });
1643
+ }
1644
+ constructor(props) {
1645
+ super(props.type, props.message, props.location);
1646
+ }
1647
+ toJSON() {
1648
+ return {
1649
+ ...super.toJSON(),
1650
+ type: "STRICT_LOCALS_DUPLICATE_DECLARATION_ERROR",
1651
+ };
1652
+ }
1653
+ toMonacoDiagnostic() {
1654
+ return {
1655
+ line: this.location.start.line,
1656
+ column: this.location.start.column,
1657
+ endLine: this.location.end.line,
1658
+ endColumn: this.location.end.column,
1659
+ message: this.message,
1660
+ severity: 'error'
1661
+ };
1662
+ }
1663
+ treeInspect() {
1664
+ let output = "";
1665
+ output += `@ StrictLocalsDuplicateDeclarationError ${this.location.treeInspectWithLabel()}\n`;
1666
+ output += `└── message: "${this.message}"\n`;
1667
+ return output;
1668
+ }
1669
+ }
1670
+ class VoidElementContentError extends HerbError {
1671
+ tag_name;
1672
+ helper_name;
1673
+ content_type;
1674
+ static from(data) {
1675
+ return new VoidElementContentError({
1676
+ type: data.type,
1677
+ message: data.message,
1678
+ location: Location.from(data.location),
1679
+ tag_name: data.tag_name ? Token.from(data.tag_name) : null,
1680
+ helper_name: data.helper_name,
1681
+ content_type: data.content_type,
1682
+ });
1683
+ }
1684
+ constructor(props) {
1685
+ super(props.type, props.message, props.location);
1686
+ this.tag_name = props.tag_name;
1687
+ this.helper_name = props.helper_name;
1688
+ this.content_type = props.content_type;
1689
+ }
1690
+ toJSON() {
1691
+ return {
1692
+ ...super.toJSON(),
1693
+ type: "VOID_ELEMENT_CONTENT_ERROR",
1694
+ tag_name: this.tag_name ? this.tag_name.toJSON() : null,
1695
+ helper_name: this.helper_name,
1696
+ content_type: this.content_type,
1697
+ };
1698
+ }
1699
+ toMonacoDiagnostic() {
1700
+ return {
1701
+ line: this.location.start.line,
1702
+ column: this.location.start.column,
1703
+ endLine: this.location.end.line,
1704
+ endColumn: this.location.end.column,
1705
+ message: this.message,
1706
+ severity: 'error'
1707
+ };
1708
+ }
1709
+ treeInspect() {
1710
+ let output = "";
1711
+ output += `@ VoidElementContentError ${this.location.treeInspectWithLabel()}\n`;
1712
+ output += `├── message: "${this.message}"\n`;
1713
+ output += `├── tag_name: ${this.tag_name ? this.tag_name.treeInspect() : "∅"}\n`;
1714
+ output += `├── helper_name: ${JSON.stringify(this.helper_name)}\n`;
1715
+ output += `└── content_type: ${JSON.stringify(this.content_type)}\n`;
1716
+ return output;
1717
+ }
1718
+ }
1719
+ class DotNotationCasingError extends HerbError {
1720
+ segment;
1721
+ static from(data) {
1722
+ return new DotNotationCasingError({
1723
+ type: data.type,
1724
+ message: data.message,
1725
+ location: Location.from(data.location),
1726
+ segment: data.segment ? Token.from(data.segment) : null,
1727
+ });
1728
+ }
1729
+ constructor(props) {
1730
+ super(props.type, props.message, props.location);
1731
+ this.segment = props.segment;
1732
+ }
1733
+ toJSON() {
1734
+ return {
1735
+ ...super.toJSON(),
1736
+ type: "DOT_NOTATION_CASING_ERROR",
1737
+ segment: this.segment ? this.segment.toJSON() : null,
1738
+ };
1739
+ }
1740
+ toMonacoDiagnostic() {
1741
+ return {
1742
+ line: this.location.start.line,
1743
+ column: this.location.start.column,
1744
+ endLine: this.location.end.line,
1745
+ endColumn: this.location.end.column,
1746
+ message: this.message,
1747
+ severity: 'error'
1748
+ };
1749
+ }
1750
+ treeInspect() {
1751
+ let output = "";
1752
+ output += `@ DotNotationCasingError ${this.location.treeInspectWithLabel()}\n`;
1753
+ output += `├── message: "${this.message}"\n`;
1754
+ output += `└── segment: ${this.segment ? this.segment.treeInspect() : "∅"}\n`;
1755
+ return output;
1756
+ }
1757
+ }
1477
1758
  function fromSerializedError(error) {
1478
1759
  switch (error.type) {
1479
1760
  case "UNEXPECTED_ERROR": return UnexpectedError.from(error);
@@ -1506,6 +1787,13 @@ function fromSerializedError(error) {
1506
1787
  case "RENDER_INVALID_AS_OPTION_ERROR": return RenderInvalidAsOptionError.from(error);
1507
1788
  case "RENDER_OBJECT_AND_COLLECTION_ERROR": return RenderObjectAndCollectionError.from(error);
1508
1789
  case "RENDER_LAYOUT_WITHOUT_BLOCK_ERROR": return RenderLayoutWithoutBlockError.from(error);
1790
+ case "STRICT_LOCALS_POSITIONAL_ARGUMENT_ERROR": return StrictLocalsPositionalArgumentError.from(error);
1791
+ case "STRICT_LOCALS_BLOCK_ARGUMENT_ERROR": return StrictLocalsBlockArgumentError.from(error);
1792
+ case "STRICT_LOCALS_SPLAT_ARGUMENT_ERROR": return StrictLocalsSplatArgumentError.from(error);
1793
+ case "STRICT_LOCALS_MISSING_PARENTHESIS_ERROR": return StrictLocalsMissingParenthesisError.from(error);
1794
+ case "STRICT_LOCALS_DUPLICATE_DECLARATION_ERROR": return StrictLocalsDuplicateDeclarationError.from(error);
1795
+ case "VOID_ELEMENT_CONTENT_ERROR": return VoidElementContentError.from(error);
1796
+ case "DOT_NOTATION_CASING_ERROR": return DotNotationCasingError.from(error);
1509
1797
  default:
1510
1798
  throw new Error(`Unknown node type: ${error.type}`);
1511
1799
  }
@@ -20094,7 +20382,7 @@ function deserializePrismNode(bytes, source) {
20094
20382
  }
20095
20383
 
20096
20384
  // NOTE: This file is generated by the templates/template.rb script and should not
20097
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.2/templates/javascript/packages/core/src/nodes.ts.erb
20385
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.4/templates/javascript/packages/core/src/nodes.ts.erb
20098
20386
  class Node {
20099
20387
  type;
20100
20388
  location;
@@ -21715,6 +22003,9 @@ class ERBBlockNode extends Node {
21715
22003
  tag_closing;
21716
22004
  prism_node;
21717
22005
  body;
22006
+ rescue_clause;
22007
+ else_clause;
22008
+ ensure_clause;
21718
22009
  end_node;
21719
22010
  static get type() {
21720
22011
  return "AST_ERB_BLOCK_NODE";
@@ -21729,6 +22020,9 @@ class ERBBlockNode extends Node {
21729
22020
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
21730
22021
  prism_node: data.prism_node ? new Uint8Array(data.prism_node) : null,
21731
22022
  body: (data.body || []).map(node => fromSerializedNode(node)),
22023
+ rescue_clause: data.rescue_clause ? fromSerializedNode((data.rescue_clause)) : null,
22024
+ else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
22025
+ ensure_clause: data.ensure_clause ? fromSerializedNode((data.ensure_clause)) : null,
21732
22026
  end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
21733
22027
  });
21734
22028
  }
@@ -21739,6 +22033,9 @@ class ERBBlockNode extends Node {
21739
22033
  this.tag_closing = props.tag_closing;
21740
22034
  this.prism_node = props.prism_node;
21741
22035
  this.body = props.body;
22036
+ this.rescue_clause = props.rescue_clause;
22037
+ this.else_clause = props.else_clause;
22038
+ this.ensure_clause = props.ensure_clause;
21742
22039
  this.end_node = props.end_node;
21743
22040
  }
21744
22041
  accept(visitor) {
@@ -21747,6 +22044,9 @@ class ERBBlockNode extends Node {
21747
22044
  childNodes() {
21748
22045
  return [
21749
22046
  ...this.body,
22047
+ this.rescue_clause,
22048
+ this.else_clause,
22049
+ this.ensure_clause,
21750
22050
  this.end_node,
21751
22051
  ];
21752
22052
  }
@@ -21762,6 +22062,9 @@ class ERBBlockNode extends Node {
21762
22062
  return [
21763
22063
  ...this.errors,
21764
22064
  ...this.body.map(node => node.recursiveErrors()),
22065
+ this.rescue_clause ? this.rescue_clause.recursiveErrors() : [],
22066
+ this.else_clause ? this.else_clause.recursiveErrors() : [],
22067
+ this.ensure_clause ? this.ensure_clause.recursiveErrors() : [],
21765
22068
  this.end_node ? this.end_node.recursiveErrors() : [],
21766
22069
  ].flat();
21767
22070
  }
@@ -21774,6 +22077,9 @@ class ERBBlockNode extends Node {
21774
22077
  tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
21775
22078
  prism_node: this.prism_node ? Array.from(this.prism_node) : null,
21776
22079
  body: this.body.map(node => node.toJSON()),
22080
+ rescue_clause: this.rescue_clause ? this.rescue_clause.toJSON() : null,
22081
+ else_clause: this.else_clause ? this.else_clause.toJSON() : null,
22082
+ ensure_clause: this.ensure_clause ? this.ensure_clause.toJSON() : null,
21777
22083
  end_node: this.end_node ? this.end_node.toJSON() : null,
21778
22084
  };
21779
22085
  }
@@ -21788,6 +22094,9 @@ class ERBBlockNode extends Node {
21788
22094
  output += `├── prism_node: ${this.source ? inspectPrismSerialized(this.prism_node, this.source, "│ ") : `(${this.prism_node.length} bytes)`}\n`;
21789
22095
  }
21790
22096
  output += `├── body: ${this.inspectArray(this.body, "│ ")}`;
22097
+ output += `├── rescue_clause: ${this.inspectNode(this.rescue_clause, "│ ")}`;
22098
+ output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
22099
+ output += `├── ensure_clause: ${this.inspectNode(this.ensure_clause, "│ ")}`;
21791
22100
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
21792
22101
  return output;
21793
22102
  }
@@ -22857,6 +23166,150 @@ class ERBRenderNode extends Node {
22857
23166
  return output;
22858
23167
  }
22859
23168
  }
23169
+ class RubyStrictLocalNode extends Node {
23170
+ name;
23171
+ default_value;
23172
+ required;
23173
+ double_splat;
23174
+ static get type() {
23175
+ return "AST_RUBY_STRICT_LOCAL_NODE";
23176
+ }
23177
+ static from(data) {
23178
+ return new RubyStrictLocalNode({
23179
+ type: data.type,
23180
+ location: Location.from(data.location),
23181
+ errors: (data.errors || []).map(error => HerbError.from(error)),
23182
+ name: data.name ? Token.from(data.name) : null,
23183
+ default_value: data.default_value ? fromSerializedNode((data.default_value)) : null,
23184
+ required: data.required,
23185
+ double_splat: data.double_splat,
23186
+ });
23187
+ }
23188
+ constructor(props) {
23189
+ super(props.type, props.location, props.errors);
23190
+ this.name = props.name;
23191
+ this.default_value = props.default_value;
23192
+ this.required = props.required;
23193
+ this.double_splat = props.double_splat;
23194
+ }
23195
+ accept(visitor) {
23196
+ visitor.visitRubyStrictLocalNode(this);
23197
+ }
23198
+ childNodes() {
23199
+ return [
23200
+ this.default_value,
23201
+ ];
23202
+ }
23203
+ compactChildNodes() {
23204
+ return this.childNodes().filter(node => node !== null && node !== undefined);
23205
+ }
23206
+ recursiveErrors() {
23207
+ return [
23208
+ ...this.errors,
23209
+ this.default_value ? this.default_value.recursiveErrors() : [],
23210
+ ].flat();
23211
+ }
23212
+ toJSON() {
23213
+ return {
23214
+ ...super.toJSON(),
23215
+ type: "AST_RUBY_STRICT_LOCAL_NODE",
23216
+ name: this.name ? this.name.toJSON() : null,
23217
+ default_value: this.default_value ? this.default_value.toJSON() : null,
23218
+ required: this.required,
23219
+ double_splat: this.double_splat,
23220
+ };
23221
+ }
23222
+ treeInspect() {
23223
+ let output = "";
23224
+ output += `@ RubyStrictLocalNode ${this.location.treeInspectWithLabel()}\n`;
23225
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
23226
+ output += `├── name: ${this.name ? this.name.treeInspect() : "∅"}\n`;
23227
+ output += `├── default_value: ${this.inspectNode(this.default_value, "│ ")}`;
23228
+ output += `├── required: ${typeof this.required === 'boolean' ? String(this.required) : "∅"}\n`;
23229
+ output += `└── double_splat: ${typeof this.double_splat === 'boolean' ? String(this.double_splat) : "∅"}\n`;
23230
+ return output;
23231
+ }
23232
+ }
23233
+ class ERBStrictLocalsNode extends Node {
23234
+ tag_opening;
23235
+ content;
23236
+ tag_closing;
23237
+ // no-op for analyzed_ruby
23238
+ prism_node;
23239
+ locals;
23240
+ static get type() {
23241
+ return "AST_ERB_STRICT_LOCALS_NODE";
23242
+ }
23243
+ static from(data) {
23244
+ return new ERBStrictLocalsNode({
23245
+ type: data.type,
23246
+ location: Location.from(data.location),
23247
+ errors: (data.errors || []).map(error => HerbError.from(error)),
23248
+ tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
23249
+ content: data.content ? Token.from(data.content) : null,
23250
+ tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
23251
+ // no-op for analyzed_ruby
23252
+ prism_node: data.prism_node ? new Uint8Array(data.prism_node) : null,
23253
+ locals: (data.locals || []).map(node => fromSerializedNode(node)),
23254
+ });
23255
+ }
23256
+ constructor(props) {
23257
+ super(props.type, props.location, props.errors);
23258
+ this.tag_opening = props.tag_opening;
23259
+ this.content = props.content;
23260
+ this.tag_closing = props.tag_closing;
23261
+ // no-op for analyzed_ruby
23262
+ this.prism_node = props.prism_node;
23263
+ this.locals = props.locals;
23264
+ }
23265
+ accept(visitor) {
23266
+ visitor.visitERBStrictLocalsNode(this);
23267
+ }
23268
+ childNodes() {
23269
+ return [
23270
+ ...this.locals,
23271
+ ];
23272
+ }
23273
+ compactChildNodes() {
23274
+ return this.childNodes().filter(node => node !== null && node !== undefined);
23275
+ }
23276
+ get prismNode() {
23277
+ if (!this.prism_node || !this.source)
23278
+ return null;
23279
+ return deserializePrismNode(this.prism_node, this.source);
23280
+ }
23281
+ recursiveErrors() {
23282
+ return [
23283
+ ...this.errors,
23284
+ ...this.locals.map(node => node.recursiveErrors()),
23285
+ ].flat();
23286
+ }
23287
+ toJSON() {
23288
+ return {
23289
+ ...super.toJSON(),
23290
+ type: "AST_ERB_STRICT_LOCALS_NODE",
23291
+ tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
23292
+ content: this.content ? this.content.toJSON() : null,
23293
+ tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
23294
+ // no-op for analyzed_ruby
23295
+ prism_node: this.prism_node ? Array.from(this.prism_node) : null,
23296
+ locals: this.locals.map(node => node.toJSON()),
23297
+ };
23298
+ }
23299
+ treeInspect() {
23300
+ let output = "";
23301
+ output += `@ ERBStrictLocalsNode ${this.location.treeInspectWithLabel()}\n`;
23302
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
23303
+ output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
23304
+ output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
23305
+ output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
23306
+ if (this.prism_node) {
23307
+ output += `├── prism_node: ${this.source ? inspectPrismSerialized(this.prism_node, this.source, "│ ") : `(${this.prism_node.length} bytes)`}\n`;
23308
+ }
23309
+ output += `└── locals: ${this.inspectArray(this.locals, " ")}`;
23310
+ return output;
23311
+ }
23312
+ }
22860
23313
  class ERBYieldNode extends Node {
22861
23314
  tag_opening;
22862
23315
  content;
@@ -23022,6 +23475,8 @@ function fromSerializedNode(node) {
23022
23475
  case "AST_ERB_UNLESS_NODE": return ERBUnlessNode.from(node);
23023
23476
  case "AST_RUBY_RENDER_LOCAL_NODE": return RubyRenderLocalNode.from(node);
23024
23477
  case "AST_ERB_RENDER_NODE": return ERBRenderNode.from(node);
23478
+ case "AST_RUBY_STRICT_LOCAL_NODE": return RubyStrictLocalNode.from(node);
23479
+ case "AST_ERB_STRICT_LOCALS_NODE": return ERBStrictLocalsNode.from(node);
23025
23480
  case "AST_ERB_YIELD_NODE": return ERBYieldNode.from(node);
23026
23481
  case "AST_ERB_IN_NODE": return ERBInNode.from(node);
23027
23482
  default:
@@ -23072,9 +23527,12 @@ const DEFAULT_PARSER_OPTIONS = {
23072
23527
  strict: true,
23073
23528
  action_view_helpers: false,
23074
23529
  render_nodes: false,
23530
+ strict_locals: false,
23075
23531
  prism_nodes: false,
23076
23532
  prism_nodes_deep: false,
23077
23533
  prism_program: false,
23534
+ dot_notation_tags: false,
23535
+ html: true,
23078
23536
  };
23079
23537
  /**
23080
23538
  * Represents the parser options used during parsing.
@@ -23090,12 +23548,18 @@ class ParserOptions {
23090
23548
  action_view_helpers;
23091
23549
  /** Whether ActionView render call detection was enabled during parsing. */
23092
23550
  render_nodes;
23551
+ /** Whether strict locals analysis was enabled during parsing. */
23552
+ strict_locals;
23093
23553
  /** Whether Prism node serialization was enabled during parsing. */
23094
23554
  prism_nodes;
23095
23555
  /** Whether deep Prism node serialization was enabled during parsing. */
23096
23556
  prism_nodes_deep;
23097
23557
  /** Whether the full Prism ProgramNode was serialized on the DocumentNode. */
23098
23558
  prism_program;
23559
+ /** Whether dot-notation component tags (e.g. Dialog.Button) are parsed as HTML elements. */
23560
+ dot_notation_tags;
23561
+ /** Whether HTML tag parsing is enabled during parsing. When false, HTML-like content is treated as literal text. */
23562
+ html;
23099
23563
  static from(options) {
23100
23564
  return new ParserOptions(options);
23101
23565
  }
@@ -23105,9 +23569,12 @@ class ParserOptions {
23105
23569
  this.analyze = options.analyze ?? DEFAULT_PARSER_OPTIONS.analyze;
23106
23570
  this.action_view_helpers = options.action_view_helpers ?? DEFAULT_PARSER_OPTIONS.action_view_helpers;
23107
23571
  this.render_nodes = options.render_nodes ?? DEFAULT_PARSER_OPTIONS.render_nodes;
23572
+ this.strict_locals = options.strict_locals ?? DEFAULT_PARSER_OPTIONS.strict_locals;
23108
23573
  this.prism_nodes = options.prism_nodes ?? DEFAULT_PARSER_OPTIONS.prism_nodes;
23109
23574
  this.prism_nodes_deep = options.prism_nodes_deep ?? DEFAULT_PARSER_OPTIONS.prism_nodes_deep;
23110
23575
  this.prism_program = options.prism_program ?? DEFAULT_PARSER_OPTIONS.prism_program;
23576
+ this.dot_notation_tags = options.dot_notation_tags ?? DEFAULT_PARSER_OPTIONS.dot_notation_tags;
23577
+ this.html = options.html ?? DEFAULT_PARSER_OPTIONS.html;
23111
23578
  }
23112
23579
  }
23113
23580
 
@@ -23184,7 +23651,7 @@ class ParseResult extends Result {
23184
23651
  }
23185
23652
 
23186
23653
  // NOTE: This file is generated by the templates/template.rb script and should not
23187
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.2/templates/javascript/packages/core/src/node-type-guards.ts.erb
23654
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.4/templates/javascript/packages/core/src/node-type-guards.ts.erb
23188
23655
  /**
23189
23656
  * Type guard functions for AST nodes.
23190
23657
  * These functions provide type checking by combining both instanceof
@@ -23495,6 +23962,22 @@ function isERBRenderNode(node) {
23495
23962
  return false;
23496
23963
  return node instanceof ERBRenderNode || node.type === "AST_ERB_RENDER_NODE" || node.constructor.type === "AST_ERB_RENDER_NODE";
23497
23964
  }
23965
+ /**
23966
+ * Checks if a node is a RubyStrictLocalNode
23967
+ */
23968
+ function isRubyStrictLocalNode(node) {
23969
+ if (!node)
23970
+ return false;
23971
+ return node instanceof RubyStrictLocalNode || node.type === "AST_RUBY_STRICT_LOCAL_NODE" || node.constructor.type === "AST_RUBY_STRICT_LOCAL_NODE";
23972
+ }
23973
+ /**
23974
+ * Checks if a node is a ERBStrictLocalsNode
23975
+ */
23976
+ function isERBStrictLocalsNode(node) {
23977
+ if (!node)
23978
+ return false;
23979
+ return node instanceof ERBStrictLocalsNode || node.type === "AST_ERB_STRICT_LOCALS_NODE" || node.constructor.type === "AST_ERB_STRICT_LOCALS_NODE";
23980
+ }
23498
23981
  /**
23499
23982
  * Checks if a node is a ERBYieldNode
23500
23983
  */
@@ -23511,6 +23994,31 @@ function isERBInNode(node) {
23511
23994
  return false;
23512
23995
  return node instanceof ERBInNode || node.type === "AST_ERB_IN_NODE" || node.constructor.type === "AST_ERB_IN_NODE";
23513
23996
  }
23997
+ /**
23998
+ * Checks if a node is any ERB node type
23999
+ */
24000
+ function isERBNode(node) {
24001
+ return isERBOpenTagNode(node) ||
24002
+ isERBContentNode(node) ||
24003
+ isERBEndNode(node) ||
24004
+ isERBElseNode(node) ||
24005
+ isERBIfNode(node) ||
24006
+ isERBBlockNode(node) ||
24007
+ isERBWhenNode(node) ||
24008
+ isERBCaseNode(node) ||
24009
+ isERBCaseMatchNode(node) ||
24010
+ isERBWhileNode(node) ||
24011
+ isERBUntilNode(node) ||
24012
+ isERBForNode(node) ||
24013
+ isERBRescueNode(node) ||
24014
+ isERBEnsureNode(node) ||
24015
+ isERBBeginNode(node) ||
24016
+ isERBUnlessNode(node) ||
24017
+ isERBRenderNode(node) ||
24018
+ isERBStrictLocalsNode(node) ||
24019
+ isERBYieldNode(node) ||
24020
+ isERBInNode(node);
24021
+ }
23514
24022
  /**
23515
24023
  * Map of node classes to their corresponding type guard functions
23516
24024
  *
@@ -23560,6 +24068,8 @@ const NODE_TYPE_GUARDS = new Map([
23560
24068
  [ERBUnlessNode, isERBUnlessNode],
23561
24069
  [RubyRenderLocalNode, isRubyRenderLocalNode],
23562
24070
  [ERBRenderNode, isERBRenderNode],
24071
+ [RubyStrictLocalNode, isRubyStrictLocalNode],
24072
+ [ERBStrictLocalsNode, isERBStrictLocalsNode],
23563
24073
  [ERBYieldNode, isERBYieldNode],
23564
24074
  [ERBInNode, isERBInNode],
23565
24075
  ]);
@@ -23612,6 +24122,8 @@ const AST_TYPE_GUARDS = new Map([
23612
24122
  ["AST_ERB_UNLESS_NODE", isERBUnlessNode],
23613
24123
  ["AST_RUBY_RENDER_LOCAL_NODE", isRubyRenderLocalNode],
23614
24124
  ["AST_ERB_RENDER_NODE", isERBRenderNode],
24125
+ ["AST_RUBY_STRICT_LOCAL_NODE", isRubyStrictLocalNode],
24126
+ ["AST_ERB_STRICT_LOCALS_NODE", isERBStrictLocalsNode],
23615
24127
  ["AST_ERB_YIELD_NODE", isERBYieldNode],
23616
24128
  ["AST_ERB_IN_NODE", isERBInNode],
23617
24129
  ]);
@@ -23669,6 +24181,17 @@ function isToken(object) {
23669
24181
  function isParseResult(object) {
23670
24182
  return (object instanceof ParseResult) || (object?.constructor?.name === "ParseResult" && "value" in object);
23671
24183
  }
24184
+
24185
+ /**
24186
+ * Checks if a node is an ERB output node (generates content: <%= %> or <%== %>)
24187
+ */
24188
+ function isERBOutputNode(node) {
24189
+ if (!isERBNode(node))
24190
+ return false;
24191
+ if (!node.tag_opening?.value)
24192
+ return false;
24193
+ return ["<%=", "<%=="].includes(node.tag_opening?.value);
24194
+ }
23672
24195
  /**
23673
24196
  * Extracts a static string from an array of literal nodes
23674
24197
  * Returns null if any node is not a literal node
@@ -23728,12 +24251,88 @@ function getNodesBeforePosition(nodes, position, inclusive = false) {
23728
24251
  function getNodesAfterPosition(nodes, position, inclusive = true) {
23729
24252
  return nodes.filter(node => node.location && isPositionAfter(node.location.start, position, inclusive));
23730
24253
  }
24254
+ // --- AST Mutation Utilities ---
24255
+ const CHILD_ARRAY_PROPS = ["children", "body", "statements", "conditions"];
24256
+ const LINKED_NODE_PROPS = ["subsequent", "else_clause"];
24257
+ /**
24258
+ * Finds the array containing a target node in the AST, along with its index.
24259
+ * Traverses child arrays and linked node properties (e.g., `subsequent`, `else_clause`).
24260
+ *
24261
+ * Useful for autofix operations that need to splice nodes in/out of their parent array.
24262
+ *
24263
+ * @param root - The root node to search from
24264
+ * @param target - The node to find
24265
+ * @returns The containing array and the target's index, or null if not found
24266
+ */
24267
+ function findParentArray(root, target) {
24268
+ const search = (node) => {
24269
+ const record = node;
24270
+ for (const prop of CHILD_ARRAY_PROPS) {
24271
+ const array = record[prop];
24272
+ if (Array.isArray(array)) {
24273
+ const index = array.indexOf(target);
24274
+ if (index !== -1) {
24275
+ return { array, index };
24276
+ }
24277
+ }
24278
+ }
24279
+ for (const prop of CHILD_ARRAY_PROPS) {
24280
+ const array = record[prop];
24281
+ if (Array.isArray(array)) {
24282
+ for (const child of array) {
24283
+ if (child && typeof child === 'object' && 'type' in child) {
24284
+ const result = search(child);
24285
+ if (result) {
24286
+ return result;
24287
+ }
24288
+ }
24289
+ }
24290
+ }
24291
+ }
24292
+ for (const prop of LINKED_NODE_PROPS) {
24293
+ const value = record[prop];
24294
+ if (value && typeof value === 'object' && 'type' in value) {
24295
+ const result = search(value);
24296
+ if (result) {
24297
+ return result;
24298
+ }
24299
+ }
24300
+ }
24301
+ return null;
24302
+ };
24303
+ return search(root);
24304
+ }
24305
+ /**
24306
+ * Creates a synthetic LiteralNode with the given content and zero location.
24307
+ * Useful for inserting whitespace or newlines during AST mutations.
24308
+ */
24309
+ function createLiteral(content) {
24310
+ return new LiteralNode({
24311
+ type: "AST_LITERAL_NODE",
24312
+ content,
24313
+ location: Location.zero,
24314
+ errors: [],
24315
+ });
24316
+ }
23731
24317
  function createSyntheticToken(value, type = "TOKEN_SYNTHETIC") {
23732
24318
  return new Token(value, Range.zero, Location.zero, type);
23733
24319
  }
24320
+ function createERBOutputNode(expression, tagOpening = "<%=", tagClosing = "%>") {
24321
+ return new ERBContentNode({
24322
+ type: "AST_ERB_CONTENT_NODE",
24323
+ tag_opening: createSyntheticToken(tagOpening),
24324
+ content: createSyntheticToken(expression),
24325
+ tag_closing: createSyntheticToken(tagClosing),
24326
+ parsed: false,
24327
+ valid: true,
24328
+ prism_node: null,
24329
+ location: Location.zero,
24330
+ errors: [],
24331
+ });
24332
+ }
23734
24333
 
23735
24334
  // NOTE: This file is generated by the templates/template.rb script and should not
23736
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.2/templates/javascript/packages/core/src/visitor.ts.erb
24335
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.4/templates/javascript/packages/core/src/visitor.ts.erb
23737
24336
  class Visitor {
23738
24337
  visit(node) {
23739
24338
  if (!node)
@@ -23921,6 +24520,15 @@ class Visitor {
23921
24520
  this.visitERBNode(node);
23922
24521
  this.visitChildNodes(node);
23923
24522
  }
24523
+ visitRubyStrictLocalNode(node) {
24524
+ this.visitNode(node);
24525
+ this.visitChildNodes(node);
24526
+ }
24527
+ visitERBStrictLocalsNode(node) {
24528
+ this.visitNode(node);
24529
+ this.visitERBNode(node);
24530
+ this.visitChildNodes(node);
24531
+ }
23924
24532
  visitERBYieldNode(node) {
23925
24533
  this.visitNode(node);
23926
24534
  this.visitERBNode(node);
@@ -23953,6 +24561,34 @@ function createWhitespaceNode() {
23953
24561
  });
23954
24562
  }
23955
24563
  class ActionViewTagHelperToHTMLVisitor extends Visitor {
24564
+ shallow;
24565
+ includeBody;
24566
+ constructor(options = {}) {
24567
+ super();
24568
+ this.shallow = options.shallow ?? false;
24569
+ this.includeBody = options.includeBody ?? true;
24570
+ }
24571
+ visitHTMLOpenTagNode(node) {
24572
+ const newChildren = [];
24573
+ for (let index = 0; index < node.children.length; index++) {
24574
+ const child = node.children[index];
24575
+ if (isHTMLAttributeNode(child)) {
24576
+ if (child.equals && child.equals.value !== "=") {
24577
+ asMutable(child).equals = createSyntheticToken("=");
24578
+ }
24579
+ if (child.value) {
24580
+ this.transformAttributeValue(child.value);
24581
+ }
24582
+ const previous = index > 0 ? node.children[index - 1] : null;
24583
+ if (!previous || !isWhitespaceNode(previous)) {
24584
+ newChildren.push(createWhitespaceNode());
24585
+ }
24586
+ }
24587
+ newChildren.push(child);
24588
+ }
24589
+ asMutable(node).children = newChildren;
24590
+ this.visitChildNodes(node);
24591
+ }
23956
24592
  visitHTMLElementNode(node) {
23957
24593
  if (!node.element_source) {
23958
24594
  this.visitChildNodes(node);
@@ -24023,7 +24659,10 @@ class ActionViewTagHelperToHTMLVisitor extends Visitor {
24023
24659
  asMutable(node).close_tag = htmlCloseTag;
24024
24660
  }
24025
24661
  asMutable(node).element_source = "HTML";
24026
- if (node.body) {
24662
+ if (!this.includeBody) {
24663
+ asMutable(node).body = [];
24664
+ }
24665
+ else if (node.body) {
24027
24666
  asMutable(node).body = node.body.map(child => {
24028
24667
  if (isRubyLiteralNode(child)) {
24029
24668
  return new ERBContentNode({
@@ -24038,7 +24677,9 @@ class ActionViewTagHelperToHTMLVisitor extends Visitor {
24038
24677
  prism_node: null
24039
24678
  });
24040
24679
  }
24041
- this.visit(child);
24680
+ if (!this.shallow) {
24681
+ this.visit(child);
24682
+ }
24042
24683
  return child;
24043
24684
  });
24044
24685
  }
@@ -24064,11 +24705,11 @@ class ActionViewTagHelperToHTMLVisitor extends Visitor {
24064
24705
  return child;
24065
24706
  });
24066
24707
  mutableValue.children = newChildren;
24067
- if (!value.quoted) {
24068
- mutableValue.quoted = true;
24069
- mutableValue.open_quote = createSyntheticToken('"');
24070
- mutableValue.close_quote = createSyntheticToken('"');
24071
- }
24708
+ }
24709
+ if (!value.quoted) {
24710
+ mutableValue.quoted = true;
24711
+ mutableValue.open_quote = createSyntheticToken('"');
24712
+ mutableValue.close_quote = createSyntheticToken('"');
24072
24713
  }
24073
24714
  }
24074
24715
  }
@@ -24079,11 +24720,132 @@ class ActionViewTagHelperToHTMLRewriter extends ASTRewriter {
24079
24720
  get description() {
24080
24721
  return "Converts ActionView tag helpers to raw HTML elements";
24081
24722
  }
24723
+ rewrite(node, context) {
24724
+ const visitor = new ActionViewTagHelperToHTMLVisitor({ shallow: context.shallow, includeBody: context.includeBody });
24725
+ visitor.visit(node);
24726
+ return node;
24727
+ }
24728
+ }
24729
+
24730
+ const STRING_NODE_TYPE = "StringNode";
24731
+ const INTERPOLATED_STRING_NODE_TYPE = "InterpolatedStringNode";
24732
+ const EMBEDDED_STATEMENTS_NODE_TYPE = "EmbeddedStatementsNode";
24733
+ class ERBStringToDirectOutputVisitor extends Visitor {
24734
+ root;
24735
+ constructor(root) {
24736
+ super();
24737
+ this.root = root;
24738
+ }
24739
+ visitERBContentNode(node) {
24740
+ if (!isERBOutputNode(node)) {
24741
+ this.visitChildNodes(node);
24742
+ return;
24743
+ }
24744
+ const prismNode = node.prismNode;
24745
+ if (!prismNode) {
24746
+ this.visitChildNodes(node);
24747
+ return;
24748
+ }
24749
+ const source = node.source;
24750
+ if (!source) {
24751
+ this.visitChildNodes(node);
24752
+ return;
24753
+ }
24754
+ if (!ERBStringToDirectOutputRewriter.isStringOutputNode(prismNode)) {
24755
+ this.visitChildNodes(node);
24756
+ return;
24757
+ }
24758
+ const replacementParts = ERBStringToDirectOutputRewriter.extractReplacementParts(prismNode, source);
24759
+ if (!replacementParts) {
24760
+ this.visitChildNodes(node);
24761
+ return;
24762
+ }
24763
+ const tagOpening = node.tag_opening?.value ?? "<%=";
24764
+ const tagClosing = node.tag_closing?.value ?? "%>";
24765
+ const parentInfo = findParentArray(this.root, node);
24766
+ if (!parentInfo) {
24767
+ this.visitChildNodes(node);
24768
+ return;
24769
+ }
24770
+ const { array: parentArray, index: nodeIndex } = parentInfo;
24771
+ const replacementNodes = [];
24772
+ for (const part of replacementParts) {
24773
+ if (part.type === "text") {
24774
+ replacementNodes.push(createLiteral(part.content));
24775
+ }
24776
+ else {
24777
+ replacementNodes.push(createERBOutputNode(` ${part.expression.trim()} `, tagOpening, tagClosing));
24778
+ }
24779
+ }
24780
+ parentArray.splice(nodeIndex, 1, ...replacementNodes);
24781
+ }
24782
+ }
24783
+ class ERBStringToDirectOutputRewriter extends ASTRewriter {
24784
+ get name() {
24785
+ return "erb-string-to-direct-output";
24786
+ }
24787
+ get description() {
24788
+ return "Replaces ERB string output with direct text and expression tags";
24789
+ }
24082
24790
  rewrite(node, _context) {
24083
- const visitor = new ActionViewTagHelperToHTMLVisitor();
24791
+ const visitor = new ERBStringToDirectOutputVisitor(node);
24084
24792
  visitor.visit(node);
24085
24793
  return node;
24086
24794
  }
24795
+ static isStringOutputNode(prismNode) {
24796
+ const nodeType = prismNode.constructor.name;
24797
+ return nodeType === STRING_NODE_TYPE || nodeType === INTERPOLATED_STRING_NODE_TYPE;
24798
+ }
24799
+ static extractStringContent(stringNode, source) {
24800
+ const unescapedValue = stringNode.unescaped?.value;
24801
+ if (typeof unescapedValue === "string") {
24802
+ return unescapedValue;
24803
+ }
24804
+ const location = stringNode.contentLoc;
24805
+ if (location) {
24806
+ return source.substring(location.startOffset, location.startOffset + location.length);
24807
+ }
24808
+ return "";
24809
+ }
24810
+ static extractExpressionSource(embeddedNode, source) {
24811
+ const openingLocation = embeddedNode.openingLoc;
24812
+ const closingLocation = embeddedNode.closingLoc;
24813
+ if (!openingLocation || !closingLocation)
24814
+ return null;
24815
+ const expressionStart = openingLocation.startOffset + openingLocation.length;
24816
+ const expressionEnd = closingLocation.startOffset;
24817
+ return source.substring(expressionStart, expressionEnd);
24818
+ }
24819
+ static extractReplacementParts(prismNode, source) {
24820
+ const nodeType = prismNode.constructor.name;
24821
+ if (nodeType === STRING_NODE_TYPE) {
24822
+ const textContent = this.extractStringContent(prismNode, source);
24823
+ return [{ type: "text", content: textContent }];
24824
+ }
24825
+ if (nodeType === INTERPOLATED_STRING_NODE_TYPE) {
24826
+ const parts = prismNode.parts;
24827
+ if (!parts || parts.length === 0)
24828
+ return null;
24829
+ const replacementParts = [];
24830
+ for (const part of parts) {
24831
+ const partType = part.constructor.name;
24832
+ if (partType === STRING_NODE_TYPE) {
24833
+ const textContent = this.extractStringContent(part, source);
24834
+ if (textContent) {
24835
+ replacementParts.push({ type: "text", content: textContent });
24836
+ }
24837
+ }
24838
+ else if (partType === EMBEDDED_STATEMENTS_NODE_TYPE) {
24839
+ const expression = this.extractExpressionSource(part, source);
24840
+ if (expression) {
24841
+ replacementParts.push({ type: "expression", expression });
24842
+ }
24843
+ }
24844
+ }
24845
+ return replacementParts.length > 0 ? replacementParts : null;
24846
+ }
24847
+ return null;
24848
+ }
24087
24849
  }
24088
24850
 
24089
24851
  function serializeAttributeValue(value) {
@@ -24173,9 +24935,10 @@ class HTMLToActionViewTagHelperVisitor extends Visitor {
24173
24935
  const isAnchor = tagName.value === "a";
24174
24936
  const isTurboFrame = tagName.value === "turbo-frame";
24175
24937
  const isScript = tagName.value === "script";
24938
+ const isImg = tagName.value === "img";
24176
24939
  const attributes = openTag.children.filter(child => !isWhitespaceNode(child));
24177
- const hasSrcAttribute = isScript && attributes.some(child => isHTMLAttributeNode(child) && getStaticAttributeName(child.name) === "src");
24178
- const { attributes: attributesString, href, id, src } = serializeAttributes(attributes, { extractHref: isAnchor, extractId: isTurboFrame, extractSrc: isScript });
24940
+ const hasSrcAttribute = (isScript || isImg) && attributes.some(child => isHTMLAttributeNode(child) && getStaticAttributeName(child.name) === "src");
24941
+ const { attributes: attributesString, href, id, src } = serializeAttributes(attributes, { extractHref: isAnchor, extractId: isTurboFrame, extractSrc: isScript || isImg });
24179
24942
  const hasBody = node.body && node.body.length > 0 && !node.is_void;
24180
24943
  const isInlineContent = hasBody && isTextOnlyBody(node.body);
24181
24944
  let content;
@@ -24196,6 +24959,10 @@ class HTMLToActionViewTagHelperVisitor extends Visitor {
24196
24959
  content = this.buildJavascriptTagContent(node, attributesString, isInlineContent);
24197
24960
  elementSource = "ActionView::Helpers::JavaScriptHelper#javascript_tag";
24198
24961
  }
24962
+ else if (isImg) {
24963
+ content = this.buildImageTagContent(attributesString, src);
24964
+ elementSource = "ActionView::Helpers::AssetTagHelper#image_tag";
24965
+ }
24199
24966
  else {
24200
24967
  content = this.buildTagContent(tagName.value, node, attributesString, isInlineContent);
24201
24968
  elementSource = "ActionView::Helpers::TagHelper#tag";
@@ -24213,7 +24980,7 @@ class HTMLToActionViewTagHelperVisitor extends Visitor {
24213
24980
  asMutable(node).open_tag = erbOpenTag;
24214
24981
  asMutable(node).element_source = elementSource;
24215
24982
  const isInlineLiteralContent = isScript && hasBody && node.body.length === 1 && isLiteralNode(node.body[0]) && !node.body[0].content.includes("\n");
24216
- const isInlineForm = isInlineContent || isInlineLiteralContent || (isTurboFrame && !hasBody) || (isScript && hasSrcAttribute);
24983
+ const isInlineForm = isInlineContent || isInlineLiteralContent || (isTurboFrame && !hasBody) || (isScript && hasSrcAttribute) || isImg;
24217
24984
  if (node.is_void) {
24218
24985
  asMutable(node).close_tag = null;
24219
24986
  }
@@ -24297,6 +25064,15 @@ class HTMLToActionViewTagHelperVisitor extends Visitor {
24297
25064
  const argString = args.join(", ");
24298
25065
  return argString ? ` javascript_include_tag ${argString} ` : ` javascript_include_tag `;
24299
25066
  }
25067
+ buildImageTagContent(attributes, source) {
25068
+ const args = [];
25069
+ if (source)
25070
+ args.push(source);
25071
+ if (attributes)
25072
+ args.push(attributes);
25073
+ const argString = args.join(", ");
25074
+ return argString ? ` image_tag ${argString} ` : ` image_tag `;
25075
+ }
24300
25076
  buildLinkToContent(node, attribute, href, isInlineContent) {
24301
25077
  const args = [];
24302
25078
  if (isInlineContent && isHTMLTextNode(node.body[0])) {
@@ -24320,7 +25096,7 @@ class HTMLToActionViewTagHelperRewriter extends ASTRewriter {
24320
25096
  return "html-to-action-view-tag-helper";
24321
25097
  }
24322
25098
  get description() {
24323
- return "Converts raw HTML elements to ActionView tag helpers (tag.*, turbo_frame_tag, javascript_tag, javascript_include_tag)";
25099
+ return "Converts raw HTML elements to ActionView tag helpers (tag.*, turbo_frame_tag, javascript_tag, javascript_include_tag, image_tag)";
24324
25100
  }
24325
25101
  rewrite(node, _context) {
24326
25102
  const visitor = new HTMLToActionViewTagHelperVisitor();
@@ -24747,6 +25523,15 @@ class IdentityPrinter extends Printer {
24747
25523
  if (node.body) {
24748
25524
  node.body.forEach(child => this.visit(child));
24749
25525
  }
25526
+ if (node.rescue_clause) {
25527
+ this.visit(node.rescue_clause);
25528
+ }
25529
+ if (node.else_clause) {
25530
+ this.visit(node.else_clause);
25531
+ }
25532
+ if (node.ensure_clause) {
25533
+ this.visit(node.ensure_clause);
25534
+ }
24750
25535
  if (node.end_node) {
24751
25536
  this.visit(node.end_node);
24752
25537
  }
@@ -24850,6 +25635,12 @@ class IdentityPrinter extends Printer {
24850
25635
  visitRubyRenderLocalNode(_node) {
24851
25636
  // extracted metadata, nothing to print
24852
25637
  }
25638
+ visitERBStrictLocalsNode(node) {
25639
+ this.printERBNode(node);
25640
+ }
25641
+ visitRubyStrictLocalNode(_node) {
25642
+ // extracted metadata, nothing to print
25643
+ }
24853
25644
  visitERBYieldNode(node) {
24854
25645
  this.printERBNode(node);
24855
25646
  }
@@ -24978,5 +25769,5 @@ function rewriteString(herb, template, rewriters, options = {}) {
24978
25769
  return output;
24979
25770
  }
24980
25771
 
24981
- export { ASTRewriter, ActionViewTagHelperToHTMLRewriter, HTMLToActionViewTagHelperRewriter, StringRewriter, asMutable, isASTRewriterClass, isRewriterClass, isStringRewriterClass, rewrite, rewriteString };
25772
+ export { ASTRewriter, ActionViewTagHelperToHTMLRewriter, ERBStringToDirectOutputRewriter, HTMLToActionViewTagHelperRewriter, StringRewriter, asMutable, isASTRewriterClass, isRewriterClass, isStringRewriterClass, rewrite, rewriteString };
24982
25773
  //# sourceMappingURL=index.esm.js.map