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