@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/index.cjs CHANGED
@@ -205,7 +205,7 @@ class Token {
205
205
  }
206
206
 
207
207
  // NOTE: This file is generated by the templates/template.rb script and should not
208
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.4/templates/javascript/packages/core/src/errors.ts.erb
208
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.5/templates/javascript/packages/core/src/errors.ts.erb
209
209
  class HerbError {
210
210
  type;
211
211
  message;
@@ -20353,6 +20353,17 @@ function inspectPrismSerialized(bytes, source, prefix = "") {
20353
20353
  }
20354
20354
  }
20355
20355
 
20356
+ /**
20357
+ * Checks if a Prism node is of a specific type by comparing constructor names.
20358
+ *
20359
+ * This is preferred over `instanceof` because `@ruby/prism` classes may be
20360
+ * duplicated across bundled packages, causing `instanceof` checks to fail.
20361
+ */
20362
+ function isPrismNodeType(node, type) {
20363
+ if (!node)
20364
+ return false;
20365
+ return node.constructor?.name === type;
20366
+ }
20356
20367
  /**
20357
20368
  * Deserialize a Prism parse result from the raw bytes produced by pm_serialize().
20358
20369
  *
@@ -20384,7 +20395,7 @@ function deserializePrismNode(bytes, source) {
20384
20395
  }
20385
20396
 
20386
20397
  // NOTE: This file is generated by the templates/template.rb script and should not
20387
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.4/templates/javascript/packages/core/src/nodes.ts.erb
20398
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.5/templates/javascript/packages/core/src/nodes.ts.erb
20388
20399
  class Node {
20389
20400
  type;
20390
20401
  location;
@@ -22005,6 +22016,7 @@ class ERBBlockNode extends Node {
22005
22016
  tag_closing;
22006
22017
  prism_node;
22007
22018
  body;
22019
+ block_arguments;
22008
22020
  rescue_clause;
22009
22021
  else_clause;
22010
22022
  ensure_clause;
@@ -22022,6 +22034,7 @@ class ERBBlockNode extends Node {
22022
22034
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
22023
22035
  prism_node: data.prism_node ? new Uint8Array(data.prism_node) : null,
22024
22036
  body: (data.body || []).map(node => fromSerializedNode(node)),
22037
+ block_arguments: (data.block_arguments || []).map(node => fromSerializedNode(node)),
22025
22038
  rescue_clause: data.rescue_clause ? fromSerializedNode((data.rescue_clause)) : null,
22026
22039
  else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
22027
22040
  ensure_clause: data.ensure_clause ? fromSerializedNode((data.ensure_clause)) : null,
@@ -22035,6 +22048,7 @@ class ERBBlockNode extends Node {
22035
22048
  this.tag_closing = props.tag_closing;
22036
22049
  this.prism_node = props.prism_node;
22037
22050
  this.body = props.body;
22051
+ this.block_arguments = props.block_arguments;
22038
22052
  this.rescue_clause = props.rescue_clause;
22039
22053
  this.else_clause = props.else_clause;
22040
22054
  this.ensure_clause = props.ensure_clause;
@@ -22046,6 +22060,7 @@ class ERBBlockNode extends Node {
22046
22060
  childNodes() {
22047
22061
  return [
22048
22062
  ...this.body,
22063
+ ...this.block_arguments,
22049
22064
  this.rescue_clause,
22050
22065
  this.else_clause,
22051
22066
  this.ensure_clause,
@@ -22064,6 +22079,7 @@ class ERBBlockNode extends Node {
22064
22079
  return [
22065
22080
  ...this.errors,
22066
22081
  ...this.body.map(node => node.recursiveErrors()),
22082
+ ...this.block_arguments.map(node => node.recursiveErrors()),
22067
22083
  this.rescue_clause ? this.rescue_clause.recursiveErrors() : [],
22068
22084
  this.else_clause ? this.else_clause.recursiveErrors() : [],
22069
22085
  this.ensure_clause ? this.ensure_clause.recursiveErrors() : [],
@@ -22079,6 +22095,7 @@ class ERBBlockNode extends Node {
22079
22095
  tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
22080
22096
  prism_node: this.prism_node ? Array.from(this.prism_node) : null,
22081
22097
  body: this.body.map(node => node.toJSON()),
22098
+ block_arguments: this.block_arguments.map(node => node.toJSON()),
22082
22099
  rescue_clause: this.rescue_clause ? this.rescue_clause.toJSON() : null,
22083
22100
  else_clause: this.else_clause ? this.else_clause.toJSON() : null,
22084
22101
  ensure_clause: this.ensure_clause ? this.ensure_clause.toJSON() : null,
@@ -22096,6 +22113,7 @@ class ERBBlockNode extends Node {
22096
22113
  output += `├── prism_node: ${this.source ? inspectPrismSerialized(this.prism_node, this.source, "│ ") : `(${this.prism_node.length} bytes)`}\n`;
22097
22114
  }
22098
22115
  output += `├── body: ${this.inspectArray(this.body, "│ ")}`;
22116
+ output += `├── block_arguments: ${this.inspectArray(this.block_arguments, "│ ")}`;
22099
22117
  output += `├── rescue_clause: ${this.inspectNode(this.rescue_clause, "│ ")}`;
22100
22118
  output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
22101
22119
  output += `├── ensure_clause: ${this.inspectNode(this.ensure_clause, "│ ")}`;
@@ -23003,12 +23021,7 @@ class RubyRenderLocalNode extends Node {
23003
23021
  return output;
23004
23022
  }
23005
23023
  }
23006
- class ERBRenderNode extends Node {
23007
- tag_opening;
23008
- content;
23009
- tag_closing;
23010
- // no-op for analyzed_ruby
23011
- prism_node;
23024
+ class RubyRenderKeywordsNode extends Node {
23012
23025
  partial;
23013
23026
  template_path;
23014
23027
  layout;
@@ -23028,18 +23041,13 @@ class ERBRenderNode extends Node {
23028
23041
  content_type;
23029
23042
  locals;
23030
23043
  static get type() {
23031
- return "AST_ERB_RENDER_NODE";
23044
+ return "AST_RUBY_RENDER_KEYWORDS_NODE";
23032
23045
  }
23033
23046
  static from(data) {
23034
- return new ERBRenderNode({
23047
+ return new RubyRenderKeywordsNode({
23035
23048
  type: data.type,
23036
23049
  location: Location.from(data.location),
23037
23050
  errors: (data.errors || []).map(error => HerbError.from(error)),
23038
- tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
23039
- content: data.content ? Token.from(data.content) : null,
23040
- tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
23041
- // no-op for analyzed_ruby
23042
- prism_node: data.prism_node ? new Uint8Array(data.prism_node) : null,
23043
23051
  partial: data.partial ? Token.from(data.partial) : null,
23044
23052
  template_path: data.template_path ? Token.from(data.template_path) : null,
23045
23053
  layout: data.layout ? Token.from(data.layout) : null,
@@ -23062,11 +23070,6 @@ class ERBRenderNode extends Node {
23062
23070
  }
23063
23071
  constructor(props) {
23064
23072
  super(props.type, props.location, props.errors);
23065
- this.tag_opening = props.tag_opening;
23066
- this.content = props.content;
23067
- this.tag_closing = props.tag_closing;
23068
- // no-op for analyzed_ruby
23069
- this.prism_node = props.prism_node;
23070
23073
  this.partial = props.partial;
23071
23074
  this.template_path = props.template_path;
23072
23075
  this.layout = props.layout;
@@ -23087,7 +23090,7 @@ class ERBRenderNode extends Node {
23087
23090
  this.locals = props.locals;
23088
23091
  }
23089
23092
  accept(visitor) {
23090
- visitor.visitERBRenderNode(this);
23093
+ visitor.visitRubyRenderKeywordsNode(this);
23091
23094
  }
23092
23095
  childNodes() {
23093
23096
  return [
@@ -23097,11 +23100,6 @@ class ERBRenderNode extends Node {
23097
23100
  compactChildNodes() {
23098
23101
  return this.childNodes().filter(node => node !== null && node !== undefined);
23099
23102
  }
23100
- get prismNode() {
23101
- if (!this.prism_node || !this.source)
23102
- return null;
23103
- return deserializePrismNode(this.prism_node, this.source);
23104
- }
23105
23103
  recursiveErrors() {
23106
23104
  return [
23107
23105
  ...this.errors,
@@ -23111,12 +23109,7 @@ class ERBRenderNode extends Node {
23111
23109
  toJSON() {
23112
23110
  return {
23113
23111
  ...super.toJSON(),
23114
- type: "AST_ERB_RENDER_NODE",
23115
- tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
23116
- content: this.content ? this.content.toJSON() : null,
23117
- tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
23118
- // no-op for analyzed_ruby
23119
- prism_node: this.prism_node ? Array.from(this.prism_node) : null,
23112
+ type: "AST_RUBY_RENDER_KEYWORDS_NODE",
23120
23113
  partial: this.partial ? this.partial.toJSON() : null,
23121
23114
  template_path: this.template_path ? this.template_path.toJSON() : null,
23122
23115
  layout: this.layout ? this.layout.toJSON() : null,
@@ -23139,14 +23132,8 @@ class ERBRenderNode extends Node {
23139
23132
  }
23140
23133
  treeInspect() {
23141
23134
  let output = "";
23142
- output += `@ ERBRenderNode ${this.location.treeInspectWithLabel()}\n`;
23135
+ output += `@ RubyRenderKeywordsNode ${this.location.treeInspectWithLabel()}\n`;
23143
23136
  output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
23144
- output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
23145
- output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
23146
- output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
23147
- if (this.prism_node) {
23148
- output += `├── prism_node: ${this.source ? inspectPrismSerialized(this.prism_node, this.source, "│ ") : `(${this.prism_node.length} bytes)`}\n`;
23149
- }
23150
23137
  output += `├── partial: ${this.partial ? this.partial.treeInspect() : "∅"}\n`;
23151
23138
  output += `├── template_path: ${this.template_path ? this.template_path.treeInspect() : "∅"}\n`;
23152
23139
  output += `├── layout: ${this.layout ? this.layout.treeInspect() : "∅"}\n`;
@@ -23168,34 +23155,156 @@ class ERBRenderNode extends Node {
23168
23155
  return output;
23169
23156
  }
23170
23157
  }
23171
- class RubyStrictLocalNode extends Node {
23158
+ class ERBRenderNode extends Node {
23159
+ tag_opening;
23160
+ content;
23161
+ tag_closing;
23162
+ // no-op for analyzed_ruby
23163
+ prism_node;
23164
+ keywords;
23165
+ body;
23166
+ block_arguments;
23167
+ rescue_clause;
23168
+ else_clause;
23169
+ ensure_clause;
23170
+ end_node;
23171
+ static get type() {
23172
+ return "AST_ERB_RENDER_NODE";
23173
+ }
23174
+ static from(data) {
23175
+ return new ERBRenderNode({
23176
+ type: data.type,
23177
+ location: Location.from(data.location),
23178
+ errors: (data.errors || []).map(error => HerbError.from(error)),
23179
+ tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
23180
+ content: data.content ? Token.from(data.content) : null,
23181
+ tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
23182
+ // no-op for analyzed_ruby
23183
+ prism_node: data.prism_node ? new Uint8Array(data.prism_node) : null,
23184
+ keywords: data.keywords ? fromSerializedNode((data.keywords)) : null,
23185
+ body: (data.body || []).map(node => fromSerializedNode(node)),
23186
+ block_arguments: (data.block_arguments || []).map(node => fromSerializedNode(node)),
23187
+ rescue_clause: data.rescue_clause ? fromSerializedNode((data.rescue_clause)) : null,
23188
+ else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
23189
+ ensure_clause: data.ensure_clause ? fromSerializedNode((data.ensure_clause)) : null,
23190
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
23191
+ });
23192
+ }
23193
+ constructor(props) {
23194
+ super(props.type, props.location, props.errors);
23195
+ this.tag_opening = props.tag_opening;
23196
+ this.content = props.content;
23197
+ this.tag_closing = props.tag_closing;
23198
+ // no-op for analyzed_ruby
23199
+ this.prism_node = props.prism_node;
23200
+ this.keywords = props.keywords;
23201
+ this.body = props.body;
23202
+ this.block_arguments = props.block_arguments;
23203
+ this.rescue_clause = props.rescue_clause;
23204
+ this.else_clause = props.else_clause;
23205
+ this.ensure_clause = props.ensure_clause;
23206
+ this.end_node = props.end_node;
23207
+ }
23208
+ accept(visitor) {
23209
+ visitor.visitERBRenderNode(this);
23210
+ }
23211
+ childNodes() {
23212
+ return [
23213
+ this.keywords,
23214
+ ...this.body,
23215
+ ...this.block_arguments,
23216
+ this.rescue_clause,
23217
+ this.else_clause,
23218
+ this.ensure_clause,
23219
+ this.end_node,
23220
+ ];
23221
+ }
23222
+ compactChildNodes() {
23223
+ return this.childNodes().filter(node => node !== null && node !== undefined);
23224
+ }
23225
+ get prismNode() {
23226
+ if (!this.prism_node || !this.source)
23227
+ return null;
23228
+ return deserializePrismNode(this.prism_node, this.source);
23229
+ }
23230
+ recursiveErrors() {
23231
+ return [
23232
+ ...this.errors,
23233
+ this.keywords ? this.keywords.recursiveErrors() : [],
23234
+ ...this.body.map(node => node.recursiveErrors()),
23235
+ ...this.block_arguments.map(node => node.recursiveErrors()),
23236
+ this.rescue_clause ? this.rescue_clause.recursiveErrors() : [],
23237
+ this.else_clause ? this.else_clause.recursiveErrors() : [],
23238
+ this.ensure_clause ? this.ensure_clause.recursiveErrors() : [],
23239
+ this.end_node ? this.end_node.recursiveErrors() : [],
23240
+ ].flat();
23241
+ }
23242
+ toJSON() {
23243
+ return {
23244
+ ...super.toJSON(),
23245
+ type: "AST_ERB_RENDER_NODE",
23246
+ tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
23247
+ content: this.content ? this.content.toJSON() : null,
23248
+ tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
23249
+ // no-op for analyzed_ruby
23250
+ prism_node: this.prism_node ? Array.from(this.prism_node) : null,
23251
+ keywords: this.keywords ? this.keywords.toJSON() : null,
23252
+ body: this.body.map(node => node.toJSON()),
23253
+ block_arguments: this.block_arguments.map(node => node.toJSON()),
23254
+ rescue_clause: this.rescue_clause ? this.rescue_clause.toJSON() : null,
23255
+ else_clause: this.else_clause ? this.else_clause.toJSON() : null,
23256
+ ensure_clause: this.ensure_clause ? this.ensure_clause.toJSON() : null,
23257
+ end_node: this.end_node ? this.end_node.toJSON() : null,
23258
+ };
23259
+ }
23260
+ treeInspect() {
23261
+ let output = "";
23262
+ output += `@ ERBRenderNode ${this.location.treeInspectWithLabel()}\n`;
23263
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
23264
+ output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
23265
+ output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
23266
+ output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
23267
+ if (this.prism_node) {
23268
+ output += `├── prism_node: ${this.source ? inspectPrismSerialized(this.prism_node, this.source, "│ ") : `(${this.prism_node.length} bytes)`}\n`;
23269
+ }
23270
+ output += `├── keywords: ${this.inspectNode(this.keywords, "│ ")}`;
23271
+ output += `├── body: ${this.inspectArray(this.body, "│ ")}`;
23272
+ output += `├── block_arguments: ${this.inspectArray(this.block_arguments, "│ ")}`;
23273
+ output += `├── rescue_clause: ${this.inspectNode(this.rescue_clause, "│ ")}`;
23274
+ output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
23275
+ output += `├── ensure_clause: ${this.inspectNode(this.ensure_clause, "│ ")}`;
23276
+ output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
23277
+ return output;
23278
+ }
23279
+ }
23280
+ class RubyParameterNode extends Node {
23172
23281
  name;
23173
23282
  default_value;
23283
+ kind;
23174
23284
  required;
23175
- double_splat;
23176
23285
  static get type() {
23177
- return "AST_RUBY_STRICT_LOCAL_NODE";
23286
+ return "AST_RUBY_PARAMETER_NODE";
23178
23287
  }
23179
23288
  static from(data) {
23180
- return new RubyStrictLocalNode({
23289
+ return new RubyParameterNode({
23181
23290
  type: data.type,
23182
23291
  location: Location.from(data.location),
23183
23292
  errors: (data.errors || []).map(error => HerbError.from(error)),
23184
23293
  name: data.name ? Token.from(data.name) : null,
23185
23294
  default_value: data.default_value ? fromSerializedNode((data.default_value)) : null,
23295
+ kind: data.kind,
23186
23296
  required: data.required,
23187
- double_splat: data.double_splat,
23188
23297
  });
23189
23298
  }
23190
23299
  constructor(props) {
23191
23300
  super(props.type, props.location, props.errors);
23192
23301
  this.name = props.name;
23193
23302
  this.default_value = props.default_value;
23303
+ this.kind = props.kind;
23194
23304
  this.required = props.required;
23195
- this.double_splat = props.double_splat;
23196
23305
  }
23197
23306
  accept(visitor) {
23198
- visitor.visitRubyStrictLocalNode(this);
23307
+ visitor.visitRubyParameterNode(this);
23199
23308
  }
23200
23309
  childNodes() {
23201
23310
  return [
@@ -23214,21 +23323,21 @@ class RubyStrictLocalNode extends Node {
23214
23323
  toJSON() {
23215
23324
  return {
23216
23325
  ...super.toJSON(),
23217
- type: "AST_RUBY_STRICT_LOCAL_NODE",
23326
+ type: "AST_RUBY_PARAMETER_NODE",
23218
23327
  name: this.name ? this.name.toJSON() : null,
23219
23328
  default_value: this.default_value ? this.default_value.toJSON() : null,
23329
+ kind: this.kind,
23220
23330
  required: this.required,
23221
- double_splat: this.double_splat,
23222
23331
  };
23223
23332
  }
23224
23333
  treeInspect() {
23225
23334
  let output = "";
23226
- output += `@ RubyStrictLocalNode ${this.location.treeInspectWithLabel()}\n`;
23335
+ output += `@ RubyParameterNode ${this.location.treeInspectWithLabel()}\n`;
23227
23336
  output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
23228
23337
  output += `├── name: ${this.name ? this.name.treeInspect() : "∅"}\n`;
23229
23338
  output += `├── default_value: ${this.inspectNode(this.default_value, "│ ")}`;
23230
- output += `├── required: ${typeof this.required === 'boolean' ? String(this.required) : "∅"}\n`;
23231
- output += `└── double_splat: ${typeof this.double_splat === 'boolean' ? String(this.double_splat) : "∅"}\n`;
23339
+ output += `├── kind: ${this.kind ? JSON.stringify(this.kind) : "∅"}\n`;
23340
+ output += `└── required: ${typeof this.required === 'boolean' ? String(this.required) : "∅"}\n`;
23232
23341
  return output;
23233
23342
  }
23234
23343
  }
@@ -23476,8 +23585,9 @@ function fromSerializedNode(node) {
23476
23585
  case "AST_ERB_BEGIN_NODE": return ERBBeginNode.from(node);
23477
23586
  case "AST_ERB_UNLESS_NODE": return ERBUnlessNode.from(node);
23478
23587
  case "AST_RUBY_RENDER_LOCAL_NODE": return RubyRenderLocalNode.from(node);
23588
+ case "AST_RUBY_RENDER_KEYWORDS_NODE": return RubyRenderKeywordsNode.from(node);
23479
23589
  case "AST_ERB_RENDER_NODE": return ERBRenderNode.from(node);
23480
- case "AST_RUBY_STRICT_LOCAL_NODE": return RubyStrictLocalNode.from(node);
23590
+ case "AST_RUBY_PARAMETER_NODE": return RubyParameterNode.from(node);
23481
23591
  case "AST_ERB_STRICT_LOCALS_NODE": return ERBStrictLocalsNode.from(node);
23482
23592
  case "AST_ERB_YIELD_NODE": return ERBYieldNode.from(node);
23483
23593
  case "AST_ERB_IN_NODE": return ERBInNode.from(node);
@@ -23653,7 +23763,7 @@ class ParseResult extends Result {
23653
23763
  }
23654
23764
 
23655
23765
  // NOTE: This file is generated by the templates/template.rb script and should not
23656
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.4/templates/javascript/packages/core/src/node-type-guards.ts.erb
23766
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.5/templates/javascript/packages/core/src/node-type-guards.ts.erb
23657
23767
  /**
23658
23768
  * Type guard functions for AST nodes.
23659
23769
  * These functions provide type checking by combining both instanceof
@@ -23956,6 +24066,14 @@ function isRubyRenderLocalNode(node) {
23956
24066
  return false;
23957
24067
  return node instanceof RubyRenderLocalNode || node.type === "AST_RUBY_RENDER_LOCAL_NODE" || node.constructor.type === "AST_RUBY_RENDER_LOCAL_NODE";
23958
24068
  }
24069
+ /**
24070
+ * Checks if a node is a RubyRenderKeywordsNode
24071
+ */
24072
+ function isRubyRenderKeywordsNode(node) {
24073
+ if (!node)
24074
+ return false;
24075
+ return node instanceof RubyRenderKeywordsNode || node.type === "AST_RUBY_RENDER_KEYWORDS_NODE" || node.constructor.type === "AST_RUBY_RENDER_KEYWORDS_NODE";
24076
+ }
23959
24077
  /**
23960
24078
  * Checks if a node is a ERBRenderNode
23961
24079
  */
@@ -23965,12 +24083,12 @@ function isERBRenderNode(node) {
23965
24083
  return node instanceof ERBRenderNode || node.type === "AST_ERB_RENDER_NODE" || node.constructor.type === "AST_ERB_RENDER_NODE";
23966
24084
  }
23967
24085
  /**
23968
- * Checks if a node is a RubyStrictLocalNode
24086
+ * Checks if a node is a RubyParameterNode
23969
24087
  */
23970
- function isRubyStrictLocalNode(node) {
24088
+ function isRubyParameterNode(node) {
23971
24089
  if (!node)
23972
24090
  return false;
23973
- return node instanceof RubyStrictLocalNode || node.type === "AST_RUBY_STRICT_LOCAL_NODE" || node.constructor.type === "AST_RUBY_STRICT_LOCAL_NODE";
24091
+ return node instanceof RubyParameterNode || node.type === "AST_RUBY_PARAMETER_NODE" || node.constructor.type === "AST_RUBY_PARAMETER_NODE";
23974
24092
  }
23975
24093
  /**
23976
24094
  * Checks if a node is a ERBStrictLocalsNode
@@ -24069,8 +24187,9 @@ const NODE_TYPE_GUARDS = new Map([
24069
24187
  [ERBBeginNode, isERBBeginNode],
24070
24188
  [ERBUnlessNode, isERBUnlessNode],
24071
24189
  [RubyRenderLocalNode, isRubyRenderLocalNode],
24190
+ [RubyRenderKeywordsNode, isRubyRenderKeywordsNode],
24072
24191
  [ERBRenderNode, isERBRenderNode],
24073
- [RubyStrictLocalNode, isRubyStrictLocalNode],
24192
+ [RubyParameterNode, isRubyParameterNode],
24074
24193
  [ERBStrictLocalsNode, isERBStrictLocalsNode],
24075
24194
  [ERBYieldNode, isERBYieldNode],
24076
24195
  [ERBInNode, isERBInNode],
@@ -24123,8 +24242,9 @@ const AST_TYPE_GUARDS = new Map([
24123
24242
  ["AST_ERB_BEGIN_NODE", isERBBeginNode],
24124
24243
  ["AST_ERB_UNLESS_NODE", isERBUnlessNode],
24125
24244
  ["AST_RUBY_RENDER_LOCAL_NODE", isRubyRenderLocalNode],
24245
+ ["AST_RUBY_RENDER_KEYWORDS_NODE", isRubyRenderKeywordsNode],
24126
24246
  ["AST_ERB_RENDER_NODE", isERBRenderNode],
24127
- ["AST_RUBY_STRICT_LOCAL_NODE", isRubyStrictLocalNode],
24247
+ ["AST_RUBY_PARAMETER_NODE", isRubyParameterNode],
24128
24248
  ["AST_ERB_STRICT_LOCALS_NODE", isERBStrictLocalsNode],
24129
24249
  ["AST_ERB_YIELD_NODE", isERBYieldNode],
24130
24250
  ["AST_ERB_IN_NODE", isERBInNode],
@@ -24334,7 +24454,7 @@ function createERBOutputNode(expression, tagOpening = "<%=", tagClosing = "%>")
24334
24454
  }
24335
24455
 
24336
24456
  // NOTE: This file is generated by the templates/template.rb script and should not
24337
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.4/templates/javascript/packages/core/src/visitor.ts.erb
24457
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.5/templates/javascript/packages/core/src/visitor.ts.erb
24338
24458
  class Visitor {
24339
24459
  visit(node) {
24340
24460
  if (!node)
@@ -24517,12 +24637,16 @@ class Visitor {
24517
24637
  this.visitNode(node);
24518
24638
  this.visitChildNodes(node);
24519
24639
  }
24640
+ visitRubyRenderKeywordsNode(node) {
24641
+ this.visitNode(node);
24642
+ this.visitChildNodes(node);
24643
+ }
24520
24644
  visitERBRenderNode(node) {
24521
24645
  this.visitNode(node);
24522
24646
  this.visitERBNode(node);
24523
24647
  this.visitChildNodes(node);
24524
24648
  }
24525
- visitRubyStrictLocalNode(node) {
24649
+ visitRubyParameterNode(node) {
24526
24650
  this.visitNode(node);
24527
24651
  this.visitChildNodes(node);
24528
24652
  }
@@ -24795,8 +24919,7 @@ class ERBStringToDirectOutputRewriter extends ASTRewriter {
24795
24919
  return node;
24796
24920
  }
24797
24921
  static isStringOutputNode(prismNode) {
24798
- const nodeType = prismNode.constructor.name;
24799
- return nodeType === STRING_NODE_TYPE || nodeType === INTERPOLATED_STRING_NODE_TYPE;
24922
+ return isPrismNodeType(prismNode, STRING_NODE_TYPE) || isPrismNodeType(prismNode, INTERPOLATED_STRING_NODE_TYPE);
24800
24923
  }
24801
24924
  static extractStringContent(stringNode, source) {
24802
24925
  const unescapedValue = stringNode.unescaped?.value;
@@ -24819,25 +24942,23 @@ class ERBStringToDirectOutputRewriter extends ASTRewriter {
24819
24942
  return source.substring(expressionStart, expressionEnd);
24820
24943
  }
24821
24944
  static extractReplacementParts(prismNode, source) {
24822
- const nodeType = prismNode.constructor.name;
24823
- if (nodeType === STRING_NODE_TYPE) {
24945
+ if (isPrismNodeType(prismNode, STRING_NODE_TYPE)) {
24824
24946
  const textContent = this.extractStringContent(prismNode, source);
24825
24947
  return [{ type: "text", content: textContent }];
24826
24948
  }
24827
- if (nodeType === INTERPOLATED_STRING_NODE_TYPE) {
24949
+ if (isPrismNodeType(prismNode, INTERPOLATED_STRING_NODE_TYPE)) {
24828
24950
  const parts = prismNode.parts;
24829
24951
  if (!parts || parts.length === 0)
24830
24952
  return null;
24831
24953
  const replacementParts = [];
24832
24954
  for (const part of parts) {
24833
- const partType = part.constructor.name;
24834
- if (partType === STRING_NODE_TYPE) {
24955
+ if (isPrismNodeType(part, STRING_NODE_TYPE)) {
24835
24956
  const textContent = this.extractStringContent(part, source);
24836
24957
  if (textContent) {
24837
24958
  replacementParts.push({ type: "text", content: textContent });
24838
24959
  }
24839
24960
  }
24840
- else if (partType === EMBEDDED_STATEMENTS_NODE_TYPE) {
24961
+ else if (isPrismNodeType(part, EMBEDDED_STATEMENTS_NODE_TYPE)) {
24841
24962
  const expression = this.extractExpressionSource(part, source);
24842
24963
  if (expression) {
24843
24964
  replacementParts.push({ type: "expression", expression });
@@ -25443,12 +25564,12 @@ class IdentityPrinter extends Printer {
25443
25564
  this.visitChildNodes(node);
25444
25565
  }
25445
25566
  visitHTMLAttributeValueNode(node) {
25446
- if (node.quoted && node.open_quote) {
25447
- this.write(node.open_quote.value);
25567
+ if (node.quoted) {
25568
+ this.write(node.open_quote?.value ?? '"');
25448
25569
  }
25449
25570
  this.visitChildNodes(node);
25450
- if (node.quoted && node.close_quote) {
25451
- this.write(node.close_quote.value);
25571
+ if (node.quoted) {
25572
+ this.write(node.close_quote?.value ?? '"');
25452
25573
  }
25453
25574
  }
25454
25575
  visitRubyLiteralNode(node) {
@@ -25633,6 +25754,24 @@ class IdentityPrinter extends Printer {
25633
25754
  }
25634
25755
  visitERBRenderNode(node) {
25635
25756
  this.printERBNode(node);
25757
+ if (node.end_node) {
25758
+ if (node.body) {
25759
+ node.body.forEach(child => this.visit(child));
25760
+ }
25761
+ if (node.rescue_clause) {
25762
+ this.visit(node.rescue_clause);
25763
+ }
25764
+ if (node.else_clause) {
25765
+ this.visit(node.else_clause);
25766
+ }
25767
+ if (node.ensure_clause) {
25768
+ this.visit(node.ensure_clause);
25769
+ }
25770
+ this.visit(node.end_node);
25771
+ }
25772
+ }
25773
+ visitRubyRenderKeywordsNode(_node) {
25774
+ // no-op: extracted metadata, nothing to print
25636
25775
  }
25637
25776
  visitRubyRenderLocalNode(_node) {
25638
25777
  // extracted metadata, nothing to print
@@ -25640,7 +25779,7 @@ class IdentityPrinter extends Printer {
25640
25779
  visitERBStrictLocalsNode(node) {
25641
25780
  this.printERBNode(node);
25642
25781
  }
25643
- visitRubyStrictLocalNode(_node) {
25782
+ visitRubyParameterNode(_node) {
25644
25783
  // extracted metadata, nothing to print
25645
25784
  }
25646
25785
  visitERBYieldNode(node) {