@herb-tools/rewriter 0.9.4 → 0.9.5

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/loader.cjs CHANGED
@@ -209,7 +209,7 @@ class Token {
209
209
  }
210
210
 
211
211
  // NOTE: This file is generated by the templates/template.rb script and should not
212
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.4/templates/javascript/packages/core/src/errors.ts.erb
212
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.5/templates/javascript/packages/core/src/errors.ts.erb
213
213
  class HerbError {
214
214
  type;
215
215
  message;
@@ -20357,6 +20357,17 @@ function inspectPrismSerialized(bytes, source, prefix = "") {
20357
20357
  }
20358
20358
  }
20359
20359
 
20360
+ /**
20361
+ * Checks if a Prism node is of a specific type by comparing constructor names.
20362
+ *
20363
+ * This is preferred over `instanceof` because `@ruby/prism` classes may be
20364
+ * duplicated across bundled packages, causing `instanceof` checks to fail.
20365
+ */
20366
+ function isPrismNodeType(node, type) {
20367
+ if (!node)
20368
+ return false;
20369
+ return node.constructor?.name === type;
20370
+ }
20360
20371
  /**
20361
20372
  * Deserialize a Prism parse result from the raw bytes produced by pm_serialize().
20362
20373
  *
@@ -20388,7 +20399,7 @@ function deserializePrismNode(bytes, source) {
20388
20399
  }
20389
20400
 
20390
20401
  // NOTE: This file is generated by the templates/template.rb script and should not
20391
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.4/templates/javascript/packages/core/src/nodes.ts.erb
20402
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.5/templates/javascript/packages/core/src/nodes.ts.erb
20392
20403
  class Node {
20393
20404
  type;
20394
20405
  location;
@@ -22009,6 +22020,7 @@ class ERBBlockNode extends Node {
22009
22020
  tag_closing;
22010
22021
  prism_node;
22011
22022
  body;
22023
+ block_arguments;
22012
22024
  rescue_clause;
22013
22025
  else_clause;
22014
22026
  ensure_clause;
@@ -22026,6 +22038,7 @@ class ERBBlockNode extends Node {
22026
22038
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
22027
22039
  prism_node: data.prism_node ? new Uint8Array(data.prism_node) : null,
22028
22040
  body: (data.body || []).map(node => fromSerializedNode(node)),
22041
+ block_arguments: (data.block_arguments || []).map(node => fromSerializedNode(node)),
22029
22042
  rescue_clause: data.rescue_clause ? fromSerializedNode((data.rescue_clause)) : null,
22030
22043
  else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
22031
22044
  ensure_clause: data.ensure_clause ? fromSerializedNode((data.ensure_clause)) : null,
@@ -22039,6 +22052,7 @@ class ERBBlockNode extends Node {
22039
22052
  this.tag_closing = props.tag_closing;
22040
22053
  this.prism_node = props.prism_node;
22041
22054
  this.body = props.body;
22055
+ this.block_arguments = props.block_arguments;
22042
22056
  this.rescue_clause = props.rescue_clause;
22043
22057
  this.else_clause = props.else_clause;
22044
22058
  this.ensure_clause = props.ensure_clause;
@@ -22050,6 +22064,7 @@ class ERBBlockNode extends Node {
22050
22064
  childNodes() {
22051
22065
  return [
22052
22066
  ...this.body,
22067
+ ...this.block_arguments,
22053
22068
  this.rescue_clause,
22054
22069
  this.else_clause,
22055
22070
  this.ensure_clause,
@@ -22068,6 +22083,7 @@ class ERBBlockNode extends Node {
22068
22083
  return [
22069
22084
  ...this.errors,
22070
22085
  ...this.body.map(node => node.recursiveErrors()),
22086
+ ...this.block_arguments.map(node => node.recursiveErrors()),
22071
22087
  this.rescue_clause ? this.rescue_clause.recursiveErrors() : [],
22072
22088
  this.else_clause ? this.else_clause.recursiveErrors() : [],
22073
22089
  this.ensure_clause ? this.ensure_clause.recursiveErrors() : [],
@@ -22083,6 +22099,7 @@ class ERBBlockNode extends Node {
22083
22099
  tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
22084
22100
  prism_node: this.prism_node ? Array.from(this.prism_node) : null,
22085
22101
  body: this.body.map(node => node.toJSON()),
22102
+ block_arguments: this.block_arguments.map(node => node.toJSON()),
22086
22103
  rescue_clause: this.rescue_clause ? this.rescue_clause.toJSON() : null,
22087
22104
  else_clause: this.else_clause ? this.else_clause.toJSON() : null,
22088
22105
  ensure_clause: this.ensure_clause ? this.ensure_clause.toJSON() : null,
@@ -22100,6 +22117,7 @@ class ERBBlockNode extends Node {
22100
22117
  output += `├── prism_node: ${this.source ? inspectPrismSerialized(this.prism_node, this.source, "│ ") : `(${this.prism_node.length} bytes)`}\n`;
22101
22118
  }
22102
22119
  output += `├── body: ${this.inspectArray(this.body, "│ ")}`;
22120
+ output += `├── block_arguments: ${this.inspectArray(this.block_arguments, "│ ")}`;
22103
22121
  output += `├── rescue_clause: ${this.inspectNode(this.rescue_clause, "│ ")}`;
22104
22122
  output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
22105
22123
  output += `├── ensure_clause: ${this.inspectNode(this.ensure_clause, "│ ")}`;
@@ -23007,12 +23025,7 @@ class RubyRenderLocalNode extends Node {
23007
23025
  return output;
23008
23026
  }
23009
23027
  }
23010
- class ERBRenderNode extends Node {
23011
- tag_opening;
23012
- content;
23013
- tag_closing;
23014
- // no-op for analyzed_ruby
23015
- prism_node;
23028
+ class RubyRenderKeywordsNode extends Node {
23016
23029
  partial;
23017
23030
  template_path;
23018
23031
  layout;
@@ -23032,18 +23045,13 @@ class ERBRenderNode extends Node {
23032
23045
  content_type;
23033
23046
  locals;
23034
23047
  static get type() {
23035
- return "AST_ERB_RENDER_NODE";
23048
+ return "AST_RUBY_RENDER_KEYWORDS_NODE";
23036
23049
  }
23037
23050
  static from(data) {
23038
- return new ERBRenderNode({
23051
+ return new RubyRenderKeywordsNode({
23039
23052
  type: data.type,
23040
23053
  location: Location.from(data.location),
23041
23054
  errors: (data.errors || []).map(error => HerbError.from(error)),
23042
- tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
23043
- content: data.content ? Token.from(data.content) : null,
23044
- tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
23045
- // no-op for analyzed_ruby
23046
- prism_node: data.prism_node ? new Uint8Array(data.prism_node) : null,
23047
23055
  partial: data.partial ? Token.from(data.partial) : null,
23048
23056
  template_path: data.template_path ? Token.from(data.template_path) : null,
23049
23057
  layout: data.layout ? Token.from(data.layout) : null,
@@ -23066,11 +23074,6 @@ class ERBRenderNode extends Node {
23066
23074
  }
23067
23075
  constructor(props) {
23068
23076
  super(props.type, props.location, props.errors);
23069
- this.tag_opening = props.tag_opening;
23070
- this.content = props.content;
23071
- this.tag_closing = props.tag_closing;
23072
- // no-op for analyzed_ruby
23073
- this.prism_node = props.prism_node;
23074
23077
  this.partial = props.partial;
23075
23078
  this.template_path = props.template_path;
23076
23079
  this.layout = props.layout;
@@ -23091,7 +23094,7 @@ class ERBRenderNode extends Node {
23091
23094
  this.locals = props.locals;
23092
23095
  }
23093
23096
  accept(visitor) {
23094
- visitor.visitERBRenderNode(this);
23097
+ visitor.visitRubyRenderKeywordsNode(this);
23095
23098
  }
23096
23099
  childNodes() {
23097
23100
  return [
@@ -23101,11 +23104,6 @@ class ERBRenderNode extends Node {
23101
23104
  compactChildNodes() {
23102
23105
  return this.childNodes().filter(node => node !== null && node !== undefined);
23103
23106
  }
23104
- get prismNode() {
23105
- if (!this.prism_node || !this.source)
23106
- return null;
23107
- return deserializePrismNode(this.prism_node, this.source);
23108
- }
23109
23107
  recursiveErrors() {
23110
23108
  return [
23111
23109
  ...this.errors,
@@ -23115,12 +23113,7 @@ class ERBRenderNode extends Node {
23115
23113
  toJSON() {
23116
23114
  return {
23117
23115
  ...super.toJSON(),
23118
- type: "AST_ERB_RENDER_NODE",
23119
- tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
23120
- content: this.content ? this.content.toJSON() : null,
23121
- tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
23122
- // no-op for analyzed_ruby
23123
- prism_node: this.prism_node ? Array.from(this.prism_node) : null,
23116
+ type: "AST_RUBY_RENDER_KEYWORDS_NODE",
23124
23117
  partial: this.partial ? this.partial.toJSON() : null,
23125
23118
  template_path: this.template_path ? this.template_path.toJSON() : null,
23126
23119
  layout: this.layout ? this.layout.toJSON() : null,
@@ -23143,14 +23136,8 @@ class ERBRenderNode extends Node {
23143
23136
  }
23144
23137
  treeInspect() {
23145
23138
  let output = "";
23146
- output += `@ ERBRenderNode ${this.location.treeInspectWithLabel()}\n`;
23139
+ output += `@ RubyRenderKeywordsNode ${this.location.treeInspectWithLabel()}\n`;
23147
23140
  output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
23148
- output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
23149
- output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
23150
- output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
23151
- if (this.prism_node) {
23152
- output += `├── prism_node: ${this.source ? inspectPrismSerialized(this.prism_node, this.source, "│ ") : `(${this.prism_node.length} bytes)`}\n`;
23153
- }
23154
23141
  output += `├── partial: ${this.partial ? this.partial.treeInspect() : "∅"}\n`;
23155
23142
  output += `├── template_path: ${this.template_path ? this.template_path.treeInspect() : "∅"}\n`;
23156
23143
  output += `├── layout: ${this.layout ? this.layout.treeInspect() : "∅"}\n`;
@@ -23172,34 +23159,156 @@ class ERBRenderNode extends Node {
23172
23159
  return output;
23173
23160
  }
23174
23161
  }
23175
- class RubyStrictLocalNode extends Node {
23162
+ class ERBRenderNode extends Node {
23163
+ tag_opening;
23164
+ content;
23165
+ tag_closing;
23166
+ // no-op for analyzed_ruby
23167
+ prism_node;
23168
+ keywords;
23169
+ body;
23170
+ block_arguments;
23171
+ rescue_clause;
23172
+ else_clause;
23173
+ ensure_clause;
23174
+ end_node;
23175
+ static get type() {
23176
+ return "AST_ERB_RENDER_NODE";
23177
+ }
23178
+ static from(data) {
23179
+ return new ERBRenderNode({
23180
+ type: data.type,
23181
+ location: Location.from(data.location),
23182
+ errors: (data.errors || []).map(error => HerbError.from(error)),
23183
+ tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
23184
+ content: data.content ? Token.from(data.content) : null,
23185
+ tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
23186
+ // no-op for analyzed_ruby
23187
+ prism_node: data.prism_node ? new Uint8Array(data.prism_node) : null,
23188
+ keywords: data.keywords ? fromSerializedNode((data.keywords)) : null,
23189
+ body: (data.body || []).map(node => fromSerializedNode(node)),
23190
+ block_arguments: (data.block_arguments || []).map(node => fromSerializedNode(node)),
23191
+ rescue_clause: data.rescue_clause ? fromSerializedNode((data.rescue_clause)) : null,
23192
+ else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
23193
+ ensure_clause: data.ensure_clause ? fromSerializedNode((data.ensure_clause)) : null,
23194
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
23195
+ });
23196
+ }
23197
+ constructor(props) {
23198
+ super(props.type, props.location, props.errors);
23199
+ this.tag_opening = props.tag_opening;
23200
+ this.content = props.content;
23201
+ this.tag_closing = props.tag_closing;
23202
+ // no-op for analyzed_ruby
23203
+ this.prism_node = props.prism_node;
23204
+ this.keywords = props.keywords;
23205
+ this.body = props.body;
23206
+ this.block_arguments = props.block_arguments;
23207
+ this.rescue_clause = props.rescue_clause;
23208
+ this.else_clause = props.else_clause;
23209
+ this.ensure_clause = props.ensure_clause;
23210
+ this.end_node = props.end_node;
23211
+ }
23212
+ accept(visitor) {
23213
+ visitor.visitERBRenderNode(this);
23214
+ }
23215
+ childNodes() {
23216
+ return [
23217
+ this.keywords,
23218
+ ...this.body,
23219
+ ...this.block_arguments,
23220
+ this.rescue_clause,
23221
+ this.else_clause,
23222
+ this.ensure_clause,
23223
+ this.end_node,
23224
+ ];
23225
+ }
23226
+ compactChildNodes() {
23227
+ return this.childNodes().filter(node => node !== null && node !== undefined);
23228
+ }
23229
+ get prismNode() {
23230
+ if (!this.prism_node || !this.source)
23231
+ return null;
23232
+ return deserializePrismNode(this.prism_node, this.source);
23233
+ }
23234
+ recursiveErrors() {
23235
+ return [
23236
+ ...this.errors,
23237
+ this.keywords ? this.keywords.recursiveErrors() : [],
23238
+ ...this.body.map(node => node.recursiveErrors()),
23239
+ ...this.block_arguments.map(node => node.recursiveErrors()),
23240
+ this.rescue_clause ? this.rescue_clause.recursiveErrors() : [],
23241
+ this.else_clause ? this.else_clause.recursiveErrors() : [],
23242
+ this.ensure_clause ? this.ensure_clause.recursiveErrors() : [],
23243
+ this.end_node ? this.end_node.recursiveErrors() : [],
23244
+ ].flat();
23245
+ }
23246
+ toJSON() {
23247
+ return {
23248
+ ...super.toJSON(),
23249
+ type: "AST_ERB_RENDER_NODE",
23250
+ tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
23251
+ content: this.content ? this.content.toJSON() : null,
23252
+ tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
23253
+ // no-op for analyzed_ruby
23254
+ prism_node: this.prism_node ? Array.from(this.prism_node) : null,
23255
+ keywords: this.keywords ? this.keywords.toJSON() : null,
23256
+ body: this.body.map(node => node.toJSON()),
23257
+ block_arguments: this.block_arguments.map(node => node.toJSON()),
23258
+ rescue_clause: this.rescue_clause ? this.rescue_clause.toJSON() : null,
23259
+ else_clause: this.else_clause ? this.else_clause.toJSON() : null,
23260
+ ensure_clause: this.ensure_clause ? this.ensure_clause.toJSON() : null,
23261
+ end_node: this.end_node ? this.end_node.toJSON() : null,
23262
+ };
23263
+ }
23264
+ treeInspect() {
23265
+ let output = "";
23266
+ output += `@ ERBRenderNode ${this.location.treeInspectWithLabel()}\n`;
23267
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
23268
+ output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
23269
+ output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
23270
+ output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
23271
+ if (this.prism_node) {
23272
+ output += `├── prism_node: ${this.source ? inspectPrismSerialized(this.prism_node, this.source, "│ ") : `(${this.prism_node.length} bytes)`}\n`;
23273
+ }
23274
+ output += `├── keywords: ${this.inspectNode(this.keywords, "│ ")}`;
23275
+ output += `├── body: ${this.inspectArray(this.body, "│ ")}`;
23276
+ output += `├── block_arguments: ${this.inspectArray(this.block_arguments, "│ ")}`;
23277
+ output += `├── rescue_clause: ${this.inspectNode(this.rescue_clause, "│ ")}`;
23278
+ output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
23279
+ output += `├── ensure_clause: ${this.inspectNode(this.ensure_clause, "│ ")}`;
23280
+ output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
23281
+ return output;
23282
+ }
23283
+ }
23284
+ class RubyParameterNode extends Node {
23176
23285
  name;
23177
23286
  default_value;
23287
+ kind;
23178
23288
  required;
23179
- double_splat;
23180
23289
  static get type() {
23181
- return "AST_RUBY_STRICT_LOCAL_NODE";
23290
+ return "AST_RUBY_PARAMETER_NODE";
23182
23291
  }
23183
23292
  static from(data) {
23184
- return new RubyStrictLocalNode({
23293
+ return new RubyParameterNode({
23185
23294
  type: data.type,
23186
23295
  location: Location.from(data.location),
23187
23296
  errors: (data.errors || []).map(error => HerbError.from(error)),
23188
23297
  name: data.name ? Token.from(data.name) : null,
23189
23298
  default_value: data.default_value ? fromSerializedNode((data.default_value)) : null,
23299
+ kind: data.kind,
23190
23300
  required: data.required,
23191
- double_splat: data.double_splat,
23192
23301
  });
23193
23302
  }
23194
23303
  constructor(props) {
23195
23304
  super(props.type, props.location, props.errors);
23196
23305
  this.name = props.name;
23197
23306
  this.default_value = props.default_value;
23307
+ this.kind = props.kind;
23198
23308
  this.required = props.required;
23199
- this.double_splat = props.double_splat;
23200
23309
  }
23201
23310
  accept(visitor) {
23202
- visitor.visitRubyStrictLocalNode(this);
23311
+ visitor.visitRubyParameterNode(this);
23203
23312
  }
23204
23313
  childNodes() {
23205
23314
  return [
@@ -23218,21 +23327,21 @@ class RubyStrictLocalNode extends Node {
23218
23327
  toJSON() {
23219
23328
  return {
23220
23329
  ...super.toJSON(),
23221
- type: "AST_RUBY_STRICT_LOCAL_NODE",
23330
+ type: "AST_RUBY_PARAMETER_NODE",
23222
23331
  name: this.name ? this.name.toJSON() : null,
23223
23332
  default_value: this.default_value ? this.default_value.toJSON() : null,
23333
+ kind: this.kind,
23224
23334
  required: this.required,
23225
- double_splat: this.double_splat,
23226
23335
  };
23227
23336
  }
23228
23337
  treeInspect() {
23229
23338
  let output = "";
23230
- output += `@ RubyStrictLocalNode ${this.location.treeInspectWithLabel()}\n`;
23339
+ output += `@ RubyParameterNode ${this.location.treeInspectWithLabel()}\n`;
23231
23340
  output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
23232
23341
  output += `├── name: ${this.name ? this.name.treeInspect() : "∅"}\n`;
23233
23342
  output += `├── default_value: ${this.inspectNode(this.default_value, "│ ")}`;
23234
- output += `├── required: ${typeof this.required === 'boolean' ? String(this.required) : "∅"}\n`;
23235
- output += `└── double_splat: ${typeof this.double_splat === 'boolean' ? String(this.double_splat) : "∅"}\n`;
23343
+ output += `├── kind: ${this.kind ? JSON.stringify(this.kind) : "∅"}\n`;
23344
+ output += `└── required: ${typeof this.required === 'boolean' ? String(this.required) : "∅"}\n`;
23236
23345
  return output;
23237
23346
  }
23238
23347
  }
@@ -23480,8 +23589,9 @@ function fromSerializedNode(node) {
23480
23589
  case "AST_ERB_BEGIN_NODE": return ERBBeginNode.from(node);
23481
23590
  case "AST_ERB_UNLESS_NODE": return ERBUnlessNode.from(node);
23482
23591
  case "AST_RUBY_RENDER_LOCAL_NODE": return RubyRenderLocalNode.from(node);
23592
+ case "AST_RUBY_RENDER_KEYWORDS_NODE": return RubyRenderKeywordsNode.from(node);
23483
23593
  case "AST_ERB_RENDER_NODE": return ERBRenderNode.from(node);
23484
- case "AST_RUBY_STRICT_LOCAL_NODE": return RubyStrictLocalNode.from(node);
23594
+ case "AST_RUBY_PARAMETER_NODE": return RubyParameterNode.from(node);
23485
23595
  case "AST_ERB_STRICT_LOCALS_NODE": return ERBStrictLocalsNode.from(node);
23486
23596
  case "AST_ERB_YIELD_NODE": return ERBYieldNode.from(node);
23487
23597
  case "AST_ERB_IN_NODE": return ERBInNode.from(node);
@@ -23657,7 +23767,7 @@ class ParseResult extends Result {
23657
23767
  }
23658
23768
 
23659
23769
  // NOTE: This file is generated by the templates/template.rb script and should not
23660
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.4/templates/javascript/packages/core/src/node-type-guards.ts.erb
23770
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.5/templates/javascript/packages/core/src/node-type-guards.ts.erb
23661
23771
  /**
23662
23772
  * Type guard functions for AST nodes.
23663
23773
  * These functions provide type checking by combining both instanceof
@@ -23960,6 +24070,14 @@ function isRubyRenderLocalNode(node) {
23960
24070
  return false;
23961
24071
  return node instanceof RubyRenderLocalNode || node.type === "AST_RUBY_RENDER_LOCAL_NODE" || node.constructor.type === "AST_RUBY_RENDER_LOCAL_NODE";
23962
24072
  }
24073
+ /**
24074
+ * Checks if a node is a RubyRenderKeywordsNode
24075
+ */
24076
+ function isRubyRenderKeywordsNode(node) {
24077
+ if (!node)
24078
+ return false;
24079
+ return node instanceof RubyRenderKeywordsNode || node.type === "AST_RUBY_RENDER_KEYWORDS_NODE" || node.constructor.type === "AST_RUBY_RENDER_KEYWORDS_NODE";
24080
+ }
23963
24081
  /**
23964
24082
  * Checks if a node is a ERBRenderNode
23965
24083
  */
@@ -23969,12 +24087,12 @@ function isERBRenderNode(node) {
23969
24087
  return node instanceof ERBRenderNode || node.type === "AST_ERB_RENDER_NODE" || node.constructor.type === "AST_ERB_RENDER_NODE";
23970
24088
  }
23971
24089
  /**
23972
- * Checks if a node is a RubyStrictLocalNode
24090
+ * Checks if a node is a RubyParameterNode
23973
24091
  */
23974
- function isRubyStrictLocalNode(node) {
24092
+ function isRubyParameterNode(node) {
23975
24093
  if (!node)
23976
24094
  return false;
23977
- return node instanceof RubyStrictLocalNode || node.type === "AST_RUBY_STRICT_LOCAL_NODE" || node.constructor.type === "AST_RUBY_STRICT_LOCAL_NODE";
24095
+ return node instanceof RubyParameterNode || node.type === "AST_RUBY_PARAMETER_NODE" || node.constructor.type === "AST_RUBY_PARAMETER_NODE";
23978
24096
  }
23979
24097
  /**
23980
24098
  * Checks if a node is a ERBStrictLocalsNode
@@ -24073,8 +24191,9 @@ const NODE_TYPE_GUARDS = new Map([
24073
24191
  [ERBBeginNode, isERBBeginNode],
24074
24192
  [ERBUnlessNode, isERBUnlessNode],
24075
24193
  [RubyRenderLocalNode, isRubyRenderLocalNode],
24194
+ [RubyRenderKeywordsNode, isRubyRenderKeywordsNode],
24076
24195
  [ERBRenderNode, isERBRenderNode],
24077
- [RubyStrictLocalNode, isRubyStrictLocalNode],
24196
+ [RubyParameterNode, isRubyParameterNode],
24078
24197
  [ERBStrictLocalsNode, isERBStrictLocalsNode],
24079
24198
  [ERBYieldNode, isERBYieldNode],
24080
24199
  [ERBInNode, isERBInNode],
@@ -24127,8 +24246,9 @@ const AST_TYPE_GUARDS = new Map([
24127
24246
  ["AST_ERB_BEGIN_NODE", isERBBeginNode],
24128
24247
  ["AST_ERB_UNLESS_NODE", isERBUnlessNode],
24129
24248
  ["AST_RUBY_RENDER_LOCAL_NODE", isRubyRenderLocalNode],
24249
+ ["AST_RUBY_RENDER_KEYWORDS_NODE", isRubyRenderKeywordsNode],
24130
24250
  ["AST_ERB_RENDER_NODE", isERBRenderNode],
24131
- ["AST_RUBY_STRICT_LOCAL_NODE", isRubyStrictLocalNode],
24251
+ ["AST_RUBY_PARAMETER_NODE", isRubyParameterNode],
24132
24252
  ["AST_ERB_STRICT_LOCALS_NODE", isERBStrictLocalsNode],
24133
24253
  ["AST_ERB_YIELD_NODE", isERBYieldNode],
24134
24254
  ["AST_ERB_IN_NODE", isERBInNode],
@@ -24443,7 +24563,7 @@ function createERBOutputNode(expression, tagOpening = "<%=", tagClosing = "%>")
24443
24563
  }
24444
24564
 
24445
24565
  // NOTE: This file is generated by the templates/template.rb script and should not
24446
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.4/templates/javascript/packages/core/src/visitor.ts.erb
24566
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.5/templates/javascript/packages/core/src/visitor.ts.erb
24447
24567
  class Visitor {
24448
24568
  visit(node) {
24449
24569
  if (!node)
@@ -24626,12 +24746,16 @@ class Visitor {
24626
24746
  this.visitNode(node);
24627
24747
  this.visitChildNodes(node);
24628
24748
  }
24749
+ visitRubyRenderKeywordsNode(node) {
24750
+ this.visitNode(node);
24751
+ this.visitChildNodes(node);
24752
+ }
24629
24753
  visitERBRenderNode(node) {
24630
24754
  this.visitNode(node);
24631
24755
  this.visitERBNode(node);
24632
24756
  this.visitChildNodes(node);
24633
24757
  }
24634
- visitRubyStrictLocalNode(node) {
24758
+ visitRubyParameterNode(node) {
24635
24759
  this.visitNode(node);
24636
24760
  this.visitChildNodes(node);
24637
24761
  }
@@ -24904,8 +25028,7 @@ class ERBStringToDirectOutputRewriter extends ASTRewriter {
24904
25028
  return node;
24905
25029
  }
24906
25030
  static isStringOutputNode(prismNode) {
24907
- const nodeType = prismNode.constructor.name;
24908
- return nodeType === STRING_NODE_TYPE || nodeType === INTERPOLATED_STRING_NODE_TYPE;
25031
+ return isPrismNodeType(prismNode, STRING_NODE_TYPE) || isPrismNodeType(prismNode, INTERPOLATED_STRING_NODE_TYPE);
24909
25032
  }
24910
25033
  static extractStringContent(stringNode, source) {
24911
25034
  const unescapedValue = stringNode.unescaped?.value;
@@ -24928,25 +25051,23 @@ class ERBStringToDirectOutputRewriter extends ASTRewriter {
24928
25051
  return source.substring(expressionStart, expressionEnd);
24929
25052
  }
24930
25053
  static extractReplacementParts(prismNode, source) {
24931
- const nodeType = prismNode.constructor.name;
24932
- if (nodeType === STRING_NODE_TYPE) {
25054
+ if (isPrismNodeType(prismNode, STRING_NODE_TYPE)) {
24933
25055
  const textContent = this.extractStringContent(prismNode, source);
24934
25056
  return [{ type: "text", content: textContent }];
24935
25057
  }
24936
- if (nodeType === INTERPOLATED_STRING_NODE_TYPE) {
25058
+ if (isPrismNodeType(prismNode, INTERPOLATED_STRING_NODE_TYPE)) {
24937
25059
  const parts = prismNode.parts;
24938
25060
  if (!parts || parts.length === 0)
24939
25061
  return null;
24940
25062
  const replacementParts = [];
24941
25063
  for (const part of parts) {
24942
- const partType = part.constructor.name;
24943
- if (partType === STRING_NODE_TYPE) {
25064
+ if (isPrismNodeType(part, STRING_NODE_TYPE)) {
24944
25065
  const textContent = this.extractStringContent(part, source);
24945
25066
  if (textContent) {
24946
25067
  replacementParts.push({ type: "text", content: textContent });
24947
25068
  }
24948
25069
  }
24949
- else if (partType === EMBEDDED_STATEMENTS_NODE_TYPE) {
25070
+ else if (isPrismNodeType(part, EMBEDDED_STATEMENTS_NODE_TYPE)) {
24950
25071
  const expression = this.extractExpressionSource(part, source);
24951
25072
  if (expression) {
24952
25073
  replacementParts.push({ type: "expression", expression });
@@ -25552,12 +25673,12 @@ class IdentityPrinter extends Printer {
25552
25673
  this.visitChildNodes(node);
25553
25674
  }
25554
25675
  visitHTMLAttributeValueNode(node) {
25555
- if (node.quoted && node.open_quote) {
25556
- this.write(node.open_quote.value);
25676
+ if (node.quoted) {
25677
+ this.write(node.open_quote?.value ?? '"');
25557
25678
  }
25558
25679
  this.visitChildNodes(node);
25559
- if (node.quoted && node.close_quote) {
25560
- this.write(node.close_quote.value);
25680
+ if (node.quoted) {
25681
+ this.write(node.close_quote?.value ?? '"');
25561
25682
  }
25562
25683
  }
25563
25684
  visitRubyLiteralNode(node) {
@@ -25742,6 +25863,24 @@ class IdentityPrinter extends Printer {
25742
25863
  }
25743
25864
  visitERBRenderNode(node) {
25744
25865
  this.printERBNode(node);
25866
+ if (node.end_node) {
25867
+ if (node.body) {
25868
+ node.body.forEach(child => this.visit(child));
25869
+ }
25870
+ if (node.rescue_clause) {
25871
+ this.visit(node.rescue_clause);
25872
+ }
25873
+ if (node.else_clause) {
25874
+ this.visit(node.else_clause);
25875
+ }
25876
+ if (node.ensure_clause) {
25877
+ this.visit(node.ensure_clause);
25878
+ }
25879
+ this.visit(node.end_node);
25880
+ }
25881
+ }
25882
+ visitRubyRenderKeywordsNode(_node) {
25883
+ // no-op: extracted metadata, nothing to print
25745
25884
  }
25746
25885
  visitRubyRenderLocalNode(_node) {
25747
25886
  // extracted metadata, nothing to print
@@ -25749,7 +25888,7 @@ class IdentityPrinter extends Printer {
25749
25888
  visitERBStrictLocalsNode(node) {
25750
25889
  this.printERBNode(node);
25751
25890
  }
25752
- visitRubyStrictLocalNode(_node) {
25891
+ visitRubyParameterNode(_node) {
25753
25892
  // extracted metadata, nothing to print
25754
25893
  }
25755
25894
  visitERBYieldNode(node) {