@herb-tools/core 0.8.9 → 0.9.0

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/src/nodes.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  // NOTE: This file is generated by the templates/template.rb script and should not
2
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.8.9/templates/javascript/packages/core/src/nodes.ts.erb
2
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.0/templates/javascript/packages/core/src/nodes.ts.erb
3
3
 
4
4
  import { Location } from "./location.js"
5
5
  import { Token, SerializedToken } from "./token.js"
6
6
  import { HerbError } from "./errors.js"
7
- import { convertToUTF8 } from "./util.js"
7
+ import { deserializePrismNode, inspectPrismSerialized } from "./prism/index.js"
8
+ import type { PrismNode } from "./prism/index.js"
8
9
 
9
10
  import type { SerializedLocation } from "./location.js"
10
11
  import type { SerializedHerbError } from "./errors.js"
@@ -28,6 +29,7 @@ export abstract class Node implements BaseNodeProps {
28
29
  readonly type: NodeType
29
30
  readonly location: Location
30
31
  readonly errors: HerbError[]
32
+ source: string | null = null
31
33
 
32
34
  static from(node: SerializedNode): Node {
33
35
  return fromSerializedNode(node)
@@ -43,6 +45,11 @@ export abstract class Node implements BaseNodeProps {
43
45
  this.errors = errors
44
46
  }
45
47
 
48
+ setSource(source: string): void {
49
+ this.source = source
50
+ this.compactChildNodes().forEach(child => child.setSource(source))
51
+ }
52
+
46
53
  toJSON(): SerializedNode {
47
54
  return {
48
55
  type: this.type,
@@ -136,14 +143,22 @@ export abstract class Node implements BaseNodeProps {
136
143
  export interface SerializedDocumentNode extends SerializedNode {
137
144
  type: "AST_DOCUMENT_NODE";
138
145
  children: SerializedNode[];
146
+ // no-op for prism_context
147
+ prism_node: number[] | null;
139
148
  }
140
149
 
141
- export interface DocumentNodeProps extends BaseNodeProps {
150
+ export interface DocumentNodeProps extends Omit<BaseNodeProps, 'type'> {
151
+ type: "AST_DOCUMENT_NODE";
142
152
  children: Node[];
153
+ // no-op for prism_context
154
+ prism_node: Uint8Array | null;
143
155
  }
144
156
 
145
157
  export class DocumentNode extends Node {
158
+ declare readonly type: "AST_DOCUMENT_NODE";
146
159
  readonly children: Node[];
160
+ // no-op for prism_context
161
+ readonly prism_node: Uint8Array | null;
147
162
 
148
163
  static get type(): NodeType {
149
164
  return "AST_DOCUMENT_NODE"
@@ -155,12 +170,16 @@ export class DocumentNode extends Node {
155
170
  location: Location.from(data.location),
156
171
  errors: (data.errors || []).map(error => HerbError.from(error)),
157
172
  children: (data.children || []).map(node => fromSerializedNode(node)),
173
+ // no-op for prism_context
174
+ prism_node: data.prism_node ? new Uint8Array(data.prism_node) : null,
158
175
  })
159
176
  }
160
177
 
161
178
  constructor(props: DocumentNodeProps) {
162
179
  super(props.type, props.location, props.errors);
163
180
  this.children = props.children;
181
+ // no-op for prism_context
182
+ this.prism_node = props.prism_node;
164
183
  }
165
184
 
166
185
  accept(visitor: Visitor): void {
@@ -177,6 +196,11 @@ export class DocumentNode extends Node {
177
196
  return this.childNodes().filter(node => node !== null && node !== undefined)
178
197
  }
179
198
 
199
+ get prismNode(): PrismNode | null {
200
+ if (!this.prism_node || !this.source) return null;
201
+ return deserializePrismNode(this.prism_node, this.source);
202
+ }
203
+
180
204
  recursiveErrors(): HerbError[] {
181
205
  return [
182
206
  ...this.errors,
@@ -189,6 +213,8 @@ export class DocumentNode extends Node {
189
213
  ...super.toJSON(),
190
214
  type: "AST_DOCUMENT_NODE",
191
215
  children: this.children.map(node => node.toJSON()),
216
+ // no-op for prism_context
217
+ prism_node: this.prism_node ? Array.from(this.prism_node) : null,
192
218
  };
193
219
  }
194
220
 
@@ -197,7 +223,15 @@ export class DocumentNode extends Node {
197
223
 
198
224
  output += `@ DocumentNode ${this.location.treeInspectWithLabel()}\n`;
199
225
  output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
200
- output += `└── children: ${this.inspectArray(this.children, " ")}`;
226
+ {
227
+ const isLast = !this.prism_node;
228
+ const symbol = isLast ? "└──" : "├──";
229
+ const childPrefix = isLast ? " " : "│ ";
230
+ output += `${symbol} children: ${this.inspectArray(this.children, childPrefix)}`;
231
+ }
232
+ if (this.prism_node) {
233
+ output += `└── prism_node: ${this.source ? inspectPrismSerialized(this.prism_node, this.source, " ") : `(${this.prism_node.length} bytes)`}\n`;
234
+ }
201
235
 
202
236
  return output
203
237
  }
@@ -208,11 +242,13 @@ export interface SerializedLiteralNode extends SerializedNode {
208
242
  content: string;
209
243
  }
210
244
 
211
- export interface LiteralNodeProps extends BaseNodeProps {
245
+ export interface LiteralNodeProps extends Omit<BaseNodeProps, 'type'> {
246
+ type: "AST_LITERAL_NODE";
212
247
  content: string;
213
248
  }
214
249
 
215
250
  export class LiteralNode extends Node {
251
+ declare readonly type: "AST_LITERAL_NODE";
216
252
  readonly content: string;
217
253
 
218
254
  static get type(): NodeType {
@@ -230,7 +266,7 @@ export class LiteralNode extends Node {
230
266
 
231
267
  constructor(props: LiteralNodeProps) {
232
268
  super(props.type, props.location, props.errors);
233
- this.content = convertToUTF8(props.content);
269
+ this.content = props.content;
234
270
  }
235
271
 
236
272
  accept(visitor: Visitor): void {
@@ -246,6 +282,7 @@ export class LiteralNode extends Node {
246
282
  return this.childNodes().filter(node => node !== null && node !== undefined)
247
283
  }
248
284
 
285
+
249
286
  recursiveErrors(): HerbError[] {
250
287
  return [
251
288
  ...this.errors,
@@ -280,7 +317,8 @@ export interface SerializedHTMLOpenTagNode extends SerializedNode {
280
317
  is_void: boolean;
281
318
  }
282
319
 
283
- export interface HTMLOpenTagNodeProps extends BaseNodeProps {
320
+ export interface HTMLOpenTagNodeProps extends Omit<BaseNodeProps, 'type'> {
321
+ type: "AST_HTML_OPEN_TAG_NODE";
284
322
  tag_opening: Token | null;
285
323
  tag_name: Token | null;
286
324
  tag_closing: Token | null;
@@ -289,6 +327,7 @@ export interface HTMLOpenTagNodeProps extends BaseNodeProps {
289
327
  }
290
328
 
291
329
  export class HTMLOpenTagNode extends Node {
330
+ declare readonly type: "AST_HTML_OPEN_TAG_NODE";
292
331
  readonly tag_opening: Token | null;
293
332
  readonly tag_name: Token | null;
294
333
  readonly tag_closing: Token | null;
@@ -335,6 +374,7 @@ export class HTMLOpenTagNode extends Node {
335
374
  return this.childNodes().filter(node => node !== null && node !== undefined)
336
375
  }
337
376
 
377
+
338
378
  recursiveErrors(): HerbError[] {
339
379
  return [
340
380
  ...this.errors,
@@ -369,6 +409,93 @@ export class HTMLOpenTagNode extends Node {
369
409
  }
370
410
  }
371
411
 
412
+ export interface SerializedHTMLConditionalOpenTagNode extends SerializedNode {
413
+ type: "AST_HTML_CONDITIONAL_OPEN_TAG_NODE";
414
+ conditional: SerializedERBIfNode | SerializedERBUnlessNode | null;
415
+ tag_name: SerializedToken | null;
416
+ is_void: boolean;
417
+ }
418
+
419
+ export interface HTMLConditionalOpenTagNodeProps extends Omit<BaseNodeProps, 'type'> {
420
+ type: "AST_HTML_CONDITIONAL_OPEN_TAG_NODE";
421
+ conditional: ERBIfNode | ERBUnlessNode | null;
422
+ tag_name: Token | null;
423
+ is_void: boolean;
424
+ }
425
+
426
+ export class HTMLConditionalOpenTagNode extends Node {
427
+ declare readonly type: "AST_HTML_CONDITIONAL_OPEN_TAG_NODE";
428
+ readonly conditional: ERBIfNode | ERBUnlessNode | null;
429
+ readonly tag_name: Token | null;
430
+ readonly is_void: boolean;
431
+
432
+ static get type(): NodeType {
433
+ return "AST_HTML_CONDITIONAL_OPEN_TAG_NODE"
434
+ }
435
+
436
+ static from(data: SerializedHTMLConditionalOpenTagNode): HTMLConditionalOpenTagNode {
437
+ return new HTMLConditionalOpenTagNode({
438
+ type: data.type,
439
+ location: Location.from(data.location),
440
+ errors: (data.errors || []).map(error => HerbError.from(error)),
441
+ conditional: data.conditional ? fromSerializedNode((data.conditional)) as ERBIfNode | ERBUnlessNode : null,
442
+ tag_name: data.tag_name ? Token.from(data.tag_name) : null,
443
+ is_void: data.is_void,
444
+ })
445
+ }
446
+
447
+ constructor(props: HTMLConditionalOpenTagNodeProps) {
448
+ super(props.type, props.location, props.errors);
449
+ this.conditional = props.conditional;
450
+ this.tag_name = props.tag_name;
451
+ this.is_void = props.is_void;
452
+ }
453
+
454
+ accept(visitor: Visitor): void {
455
+ visitor.visitHTMLConditionalOpenTagNode(this)
456
+ }
457
+
458
+ childNodes(): (Node | null | undefined)[] {
459
+ return [
460
+ this.conditional,
461
+ ];
462
+ }
463
+
464
+ compactChildNodes(): Node[] {
465
+ return this.childNodes().filter(node => node !== null && node !== undefined)
466
+ }
467
+
468
+
469
+ recursiveErrors(): HerbError[] {
470
+ return [
471
+ ...this.errors,
472
+ this.conditional ? this.conditional.recursiveErrors() : [],
473
+ ].flat();
474
+ }
475
+
476
+ toJSON(): SerializedHTMLConditionalOpenTagNode {
477
+ return {
478
+ ...super.toJSON(),
479
+ type: "AST_HTML_CONDITIONAL_OPEN_TAG_NODE",
480
+ conditional: this.conditional ? this.conditional.toJSON() : null,
481
+ tag_name: this.tag_name ? this.tag_name.toJSON() : null,
482
+ is_void: this.is_void,
483
+ };
484
+ }
485
+
486
+ treeInspect(): string {
487
+ let output = "";
488
+
489
+ output += `@ HTMLConditionalOpenTagNode ${this.location.treeInspectWithLabel()}\n`;
490
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
491
+ output += `├── conditional: ${this.inspectNode(this.conditional, "│ ")}`;
492
+ output += `├── tag_name: ${this.tag_name ? this.tag_name.treeInspect() : "∅"}\n`;
493
+ output += `└── is_void: ${typeof this.is_void === 'boolean' ? String(this.is_void) : "∅"}\n`;
494
+
495
+ return output
496
+ }
497
+ }
498
+
372
499
  export interface SerializedHTMLCloseTagNode extends SerializedNode {
373
500
  type: "AST_HTML_CLOSE_TAG_NODE";
374
501
  tag_opening: SerializedToken | null;
@@ -377,14 +504,16 @@ export interface SerializedHTMLCloseTagNode extends SerializedNode {
377
504
  tag_closing: SerializedToken | null;
378
505
  }
379
506
 
380
- export interface HTMLCloseTagNodeProps extends BaseNodeProps {
507
+ export interface HTMLCloseTagNodeProps extends Omit<BaseNodeProps, 'type'> {
508
+ type: "AST_HTML_CLOSE_TAG_NODE";
381
509
  tag_opening: Token | null;
382
510
  tag_name: Token | null;
383
- children: Node[];
511
+ children: any[];
384
512
  tag_closing: Token | null;
385
513
  }
386
514
 
387
515
  export class HTMLCloseTagNode extends Node {
516
+ declare readonly type: "AST_HTML_CLOSE_TAG_NODE";
388
517
  readonly tag_opening: Token | null;
389
518
  readonly tag_name: Token | null;
390
519
  readonly children: Node[];
@@ -428,6 +557,7 @@ export class HTMLCloseTagNode extends Node {
428
557
  return this.childNodes().filter(node => node !== null && node !== undefined)
429
558
  }
430
559
 
560
+
431
561
  recursiveErrors(): HerbError[] {
432
562
  return [
433
563
  ...this.errors,
@@ -460,32 +590,176 @@ export class HTMLCloseTagNode extends Node {
460
590
  }
461
591
  }
462
592
 
593
+ export interface SerializedHTMLOmittedCloseTagNode extends SerializedNode {
594
+ type: "AST_HTML_OMITTED_CLOSE_TAG_NODE";
595
+ tag_name: SerializedToken | null;
596
+ }
597
+
598
+ export interface HTMLOmittedCloseTagNodeProps extends Omit<BaseNodeProps, 'type'> {
599
+ type: "AST_HTML_OMITTED_CLOSE_TAG_NODE";
600
+ tag_name: Token | null;
601
+ }
602
+
603
+ export class HTMLOmittedCloseTagNode extends Node {
604
+ declare readonly type: "AST_HTML_OMITTED_CLOSE_TAG_NODE";
605
+ readonly tag_name: Token | null;
606
+
607
+ static get type(): NodeType {
608
+ return "AST_HTML_OMITTED_CLOSE_TAG_NODE"
609
+ }
610
+
611
+ static from(data: SerializedHTMLOmittedCloseTagNode): HTMLOmittedCloseTagNode {
612
+ return new HTMLOmittedCloseTagNode({
613
+ type: data.type,
614
+ location: Location.from(data.location),
615
+ errors: (data.errors || []).map(error => HerbError.from(error)),
616
+ tag_name: data.tag_name ? Token.from(data.tag_name) : null,
617
+ })
618
+ }
619
+
620
+ constructor(props: HTMLOmittedCloseTagNodeProps) {
621
+ super(props.type, props.location, props.errors);
622
+ this.tag_name = props.tag_name;
623
+ }
624
+
625
+ accept(visitor: Visitor): void {
626
+ visitor.visitHTMLOmittedCloseTagNode(this)
627
+ }
628
+
629
+ childNodes(): (Node | null | undefined)[] {
630
+ return [
631
+ ];
632
+ }
633
+
634
+ compactChildNodes(): Node[] {
635
+ return this.childNodes().filter(node => node !== null && node !== undefined)
636
+ }
637
+
638
+
639
+ recursiveErrors(): HerbError[] {
640
+ return [
641
+ ...this.errors,
642
+ ].flat();
643
+ }
644
+
645
+ toJSON(): SerializedHTMLOmittedCloseTagNode {
646
+ return {
647
+ ...super.toJSON(),
648
+ type: "AST_HTML_OMITTED_CLOSE_TAG_NODE",
649
+ tag_name: this.tag_name ? this.tag_name.toJSON() : null,
650
+ };
651
+ }
652
+
653
+ treeInspect(): string {
654
+ let output = "";
655
+
656
+ output += `@ HTMLOmittedCloseTagNode ${this.location.treeInspectWithLabel()}\n`;
657
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
658
+ output += `└── tag_name: ${this.tag_name ? this.tag_name.treeInspect() : "∅"}\n`;
659
+
660
+ return output
661
+ }
662
+ }
663
+
664
+ export interface SerializedHTMLVirtualCloseTagNode extends SerializedNode {
665
+ type: "AST_HTML_VIRTUAL_CLOSE_TAG_NODE";
666
+ tag_name: SerializedToken | null;
667
+ }
668
+
669
+ export interface HTMLVirtualCloseTagNodeProps extends Omit<BaseNodeProps, 'type'> {
670
+ type: "AST_HTML_VIRTUAL_CLOSE_TAG_NODE";
671
+ tag_name: Token | null;
672
+ }
673
+
674
+ export class HTMLVirtualCloseTagNode extends Node {
675
+ declare readonly type: "AST_HTML_VIRTUAL_CLOSE_TAG_NODE";
676
+ readonly tag_name: Token | null;
677
+
678
+ static get type(): NodeType {
679
+ return "AST_HTML_VIRTUAL_CLOSE_TAG_NODE"
680
+ }
681
+
682
+ static from(data: SerializedHTMLVirtualCloseTagNode): HTMLVirtualCloseTagNode {
683
+ return new HTMLVirtualCloseTagNode({
684
+ type: data.type,
685
+ location: Location.from(data.location),
686
+ errors: (data.errors || []).map(error => HerbError.from(error)),
687
+ tag_name: data.tag_name ? Token.from(data.tag_name) : null,
688
+ })
689
+ }
690
+
691
+ constructor(props: HTMLVirtualCloseTagNodeProps) {
692
+ super(props.type, props.location, props.errors);
693
+ this.tag_name = props.tag_name;
694
+ }
695
+
696
+ accept(visitor: Visitor): void {
697
+ visitor.visitHTMLVirtualCloseTagNode(this)
698
+ }
699
+
700
+ childNodes(): (Node | null | undefined)[] {
701
+ return [
702
+ ];
703
+ }
704
+
705
+ compactChildNodes(): Node[] {
706
+ return this.childNodes().filter(node => node !== null && node !== undefined)
707
+ }
708
+
709
+
710
+ recursiveErrors(): HerbError[] {
711
+ return [
712
+ ...this.errors,
713
+ ].flat();
714
+ }
715
+
716
+ toJSON(): SerializedHTMLVirtualCloseTagNode {
717
+ return {
718
+ ...super.toJSON(),
719
+ type: "AST_HTML_VIRTUAL_CLOSE_TAG_NODE",
720
+ tag_name: this.tag_name ? this.tag_name.toJSON() : null,
721
+ };
722
+ }
723
+
724
+ treeInspect(): string {
725
+ let output = "";
726
+
727
+ output += `@ HTMLVirtualCloseTagNode ${this.location.treeInspectWithLabel()}\n`;
728
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
729
+ output += `└── tag_name: ${this.tag_name ? this.tag_name.treeInspect() : "∅"}\n`;
730
+
731
+ return output
732
+ }
733
+ }
734
+
463
735
  export interface SerializedHTMLElementNode extends SerializedNode {
464
736
  type: "AST_HTML_ELEMENT_NODE";
465
- open_tag: SerializedHTMLOpenTagNode | null;
737
+ open_tag: SerializedHTMLOpenTagNode | SerializedHTMLConditionalOpenTagNode | SerializedERBOpenTagNode | null;
466
738
  tag_name: SerializedToken | null;
467
739
  body: SerializedNode[];
468
- close_tag: SerializedHTMLCloseTagNode | null;
740
+ close_tag: SerializedHTMLCloseTagNode | SerializedHTMLOmittedCloseTagNode | SerializedHTMLVirtualCloseTagNode | SerializedERBEndNode | null;
469
741
  is_void: boolean;
470
- source: string;
742
+ element_source: string;
471
743
  }
472
744
 
473
- export interface HTMLElementNodeProps extends BaseNodeProps {
474
- open_tag: HTMLOpenTagNode | null;
745
+ export interface HTMLElementNodeProps extends Omit<BaseNodeProps, 'type'> {
746
+ type: "AST_HTML_ELEMENT_NODE";
747
+ open_tag: HTMLOpenTagNode | HTMLConditionalOpenTagNode | ERBOpenTagNode | null;
475
748
  tag_name: Token | null;
476
749
  body: Node[];
477
- close_tag: HTMLCloseTagNode | null;
750
+ close_tag: HTMLCloseTagNode | HTMLOmittedCloseTagNode | HTMLVirtualCloseTagNode | ERBEndNode | null;
478
751
  is_void: boolean;
479
- source: string;
752
+ element_source: string;
480
753
  }
481
754
 
482
755
  export class HTMLElementNode extends Node {
483
- readonly open_tag: HTMLOpenTagNode | null;
756
+ declare readonly type: "AST_HTML_ELEMENT_NODE";
757
+ readonly open_tag: HTMLOpenTagNode | HTMLConditionalOpenTagNode | ERBOpenTagNode | null;
484
758
  readonly tag_name: Token | null;
485
759
  readonly body: Node[];
486
- readonly close_tag: HTMLCloseTagNode | null;
760
+ readonly close_tag: HTMLCloseTagNode | HTMLOmittedCloseTagNode | HTMLVirtualCloseTagNode | ERBEndNode | null;
487
761
  readonly is_void: boolean;
488
- readonly source: string;
762
+ readonly element_source: string;
489
763
 
490
764
  static get type(): NodeType {
491
765
  return "AST_HTML_ELEMENT_NODE"
@@ -496,12 +770,12 @@ export class HTMLElementNode extends Node {
496
770
  type: data.type,
497
771
  location: Location.from(data.location),
498
772
  errors: (data.errors || []).map(error => HerbError.from(error)),
499
- open_tag: data.open_tag ? fromSerializedNode((data.open_tag)) : null,
773
+ open_tag: data.open_tag ? fromSerializedNode((data.open_tag)) as HTMLOpenTagNode | HTMLConditionalOpenTagNode | ERBOpenTagNode : null,
500
774
  tag_name: data.tag_name ? Token.from(data.tag_name) : null,
501
775
  body: (data.body || []).map(node => fromSerializedNode(node)),
502
- close_tag: data.close_tag ? fromSerializedNode((data.close_tag)) : null,
776
+ close_tag: data.close_tag ? fromSerializedNode((data.close_tag)) as HTMLCloseTagNode | HTMLOmittedCloseTagNode | HTMLVirtualCloseTagNode | ERBEndNode : null,
503
777
  is_void: data.is_void,
504
- source: data.source,
778
+ element_source: data.element_source,
505
779
  })
506
780
  }
507
781
 
@@ -512,18 +786,411 @@ export class HTMLElementNode extends Node {
512
786
  this.body = props.body;
513
787
  this.close_tag = props.close_tag;
514
788
  this.is_void = props.is_void;
515
- this.source = props.source;
789
+ this.element_source = props.element_source;
790
+ }
791
+
792
+ accept(visitor: Visitor): void {
793
+ visitor.visitHTMLElementNode(this)
794
+ }
795
+
796
+ childNodes(): (Node | null | undefined)[] {
797
+ return [
798
+ this.open_tag,
799
+ ...this.body,
800
+ this.close_tag,
801
+ ];
802
+ }
803
+
804
+ compactChildNodes(): Node[] {
805
+ return this.childNodes().filter(node => node !== null && node !== undefined)
806
+ }
807
+
808
+
809
+ recursiveErrors(): HerbError[] {
810
+ return [
811
+ ...this.errors,
812
+ this.open_tag ? this.open_tag.recursiveErrors() : [],
813
+ ...this.body.map(node => node.recursiveErrors()),
814
+ this.close_tag ? this.close_tag.recursiveErrors() : [],
815
+ ].flat();
816
+ }
817
+
818
+ toJSON(): SerializedHTMLElementNode {
819
+ return {
820
+ ...super.toJSON(),
821
+ type: "AST_HTML_ELEMENT_NODE",
822
+ open_tag: this.open_tag ? this.open_tag.toJSON() : null,
823
+ tag_name: this.tag_name ? this.tag_name.toJSON() : null,
824
+ body: this.body.map(node => node.toJSON()),
825
+ close_tag: this.close_tag ? this.close_tag.toJSON() : null,
826
+ is_void: this.is_void,
827
+ element_source: this.element_source,
828
+ };
829
+ }
830
+
831
+ treeInspect(): string {
832
+ let output = "";
833
+
834
+ output += `@ HTMLElementNode ${this.location.treeInspectWithLabel()}\n`;
835
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
836
+ output += `├── open_tag: ${this.inspectNode(this.open_tag, "│ ")}`;
837
+ output += `├── tag_name: ${this.tag_name ? this.tag_name.treeInspect() : "∅"}\n`;
838
+ output += `├── body: ${this.inspectArray(this.body, "│ ")}`;
839
+ output += `├── close_tag: ${this.inspectNode(this.close_tag, "│ ")}`;
840
+ output += `├── is_void: ${typeof this.is_void === 'boolean' ? String(this.is_void) : "∅"}\n`;
841
+ output += `└── element_source: ${this.element_source ? JSON.stringify(this.element_source) : "∅"}\n`;
842
+
843
+ return output
844
+ }
845
+ }
846
+
847
+ export interface SerializedHTMLConditionalElementNode extends SerializedNode {
848
+ type: "AST_HTML_CONDITIONAL_ELEMENT_NODE";
849
+ condition: string;
850
+ open_conditional: SerializedERBIfNode | SerializedERBUnlessNode | null;
851
+ open_tag: SerializedHTMLOpenTagNode | null;
852
+ body: SerializedNode[];
853
+ close_tag: SerializedHTMLCloseTagNode | SerializedHTMLOmittedCloseTagNode | null;
854
+ close_conditional: SerializedERBIfNode | SerializedERBUnlessNode | null;
855
+ tag_name: SerializedToken | null;
856
+ element_source: string;
857
+ }
858
+
859
+ export interface HTMLConditionalElementNodeProps extends Omit<BaseNodeProps, 'type'> {
860
+ type: "AST_HTML_CONDITIONAL_ELEMENT_NODE";
861
+ condition: string;
862
+ open_conditional: ERBIfNode | ERBUnlessNode | null;
863
+ open_tag: HTMLOpenTagNode | null;
864
+ body: Node[];
865
+ close_tag: HTMLCloseTagNode | HTMLOmittedCloseTagNode | null;
866
+ close_conditional: ERBIfNode | ERBUnlessNode | null;
867
+ tag_name: Token | null;
868
+ element_source: string;
869
+ }
870
+
871
+ export class HTMLConditionalElementNode extends Node {
872
+ declare readonly type: "AST_HTML_CONDITIONAL_ELEMENT_NODE";
873
+ readonly condition: string;
874
+ readonly open_conditional: ERBIfNode | ERBUnlessNode | null;
875
+ readonly open_tag: HTMLOpenTagNode | null;
876
+ readonly body: Node[];
877
+ readonly close_tag: HTMLCloseTagNode | HTMLOmittedCloseTagNode | null;
878
+ readonly close_conditional: ERBIfNode | ERBUnlessNode | null;
879
+ readonly tag_name: Token | null;
880
+ readonly element_source: string;
881
+
882
+ static get type(): NodeType {
883
+ return "AST_HTML_CONDITIONAL_ELEMENT_NODE"
884
+ }
885
+
886
+ static from(data: SerializedHTMLConditionalElementNode): HTMLConditionalElementNode {
887
+ return new HTMLConditionalElementNode({
888
+ type: data.type,
889
+ location: Location.from(data.location),
890
+ errors: (data.errors || []).map(error => HerbError.from(error)),
891
+ condition: data.condition,
892
+ open_conditional: data.open_conditional ? fromSerializedNode((data.open_conditional)) as ERBIfNode | ERBUnlessNode : null,
893
+ open_tag: data.open_tag ? fromSerializedNode((data.open_tag)) as HTMLOpenTagNode : null,
894
+ body: (data.body || []).map(node => fromSerializedNode(node)),
895
+ close_tag: data.close_tag ? fromSerializedNode((data.close_tag)) as HTMLCloseTagNode | HTMLOmittedCloseTagNode : null,
896
+ close_conditional: data.close_conditional ? fromSerializedNode((data.close_conditional)) as ERBIfNode | ERBUnlessNode : null,
897
+ tag_name: data.tag_name ? Token.from(data.tag_name) : null,
898
+ element_source: data.element_source,
899
+ })
900
+ }
901
+
902
+ constructor(props: HTMLConditionalElementNodeProps) {
903
+ super(props.type, props.location, props.errors);
904
+ this.condition = props.condition;
905
+ this.open_conditional = props.open_conditional;
906
+ this.open_tag = props.open_tag;
907
+ this.body = props.body;
908
+ this.close_tag = props.close_tag;
909
+ this.close_conditional = props.close_conditional;
910
+ this.tag_name = props.tag_name;
911
+ this.element_source = props.element_source;
912
+ }
913
+
914
+ accept(visitor: Visitor): void {
915
+ visitor.visitHTMLConditionalElementNode(this)
916
+ }
917
+
918
+ childNodes(): (Node | null | undefined)[] {
919
+ return [
920
+ this.open_conditional,
921
+ this.open_tag,
922
+ ...this.body,
923
+ this.close_tag,
924
+ this.close_conditional,
925
+ ];
926
+ }
927
+
928
+ compactChildNodes(): Node[] {
929
+ return this.childNodes().filter(node => node !== null && node !== undefined)
930
+ }
931
+
932
+
933
+ recursiveErrors(): HerbError[] {
934
+ return [
935
+ ...this.errors,
936
+ this.open_conditional ? this.open_conditional.recursiveErrors() : [],
937
+ this.open_tag ? this.open_tag.recursiveErrors() : [],
938
+ ...this.body.map(node => node.recursiveErrors()),
939
+ this.close_tag ? this.close_tag.recursiveErrors() : [],
940
+ this.close_conditional ? this.close_conditional.recursiveErrors() : [],
941
+ ].flat();
942
+ }
943
+
944
+ toJSON(): SerializedHTMLConditionalElementNode {
945
+ return {
946
+ ...super.toJSON(),
947
+ type: "AST_HTML_CONDITIONAL_ELEMENT_NODE",
948
+ condition: this.condition,
949
+ open_conditional: this.open_conditional ? this.open_conditional.toJSON() : null,
950
+ open_tag: this.open_tag ? this.open_tag.toJSON() : null,
951
+ body: this.body.map(node => node.toJSON()),
952
+ close_tag: this.close_tag ? this.close_tag.toJSON() : null,
953
+ close_conditional: this.close_conditional ? this.close_conditional.toJSON() : null,
954
+ tag_name: this.tag_name ? this.tag_name.toJSON() : null,
955
+ element_source: this.element_source,
956
+ };
957
+ }
958
+
959
+ treeInspect(): string {
960
+ let output = "";
961
+
962
+ output += `@ HTMLConditionalElementNode ${this.location.treeInspectWithLabel()}\n`;
963
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
964
+ output += `├── condition: ${this.condition ? JSON.stringify(this.condition) : "∅"}\n`;
965
+ output += `├── open_conditional: ${this.inspectNode(this.open_conditional, "│ ")}`;
966
+ output += `├── open_tag: ${this.inspectNode(this.open_tag, "│ ")}`;
967
+ output += `├── body: ${this.inspectArray(this.body, "│ ")}`;
968
+ output += `├── close_tag: ${this.inspectNode(this.close_tag, "│ ")}`;
969
+ output += `├── close_conditional: ${this.inspectNode(this.close_conditional, "│ ")}`;
970
+ output += `├── tag_name: ${this.tag_name ? this.tag_name.treeInspect() : "∅"}\n`;
971
+ output += `└── element_source: ${this.element_source ? JSON.stringify(this.element_source) : "∅"}\n`;
972
+
973
+ return output
974
+ }
975
+ }
976
+
977
+ export interface SerializedHTMLAttributeValueNode extends SerializedNode {
978
+ type: "AST_HTML_ATTRIBUTE_VALUE_NODE";
979
+ open_quote: SerializedToken | null;
980
+ children: SerializedNode[];
981
+ close_quote: SerializedToken | null;
982
+ quoted: boolean;
983
+ }
984
+
985
+ export interface HTMLAttributeValueNodeProps extends Omit<BaseNodeProps, 'type'> {
986
+ type: "AST_HTML_ATTRIBUTE_VALUE_NODE";
987
+ open_quote: Token | null;
988
+ children: Node[];
989
+ close_quote: Token | null;
990
+ quoted: boolean;
991
+ }
992
+
993
+ export class HTMLAttributeValueNode extends Node {
994
+ declare readonly type: "AST_HTML_ATTRIBUTE_VALUE_NODE";
995
+ readonly open_quote: Token | null;
996
+ readonly children: Node[];
997
+ readonly close_quote: Token | null;
998
+ readonly quoted: boolean;
999
+
1000
+ static get type(): NodeType {
1001
+ return "AST_HTML_ATTRIBUTE_VALUE_NODE"
1002
+ }
1003
+
1004
+ static from(data: SerializedHTMLAttributeValueNode): HTMLAttributeValueNode {
1005
+ return new HTMLAttributeValueNode({
1006
+ type: data.type,
1007
+ location: Location.from(data.location),
1008
+ errors: (data.errors || []).map(error => HerbError.from(error)),
1009
+ open_quote: data.open_quote ? Token.from(data.open_quote) : null,
1010
+ children: (data.children || []).map(node => fromSerializedNode(node)),
1011
+ close_quote: data.close_quote ? Token.from(data.close_quote) : null,
1012
+ quoted: data.quoted,
1013
+ })
1014
+ }
1015
+
1016
+ constructor(props: HTMLAttributeValueNodeProps) {
1017
+ super(props.type, props.location, props.errors);
1018
+ this.open_quote = props.open_quote;
1019
+ this.children = props.children;
1020
+ this.close_quote = props.close_quote;
1021
+ this.quoted = props.quoted;
1022
+ }
1023
+
1024
+ accept(visitor: Visitor): void {
1025
+ visitor.visitHTMLAttributeValueNode(this)
1026
+ }
1027
+
1028
+ childNodes(): (Node | null | undefined)[] {
1029
+ return [
1030
+ ...this.children,
1031
+ ];
1032
+ }
1033
+
1034
+ compactChildNodes(): Node[] {
1035
+ return this.childNodes().filter(node => node !== null && node !== undefined)
1036
+ }
1037
+
1038
+
1039
+ recursiveErrors(): HerbError[] {
1040
+ return [
1041
+ ...this.errors,
1042
+ ...this.children.map(node => node.recursiveErrors()),
1043
+ ].flat();
1044
+ }
1045
+
1046
+ toJSON(): SerializedHTMLAttributeValueNode {
1047
+ return {
1048
+ ...super.toJSON(),
1049
+ type: "AST_HTML_ATTRIBUTE_VALUE_NODE",
1050
+ open_quote: this.open_quote ? this.open_quote.toJSON() : null,
1051
+ children: this.children.map(node => node.toJSON()),
1052
+ close_quote: this.close_quote ? this.close_quote.toJSON() : null,
1053
+ quoted: this.quoted,
1054
+ };
1055
+ }
1056
+
1057
+ treeInspect(): string {
1058
+ let output = "";
1059
+
1060
+ output += `@ HTMLAttributeValueNode ${this.location.treeInspectWithLabel()}\n`;
1061
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
1062
+ output += `├── open_quote: ${this.open_quote ? this.open_quote.treeInspect() : "∅"}\n`;
1063
+ output += `├── children: ${this.inspectArray(this.children, "│ ")}`;
1064
+ output += `├── close_quote: ${this.close_quote ? this.close_quote.treeInspect() : "∅"}\n`;
1065
+ output += `└── quoted: ${typeof this.quoted === 'boolean' ? String(this.quoted) : "∅"}\n`;
1066
+
1067
+ return output
1068
+ }
1069
+ }
1070
+
1071
+ export interface SerializedHTMLAttributeNameNode extends SerializedNode {
1072
+ type: "AST_HTML_ATTRIBUTE_NAME_NODE";
1073
+ children: SerializedNode[];
1074
+ }
1075
+
1076
+ export interface HTMLAttributeNameNodeProps extends Omit<BaseNodeProps, 'type'> {
1077
+ type: "AST_HTML_ATTRIBUTE_NAME_NODE";
1078
+ children: any[];
1079
+ }
1080
+
1081
+ export class HTMLAttributeNameNode extends Node {
1082
+ declare readonly type: "AST_HTML_ATTRIBUTE_NAME_NODE";
1083
+ readonly children: Node[];
1084
+
1085
+ static get type(): NodeType {
1086
+ return "AST_HTML_ATTRIBUTE_NAME_NODE"
1087
+ }
1088
+
1089
+ static from(data: SerializedHTMLAttributeNameNode): HTMLAttributeNameNode {
1090
+ return new HTMLAttributeNameNode({
1091
+ type: data.type,
1092
+ location: Location.from(data.location),
1093
+ errors: (data.errors || []).map(error => HerbError.from(error)),
1094
+ children: (data.children || []).map(node => fromSerializedNode(node)),
1095
+ })
1096
+ }
1097
+
1098
+ constructor(props: HTMLAttributeNameNodeProps) {
1099
+ super(props.type, props.location, props.errors);
1100
+ this.children = props.children;
1101
+ }
1102
+
1103
+ accept(visitor: Visitor): void {
1104
+ visitor.visitHTMLAttributeNameNode(this)
1105
+ }
1106
+
1107
+ childNodes(): (Node | null | undefined)[] {
1108
+ return [
1109
+ ...this.children,
1110
+ ];
1111
+ }
1112
+
1113
+ compactChildNodes(): Node[] {
1114
+ return this.childNodes().filter(node => node !== null && node !== undefined)
1115
+ }
1116
+
1117
+
1118
+ recursiveErrors(): HerbError[] {
1119
+ return [
1120
+ ...this.errors,
1121
+ ...this.children.map(node => node.recursiveErrors()),
1122
+ ].flat();
1123
+ }
1124
+
1125
+ toJSON(): SerializedHTMLAttributeNameNode {
1126
+ return {
1127
+ ...super.toJSON(),
1128
+ type: "AST_HTML_ATTRIBUTE_NAME_NODE",
1129
+ children: this.children.map(node => node.toJSON()),
1130
+ };
1131
+ }
1132
+
1133
+ treeInspect(): string {
1134
+ let output = "";
1135
+
1136
+ output += `@ HTMLAttributeNameNode ${this.location.treeInspectWithLabel()}\n`;
1137
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
1138
+ output += `└── children: ${this.inspectArray(this.children, " ")}`;
1139
+
1140
+ return output
1141
+ }
1142
+ }
1143
+
1144
+ export interface SerializedHTMLAttributeNode extends SerializedNode {
1145
+ type: "AST_HTML_ATTRIBUTE_NODE";
1146
+ name: SerializedHTMLAttributeNameNode | null;
1147
+ equals: SerializedToken | null;
1148
+ value: SerializedHTMLAttributeValueNode | null;
1149
+ }
1150
+
1151
+ export interface HTMLAttributeNodeProps extends Omit<BaseNodeProps, 'type'> {
1152
+ type: "AST_HTML_ATTRIBUTE_NODE";
1153
+ name: HTMLAttributeNameNode | null;
1154
+ equals: Token | null;
1155
+ value: HTMLAttributeValueNode | null;
1156
+ }
1157
+
1158
+ export class HTMLAttributeNode extends Node {
1159
+ declare readonly type: "AST_HTML_ATTRIBUTE_NODE";
1160
+ readonly name: HTMLAttributeNameNode | null;
1161
+ readonly equals: Token | null;
1162
+ readonly value: HTMLAttributeValueNode | null;
1163
+
1164
+ static get type(): NodeType {
1165
+ return "AST_HTML_ATTRIBUTE_NODE"
1166
+ }
1167
+
1168
+ static from(data: SerializedHTMLAttributeNode): HTMLAttributeNode {
1169
+ return new HTMLAttributeNode({
1170
+ type: data.type,
1171
+ location: Location.from(data.location),
1172
+ errors: (data.errors || []).map(error => HerbError.from(error)),
1173
+ name: data.name ? fromSerializedNode((data.name)) as HTMLAttributeNameNode : null,
1174
+ equals: data.equals ? Token.from(data.equals) : null,
1175
+ value: data.value ? fromSerializedNode((data.value)) as HTMLAttributeValueNode : null,
1176
+ })
1177
+ }
1178
+
1179
+ constructor(props: HTMLAttributeNodeProps) {
1180
+ super(props.type, props.location, props.errors);
1181
+ this.name = props.name;
1182
+ this.equals = props.equals;
1183
+ this.value = props.value;
516
1184
  }
517
1185
 
518
1186
  accept(visitor: Visitor): void {
519
- visitor.visitHTMLElementNode(this)
1187
+ visitor.visitHTMLAttributeNode(this)
520
1188
  }
521
1189
 
522
1190
  childNodes(): (Node | null | undefined)[] {
523
1191
  return [
524
- this.open_tag,
525
- ...this.body,
526
- this.close_tag,
1192
+ this.name,
1193
+ this.value,
527
1194
  ];
528
1195
  }
529
1196
 
@@ -531,96 +1198,76 @@ export class HTMLElementNode extends Node {
531
1198
  return this.childNodes().filter(node => node !== null && node !== undefined)
532
1199
  }
533
1200
 
1201
+
534
1202
  recursiveErrors(): HerbError[] {
535
1203
  return [
536
1204
  ...this.errors,
537
- this.open_tag ? this.open_tag.recursiveErrors() : [],
538
- ...this.body.map(node => node.recursiveErrors()),
539
- this.close_tag ? this.close_tag.recursiveErrors() : [],
1205
+ this.name ? this.name.recursiveErrors() : [],
1206
+ this.value ? this.value.recursiveErrors() : [],
540
1207
  ].flat();
541
1208
  }
542
1209
 
543
- toJSON(): SerializedHTMLElementNode {
1210
+ toJSON(): SerializedHTMLAttributeNode {
544
1211
  return {
545
1212
  ...super.toJSON(),
546
- type: "AST_HTML_ELEMENT_NODE",
547
- open_tag: this.open_tag ? this.open_tag.toJSON() : null,
548
- tag_name: this.tag_name ? this.tag_name.toJSON() : null,
549
- body: this.body.map(node => node.toJSON()),
550
- close_tag: this.close_tag ? this.close_tag.toJSON() : null,
551
- is_void: this.is_void,
552
- source: this.source,
1213
+ type: "AST_HTML_ATTRIBUTE_NODE",
1214
+ name: this.name ? this.name.toJSON() : null,
1215
+ equals: this.equals ? this.equals.toJSON() : null,
1216
+ value: this.value ? this.value.toJSON() : null,
553
1217
  };
554
1218
  }
555
1219
 
556
1220
  treeInspect(): string {
557
1221
  let output = "";
558
1222
 
559
- output += `@ HTMLElementNode ${this.location.treeInspectWithLabel()}\n`;
1223
+ output += `@ HTMLAttributeNode ${this.location.treeInspectWithLabel()}\n`;
560
1224
  output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
561
- output += `├── open_tag: ${this.inspectNode(this.open_tag, "│ ")}`;
562
- output += `├── tag_name: ${this.tag_name ? this.tag_name.treeInspect() : "∅"}\n`;
563
- output += `├── body: ${this.inspectArray(this.body, "")}`;
564
- output += `├── close_tag: ${this.inspectNode(this.close_tag, "│ ")}`;
565
- output += `├── is_void: ${typeof this.is_void === 'boolean' ? String(this.is_void) : "∅"}\n`;
566
- output += `└── source: ${this.source ? JSON.stringify(this.source) : "∅"}\n`;
1225
+ output += `├── name: ${this.inspectNode(this.name, "│ ")}`;
1226
+ output += `├── equals: ${this.equals ? this.equals.treeInspect() : "∅"}\n`;
1227
+ output += `└── value: ${this.inspectNode(this.value, " ")}`;
567
1228
 
568
1229
  return output
569
1230
  }
570
1231
  }
571
1232
 
572
- export interface SerializedHTMLAttributeValueNode extends SerializedNode {
573
- type: "AST_HTML_ATTRIBUTE_VALUE_NODE";
574
- open_quote: SerializedToken | null;
575
- children: SerializedNode[];
576
- close_quote: SerializedToken | null;
577
- quoted: boolean;
1233
+ export interface SerializedRubyLiteralNode extends SerializedNode {
1234
+ type: "AST_RUBY_LITERAL_NODE";
1235
+ content: string;
578
1236
  }
579
1237
 
580
- export interface HTMLAttributeValueNodeProps extends BaseNodeProps {
581
- open_quote: Token | null;
582
- children: Node[];
583
- close_quote: Token | null;
584
- quoted: boolean;
1238
+ export interface RubyLiteralNodeProps extends Omit<BaseNodeProps, 'type'> {
1239
+ type: "AST_RUBY_LITERAL_NODE";
1240
+ content: string;
585
1241
  }
586
1242
 
587
- export class HTMLAttributeValueNode extends Node {
588
- readonly open_quote: Token | null;
589
- readonly children: Node[];
590
- readonly close_quote: Token | null;
591
- readonly quoted: boolean;
1243
+ export class RubyLiteralNode extends Node {
1244
+ declare readonly type: "AST_RUBY_LITERAL_NODE";
1245
+ readonly content: string;
592
1246
 
593
1247
  static get type(): NodeType {
594
- return "AST_HTML_ATTRIBUTE_VALUE_NODE"
1248
+ return "AST_RUBY_LITERAL_NODE"
595
1249
  }
596
1250
 
597
- static from(data: SerializedHTMLAttributeValueNode): HTMLAttributeValueNode {
598
- return new HTMLAttributeValueNode({
1251
+ static from(data: SerializedRubyLiteralNode): RubyLiteralNode {
1252
+ return new RubyLiteralNode({
599
1253
  type: data.type,
600
1254
  location: Location.from(data.location),
601
1255
  errors: (data.errors || []).map(error => HerbError.from(error)),
602
- open_quote: data.open_quote ? Token.from(data.open_quote) : null,
603
- children: (data.children || []).map(node => fromSerializedNode(node)),
604
- close_quote: data.close_quote ? Token.from(data.close_quote) : null,
605
- quoted: data.quoted,
1256
+ content: data.content,
606
1257
  })
607
1258
  }
608
1259
 
609
- constructor(props: HTMLAttributeValueNodeProps) {
1260
+ constructor(props: RubyLiteralNodeProps) {
610
1261
  super(props.type, props.location, props.errors);
611
- this.open_quote = props.open_quote;
612
- this.children = props.children;
613
- this.close_quote = props.close_quote;
614
- this.quoted = props.quoted;
1262
+ this.content = props.content;
615
1263
  }
616
1264
 
617
1265
  accept(visitor: Visitor): void {
618
- visitor.visitHTMLAttributeValueNode(this)
1266
+ visitor.visitRubyLiteralNode(this)
619
1267
  }
620
1268
 
621
1269
  childNodes(): (Node | null | undefined)[] {
622
1270
  return [
623
- ...this.children,
624
1271
  ];
625
1272
  }
626
1273
 
@@ -628,75 +1275,75 @@ export class HTMLAttributeValueNode extends Node {
628
1275
  return this.childNodes().filter(node => node !== null && node !== undefined)
629
1276
  }
630
1277
 
1278
+
631
1279
  recursiveErrors(): HerbError[] {
632
1280
  return [
633
1281
  ...this.errors,
634
- ...this.children.map(node => node.recursiveErrors()),
635
1282
  ].flat();
636
1283
  }
637
1284
 
638
- toJSON(): SerializedHTMLAttributeValueNode {
1285
+ toJSON(): SerializedRubyLiteralNode {
639
1286
  return {
640
1287
  ...super.toJSON(),
641
- type: "AST_HTML_ATTRIBUTE_VALUE_NODE",
642
- open_quote: this.open_quote ? this.open_quote.toJSON() : null,
643
- children: this.children.map(node => node.toJSON()),
644
- close_quote: this.close_quote ? this.close_quote.toJSON() : null,
645
- quoted: this.quoted,
1288
+ type: "AST_RUBY_LITERAL_NODE",
1289
+ content: this.content,
646
1290
  };
647
1291
  }
648
1292
 
649
1293
  treeInspect(): string {
650
1294
  let output = "";
651
1295
 
652
- output += `@ HTMLAttributeValueNode ${this.location.treeInspectWithLabel()}\n`;
1296
+ output += `@ RubyLiteralNode ${this.location.treeInspectWithLabel()}\n`;
653
1297
  output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
654
- output += `├── open_quote: ${this.open_quote ? this.open_quote.treeInspect() : "∅"}\n`;
655
- output += `├── children: ${this.inspectArray(this.children, "│ ")}`;
656
- output += `├── close_quote: ${this.close_quote ? this.close_quote.treeInspect() : "∅"}\n`;
657
- output += `└── quoted: ${typeof this.quoted === 'boolean' ? String(this.quoted) : "∅"}\n`;
1298
+ output += `└── content: ${this.content ? JSON.stringify(this.content) : "∅"}\n`;
658
1299
 
659
1300
  return output
660
1301
  }
661
1302
  }
662
1303
 
663
- export interface SerializedHTMLAttributeNameNode extends SerializedNode {
664
- type: "AST_HTML_ATTRIBUTE_NAME_NODE";
665
- children: SerializedNode[];
1304
+ export interface SerializedRubyHTMLAttributesSplatNode extends SerializedNode {
1305
+ type: "AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE";
1306
+ content: string;
1307
+ prefix: string;
666
1308
  }
667
1309
 
668
- export interface HTMLAttributeNameNodeProps extends BaseNodeProps {
669
- children: Node[];
1310
+ export interface RubyHTMLAttributesSplatNodeProps extends Omit<BaseNodeProps, 'type'> {
1311
+ type: "AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE";
1312
+ content: string;
1313
+ prefix: string;
670
1314
  }
671
1315
 
672
- export class HTMLAttributeNameNode extends Node {
673
- readonly children: Node[];
1316
+ export class RubyHTMLAttributesSplatNode extends Node {
1317
+ declare readonly type: "AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE";
1318
+ readonly content: string;
1319
+ readonly prefix: string;
674
1320
 
675
1321
  static get type(): NodeType {
676
- return "AST_HTML_ATTRIBUTE_NAME_NODE"
1322
+ return "AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE"
677
1323
  }
678
1324
 
679
- static from(data: SerializedHTMLAttributeNameNode): HTMLAttributeNameNode {
680
- return new HTMLAttributeNameNode({
1325
+ static from(data: SerializedRubyHTMLAttributesSplatNode): RubyHTMLAttributesSplatNode {
1326
+ return new RubyHTMLAttributesSplatNode({
681
1327
  type: data.type,
682
1328
  location: Location.from(data.location),
683
1329
  errors: (data.errors || []).map(error => HerbError.from(error)),
684
- children: (data.children || []).map(node => fromSerializedNode(node)),
1330
+ content: data.content,
1331
+ prefix: data.prefix,
685
1332
  })
686
1333
  }
687
1334
 
688
- constructor(props: HTMLAttributeNameNodeProps) {
1335
+ constructor(props: RubyHTMLAttributesSplatNodeProps) {
689
1336
  super(props.type, props.location, props.errors);
690
- this.children = props.children;
1337
+ this.content = props.content;
1338
+ this.prefix = props.prefix;
691
1339
  }
692
1340
 
693
1341
  accept(visitor: Visitor): void {
694
- visitor.visitHTMLAttributeNameNode(this)
1342
+ visitor.visitRubyHTMLAttributesSplatNode(this)
695
1343
  }
696
1344
 
697
1345
  childNodes(): (Node | null | undefined)[] {
698
1346
  return [
699
- ...this.children,
700
1347
  ];
701
1348
  }
702
1349
 
@@ -704,80 +1351,93 @@ export class HTMLAttributeNameNode extends Node {
704
1351
  return this.childNodes().filter(node => node !== null && node !== undefined)
705
1352
  }
706
1353
 
1354
+
707
1355
  recursiveErrors(): HerbError[] {
708
1356
  return [
709
1357
  ...this.errors,
710
- ...this.children.map(node => node.recursiveErrors()),
711
1358
  ].flat();
712
1359
  }
713
1360
 
714
- toJSON(): SerializedHTMLAttributeNameNode {
1361
+ toJSON(): SerializedRubyHTMLAttributesSplatNode {
715
1362
  return {
716
1363
  ...super.toJSON(),
717
- type: "AST_HTML_ATTRIBUTE_NAME_NODE",
718
- children: this.children.map(node => node.toJSON()),
1364
+ type: "AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE",
1365
+ content: this.content,
1366
+ prefix: this.prefix,
719
1367
  };
720
1368
  }
721
1369
 
722
1370
  treeInspect(): string {
723
1371
  let output = "";
724
1372
 
725
- output += `@ HTMLAttributeNameNode ${this.location.treeInspectWithLabel()}\n`;
1373
+ output += `@ RubyHTMLAttributesSplatNode ${this.location.treeInspectWithLabel()}\n`;
726
1374
  output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
727
- output += `└── children: ${this.inspectArray(this.children, " ")}`;
1375
+ output += `├── content: ${this.content ? JSON.stringify(this.content) : ""}\n`;
1376
+ output += `└── prefix: ${this.prefix ? JSON.stringify(this.prefix) : "∅"}\n`;
728
1377
 
729
1378
  return output
730
1379
  }
731
1380
  }
732
1381
 
733
- export interface SerializedHTMLAttributeNode extends SerializedNode {
734
- type: "AST_HTML_ATTRIBUTE_NODE";
735
- name: SerializedHTMLAttributeNameNode | null;
736
- equals: SerializedToken | null;
737
- value: SerializedHTMLAttributeValueNode | null;
1382
+ export interface SerializedERBOpenTagNode extends SerializedNode {
1383
+ type: "AST_ERB_OPEN_TAG_NODE";
1384
+ tag_opening: SerializedToken | null;
1385
+ content: SerializedToken | null;
1386
+ tag_closing: SerializedToken | null;
1387
+ tag_name: SerializedToken | null;
1388
+ children: SerializedNode[];
738
1389
  }
739
1390
 
740
- export interface HTMLAttributeNodeProps extends BaseNodeProps {
741
- name: HTMLAttributeNameNode | null;
742
- equals: Token | null;
743
- value: HTMLAttributeValueNode | null;
1391
+ export interface ERBOpenTagNodeProps extends Omit<BaseNodeProps, 'type'> {
1392
+ type: "AST_ERB_OPEN_TAG_NODE";
1393
+ tag_opening: Token | null;
1394
+ content: Token | null;
1395
+ tag_closing: Token | null;
1396
+ tag_name: Token | null;
1397
+ children: Node[];
744
1398
  }
745
1399
 
746
- export class HTMLAttributeNode extends Node {
747
- readonly name: HTMLAttributeNameNode | null;
748
- readonly equals: Token | null;
749
- readonly value: HTMLAttributeValueNode | null;
1400
+ export class ERBOpenTagNode extends Node {
1401
+ declare readonly type: "AST_ERB_OPEN_TAG_NODE";
1402
+ readonly tag_opening: Token | null;
1403
+ readonly content: Token | null;
1404
+ readonly tag_closing: Token | null;
1405
+ readonly tag_name: Token | null;
1406
+ readonly children: Node[];
750
1407
 
751
1408
  static get type(): NodeType {
752
- return "AST_HTML_ATTRIBUTE_NODE"
1409
+ return "AST_ERB_OPEN_TAG_NODE"
753
1410
  }
754
1411
 
755
- static from(data: SerializedHTMLAttributeNode): HTMLAttributeNode {
756
- return new HTMLAttributeNode({
1412
+ static from(data: SerializedERBOpenTagNode): ERBOpenTagNode {
1413
+ return new ERBOpenTagNode({
757
1414
  type: data.type,
758
1415
  location: Location.from(data.location),
759
1416
  errors: (data.errors || []).map(error => HerbError.from(error)),
760
- name: data.name ? fromSerializedNode((data.name)) : null,
761
- equals: data.equals ? Token.from(data.equals) : null,
762
- value: data.value ? fromSerializedNode((data.value)) : null,
1417
+ tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
1418
+ content: data.content ? Token.from(data.content) : null,
1419
+ tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
1420
+ tag_name: data.tag_name ? Token.from(data.tag_name) : null,
1421
+ children: (data.children || []).map(node => fromSerializedNode(node)),
763
1422
  })
764
1423
  }
765
1424
 
766
- constructor(props: HTMLAttributeNodeProps) {
1425
+ constructor(props: ERBOpenTagNodeProps) {
767
1426
  super(props.type, props.location, props.errors);
768
- this.name = props.name;
769
- this.equals = props.equals;
770
- this.value = props.value;
1427
+ this.tag_opening = props.tag_opening;
1428
+ this.content = props.content;
1429
+ this.tag_closing = props.tag_closing;
1430
+ this.tag_name = props.tag_name;
1431
+ this.children = props.children;
771
1432
  }
772
1433
 
773
1434
  accept(visitor: Visitor): void {
774
- visitor.visitHTMLAttributeNode(this)
1435
+ visitor.visitERBOpenTagNode(this)
775
1436
  }
776
1437
 
777
1438
  childNodes(): (Node | null | undefined)[] {
778
1439
  return [
779
- this.name,
780
- this.value,
1440
+ ...this.children,
781
1441
  ];
782
1442
  }
783
1443
 
@@ -785,32 +1445,36 @@ export class HTMLAttributeNode extends Node {
785
1445
  return this.childNodes().filter(node => node !== null && node !== undefined)
786
1446
  }
787
1447
 
1448
+
788
1449
  recursiveErrors(): HerbError[] {
789
1450
  return [
790
1451
  ...this.errors,
791
- this.name ? this.name.recursiveErrors() : [],
792
- this.value ? this.value.recursiveErrors() : [],
1452
+ ...this.children.map(node => node.recursiveErrors()),
793
1453
  ].flat();
794
1454
  }
795
1455
 
796
- toJSON(): SerializedHTMLAttributeNode {
1456
+ toJSON(): SerializedERBOpenTagNode {
797
1457
  return {
798
1458
  ...super.toJSON(),
799
- type: "AST_HTML_ATTRIBUTE_NODE",
800
- name: this.name ? this.name.toJSON() : null,
801
- equals: this.equals ? this.equals.toJSON() : null,
802
- value: this.value ? this.value.toJSON() : null,
1459
+ type: "AST_ERB_OPEN_TAG_NODE",
1460
+ tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
1461
+ content: this.content ? this.content.toJSON() : null,
1462
+ tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
1463
+ tag_name: this.tag_name ? this.tag_name.toJSON() : null,
1464
+ children: this.children.map(node => node.toJSON()),
803
1465
  };
804
1466
  }
805
1467
 
806
1468
  treeInspect(): string {
807
1469
  let output = "";
808
1470
 
809
- output += `@ HTMLAttributeNode ${this.location.treeInspectWithLabel()}\n`;
1471
+ output += `@ ERBOpenTagNode ${this.location.treeInspectWithLabel()}\n`;
810
1472
  output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
811
- output += `├── name: ${this.inspectNode(this.name, "")}`;
812
- output += `├── equals: ${this.equals ? this.equals.treeInspect() : "∅"}\n`;
813
- output += `└── value: ${this.inspectNode(this.value, " ")}`;
1473
+ output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : ""}\n`;
1474
+ output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
1475
+ output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : ""}\n`;
1476
+ output += `├── tag_name: ${this.tag_name ? this.tag_name.treeInspect() : "∅"}\n`;
1477
+ output += `└── children: ${this.inspectArray(this.children, " ")}`;
814
1478
 
815
1479
  return output
816
1480
  }
@@ -821,11 +1485,13 @@ export interface SerializedHTMLTextNode extends SerializedNode {
821
1485
  content: string;
822
1486
  }
823
1487
 
824
- export interface HTMLTextNodeProps extends BaseNodeProps {
1488
+ export interface HTMLTextNodeProps extends Omit<BaseNodeProps, 'type'> {
1489
+ type: "AST_HTML_TEXT_NODE";
825
1490
  content: string;
826
1491
  }
827
1492
 
828
1493
  export class HTMLTextNode extends Node {
1494
+ declare readonly type: "AST_HTML_TEXT_NODE";
829
1495
  readonly content: string;
830
1496
 
831
1497
  static get type(): NodeType {
@@ -843,7 +1509,7 @@ export class HTMLTextNode extends Node {
843
1509
 
844
1510
  constructor(props: HTMLTextNodeProps) {
845
1511
  super(props.type, props.location, props.errors);
846
- this.content = convertToUTF8(props.content);
1512
+ this.content = props.content;
847
1513
  }
848
1514
 
849
1515
  accept(visitor: Visitor): void {
@@ -859,6 +1525,7 @@ export class HTMLTextNode extends Node {
859
1525
  return this.childNodes().filter(node => node !== null && node !== undefined)
860
1526
  }
861
1527
 
1528
+
862
1529
  recursiveErrors(): HerbError[] {
863
1530
  return [
864
1531
  ...this.errors,
@@ -891,13 +1558,15 @@ export interface SerializedHTMLCommentNode extends SerializedNode {
891
1558
  comment_end: SerializedToken | null;
892
1559
  }
893
1560
 
894
- export interface HTMLCommentNodeProps extends BaseNodeProps {
1561
+ export interface HTMLCommentNodeProps extends Omit<BaseNodeProps, 'type'> {
1562
+ type: "AST_HTML_COMMENT_NODE";
895
1563
  comment_start: Token | null;
896
1564
  children: Node[];
897
1565
  comment_end: Token | null;
898
1566
  }
899
1567
 
900
1568
  export class HTMLCommentNode extends Node {
1569
+ declare readonly type: "AST_HTML_COMMENT_NODE";
901
1570
  readonly comment_start: Token | null;
902
1571
  readonly children: Node[];
903
1572
  readonly comment_end: Token | null;
@@ -938,6 +1607,7 @@ export class HTMLCommentNode extends Node {
938
1607
  return this.childNodes().filter(node => node !== null && node !== undefined)
939
1608
  }
940
1609
 
1610
+
941
1611
  recursiveErrors(): HerbError[] {
942
1612
  return [
943
1613
  ...this.errors,
@@ -975,13 +1645,15 @@ export interface SerializedHTMLDoctypeNode extends SerializedNode {
975
1645
  tag_closing: SerializedToken | null;
976
1646
  }
977
1647
 
978
- export interface HTMLDoctypeNodeProps extends BaseNodeProps {
1648
+ export interface HTMLDoctypeNodeProps extends Omit<BaseNodeProps, 'type'> {
1649
+ type: "AST_HTML_DOCTYPE_NODE";
979
1650
  tag_opening: Token | null;
980
1651
  children: Node[];
981
1652
  tag_closing: Token | null;
982
1653
  }
983
1654
 
984
1655
  export class HTMLDoctypeNode extends Node {
1656
+ declare readonly type: "AST_HTML_DOCTYPE_NODE";
985
1657
  readonly tag_opening: Token | null;
986
1658
  readonly children: Node[];
987
1659
  readonly tag_closing: Token | null;
@@ -1022,6 +1694,7 @@ export class HTMLDoctypeNode extends Node {
1022
1694
  return this.childNodes().filter(node => node !== null && node !== undefined)
1023
1695
  }
1024
1696
 
1697
+
1025
1698
  recursiveErrors(): HerbError[] {
1026
1699
  return [
1027
1700
  ...this.errors,
@@ -1059,13 +1732,15 @@ export interface SerializedXMLDeclarationNode extends SerializedNode {
1059
1732
  tag_closing: SerializedToken | null;
1060
1733
  }
1061
1734
 
1062
- export interface XMLDeclarationNodeProps extends BaseNodeProps {
1735
+ export interface XMLDeclarationNodeProps extends Omit<BaseNodeProps, 'type'> {
1736
+ type: "AST_XML_DECLARATION_NODE";
1063
1737
  tag_opening: Token | null;
1064
1738
  children: Node[];
1065
1739
  tag_closing: Token | null;
1066
1740
  }
1067
1741
 
1068
1742
  export class XMLDeclarationNode extends Node {
1743
+ declare readonly type: "AST_XML_DECLARATION_NODE";
1069
1744
  readonly tag_opening: Token | null;
1070
1745
  readonly children: Node[];
1071
1746
  readonly tag_closing: Token | null;
@@ -1106,6 +1781,7 @@ export class XMLDeclarationNode extends Node {
1106
1781
  return this.childNodes().filter(node => node !== null && node !== undefined)
1107
1782
  }
1108
1783
 
1784
+
1109
1785
  recursiveErrors(): HerbError[] {
1110
1786
  return [
1111
1787
  ...this.errors,
@@ -1143,13 +1819,15 @@ export interface SerializedCDATANode extends SerializedNode {
1143
1819
  tag_closing: SerializedToken | null;
1144
1820
  }
1145
1821
 
1146
- export interface CDATANodeProps extends BaseNodeProps {
1822
+ export interface CDATANodeProps extends Omit<BaseNodeProps, 'type'> {
1823
+ type: "AST_CDATA_NODE";
1147
1824
  tag_opening: Token | null;
1148
1825
  children: Node[];
1149
1826
  tag_closing: Token | null;
1150
1827
  }
1151
1828
 
1152
1829
  export class CDATANode extends Node {
1830
+ declare readonly type: "AST_CDATA_NODE";
1153
1831
  readonly tag_opening: Token | null;
1154
1832
  readonly children: Node[];
1155
1833
  readonly tag_closing: Token | null;
@@ -1190,6 +1868,7 @@ export class CDATANode extends Node {
1190
1868
  return this.childNodes().filter(node => node !== null && node !== undefined)
1191
1869
  }
1192
1870
 
1871
+
1193
1872
  recursiveErrors(): HerbError[] {
1194
1873
  return [
1195
1874
  ...this.errors,
@@ -1225,11 +1904,13 @@ export interface SerializedWhitespaceNode extends SerializedNode {
1225
1904
  value: SerializedToken | null;
1226
1905
  }
1227
1906
 
1228
- export interface WhitespaceNodeProps extends BaseNodeProps {
1907
+ export interface WhitespaceNodeProps extends Omit<BaseNodeProps, 'type'> {
1908
+ type: "AST_WHITESPACE_NODE";
1229
1909
  value: Token | null;
1230
1910
  }
1231
1911
 
1232
1912
  export class WhitespaceNode extends Node {
1913
+ declare readonly type: "AST_WHITESPACE_NODE";
1233
1914
  readonly value: Token | null;
1234
1915
 
1235
1916
  static get type(): NodeType {
@@ -1263,6 +1944,7 @@ export class WhitespaceNode extends Node {
1263
1944
  return this.childNodes().filter(node => node !== null && node !== undefined)
1264
1945
  }
1265
1946
 
1947
+
1266
1948
  recursiveErrors(): HerbError[] {
1267
1949
  return [
1268
1950
  ...this.errors,
@@ -1296,24 +1978,29 @@ export interface SerializedERBContentNode extends SerializedNode {
1296
1978
  // no-op for analyzed_ruby
1297
1979
  parsed: boolean;
1298
1980
  valid: boolean;
1981
+ prism_node: number[] | null;
1299
1982
  }
1300
1983
 
1301
- export interface ERBContentNodeProps extends BaseNodeProps {
1984
+ export interface ERBContentNodeProps extends Omit<BaseNodeProps, 'type'> {
1985
+ type: "AST_ERB_CONTENT_NODE";
1302
1986
  tag_opening: Token | null;
1303
1987
  content: Token | null;
1304
1988
  tag_closing: Token | null;
1305
1989
  // no-op for analyzed_ruby
1306
1990
  parsed: boolean;
1307
1991
  valid: boolean;
1992
+ prism_node: Uint8Array | null;
1308
1993
  }
1309
1994
 
1310
1995
  export class ERBContentNode extends Node {
1996
+ declare readonly type: "AST_ERB_CONTENT_NODE";
1311
1997
  readonly tag_opening: Token | null;
1312
1998
  readonly content: Token | null;
1313
1999
  readonly tag_closing: Token | null;
1314
2000
  // no-op for analyzed_ruby
1315
2001
  readonly parsed: boolean;
1316
2002
  readonly valid: boolean;
2003
+ readonly prism_node: Uint8Array | null;
1317
2004
 
1318
2005
  static get type(): NodeType {
1319
2006
  return "AST_ERB_CONTENT_NODE"
@@ -1330,6 +2017,7 @@ export class ERBContentNode extends Node {
1330
2017
  // no-op for analyzed_ruby
1331
2018
  parsed: data.parsed,
1332
2019
  valid: data.valid,
2020
+ prism_node: data.prism_node ? new Uint8Array(data.prism_node) : null,
1333
2021
  })
1334
2022
  }
1335
2023
 
@@ -1341,6 +2029,7 @@ export class ERBContentNode extends Node {
1341
2029
  // no-op for analyzed_ruby
1342
2030
  this.parsed = props.parsed;
1343
2031
  this.valid = props.valid;
2032
+ this.prism_node = props.prism_node;
1344
2033
  }
1345
2034
 
1346
2035
  accept(visitor: Visitor): void {
@@ -1356,6 +2045,11 @@ export class ERBContentNode extends Node {
1356
2045
  return this.childNodes().filter(node => node !== null && node !== undefined)
1357
2046
  }
1358
2047
 
2048
+ get prismNode(): PrismNode | null {
2049
+ if (!this.prism_node || !this.source) return null;
2050
+ return deserializePrismNode(this.prism_node, this.source);
2051
+ }
2052
+
1359
2053
  recursiveErrors(): HerbError[] {
1360
2054
  return [
1361
2055
  ...this.errors,
@@ -1372,6 +2066,7 @@ export class ERBContentNode extends Node {
1372
2066
  // no-op for analyzed_ruby
1373
2067
  parsed: this.parsed,
1374
2068
  valid: this.valid,
2069
+ prism_node: this.prism_node ? Array.from(this.prism_node) : null,
1375
2070
  };
1376
2071
  }
1377
2072
 
@@ -1383,9 +2078,15 @@ export class ERBContentNode extends Node {
1383
2078
  output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
1384
2079
  output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
1385
2080
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
1386
- // no-op for analyzed_ruby
1387
2081
  output += `├── parsed: ${typeof this.parsed === 'boolean' ? String(this.parsed) : "∅"}\n`;
1388
- output += `└── valid: ${typeof this.valid === 'boolean' ? String(this.valid) : "∅"}\n`;
2082
+ {
2083
+ const isLast = !this.prism_node;
2084
+ const symbol = isLast ? "└──" : "├──";
2085
+ output += `${symbol} valid: ${typeof this.valid === 'boolean' ? String(this.valid) : "∅"}\n`;
2086
+ }
2087
+ if (this.prism_node) {
2088
+ output += `└── prism_node: ${this.source ? inspectPrismSerialized(this.prism_node, this.source, " ") : `(${this.prism_node.length} bytes)`}\n`;
2089
+ }
1389
2090
 
1390
2091
  return output
1391
2092
  }
@@ -1398,13 +2099,15 @@ export interface SerializedERBEndNode extends SerializedNode {
1398
2099
  tag_closing: SerializedToken | null;
1399
2100
  }
1400
2101
 
1401
- export interface ERBEndNodeProps extends BaseNodeProps {
2102
+ export interface ERBEndNodeProps extends Omit<BaseNodeProps, 'type'> {
2103
+ type: "AST_ERB_END_NODE";
1402
2104
  tag_opening: Token | null;
1403
2105
  content: Token | null;
1404
2106
  tag_closing: Token | null;
1405
2107
  }
1406
2108
 
1407
2109
  export class ERBEndNode extends Node {
2110
+ declare readonly type: "AST_ERB_END_NODE";
1408
2111
  readonly tag_opening: Token | null;
1409
2112
  readonly content: Token | null;
1410
2113
  readonly tag_closing: Token | null;
@@ -1444,6 +2147,7 @@ export class ERBEndNode extends Node {
1444
2147
  return this.childNodes().filter(node => node !== null && node !== undefined)
1445
2148
  }
1446
2149
 
2150
+
1447
2151
  recursiveErrors(): HerbError[] {
1448
2152
  return [
1449
2153
  ...this.errors,
@@ -1481,7 +2185,8 @@ export interface SerializedERBElseNode extends SerializedNode {
1481
2185
  statements: SerializedNode[];
1482
2186
  }
1483
2187
 
1484
- export interface ERBElseNodeProps extends BaseNodeProps {
2188
+ export interface ERBElseNodeProps extends Omit<BaseNodeProps, 'type'> {
2189
+ type: "AST_ERB_ELSE_NODE";
1485
2190
  tag_opening: Token | null;
1486
2191
  content: Token | null;
1487
2192
  tag_closing: Token | null;
@@ -1489,6 +2194,7 @@ export interface ERBElseNodeProps extends BaseNodeProps {
1489
2194
  }
1490
2195
 
1491
2196
  export class ERBElseNode extends Node {
2197
+ declare readonly type: "AST_ERB_ELSE_NODE";
1492
2198
  readonly tag_opening: Token | null;
1493
2199
  readonly content: Token | null;
1494
2200
  readonly tag_closing: Token | null;
@@ -1532,6 +2238,7 @@ export class ERBElseNode extends Node {
1532
2238
  return this.childNodes().filter(node => node !== null && node !== undefined)
1533
2239
  }
1534
2240
 
2241
+
1535
2242
  recursiveErrors(): HerbError[] {
1536
2243
  return [
1537
2244
  ...this.errors,
@@ -1570,28 +2277,33 @@ export interface SerializedERBIfNode extends SerializedNode {
1570
2277
  content: SerializedToken | null;
1571
2278
  tag_closing: SerializedToken | null;
1572
2279
  then_keyword: SerializedLocation | null;
2280
+ prism_node: number[] | null;
1573
2281
  statements: SerializedNode[];
1574
- subsequent: SerializedNode | null;
2282
+ subsequent: SerializedERBIfNode | SerializedERBElseNode | null;
1575
2283
  end_node: SerializedERBEndNode | null;
1576
2284
  }
1577
2285
 
1578
- export interface ERBIfNodeProps extends BaseNodeProps {
2286
+ export interface ERBIfNodeProps extends Omit<BaseNodeProps, 'type'> {
2287
+ type: "AST_ERB_IF_NODE";
1579
2288
  tag_opening: Token | null;
1580
2289
  content: Token | null;
1581
2290
  tag_closing: Token | null;
1582
2291
  then_keyword: Location | null;
2292
+ prism_node: Uint8Array | null;
1583
2293
  statements: Node[];
1584
- subsequent: Node | null;
2294
+ subsequent: ERBIfNode | ERBElseNode | null;
1585
2295
  end_node: ERBEndNode | null;
1586
2296
  }
1587
2297
 
1588
2298
  export class ERBIfNode extends Node {
2299
+ declare readonly type: "AST_ERB_IF_NODE";
1589
2300
  readonly tag_opening: Token | null;
1590
2301
  readonly content: Token | null;
1591
2302
  readonly tag_closing: Token | null;
1592
2303
  readonly then_keyword: Location | null;
2304
+ readonly prism_node: Uint8Array | null;
1593
2305
  readonly statements: Node[];
1594
- readonly subsequent: Node | null;
2306
+ readonly subsequent: ERBIfNode | ERBElseNode | null;
1595
2307
  readonly end_node: ERBEndNode | null;
1596
2308
 
1597
2309
  static get type(): NodeType {
@@ -1607,9 +2319,10 @@ export class ERBIfNode extends Node {
1607
2319
  content: data.content ? Token.from(data.content) : null,
1608
2320
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
1609
2321
  then_keyword: data.then_keyword ? Location.from(data.then_keyword) : null,
2322
+ prism_node: data.prism_node ? new Uint8Array(data.prism_node) : null,
1610
2323
  statements: (data.statements || []).map(node => fromSerializedNode(node)),
1611
- subsequent: data.subsequent ? fromSerializedNode((data.subsequent)) : null,
1612
- end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
2324
+ subsequent: data.subsequent ? fromSerializedNode((data.subsequent)) as ERBIfNode | ERBElseNode : null,
2325
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) as ERBEndNode : null,
1613
2326
  })
1614
2327
  }
1615
2328
 
@@ -1619,6 +2332,7 @@ export class ERBIfNode extends Node {
1619
2332
  this.content = props.content;
1620
2333
  this.tag_closing = props.tag_closing;
1621
2334
  this.then_keyword = props.then_keyword;
2335
+ this.prism_node = props.prism_node;
1622
2336
  this.statements = props.statements;
1623
2337
  this.subsequent = props.subsequent;
1624
2338
  this.end_node = props.end_node;
@@ -1640,6 +2354,11 @@ export class ERBIfNode extends Node {
1640
2354
  return this.childNodes().filter(node => node !== null && node !== undefined)
1641
2355
  }
1642
2356
 
2357
+ get prismNode(): PrismNode | null {
2358
+ if (!this.prism_node || !this.source) return null;
2359
+ return deserializePrismNode(this.prism_node, this.source);
2360
+ }
2361
+
1643
2362
  recursiveErrors(): HerbError[] {
1644
2363
  return [
1645
2364
  ...this.errors,
@@ -1657,6 +2376,7 @@ export class ERBIfNode extends Node {
1657
2376
  content: this.content ? this.content.toJSON() : null,
1658
2377
  tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
1659
2378
  then_keyword: this.then_keyword ? this.then_keyword.toJSON() : null,
2379
+ prism_node: this.prism_node ? Array.from(this.prism_node) : null,
1660
2380
  statements: this.statements.map(node => node.toJSON()),
1661
2381
  subsequent: this.subsequent ? this.subsequent.toJSON() : null,
1662
2382
  end_node: this.end_node ? this.end_node.toJSON() : null,
@@ -1672,6 +2392,9 @@ export class ERBIfNode extends Node {
1672
2392
  output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
1673
2393
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
1674
2394
  output += `├── then_keyword: ${this.then_keyword ? "(location: " + this.then_keyword.treeInspect() + ")" : "∅"}\n`;
2395
+ if (this.prism_node) {
2396
+ output += `├── prism_node: ${this.source ? inspectPrismSerialized(this.prism_node, this.source, "│ ") : `(${this.prism_node.length} bytes)`}\n`;
2397
+ }
1675
2398
  output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
1676
2399
  output += `├── subsequent: ${this.inspectNode(this.subsequent, "│ ")}`;
1677
2400
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
@@ -1685,22 +2408,27 @@ export interface SerializedERBBlockNode extends SerializedNode {
1685
2408
  tag_opening: SerializedToken | null;
1686
2409
  content: SerializedToken | null;
1687
2410
  tag_closing: SerializedToken | null;
2411
+ prism_node: number[] | null;
1688
2412
  body: SerializedNode[];
1689
2413
  end_node: SerializedERBEndNode | null;
1690
2414
  }
1691
2415
 
1692
- export interface ERBBlockNodeProps extends BaseNodeProps {
2416
+ export interface ERBBlockNodeProps extends Omit<BaseNodeProps, 'type'> {
2417
+ type: "AST_ERB_BLOCK_NODE";
1693
2418
  tag_opening: Token | null;
1694
2419
  content: Token | null;
1695
2420
  tag_closing: Token | null;
2421
+ prism_node: Uint8Array | null;
1696
2422
  body: Node[];
1697
2423
  end_node: ERBEndNode | null;
1698
2424
  }
1699
2425
 
1700
2426
  export class ERBBlockNode extends Node {
2427
+ declare readonly type: "AST_ERB_BLOCK_NODE";
1701
2428
  readonly tag_opening: Token | null;
1702
2429
  readonly content: Token | null;
1703
2430
  readonly tag_closing: Token | null;
2431
+ readonly prism_node: Uint8Array | null;
1704
2432
  readonly body: Node[];
1705
2433
  readonly end_node: ERBEndNode | null;
1706
2434
 
@@ -1716,8 +2444,9 @@ export class ERBBlockNode extends Node {
1716
2444
  tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
1717
2445
  content: data.content ? Token.from(data.content) : null,
1718
2446
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2447
+ prism_node: data.prism_node ? new Uint8Array(data.prism_node) : null,
1719
2448
  body: (data.body || []).map(node => fromSerializedNode(node)),
1720
- end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
2449
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) as ERBEndNode : null,
1721
2450
  })
1722
2451
  }
1723
2452
 
@@ -1726,6 +2455,7 @@ export class ERBBlockNode extends Node {
1726
2455
  this.tag_opening = props.tag_opening;
1727
2456
  this.content = props.content;
1728
2457
  this.tag_closing = props.tag_closing;
2458
+ this.prism_node = props.prism_node;
1729
2459
  this.body = props.body;
1730
2460
  this.end_node = props.end_node;
1731
2461
  }
@@ -1745,6 +2475,11 @@ export class ERBBlockNode extends Node {
1745
2475
  return this.childNodes().filter(node => node !== null && node !== undefined)
1746
2476
  }
1747
2477
 
2478
+ get prismNode(): PrismNode | null {
2479
+ if (!this.prism_node || !this.source) return null;
2480
+ return deserializePrismNode(this.prism_node, this.source);
2481
+ }
2482
+
1748
2483
  recursiveErrors(): HerbError[] {
1749
2484
  return [
1750
2485
  ...this.errors,
@@ -1760,6 +2495,7 @@ export class ERBBlockNode extends Node {
1760
2495
  tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
1761
2496
  content: this.content ? this.content.toJSON() : null,
1762
2497
  tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
2498
+ prism_node: this.prism_node ? Array.from(this.prism_node) : null,
1763
2499
  body: this.body.map(node => node.toJSON()),
1764
2500
  end_node: this.end_node ? this.end_node.toJSON() : null,
1765
2501
  };
@@ -1773,6 +2509,9 @@ export class ERBBlockNode extends Node {
1773
2509
  output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
1774
2510
  output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
1775
2511
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
2512
+ if (this.prism_node) {
2513
+ output += `├── prism_node: ${this.source ? inspectPrismSerialized(this.prism_node, this.source, "│ ") : `(${this.prism_node.length} bytes)`}\n`;
2514
+ }
1776
2515
  output += `├── body: ${this.inspectArray(this.body, "│ ")}`;
1777
2516
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
1778
2517
 
@@ -1789,7 +2528,8 @@ export interface SerializedERBWhenNode extends SerializedNode {
1789
2528
  statements: SerializedNode[];
1790
2529
  }
1791
2530
 
1792
- export interface ERBWhenNodeProps extends BaseNodeProps {
2531
+ export interface ERBWhenNodeProps extends Omit<BaseNodeProps, 'type'> {
2532
+ type: "AST_ERB_WHEN_NODE";
1793
2533
  tag_opening: Token | null;
1794
2534
  content: Token | null;
1795
2535
  tag_closing: Token | null;
@@ -1798,6 +2538,7 @@ export interface ERBWhenNodeProps extends BaseNodeProps {
1798
2538
  }
1799
2539
 
1800
2540
  export class ERBWhenNode extends Node {
2541
+ declare readonly type: "AST_ERB_WHEN_NODE";
1801
2542
  readonly tag_opening: Token | null;
1802
2543
  readonly content: Token | null;
1803
2544
  readonly tag_closing: Token | null;
@@ -1844,6 +2585,7 @@ export class ERBWhenNode extends Node {
1844
2585
  return this.childNodes().filter(node => node !== null && node !== undefined)
1845
2586
  }
1846
2587
 
2588
+
1847
2589
  recursiveErrors(): HerbError[] {
1848
2590
  return [
1849
2591
  ...this.errors,
@@ -1884,26 +2626,31 @@ export interface SerializedERBCaseNode extends SerializedNode {
1884
2626
  content: SerializedToken | null;
1885
2627
  tag_closing: SerializedToken | null;
1886
2628
  children: SerializedNode[];
2629
+ prism_node: number[] | null;
1887
2630
  conditions: SerializedNode[];
1888
2631
  else_clause: SerializedERBElseNode | null;
1889
2632
  end_node: SerializedERBEndNode | null;
1890
2633
  }
1891
2634
 
1892
- export interface ERBCaseNodeProps extends BaseNodeProps {
2635
+ export interface ERBCaseNodeProps extends Omit<BaseNodeProps, 'type'> {
2636
+ type: "AST_ERB_CASE_NODE";
1893
2637
  tag_opening: Token | null;
1894
2638
  content: Token | null;
1895
2639
  tag_closing: Token | null;
1896
2640
  children: Node[];
2641
+ prism_node: Uint8Array | null;
1897
2642
  conditions: any[];
1898
2643
  else_clause: ERBElseNode | null;
1899
2644
  end_node: ERBEndNode | null;
1900
2645
  }
1901
2646
 
1902
2647
  export class ERBCaseNode extends Node {
2648
+ declare readonly type: "AST_ERB_CASE_NODE";
1903
2649
  readonly tag_opening: Token | null;
1904
2650
  readonly content: Token | null;
1905
2651
  readonly tag_closing: Token | null;
1906
2652
  readonly children: Node[];
2653
+ readonly prism_node: Uint8Array | null;
1907
2654
  readonly conditions: Node[];
1908
2655
  readonly else_clause: ERBElseNode | null;
1909
2656
  readonly end_node: ERBEndNode | null;
@@ -1921,9 +2668,10 @@ export class ERBCaseNode extends Node {
1921
2668
  content: data.content ? Token.from(data.content) : null,
1922
2669
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
1923
2670
  children: (data.children || []).map(node => fromSerializedNode(node)),
2671
+ prism_node: data.prism_node ? new Uint8Array(data.prism_node) : null,
1924
2672
  conditions: (data.conditions || []).map(node => fromSerializedNode(node)),
1925
- else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
1926
- end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
2673
+ else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) as ERBElseNode : null,
2674
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) as ERBEndNode : null,
1927
2675
  })
1928
2676
  }
1929
2677
 
@@ -1933,6 +2681,7 @@ export class ERBCaseNode extends Node {
1933
2681
  this.content = props.content;
1934
2682
  this.tag_closing = props.tag_closing;
1935
2683
  this.children = props.children;
2684
+ this.prism_node = props.prism_node;
1936
2685
  this.conditions = props.conditions;
1937
2686
  this.else_clause = props.else_clause;
1938
2687
  this.end_node = props.end_node;
@@ -1955,6 +2704,11 @@ export class ERBCaseNode extends Node {
1955
2704
  return this.childNodes().filter(node => node !== null && node !== undefined)
1956
2705
  }
1957
2706
 
2707
+ get prismNode(): PrismNode | null {
2708
+ if (!this.prism_node || !this.source) return null;
2709
+ return deserializePrismNode(this.prism_node, this.source);
2710
+ }
2711
+
1958
2712
  recursiveErrors(): HerbError[] {
1959
2713
  return [
1960
2714
  ...this.errors,
@@ -1973,6 +2727,7 @@ export class ERBCaseNode extends Node {
1973
2727
  content: this.content ? this.content.toJSON() : null,
1974
2728
  tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
1975
2729
  children: this.children.map(node => node.toJSON()),
2730
+ prism_node: this.prism_node ? Array.from(this.prism_node) : null,
1976
2731
  conditions: this.conditions.map(node => node.toJSON()),
1977
2732
  else_clause: this.else_clause ? this.else_clause.toJSON() : null,
1978
2733
  end_node: this.end_node ? this.end_node.toJSON() : null,
@@ -1988,6 +2743,9 @@ export class ERBCaseNode extends Node {
1988
2743
  output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
1989
2744
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
1990
2745
  output += `├── children: ${this.inspectArray(this.children, "│ ")}`;
2746
+ if (this.prism_node) {
2747
+ output += `├── prism_node: ${this.source ? inspectPrismSerialized(this.prism_node, this.source, "│ ") : `(${this.prism_node.length} bytes)`}\n`;
2748
+ }
1991
2749
  output += `├── conditions: ${this.inspectArray(this.conditions, "│ ")}`;
1992
2750
  output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
1993
2751
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
@@ -2002,26 +2760,31 @@ export interface SerializedERBCaseMatchNode extends SerializedNode {
2002
2760
  content: SerializedToken | null;
2003
2761
  tag_closing: SerializedToken | null;
2004
2762
  children: SerializedNode[];
2763
+ prism_node: number[] | null;
2005
2764
  conditions: SerializedNode[];
2006
2765
  else_clause: SerializedERBElseNode | null;
2007
2766
  end_node: SerializedERBEndNode | null;
2008
2767
  }
2009
2768
 
2010
- export interface ERBCaseMatchNodeProps extends BaseNodeProps {
2769
+ export interface ERBCaseMatchNodeProps extends Omit<BaseNodeProps, 'type'> {
2770
+ type: "AST_ERB_CASE_MATCH_NODE";
2011
2771
  tag_opening: Token | null;
2012
2772
  content: Token | null;
2013
2773
  tag_closing: Token | null;
2014
2774
  children: Node[];
2775
+ prism_node: Uint8Array | null;
2015
2776
  conditions: any[];
2016
2777
  else_clause: ERBElseNode | null;
2017
2778
  end_node: ERBEndNode | null;
2018
2779
  }
2019
2780
 
2020
2781
  export class ERBCaseMatchNode extends Node {
2782
+ declare readonly type: "AST_ERB_CASE_MATCH_NODE";
2021
2783
  readonly tag_opening: Token | null;
2022
2784
  readonly content: Token | null;
2023
2785
  readonly tag_closing: Token | null;
2024
2786
  readonly children: Node[];
2787
+ readonly prism_node: Uint8Array | null;
2025
2788
  readonly conditions: Node[];
2026
2789
  readonly else_clause: ERBElseNode | null;
2027
2790
  readonly end_node: ERBEndNode | null;
@@ -2039,9 +2802,10 @@ export class ERBCaseMatchNode extends Node {
2039
2802
  content: data.content ? Token.from(data.content) : null,
2040
2803
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2041
2804
  children: (data.children || []).map(node => fromSerializedNode(node)),
2805
+ prism_node: data.prism_node ? new Uint8Array(data.prism_node) : null,
2042
2806
  conditions: (data.conditions || []).map(node => fromSerializedNode(node)),
2043
- else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
2044
- end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
2807
+ else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) as ERBElseNode : null,
2808
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) as ERBEndNode : null,
2045
2809
  })
2046
2810
  }
2047
2811
 
@@ -2051,6 +2815,7 @@ export class ERBCaseMatchNode extends Node {
2051
2815
  this.content = props.content;
2052
2816
  this.tag_closing = props.tag_closing;
2053
2817
  this.children = props.children;
2818
+ this.prism_node = props.prism_node;
2054
2819
  this.conditions = props.conditions;
2055
2820
  this.else_clause = props.else_clause;
2056
2821
  this.end_node = props.end_node;
@@ -2073,6 +2838,11 @@ export class ERBCaseMatchNode extends Node {
2073
2838
  return this.childNodes().filter(node => node !== null && node !== undefined)
2074
2839
  }
2075
2840
 
2841
+ get prismNode(): PrismNode | null {
2842
+ if (!this.prism_node || !this.source) return null;
2843
+ return deserializePrismNode(this.prism_node, this.source);
2844
+ }
2845
+
2076
2846
  recursiveErrors(): HerbError[] {
2077
2847
  return [
2078
2848
  ...this.errors,
@@ -2091,6 +2861,7 @@ export class ERBCaseMatchNode extends Node {
2091
2861
  content: this.content ? this.content.toJSON() : null,
2092
2862
  tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
2093
2863
  children: this.children.map(node => node.toJSON()),
2864
+ prism_node: this.prism_node ? Array.from(this.prism_node) : null,
2094
2865
  conditions: this.conditions.map(node => node.toJSON()),
2095
2866
  else_clause: this.else_clause ? this.else_clause.toJSON() : null,
2096
2867
  end_node: this.end_node ? this.end_node.toJSON() : null,
@@ -2106,6 +2877,9 @@ export class ERBCaseMatchNode extends Node {
2106
2877
  output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
2107
2878
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
2108
2879
  output += `├── children: ${this.inspectArray(this.children, "│ ")}`;
2880
+ if (this.prism_node) {
2881
+ output += `├── prism_node: ${this.source ? inspectPrismSerialized(this.prism_node, this.source, "│ ") : `(${this.prism_node.length} bytes)`}\n`;
2882
+ }
2109
2883
  output += `├── conditions: ${this.inspectArray(this.conditions, "│ ")}`;
2110
2884
  output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
2111
2885
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
@@ -2119,22 +2893,27 @@ export interface SerializedERBWhileNode extends SerializedNode {
2119
2893
  tag_opening: SerializedToken | null;
2120
2894
  content: SerializedToken | null;
2121
2895
  tag_closing: SerializedToken | null;
2896
+ prism_node: number[] | null;
2122
2897
  statements: SerializedNode[];
2123
2898
  end_node: SerializedERBEndNode | null;
2124
2899
  }
2125
2900
 
2126
- export interface ERBWhileNodeProps extends BaseNodeProps {
2901
+ export interface ERBWhileNodeProps extends Omit<BaseNodeProps, 'type'> {
2902
+ type: "AST_ERB_WHILE_NODE";
2127
2903
  tag_opening: Token | null;
2128
2904
  content: Token | null;
2129
2905
  tag_closing: Token | null;
2906
+ prism_node: Uint8Array | null;
2130
2907
  statements: Node[];
2131
2908
  end_node: ERBEndNode | null;
2132
2909
  }
2133
2910
 
2134
2911
  export class ERBWhileNode extends Node {
2912
+ declare readonly type: "AST_ERB_WHILE_NODE";
2135
2913
  readonly tag_opening: Token | null;
2136
2914
  readonly content: Token | null;
2137
2915
  readonly tag_closing: Token | null;
2916
+ readonly prism_node: Uint8Array | null;
2138
2917
  readonly statements: Node[];
2139
2918
  readonly end_node: ERBEndNode | null;
2140
2919
 
@@ -2150,8 +2929,9 @@ export class ERBWhileNode extends Node {
2150
2929
  tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
2151
2930
  content: data.content ? Token.from(data.content) : null,
2152
2931
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2932
+ prism_node: data.prism_node ? new Uint8Array(data.prism_node) : null,
2153
2933
  statements: (data.statements || []).map(node => fromSerializedNode(node)),
2154
- end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
2934
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) as ERBEndNode : null,
2155
2935
  })
2156
2936
  }
2157
2937
 
@@ -2160,6 +2940,7 @@ export class ERBWhileNode extends Node {
2160
2940
  this.tag_opening = props.tag_opening;
2161
2941
  this.content = props.content;
2162
2942
  this.tag_closing = props.tag_closing;
2943
+ this.prism_node = props.prism_node;
2163
2944
  this.statements = props.statements;
2164
2945
  this.end_node = props.end_node;
2165
2946
  }
@@ -2179,6 +2960,11 @@ export class ERBWhileNode extends Node {
2179
2960
  return this.childNodes().filter(node => node !== null && node !== undefined)
2180
2961
  }
2181
2962
 
2963
+ get prismNode(): PrismNode | null {
2964
+ if (!this.prism_node || !this.source) return null;
2965
+ return deserializePrismNode(this.prism_node, this.source);
2966
+ }
2967
+
2182
2968
  recursiveErrors(): HerbError[] {
2183
2969
  return [
2184
2970
  ...this.errors,
@@ -2194,6 +2980,7 @@ export class ERBWhileNode extends Node {
2194
2980
  tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
2195
2981
  content: this.content ? this.content.toJSON() : null,
2196
2982
  tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
2983
+ prism_node: this.prism_node ? Array.from(this.prism_node) : null,
2197
2984
  statements: this.statements.map(node => node.toJSON()),
2198
2985
  end_node: this.end_node ? this.end_node.toJSON() : null,
2199
2986
  };
@@ -2207,6 +2994,9 @@ export class ERBWhileNode extends Node {
2207
2994
  output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
2208
2995
  output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
2209
2996
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
2997
+ if (this.prism_node) {
2998
+ output += `├── prism_node: ${this.source ? inspectPrismSerialized(this.prism_node, this.source, "│ ") : `(${this.prism_node.length} bytes)`}\n`;
2999
+ }
2210
3000
  output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
2211
3001
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
2212
3002
 
@@ -2219,22 +3009,27 @@ export interface SerializedERBUntilNode extends SerializedNode {
2219
3009
  tag_opening: SerializedToken | null;
2220
3010
  content: SerializedToken | null;
2221
3011
  tag_closing: SerializedToken | null;
3012
+ prism_node: number[] | null;
2222
3013
  statements: SerializedNode[];
2223
3014
  end_node: SerializedERBEndNode | null;
2224
3015
  }
2225
3016
 
2226
- export interface ERBUntilNodeProps extends BaseNodeProps {
3017
+ export interface ERBUntilNodeProps extends Omit<BaseNodeProps, 'type'> {
3018
+ type: "AST_ERB_UNTIL_NODE";
2227
3019
  tag_opening: Token | null;
2228
3020
  content: Token | null;
2229
3021
  tag_closing: Token | null;
3022
+ prism_node: Uint8Array | null;
2230
3023
  statements: Node[];
2231
3024
  end_node: ERBEndNode | null;
2232
3025
  }
2233
3026
 
2234
3027
  export class ERBUntilNode extends Node {
3028
+ declare readonly type: "AST_ERB_UNTIL_NODE";
2235
3029
  readonly tag_opening: Token | null;
2236
3030
  readonly content: Token | null;
2237
3031
  readonly tag_closing: Token | null;
3032
+ readonly prism_node: Uint8Array | null;
2238
3033
  readonly statements: Node[];
2239
3034
  readonly end_node: ERBEndNode | null;
2240
3035
 
@@ -2250,8 +3045,9 @@ export class ERBUntilNode extends Node {
2250
3045
  tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
2251
3046
  content: data.content ? Token.from(data.content) : null,
2252
3047
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
3048
+ prism_node: data.prism_node ? new Uint8Array(data.prism_node) : null,
2253
3049
  statements: (data.statements || []).map(node => fromSerializedNode(node)),
2254
- end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
3050
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) as ERBEndNode : null,
2255
3051
  })
2256
3052
  }
2257
3053
 
@@ -2260,6 +3056,7 @@ export class ERBUntilNode extends Node {
2260
3056
  this.tag_opening = props.tag_opening;
2261
3057
  this.content = props.content;
2262
3058
  this.tag_closing = props.tag_closing;
3059
+ this.prism_node = props.prism_node;
2263
3060
  this.statements = props.statements;
2264
3061
  this.end_node = props.end_node;
2265
3062
  }
@@ -2279,6 +3076,11 @@ export class ERBUntilNode extends Node {
2279
3076
  return this.childNodes().filter(node => node !== null && node !== undefined)
2280
3077
  }
2281
3078
 
3079
+ get prismNode(): PrismNode | null {
3080
+ if (!this.prism_node || !this.source) return null;
3081
+ return deserializePrismNode(this.prism_node, this.source);
3082
+ }
3083
+
2282
3084
  recursiveErrors(): HerbError[] {
2283
3085
  return [
2284
3086
  ...this.errors,
@@ -2294,6 +3096,7 @@ export class ERBUntilNode extends Node {
2294
3096
  tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
2295
3097
  content: this.content ? this.content.toJSON() : null,
2296
3098
  tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
3099
+ prism_node: this.prism_node ? Array.from(this.prism_node) : null,
2297
3100
  statements: this.statements.map(node => node.toJSON()),
2298
3101
  end_node: this.end_node ? this.end_node.toJSON() : null,
2299
3102
  };
@@ -2307,6 +3110,9 @@ export class ERBUntilNode extends Node {
2307
3110
  output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
2308
3111
  output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
2309
3112
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
3113
+ if (this.prism_node) {
3114
+ output += `├── prism_node: ${this.source ? inspectPrismSerialized(this.prism_node, this.source, "│ ") : `(${this.prism_node.length} bytes)`}\n`;
3115
+ }
2310
3116
  output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
2311
3117
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
2312
3118
 
@@ -2319,22 +3125,27 @@ export interface SerializedERBForNode extends SerializedNode {
2319
3125
  tag_opening: SerializedToken | null;
2320
3126
  content: SerializedToken | null;
2321
3127
  tag_closing: SerializedToken | null;
3128
+ prism_node: number[] | null;
2322
3129
  statements: SerializedNode[];
2323
3130
  end_node: SerializedERBEndNode | null;
2324
3131
  }
2325
3132
 
2326
- export interface ERBForNodeProps extends BaseNodeProps {
3133
+ export interface ERBForNodeProps extends Omit<BaseNodeProps, 'type'> {
3134
+ type: "AST_ERB_FOR_NODE";
2327
3135
  tag_opening: Token | null;
2328
3136
  content: Token | null;
2329
3137
  tag_closing: Token | null;
3138
+ prism_node: Uint8Array | null;
2330
3139
  statements: Node[];
2331
3140
  end_node: ERBEndNode | null;
2332
3141
  }
2333
3142
 
2334
3143
  export class ERBForNode extends Node {
3144
+ declare readonly type: "AST_ERB_FOR_NODE";
2335
3145
  readonly tag_opening: Token | null;
2336
3146
  readonly content: Token | null;
2337
3147
  readonly tag_closing: Token | null;
3148
+ readonly prism_node: Uint8Array | null;
2338
3149
  readonly statements: Node[];
2339
3150
  readonly end_node: ERBEndNode | null;
2340
3151
 
@@ -2350,8 +3161,9 @@ export class ERBForNode extends Node {
2350
3161
  tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
2351
3162
  content: data.content ? Token.from(data.content) : null,
2352
3163
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
3164
+ prism_node: data.prism_node ? new Uint8Array(data.prism_node) : null,
2353
3165
  statements: (data.statements || []).map(node => fromSerializedNode(node)),
2354
- end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
3166
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) as ERBEndNode : null,
2355
3167
  })
2356
3168
  }
2357
3169
 
@@ -2360,6 +3172,7 @@ export class ERBForNode extends Node {
2360
3172
  this.tag_opening = props.tag_opening;
2361
3173
  this.content = props.content;
2362
3174
  this.tag_closing = props.tag_closing;
3175
+ this.prism_node = props.prism_node;
2363
3176
  this.statements = props.statements;
2364
3177
  this.end_node = props.end_node;
2365
3178
  }
@@ -2379,6 +3192,11 @@ export class ERBForNode extends Node {
2379
3192
  return this.childNodes().filter(node => node !== null && node !== undefined)
2380
3193
  }
2381
3194
 
3195
+ get prismNode(): PrismNode | null {
3196
+ if (!this.prism_node || !this.source) return null;
3197
+ return deserializePrismNode(this.prism_node, this.source);
3198
+ }
3199
+
2382
3200
  recursiveErrors(): HerbError[] {
2383
3201
  return [
2384
3202
  ...this.errors,
@@ -2394,6 +3212,7 @@ export class ERBForNode extends Node {
2394
3212
  tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
2395
3213
  content: this.content ? this.content.toJSON() : null,
2396
3214
  tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
3215
+ prism_node: this.prism_node ? Array.from(this.prism_node) : null,
2397
3216
  statements: this.statements.map(node => node.toJSON()),
2398
3217
  end_node: this.end_node ? this.end_node.toJSON() : null,
2399
3218
  };
@@ -2407,6 +3226,9 @@ export class ERBForNode extends Node {
2407
3226
  output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
2408
3227
  output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
2409
3228
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
3229
+ if (this.prism_node) {
3230
+ output += `├── prism_node: ${this.source ? inspectPrismSerialized(this.prism_node, this.source, "│ ") : `(${this.prism_node.length} bytes)`}\n`;
3231
+ }
2410
3232
  output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
2411
3233
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
2412
3234
 
@@ -2423,7 +3245,8 @@ export interface SerializedERBRescueNode extends SerializedNode {
2423
3245
  subsequent: SerializedERBRescueNode | null;
2424
3246
  }
2425
3247
 
2426
- export interface ERBRescueNodeProps extends BaseNodeProps {
3248
+ export interface ERBRescueNodeProps extends Omit<BaseNodeProps, 'type'> {
3249
+ type: "AST_ERB_RESCUE_NODE";
2427
3250
  tag_opening: Token | null;
2428
3251
  content: Token | null;
2429
3252
  tag_closing: Token | null;
@@ -2432,6 +3255,7 @@ export interface ERBRescueNodeProps extends BaseNodeProps {
2432
3255
  }
2433
3256
 
2434
3257
  export class ERBRescueNode extends Node {
3258
+ declare readonly type: "AST_ERB_RESCUE_NODE";
2435
3259
  readonly tag_opening: Token | null;
2436
3260
  readonly content: Token | null;
2437
3261
  readonly tag_closing: Token | null;
@@ -2451,7 +3275,7 @@ export class ERBRescueNode extends Node {
2451
3275
  content: data.content ? Token.from(data.content) : null,
2452
3276
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2453
3277
  statements: (data.statements || []).map(node => fromSerializedNode(node)),
2454
- subsequent: data.subsequent ? fromSerializedNode((data.subsequent)) : null,
3278
+ subsequent: data.subsequent ? fromSerializedNode((data.subsequent)) as ERBRescueNode : null,
2455
3279
  })
2456
3280
  }
2457
3281
 
@@ -2479,6 +3303,7 @@ export class ERBRescueNode extends Node {
2479
3303
  return this.childNodes().filter(node => node !== null && node !== undefined)
2480
3304
  }
2481
3305
 
3306
+
2482
3307
  recursiveErrors(): HerbError[] {
2483
3308
  return [
2484
3309
  ...this.errors,
@@ -2522,7 +3347,8 @@ export interface SerializedERBEnsureNode extends SerializedNode {
2522
3347
  statements: SerializedNode[];
2523
3348
  }
2524
3349
 
2525
- export interface ERBEnsureNodeProps extends BaseNodeProps {
3350
+ export interface ERBEnsureNodeProps extends Omit<BaseNodeProps, 'type'> {
3351
+ type: "AST_ERB_ENSURE_NODE";
2526
3352
  tag_opening: Token | null;
2527
3353
  content: Token | null;
2528
3354
  tag_closing: Token | null;
@@ -2530,6 +3356,7 @@ export interface ERBEnsureNodeProps extends BaseNodeProps {
2530
3356
  }
2531
3357
 
2532
3358
  export class ERBEnsureNode extends Node {
3359
+ declare readonly type: "AST_ERB_ENSURE_NODE";
2533
3360
  readonly tag_opening: Token | null;
2534
3361
  readonly content: Token | null;
2535
3362
  readonly tag_closing: Token | null;
@@ -2573,6 +3400,7 @@ export class ERBEnsureNode extends Node {
2573
3400
  return this.childNodes().filter(node => node !== null && node !== undefined)
2574
3401
  }
2575
3402
 
3403
+
2576
3404
  recursiveErrors(): HerbError[] {
2577
3405
  return [
2578
3406
  ...this.errors,
@@ -2610,6 +3438,7 @@ export interface SerializedERBBeginNode extends SerializedNode {
2610
3438
  tag_opening: SerializedToken | null;
2611
3439
  content: SerializedToken | null;
2612
3440
  tag_closing: SerializedToken | null;
3441
+ prism_node: number[] | null;
2613
3442
  statements: SerializedNode[];
2614
3443
  rescue_clause: SerializedERBRescueNode | null;
2615
3444
  else_clause: SerializedERBElseNode | null;
@@ -2617,10 +3446,12 @@ export interface SerializedERBBeginNode extends SerializedNode {
2617
3446
  end_node: SerializedERBEndNode | null;
2618
3447
  }
2619
3448
 
2620
- export interface ERBBeginNodeProps extends BaseNodeProps {
3449
+ export interface ERBBeginNodeProps extends Omit<BaseNodeProps, 'type'> {
3450
+ type: "AST_ERB_BEGIN_NODE";
2621
3451
  tag_opening: Token | null;
2622
3452
  content: Token | null;
2623
3453
  tag_closing: Token | null;
3454
+ prism_node: Uint8Array | null;
2624
3455
  statements: Node[];
2625
3456
  rescue_clause: ERBRescueNode | null;
2626
3457
  else_clause: ERBElseNode | null;
@@ -2629,9 +3460,11 @@ export interface ERBBeginNodeProps extends BaseNodeProps {
2629
3460
  }
2630
3461
 
2631
3462
  export class ERBBeginNode extends Node {
3463
+ declare readonly type: "AST_ERB_BEGIN_NODE";
2632
3464
  readonly tag_opening: Token | null;
2633
3465
  readonly content: Token | null;
2634
3466
  readonly tag_closing: Token | null;
3467
+ readonly prism_node: Uint8Array | null;
2635
3468
  readonly statements: Node[];
2636
3469
  readonly rescue_clause: ERBRescueNode | null;
2637
3470
  readonly else_clause: ERBElseNode | null;
@@ -2650,11 +3483,12 @@ export class ERBBeginNode extends Node {
2650
3483
  tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
2651
3484
  content: data.content ? Token.from(data.content) : null,
2652
3485
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
3486
+ prism_node: data.prism_node ? new Uint8Array(data.prism_node) : null,
2653
3487
  statements: (data.statements || []).map(node => fromSerializedNode(node)),
2654
- rescue_clause: data.rescue_clause ? fromSerializedNode((data.rescue_clause)) : null,
2655
- else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
2656
- ensure_clause: data.ensure_clause ? fromSerializedNode((data.ensure_clause)) : null,
2657
- end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
3488
+ rescue_clause: data.rescue_clause ? fromSerializedNode((data.rescue_clause)) as ERBRescueNode : null,
3489
+ else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) as ERBElseNode : null,
3490
+ ensure_clause: data.ensure_clause ? fromSerializedNode((data.ensure_clause)) as ERBEnsureNode : null,
3491
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) as ERBEndNode : null,
2658
3492
  })
2659
3493
  }
2660
3494
 
@@ -2663,6 +3497,7 @@ export class ERBBeginNode extends Node {
2663
3497
  this.tag_opening = props.tag_opening;
2664
3498
  this.content = props.content;
2665
3499
  this.tag_closing = props.tag_closing;
3500
+ this.prism_node = props.prism_node;
2666
3501
  this.statements = props.statements;
2667
3502
  this.rescue_clause = props.rescue_clause;
2668
3503
  this.else_clause = props.else_clause;
@@ -2688,6 +3523,11 @@ export class ERBBeginNode extends Node {
2688
3523
  return this.childNodes().filter(node => node !== null && node !== undefined)
2689
3524
  }
2690
3525
 
3526
+ get prismNode(): PrismNode | null {
3527
+ if (!this.prism_node || !this.source) return null;
3528
+ return deserializePrismNode(this.prism_node, this.source);
3529
+ }
3530
+
2691
3531
  recursiveErrors(): HerbError[] {
2692
3532
  return [
2693
3533
  ...this.errors,
@@ -2706,6 +3546,7 @@ export class ERBBeginNode extends Node {
2706
3546
  tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
2707
3547
  content: this.content ? this.content.toJSON() : null,
2708
3548
  tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
3549
+ prism_node: this.prism_node ? Array.from(this.prism_node) : null,
2709
3550
  statements: this.statements.map(node => node.toJSON()),
2710
3551
  rescue_clause: this.rescue_clause ? this.rescue_clause.toJSON() : null,
2711
3552
  else_clause: this.else_clause ? this.else_clause.toJSON() : null,
@@ -2722,6 +3563,9 @@ export class ERBBeginNode extends Node {
2722
3563
  output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
2723
3564
  output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
2724
3565
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
3566
+ if (this.prism_node) {
3567
+ output += `├── prism_node: ${this.source ? inspectPrismSerialized(this.prism_node, this.source, "│ ") : `(${this.prism_node.length} bytes)`}\n`;
3568
+ }
2725
3569
  output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
2726
3570
  output += `├── rescue_clause: ${this.inspectNode(this.rescue_clause, "│ ")}`;
2727
3571
  output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
@@ -2738,26 +3582,31 @@ export interface SerializedERBUnlessNode extends SerializedNode {
2738
3582
  content: SerializedToken | null;
2739
3583
  tag_closing: SerializedToken | null;
2740
3584
  then_keyword: SerializedLocation | null;
3585
+ prism_node: number[] | null;
2741
3586
  statements: SerializedNode[];
2742
3587
  else_clause: SerializedERBElseNode | null;
2743
3588
  end_node: SerializedERBEndNode | null;
2744
3589
  }
2745
3590
 
2746
- export interface ERBUnlessNodeProps extends BaseNodeProps {
3591
+ export interface ERBUnlessNodeProps extends Omit<BaseNodeProps, 'type'> {
3592
+ type: "AST_ERB_UNLESS_NODE";
2747
3593
  tag_opening: Token | null;
2748
3594
  content: Token | null;
2749
3595
  tag_closing: Token | null;
2750
3596
  then_keyword: Location | null;
3597
+ prism_node: Uint8Array | null;
2751
3598
  statements: Node[];
2752
3599
  else_clause: ERBElseNode | null;
2753
3600
  end_node: ERBEndNode | null;
2754
3601
  }
2755
3602
 
2756
3603
  export class ERBUnlessNode extends Node {
3604
+ declare readonly type: "AST_ERB_UNLESS_NODE";
2757
3605
  readonly tag_opening: Token | null;
2758
3606
  readonly content: Token | null;
2759
3607
  readonly tag_closing: Token | null;
2760
3608
  readonly then_keyword: Location | null;
3609
+ readonly prism_node: Uint8Array | null;
2761
3610
  readonly statements: Node[];
2762
3611
  readonly else_clause: ERBElseNode | null;
2763
3612
  readonly end_node: ERBEndNode | null;
@@ -2775,9 +3624,10 @@ export class ERBUnlessNode extends Node {
2775
3624
  content: data.content ? Token.from(data.content) : null,
2776
3625
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2777
3626
  then_keyword: data.then_keyword ? Location.from(data.then_keyword) : null,
3627
+ prism_node: data.prism_node ? new Uint8Array(data.prism_node) : null,
2778
3628
  statements: (data.statements || []).map(node => fromSerializedNode(node)),
2779
- else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
2780
- end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
3629
+ else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) as ERBElseNode : null,
3630
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) as ERBEndNode : null,
2781
3631
  })
2782
3632
  }
2783
3633
 
@@ -2787,6 +3637,7 @@ export class ERBUnlessNode extends Node {
2787
3637
  this.content = props.content;
2788
3638
  this.tag_closing = props.tag_closing;
2789
3639
  this.then_keyword = props.then_keyword;
3640
+ this.prism_node = props.prism_node;
2790
3641
  this.statements = props.statements;
2791
3642
  this.else_clause = props.else_clause;
2792
3643
  this.end_node = props.end_node;
@@ -2808,6 +3659,11 @@ export class ERBUnlessNode extends Node {
2808
3659
  return this.childNodes().filter(node => node !== null && node !== undefined)
2809
3660
  }
2810
3661
 
3662
+ get prismNode(): PrismNode | null {
3663
+ if (!this.prism_node || !this.source) return null;
3664
+ return deserializePrismNode(this.prism_node, this.source);
3665
+ }
3666
+
2811
3667
  recursiveErrors(): HerbError[] {
2812
3668
  return [
2813
3669
  ...this.errors,
@@ -2825,6 +3681,7 @@ export class ERBUnlessNode extends Node {
2825
3681
  content: this.content ? this.content.toJSON() : null,
2826
3682
  tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
2827
3683
  then_keyword: this.then_keyword ? this.then_keyword.toJSON() : null,
3684
+ prism_node: this.prism_node ? Array.from(this.prism_node) : null,
2828
3685
  statements: this.statements.map(node => node.toJSON()),
2829
3686
  else_clause: this.else_clause ? this.else_clause.toJSON() : null,
2830
3687
  end_node: this.end_node ? this.end_node.toJSON() : null,
@@ -2840,6 +3697,9 @@ export class ERBUnlessNode extends Node {
2840
3697
  output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
2841
3698
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
2842
3699
  output += `├── then_keyword: ${this.then_keyword ? "(location: " + this.then_keyword.treeInspect() + ")" : "∅"}\n`;
3700
+ if (this.prism_node) {
3701
+ output += `├── prism_node: ${this.source ? inspectPrismSerialized(this.prism_node, this.source, "│ ") : `(${this.prism_node.length} bytes)`}\n`;
3702
+ }
2843
3703
  output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
2844
3704
  output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
2845
3705
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
@@ -2855,13 +3715,15 @@ export interface SerializedERBYieldNode extends SerializedNode {
2855
3715
  tag_closing: SerializedToken | null;
2856
3716
  }
2857
3717
 
2858
- export interface ERBYieldNodeProps extends BaseNodeProps {
3718
+ export interface ERBYieldNodeProps extends Omit<BaseNodeProps, 'type'> {
3719
+ type: "AST_ERB_YIELD_NODE";
2859
3720
  tag_opening: Token | null;
2860
3721
  content: Token | null;
2861
3722
  tag_closing: Token | null;
2862
3723
  }
2863
3724
 
2864
3725
  export class ERBYieldNode extends Node {
3726
+ declare readonly type: "AST_ERB_YIELD_NODE";
2865
3727
  readonly tag_opening: Token | null;
2866
3728
  readonly content: Token | null;
2867
3729
  readonly tag_closing: Token | null;
@@ -2901,6 +3763,7 @@ export class ERBYieldNode extends Node {
2901
3763
  return this.childNodes().filter(node => node !== null && node !== undefined)
2902
3764
  }
2903
3765
 
3766
+
2904
3767
  recursiveErrors(): HerbError[] {
2905
3768
  return [
2906
3769
  ...this.errors,
@@ -2939,7 +3802,8 @@ export interface SerializedERBInNode extends SerializedNode {
2939
3802
  statements: SerializedNode[];
2940
3803
  }
2941
3804
 
2942
- export interface ERBInNodeProps extends BaseNodeProps {
3805
+ export interface ERBInNodeProps extends Omit<BaseNodeProps, 'type'> {
3806
+ type: "AST_ERB_IN_NODE";
2943
3807
  tag_opening: Token | null;
2944
3808
  content: Token | null;
2945
3809
  tag_closing: Token | null;
@@ -2948,6 +3812,7 @@ export interface ERBInNodeProps extends BaseNodeProps {
2948
3812
  }
2949
3813
 
2950
3814
  export class ERBInNode extends Node {
3815
+ declare readonly type: "AST_ERB_IN_NODE";
2951
3816
  readonly tag_opening: Token | null;
2952
3817
  readonly content: Token | null;
2953
3818
  readonly tag_closing: Token | null;
@@ -2994,6 +3859,7 @@ export class ERBInNode extends Node {
2994
3859
  return this.childNodes().filter(node => node !== null && node !== undefined)
2995
3860
  }
2996
3861
 
3862
+
2997
3863
  recursiveErrors(): HerbError[] {
2998
3864
  return [
2999
3865
  ...this.errors,
@@ -3030,15 +3896,22 @@ export class ERBInNode extends Node {
3030
3896
 
3031
3897
 
3032
3898
  export type ConcreteNode =
3033
- DocumentNode | LiteralNode | HTMLOpenTagNode | HTMLCloseTagNode | HTMLElementNode | HTMLAttributeValueNode | HTMLAttributeNameNode | HTMLAttributeNode | HTMLTextNode | HTMLCommentNode | HTMLDoctypeNode | XMLDeclarationNode | CDATANode | WhitespaceNode | ERBContentNode | ERBEndNode | ERBElseNode | ERBIfNode | ERBBlockNode | ERBWhenNode | ERBCaseNode | ERBCaseMatchNode | ERBWhileNode | ERBUntilNode | ERBForNode | ERBRescueNode | ERBEnsureNode | ERBBeginNode | ERBUnlessNode | ERBYieldNode | ERBInNode
3899
+ DocumentNode | LiteralNode | HTMLOpenTagNode | HTMLConditionalOpenTagNode | HTMLCloseTagNode | HTMLOmittedCloseTagNode | HTMLVirtualCloseTagNode | HTMLElementNode | HTMLConditionalElementNode | HTMLAttributeValueNode | HTMLAttributeNameNode | HTMLAttributeNode | RubyLiteralNode | RubyHTMLAttributesSplatNode | ERBOpenTagNode | HTMLTextNode | HTMLCommentNode | HTMLDoctypeNode | XMLDeclarationNode | CDATANode | WhitespaceNode | ERBContentNode | ERBEndNode | ERBElseNode | ERBIfNode | ERBBlockNode | ERBWhenNode | ERBCaseNode | ERBCaseMatchNode | ERBWhileNode | ERBUntilNode | ERBForNode | ERBRescueNode | ERBEnsureNode | ERBBeginNode | ERBUnlessNode | ERBYieldNode | ERBInNode
3034
3900
  export function fromSerializedNode(node: SerializedDocumentNode): DocumentNode;
3035
3901
  export function fromSerializedNode(node: SerializedLiteralNode): LiteralNode;
3036
3902
  export function fromSerializedNode(node: SerializedHTMLOpenTagNode): HTMLOpenTagNode;
3903
+ export function fromSerializedNode(node: SerializedHTMLConditionalOpenTagNode): HTMLConditionalOpenTagNode;
3037
3904
  export function fromSerializedNode(node: SerializedHTMLCloseTagNode): HTMLCloseTagNode;
3905
+ export function fromSerializedNode(node: SerializedHTMLOmittedCloseTagNode): HTMLOmittedCloseTagNode;
3906
+ export function fromSerializedNode(node: SerializedHTMLVirtualCloseTagNode): HTMLVirtualCloseTagNode;
3038
3907
  export function fromSerializedNode(node: SerializedHTMLElementNode): HTMLElementNode;
3908
+ export function fromSerializedNode(node: SerializedHTMLConditionalElementNode): HTMLConditionalElementNode;
3039
3909
  export function fromSerializedNode(node: SerializedHTMLAttributeValueNode): HTMLAttributeValueNode;
3040
3910
  export function fromSerializedNode(node: SerializedHTMLAttributeNameNode): HTMLAttributeNameNode;
3041
3911
  export function fromSerializedNode(node: SerializedHTMLAttributeNode): HTMLAttributeNode;
3912
+ export function fromSerializedNode(node: SerializedRubyLiteralNode): RubyLiteralNode;
3913
+ export function fromSerializedNode(node: SerializedRubyHTMLAttributesSplatNode): RubyHTMLAttributesSplatNode;
3914
+ export function fromSerializedNode(node: SerializedERBOpenTagNode): ERBOpenTagNode;
3042
3915
  export function fromSerializedNode(node: SerializedHTMLTextNode): HTMLTextNode;
3043
3916
  export function fromSerializedNode(node: SerializedHTMLCommentNode): HTMLCommentNode;
3044
3917
  export function fromSerializedNode(node: SerializedHTMLDoctypeNode): HTMLDoctypeNode;
@@ -3069,11 +3942,18 @@ export function fromSerializedNode(node: SerializedNode): Node {
3069
3942
  case "AST_DOCUMENT_NODE": return DocumentNode.from(node as SerializedDocumentNode);
3070
3943
  case "AST_LITERAL_NODE": return LiteralNode.from(node as SerializedLiteralNode);
3071
3944
  case "AST_HTML_OPEN_TAG_NODE": return HTMLOpenTagNode.from(node as SerializedHTMLOpenTagNode);
3945
+ case "AST_HTML_CONDITIONAL_OPEN_TAG_NODE": return HTMLConditionalOpenTagNode.from(node as SerializedHTMLConditionalOpenTagNode);
3072
3946
  case "AST_HTML_CLOSE_TAG_NODE": return HTMLCloseTagNode.from(node as SerializedHTMLCloseTagNode);
3947
+ case "AST_HTML_OMITTED_CLOSE_TAG_NODE": return HTMLOmittedCloseTagNode.from(node as SerializedHTMLOmittedCloseTagNode);
3948
+ case "AST_HTML_VIRTUAL_CLOSE_TAG_NODE": return HTMLVirtualCloseTagNode.from(node as SerializedHTMLVirtualCloseTagNode);
3073
3949
  case "AST_HTML_ELEMENT_NODE": return HTMLElementNode.from(node as SerializedHTMLElementNode);
3950
+ case "AST_HTML_CONDITIONAL_ELEMENT_NODE": return HTMLConditionalElementNode.from(node as SerializedHTMLConditionalElementNode);
3074
3951
  case "AST_HTML_ATTRIBUTE_VALUE_NODE": return HTMLAttributeValueNode.from(node as SerializedHTMLAttributeValueNode);
3075
3952
  case "AST_HTML_ATTRIBUTE_NAME_NODE": return HTMLAttributeNameNode.from(node as SerializedHTMLAttributeNameNode);
3076
3953
  case "AST_HTML_ATTRIBUTE_NODE": return HTMLAttributeNode.from(node as SerializedHTMLAttributeNode);
3954
+ case "AST_RUBY_LITERAL_NODE": return RubyLiteralNode.from(node as SerializedRubyLiteralNode);
3955
+ case "AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE": return RubyHTMLAttributesSplatNode.from(node as SerializedRubyHTMLAttributesSplatNode);
3956
+ case "AST_ERB_OPEN_TAG_NODE": return ERBOpenTagNode.from(node as SerializedERBOpenTagNode);
3077
3957
  case "AST_HTML_TEXT_NODE": return HTMLTextNode.from(node as SerializedHTMLTextNode);
3078
3958
  case "AST_HTML_COMMENT_NODE": return HTMLCommentNode.from(node as SerializedHTMLCommentNode);
3079
3959
  case "AST_HTML_DOCTYPE_NODE": return HTMLDoctypeNode.from(node as SerializedHTMLDoctypeNode);
@@ -3107,11 +3987,18 @@ export type NodeType =
3107
3987
  | "AST_DOCUMENT_NODE"
3108
3988
  | "AST_LITERAL_NODE"
3109
3989
  | "AST_HTML_OPEN_TAG_NODE"
3990
+ | "AST_HTML_CONDITIONAL_OPEN_TAG_NODE"
3110
3991
  | "AST_HTML_CLOSE_TAG_NODE"
3992
+ | "AST_HTML_OMITTED_CLOSE_TAG_NODE"
3993
+ | "AST_HTML_VIRTUAL_CLOSE_TAG_NODE"
3111
3994
  | "AST_HTML_ELEMENT_NODE"
3995
+ | "AST_HTML_CONDITIONAL_ELEMENT_NODE"
3112
3996
  | "AST_HTML_ATTRIBUTE_VALUE_NODE"
3113
3997
  | "AST_HTML_ATTRIBUTE_NAME_NODE"
3114
3998
  | "AST_HTML_ATTRIBUTE_NODE"
3999
+ | "AST_RUBY_LITERAL_NODE"
4000
+ | "AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE"
4001
+ | "AST_ERB_OPEN_TAG_NODE"
3115
4002
  | "AST_HTML_TEXT_NODE"
3116
4003
  | "AST_HTML_COMMENT_NODE"
3117
4004
  | "AST_HTML_DOCTYPE_NODE"
@@ -3139,6 +4026,7 @@ export type NodeType =
3139
4026
  export type ERBNodeType = Extract<NodeType, `AST_ERB_${string}`>;
3140
4027
 
3141
4028
  export type ERBNode =
4029
+ | ERBOpenTagNode
3142
4030
  | ERBContentNode
3143
4031
  | ERBEndNode
3144
4032
  | ERBElseNode
@@ -3158,6 +4046,7 @@ export type ERBNode =
3158
4046
  | ERBInNode
3159
4047
 
3160
4048
  export const ERBNodeClasses = [
4049
+ ERBOpenTagNode,
3161
4050
  ERBContentNode,
3162
4051
  ERBEndNode,
3163
4052
  ERBElseNode,