@herb-tools/core 0.5.0 → 0.6.1

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,5 +1,5 @@
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.5.0/templates/javascript/packages/core/src/nodes.ts.erb
2
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.6.1/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"
@@ -33,6 +33,10 @@ export abstract class Node implements BaseNodeProps {
33
33
  return fromSerializedNode(node)
34
34
  }
35
35
 
36
+ static get type(): NodeType {
37
+ throw new Error("AST_NODE")
38
+ }
39
+
36
40
  constructor(type: NodeType, location: Location, errors: HerbError[]) {
37
41
  this.type = type
38
42
  this.location = location
@@ -51,6 +55,14 @@ export abstract class Node implements BaseNodeProps {
51
55
  return this.treeInspect(0)
52
56
  }
53
57
 
58
+ is<T extends Node>(nodeClass: { new(...args: any[]): T; prototype: T, type: NodeType }): this is T {
59
+ return this.type === nodeClass.type
60
+ }
61
+
62
+ isOfType<T extends Node>(type: NodeType): this is T {
63
+ return this.type === type
64
+ }
65
+
54
66
  get isSingleLine(): boolean {
55
67
  return this.location.start.line === this.location.end.line
56
68
  }
@@ -133,6 +145,10 @@ export interface DocumentNodeProps extends BaseNodeProps {
133
145
  export class DocumentNode extends Node {
134
146
  readonly children: Node[];
135
147
 
148
+ static get type(): NodeType {
149
+ return "AST_DOCUMENT_NODE"
150
+ }
151
+
136
152
  static from(data: SerializedDocumentNode): DocumentNode {
137
153
  return new DocumentNode({
138
154
  type: data.type,
@@ -183,8 +199,6 @@ export class DocumentNode extends Node {
183
199
  output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
184
200
  output += `└── children: ${this.inspectArray(this.children, " ")}`;
185
201
 
186
- // output += "\n";
187
-
188
202
  return output
189
203
  }
190
204
  }
@@ -201,6 +215,10 @@ export interface LiteralNodeProps extends BaseNodeProps {
201
215
  export class LiteralNode extends Node {
202
216
  readonly content: string;
203
217
 
218
+ static get type(): NodeType {
219
+ return "AST_LITERAL_NODE"
220
+ }
221
+
204
222
  static from(data: SerializedLiteralNode): LiteralNode {
205
223
  return new LiteralNode({
206
224
  type: data.type,
@@ -249,8 +267,6 @@ export class LiteralNode extends Node {
249
267
  output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
250
268
  output += `└── content: ${this.content ? JSON.stringify(this.content) : "∅"}\n`;
251
269
 
252
- // output += "\n";
253
-
254
270
  return output
255
271
  }
256
272
  }
@@ -279,6 +295,10 @@ export class HTMLOpenTagNode extends Node {
279
295
  readonly children: Node[];
280
296
  readonly is_void: boolean;
281
297
 
298
+ static get type(): NodeType {
299
+ return "AST_HTML_OPEN_TAG_NODE"
300
+ }
301
+
282
302
  static from(data: SerializedHTMLOpenTagNode): HTMLOpenTagNode {
283
303
  return new HTMLOpenTagNode({
284
304
  type: data.type,
@@ -345,8 +365,6 @@ export class HTMLOpenTagNode extends Node {
345
365
  output += `├── children: ${this.inspectArray(this.children, "│ ")}`;
346
366
  output += `└── is_void: ${typeof this.is_void === 'boolean' ? String(this.is_void) : "∅"}\n`;
347
367
 
348
- // output += "\n";
349
-
350
368
  return output
351
369
  }
352
370
  }
@@ -355,20 +373,27 @@ export interface SerializedHTMLCloseTagNode extends SerializedNode {
355
373
  type: "AST_HTML_CLOSE_TAG_NODE";
356
374
  tag_opening: SerializedToken | null;
357
375
  tag_name: SerializedToken | null;
376
+ children: SerializedNode[];
358
377
  tag_closing: SerializedToken | null;
359
378
  }
360
379
 
361
380
  export interface HTMLCloseTagNodeProps extends BaseNodeProps {
362
381
  tag_opening: Token | null;
363
382
  tag_name: Token | null;
383
+ children: Node[];
364
384
  tag_closing: Token | null;
365
385
  }
366
386
 
367
387
  export class HTMLCloseTagNode extends Node {
368
388
  readonly tag_opening: Token | null;
369
389
  readonly tag_name: Token | null;
390
+ readonly children: Node[];
370
391
  readonly tag_closing: Token | null;
371
392
 
393
+ static get type(): NodeType {
394
+ return "AST_HTML_CLOSE_TAG_NODE"
395
+ }
396
+
372
397
  static from(data: SerializedHTMLCloseTagNode): HTMLCloseTagNode {
373
398
  return new HTMLCloseTagNode({
374
399
  type: data.type,
@@ -376,6 +401,7 @@ export class HTMLCloseTagNode extends Node {
376
401
  errors: (data.errors || []).map(error => HerbError.from(error)),
377
402
  tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
378
403
  tag_name: data.tag_name ? Token.from(data.tag_name) : null,
404
+ children: (data.children || []).map(node => fromSerializedNode(node)),
379
405
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
380
406
  })
381
407
  }
@@ -384,6 +410,7 @@ export class HTMLCloseTagNode extends Node {
384
410
  super(props.type, props.location, props.errors);
385
411
  this.tag_opening = props.tag_opening;
386
412
  this.tag_name = props.tag_name;
413
+ this.children = props.children;
387
414
  this.tag_closing = props.tag_closing;
388
415
  }
389
416
 
@@ -393,6 +420,7 @@ export class HTMLCloseTagNode extends Node {
393
420
 
394
421
  childNodes(): (Node | null | undefined)[] {
395
422
  return [
423
+ ...this.children,
396
424
  ];
397
425
  }
398
426
 
@@ -403,6 +431,7 @@ export class HTMLCloseTagNode extends Node {
403
431
  recursiveErrors(): HerbError[] {
404
432
  return [
405
433
  ...this.errors,
434
+ ...this.children.map(node => node.recursiveErrors()),
406
435
  ].flat();
407
436
  }
408
437
 
@@ -412,6 +441,7 @@ export class HTMLCloseTagNode extends Node {
412
441
  type: "AST_HTML_CLOSE_TAG_NODE",
413
442
  tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
414
443
  tag_name: this.tag_name ? this.tag_name.toJSON() : null,
444
+ children: this.children.map(node => node.toJSON()),
415
445
  tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
416
446
  };
417
447
  }
@@ -423,143 +453,50 @@ export class HTMLCloseTagNode extends Node {
423
453
  output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
424
454
  output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
425
455
  output += `├── tag_name: ${this.tag_name ? this.tag_name.treeInspect() : "∅"}\n`;
456
+ output += `├── children: ${this.inspectArray(this.children, "│ ")}`;
426
457
  output += `└── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
427
458
 
428
- // output += "\n";
429
-
430
- return output
431
- }
432
- }
433
-
434
- export interface SerializedHTMLSelfCloseTagNode extends SerializedNode {
435
- type: "AST_HTML_SELF_CLOSE_TAG_NODE";
436
- tag_opening: SerializedToken | null;
437
- tag_name: SerializedToken | null;
438
- attributes: SerializedNode[];
439
- tag_closing: SerializedToken | null;
440
- is_void: boolean;
441
- }
442
-
443
- export interface HTMLSelfCloseTagNodeProps extends BaseNodeProps {
444
- tag_opening: Token | null;
445
- tag_name: Token | null;
446
- attributes: any[];
447
- tag_closing: Token | null;
448
- is_void: boolean;
449
- }
450
-
451
- export class HTMLSelfCloseTagNode extends Node {
452
- readonly tag_opening: Token | null;
453
- readonly tag_name: Token | null;
454
- readonly attributes: any[];
455
- readonly tag_closing: Token | null;
456
- readonly is_void: boolean;
457
-
458
- static from(data: SerializedHTMLSelfCloseTagNode): HTMLSelfCloseTagNode {
459
- return new HTMLSelfCloseTagNode({
460
- type: data.type,
461
- location: Location.from(data.location),
462
- errors: (data.errors || []).map(error => HerbError.from(error)),
463
- tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
464
- tag_name: data.tag_name ? Token.from(data.tag_name) : null,
465
- attributes: (data.attributes || []).map(node => fromSerializedNode(node)),
466
- tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
467
- is_void: data.is_void,
468
- })
469
- }
470
-
471
- constructor(props: HTMLSelfCloseTagNodeProps) {
472
- super(props.type, props.location, props.errors);
473
- this.tag_opening = props.tag_opening;
474
- this.tag_name = props.tag_name;
475
- this.attributes = props.attributes;
476
- this.tag_closing = props.tag_closing;
477
- this.is_void = props.is_void;
478
- }
479
-
480
- accept(visitor: Visitor): void {
481
- visitor.visitHTMLSelfCloseTagNode(this)
482
- }
483
-
484
- childNodes(): (Node | null | undefined)[] {
485
- return [
486
- ...this.attributes,
487
- ];
488
- }
489
-
490
- compactChildNodes(): Node[] {
491
- return this.childNodes().filter(node => node !== null && node !== undefined)
492
- }
493
-
494
- recursiveErrors(): HerbError[] {
495
- return [
496
- ...this.errors,
497
- ...this.attributes.map(node => node.recursiveErrors()),
498
- ].flat();
499
- }
500
-
501
- toJSON(): SerializedHTMLSelfCloseTagNode {
502
- return {
503
- ...super.toJSON(),
504
- type: "AST_HTML_SELF_CLOSE_TAG_NODE",
505
- tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
506
- tag_name: this.tag_name ? this.tag_name.toJSON() : null,
507
- attributes: this.attributes.map(node => node.toJSON()),
508
- tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
509
- is_void: this.is_void,
510
- };
511
- }
512
-
513
- treeInspect(): string {
514
- let output = "";
515
-
516
- output += `@ HTMLSelfCloseTagNode ${this.location.treeInspectWithLabel()}\n`;
517
- output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
518
- output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
519
- output += `├── tag_name: ${this.tag_name ? this.tag_name.treeInspect() : "∅"}\n`;
520
- output += `├── attributes: ${this.inspectArray(this.attributes, "│ ")}`;
521
- output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
522
- output += `└── is_void: ${typeof this.is_void === 'boolean' ? String(this.is_void) : "∅"}\n`;
523
-
524
- // output += "\n";
525
-
526
459
  return output
527
460
  }
528
461
  }
529
462
 
530
463
  export interface SerializedHTMLElementNode extends SerializedNode {
531
464
  type: "AST_HTML_ELEMENT_NODE";
532
- open_tag: SerializedNode | null;
465
+ open_tag: SerializedHTMLOpenTagNode | null;
533
466
  tag_name: SerializedToken | null;
534
467
  body: SerializedNode[];
535
- close_tag: SerializedNode | null;
468
+ close_tag: SerializedHTMLCloseTagNode | null;
536
469
  is_void: boolean;
537
470
  }
538
471
 
539
472
  export interface HTMLElementNodeProps extends BaseNodeProps {
540
- open_tag: Node | null;
473
+ open_tag: HTMLOpenTagNode | null;
541
474
  tag_name: Token | null;
542
475
  body: Node[];
543
- close_tag: Node | null;
476
+ close_tag: HTMLCloseTagNode | null;
544
477
  is_void: boolean;
545
478
  }
546
479
 
547
480
  export class HTMLElementNode extends Node {
548
- readonly open_tag: Node | null;
481
+ readonly open_tag: HTMLOpenTagNode | null;
549
482
  readonly tag_name: Token | null;
550
483
  readonly body: Node[];
551
- readonly close_tag: Node | null;
484
+ readonly close_tag: HTMLCloseTagNode | null;
552
485
  readonly is_void: boolean;
553
486
 
487
+ static get type(): NodeType {
488
+ return "AST_HTML_ELEMENT_NODE"
489
+ }
490
+
554
491
  static from(data: SerializedHTMLElementNode): HTMLElementNode {
555
492
  return new HTMLElementNode({
556
493
  type: data.type,
557
494
  location: Location.from(data.location),
558
495
  errors: (data.errors || []).map(error => HerbError.from(error)),
559
- open_tag: data.open_tag ? fromSerializedNode((data.open_tag as any)) : null,
496
+ open_tag: data.open_tag ? fromSerializedNode((data.open_tag)) : null,
560
497
  tag_name: data.tag_name ? Token.from(data.tag_name) : null,
561
498
  body: (data.body || []).map(node => fromSerializedNode(node)),
562
- close_tag: data.close_tag ? fromSerializedNode((data.close_tag as any)) : null,
499
+ close_tag: data.close_tag ? fromSerializedNode((data.close_tag)) : null,
563
500
  is_void: data.is_void,
564
501
  })
565
502
  }
@@ -621,8 +558,6 @@ export class HTMLElementNode extends Node {
621
558
  output += `├── close_tag: ${this.inspectNode(this.close_tag, "│ ")}`;
622
559
  output += `└── is_void: ${typeof this.is_void === 'boolean' ? String(this.is_void) : "∅"}\n`;
623
560
 
624
- // output += "\n";
625
-
626
561
  return output
627
562
  }
628
563
  }
@@ -648,6 +583,10 @@ export class HTMLAttributeValueNode extends Node {
648
583
  readonly close_quote: Token | null;
649
584
  readonly quoted: boolean;
650
585
 
586
+ static get type(): NodeType {
587
+ return "AST_HTML_ATTRIBUTE_VALUE_NODE"
588
+ }
589
+
651
590
  static from(data: SerializedHTMLAttributeValueNode): HTMLAttributeValueNode {
652
591
  return new HTMLAttributeValueNode({
653
592
  type: data.type,
@@ -710,36 +649,38 @@ export class HTMLAttributeValueNode extends Node {
710
649
  output += `├── close_quote: ${this.close_quote ? this.close_quote.treeInspect() : "∅"}\n`;
711
650
  output += `└── quoted: ${typeof this.quoted === 'boolean' ? String(this.quoted) : "∅"}\n`;
712
651
 
713
- // output += "\n";
714
-
715
652
  return output
716
653
  }
717
654
  }
718
655
 
719
656
  export interface SerializedHTMLAttributeNameNode extends SerializedNode {
720
657
  type: "AST_HTML_ATTRIBUTE_NAME_NODE";
721
- name: SerializedToken | null;
658
+ children: SerializedNode[];
722
659
  }
723
660
 
724
661
  export interface HTMLAttributeNameNodeProps extends BaseNodeProps {
725
- name: Token | null;
662
+ children: Node[];
726
663
  }
727
664
 
728
665
  export class HTMLAttributeNameNode extends Node {
729
- readonly name: Token | null;
666
+ readonly children: Node[];
667
+
668
+ static get type(): NodeType {
669
+ return "AST_HTML_ATTRIBUTE_NAME_NODE"
670
+ }
730
671
 
731
672
  static from(data: SerializedHTMLAttributeNameNode): HTMLAttributeNameNode {
732
673
  return new HTMLAttributeNameNode({
733
674
  type: data.type,
734
675
  location: Location.from(data.location),
735
676
  errors: (data.errors || []).map(error => HerbError.from(error)),
736
- name: data.name ? Token.from(data.name) : null,
677
+ children: (data.children || []).map(node => fromSerializedNode(node)),
737
678
  })
738
679
  }
739
680
 
740
681
  constructor(props: HTMLAttributeNameNodeProps) {
741
682
  super(props.type, props.location, props.errors);
742
- this.name = props.name;
683
+ this.children = props.children;
743
684
  }
744
685
 
745
686
  accept(visitor: Visitor): void {
@@ -748,6 +689,7 @@ export class HTMLAttributeNameNode extends Node {
748
689
 
749
690
  childNodes(): (Node | null | undefined)[] {
750
691
  return [
692
+ ...this.children,
751
693
  ];
752
694
  }
753
695
 
@@ -758,6 +700,7 @@ export class HTMLAttributeNameNode extends Node {
758
700
  recursiveErrors(): HerbError[] {
759
701
  return [
760
702
  ...this.errors,
703
+ ...this.children.map(node => node.recursiveErrors()),
761
704
  ].flat();
762
705
  }
763
706
 
@@ -765,7 +708,7 @@ export class HTMLAttributeNameNode extends Node {
765
708
  return {
766
709
  ...super.toJSON(),
767
710
  type: "AST_HTML_ATTRIBUTE_NAME_NODE",
768
- name: this.name ? this.name.toJSON() : null,
711
+ children: this.children.map(node => node.toJSON()),
769
712
  };
770
713
  }
771
714
 
@@ -774,9 +717,7 @@ export class HTMLAttributeNameNode extends Node {
774
717
 
775
718
  output += `@ HTMLAttributeNameNode ${this.location.treeInspectWithLabel()}\n`;
776
719
  output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
777
- output += `└── name: ${this.name ? this.name.treeInspect() : ""}\n`;
778
-
779
- // output += "\n";
720
+ output += `└── children: ${this.inspectArray(this.children, " ")}`;
780
721
 
781
722
  return output
782
723
  }
@@ -784,30 +725,34 @@ export class HTMLAttributeNameNode extends Node {
784
725
 
785
726
  export interface SerializedHTMLAttributeNode extends SerializedNode {
786
727
  type: "AST_HTML_ATTRIBUTE_NODE";
787
- name: SerializedNode | null;
728
+ name: SerializedHTMLAttributeNameNode | null;
788
729
  equals: SerializedToken | null;
789
- value: SerializedNode | null;
730
+ value: SerializedHTMLAttributeValueNode | null;
790
731
  }
791
732
 
792
733
  export interface HTMLAttributeNodeProps extends BaseNodeProps {
793
- name: Node | null;
734
+ name: HTMLAttributeNameNode | null;
794
735
  equals: Token | null;
795
- value: Node | null;
736
+ value: HTMLAttributeValueNode | null;
796
737
  }
797
738
 
798
739
  export class HTMLAttributeNode extends Node {
799
- readonly name: Node | null;
740
+ readonly name: HTMLAttributeNameNode | null;
800
741
  readonly equals: Token | null;
801
- readonly value: Node | null;
742
+ readonly value: HTMLAttributeValueNode | null;
743
+
744
+ static get type(): NodeType {
745
+ return "AST_HTML_ATTRIBUTE_NODE"
746
+ }
802
747
 
803
748
  static from(data: SerializedHTMLAttributeNode): HTMLAttributeNode {
804
749
  return new HTMLAttributeNode({
805
750
  type: data.type,
806
751
  location: Location.from(data.location),
807
752
  errors: (data.errors || []).map(error => HerbError.from(error)),
808
- name: data.name ? fromSerializedNode((data.name as any)) : null,
753
+ name: data.name ? fromSerializedNode((data.name)) : null,
809
754
  equals: data.equals ? Token.from(data.equals) : null,
810
- value: data.value ? fromSerializedNode((data.value as any)) : null,
755
+ value: data.value ? fromSerializedNode((data.value)) : null,
811
756
  })
812
757
  }
813
758
 
@@ -860,8 +805,6 @@ export class HTMLAttributeNode extends Node {
860
805
  output += `├── equals: ${this.equals ? this.equals.treeInspect() : "∅"}\n`;
861
806
  output += `└── value: ${this.inspectNode(this.value, " ")}`;
862
807
 
863
- // output += "\n";
864
-
865
808
  return output
866
809
  }
867
810
  }
@@ -878,6 +821,10 @@ export interface HTMLTextNodeProps extends BaseNodeProps {
878
821
  export class HTMLTextNode extends Node {
879
822
  readonly content: string;
880
823
 
824
+ static get type(): NodeType {
825
+ return "AST_HTML_TEXT_NODE"
826
+ }
827
+
881
828
  static from(data: SerializedHTMLTextNode): HTMLTextNode {
882
829
  return new HTMLTextNode({
883
830
  type: data.type,
@@ -926,8 +873,6 @@ export class HTMLTextNode extends Node {
926
873
  output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
927
874
  output += `└── content: ${this.content ? JSON.stringify(this.content) : "∅"}\n`;
928
875
 
929
- // output += "\n";
930
-
931
876
  return output
932
877
  }
933
878
  }
@@ -950,6 +895,10 @@ export class HTMLCommentNode extends Node {
950
895
  readonly children: Node[];
951
896
  readonly comment_end: Token | null;
952
897
 
898
+ static get type(): NodeType {
899
+ return "AST_HTML_COMMENT_NODE"
900
+ }
901
+
953
902
  static from(data: SerializedHTMLCommentNode): HTMLCommentNode {
954
903
  return new HTMLCommentNode({
955
904
  type: data.type,
@@ -1008,8 +957,6 @@ export class HTMLCommentNode extends Node {
1008
957
  output += `├── children: ${this.inspectArray(this.children, "│ ")}`;
1009
958
  output += `└── comment_end: ${this.comment_end ? this.comment_end.treeInspect() : "∅"}\n`;
1010
959
 
1011
- // output += "\n";
1012
-
1013
960
  return output
1014
961
  }
1015
962
  }
@@ -1032,6 +979,10 @@ export class HTMLDoctypeNode extends Node {
1032
979
  readonly children: Node[];
1033
980
  readonly tag_closing: Token | null;
1034
981
 
982
+ static get type(): NodeType {
983
+ return "AST_HTML_DOCTYPE_NODE"
984
+ }
985
+
1035
986
  static from(data: SerializedHTMLDoctypeNode): HTMLDoctypeNode {
1036
987
  return new HTMLDoctypeNode({
1037
988
  type: data.type,
@@ -1090,7 +1041,173 @@ export class HTMLDoctypeNode extends Node {
1090
1041
  output += `├── children: ${this.inspectArray(this.children, "│ ")}`;
1091
1042
  output += `└── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
1092
1043
 
1093
- // output += "\n";
1044
+ return output
1045
+ }
1046
+ }
1047
+
1048
+ export interface SerializedXMLDeclarationNode extends SerializedNode {
1049
+ type: "AST_XML_DECLARATION_NODE";
1050
+ tag_opening: SerializedToken | null;
1051
+ children: SerializedNode[];
1052
+ tag_closing: SerializedToken | null;
1053
+ }
1054
+
1055
+ export interface XMLDeclarationNodeProps extends BaseNodeProps {
1056
+ tag_opening: Token | null;
1057
+ children: Node[];
1058
+ tag_closing: Token | null;
1059
+ }
1060
+
1061
+ export class XMLDeclarationNode extends Node {
1062
+ readonly tag_opening: Token | null;
1063
+ readonly children: Node[];
1064
+ readonly tag_closing: Token | null;
1065
+
1066
+ static get type(): NodeType {
1067
+ return "AST_XML_DECLARATION_NODE"
1068
+ }
1069
+
1070
+ static from(data: SerializedXMLDeclarationNode): XMLDeclarationNode {
1071
+ return new XMLDeclarationNode({
1072
+ type: data.type,
1073
+ location: Location.from(data.location),
1074
+ errors: (data.errors || []).map(error => HerbError.from(error)),
1075
+ tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
1076
+ children: (data.children || []).map(node => fromSerializedNode(node)),
1077
+ tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
1078
+ })
1079
+ }
1080
+
1081
+ constructor(props: XMLDeclarationNodeProps) {
1082
+ super(props.type, props.location, props.errors);
1083
+ this.tag_opening = props.tag_opening;
1084
+ this.children = props.children;
1085
+ this.tag_closing = props.tag_closing;
1086
+ }
1087
+
1088
+ accept(visitor: Visitor): void {
1089
+ visitor.visitXMLDeclarationNode(this)
1090
+ }
1091
+
1092
+ childNodes(): (Node | null | undefined)[] {
1093
+ return [
1094
+ ...this.children,
1095
+ ];
1096
+ }
1097
+
1098
+ compactChildNodes(): Node[] {
1099
+ return this.childNodes().filter(node => node !== null && node !== undefined)
1100
+ }
1101
+
1102
+ recursiveErrors(): HerbError[] {
1103
+ return [
1104
+ ...this.errors,
1105
+ ...this.children.map(node => node.recursiveErrors()),
1106
+ ].flat();
1107
+ }
1108
+
1109
+ toJSON(): SerializedXMLDeclarationNode {
1110
+ return {
1111
+ ...super.toJSON(),
1112
+ type: "AST_XML_DECLARATION_NODE",
1113
+ tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
1114
+ children: this.children.map(node => node.toJSON()),
1115
+ tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
1116
+ };
1117
+ }
1118
+
1119
+ treeInspect(): string {
1120
+ let output = "";
1121
+
1122
+ output += `@ XMLDeclarationNode ${this.location.treeInspectWithLabel()}\n`;
1123
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
1124
+ output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
1125
+ output += `├── children: ${this.inspectArray(this.children, "│ ")}`;
1126
+ output += `└── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
1127
+
1128
+ return output
1129
+ }
1130
+ }
1131
+
1132
+ export interface SerializedCDATANode extends SerializedNode {
1133
+ type: "AST_CDATA_NODE";
1134
+ tag_opening: SerializedToken | null;
1135
+ children: SerializedNode[];
1136
+ tag_closing: SerializedToken | null;
1137
+ }
1138
+
1139
+ export interface CDATANodeProps extends BaseNodeProps {
1140
+ tag_opening: Token | null;
1141
+ children: Node[];
1142
+ tag_closing: Token | null;
1143
+ }
1144
+
1145
+ export class CDATANode extends Node {
1146
+ readonly tag_opening: Token | null;
1147
+ readonly children: Node[];
1148
+ readonly tag_closing: Token | null;
1149
+
1150
+ static get type(): NodeType {
1151
+ return "AST_CDATA_NODE"
1152
+ }
1153
+
1154
+ static from(data: SerializedCDATANode): CDATANode {
1155
+ return new CDATANode({
1156
+ type: data.type,
1157
+ location: Location.from(data.location),
1158
+ errors: (data.errors || []).map(error => HerbError.from(error)),
1159
+ tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
1160
+ children: (data.children || []).map(node => fromSerializedNode(node)),
1161
+ tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
1162
+ })
1163
+ }
1164
+
1165
+ constructor(props: CDATANodeProps) {
1166
+ super(props.type, props.location, props.errors);
1167
+ this.tag_opening = props.tag_opening;
1168
+ this.children = props.children;
1169
+ this.tag_closing = props.tag_closing;
1170
+ }
1171
+
1172
+ accept(visitor: Visitor): void {
1173
+ visitor.visitCDATANode(this)
1174
+ }
1175
+
1176
+ childNodes(): (Node | null | undefined)[] {
1177
+ return [
1178
+ ...this.children,
1179
+ ];
1180
+ }
1181
+
1182
+ compactChildNodes(): Node[] {
1183
+ return this.childNodes().filter(node => node !== null && node !== undefined)
1184
+ }
1185
+
1186
+ recursiveErrors(): HerbError[] {
1187
+ return [
1188
+ ...this.errors,
1189
+ ...this.children.map(node => node.recursiveErrors()),
1190
+ ].flat();
1191
+ }
1192
+
1193
+ toJSON(): SerializedCDATANode {
1194
+ return {
1195
+ ...super.toJSON(),
1196
+ type: "AST_CDATA_NODE",
1197
+ tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
1198
+ children: this.children.map(node => node.toJSON()),
1199
+ tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
1200
+ };
1201
+ }
1202
+
1203
+ treeInspect(): string {
1204
+ let output = "";
1205
+
1206
+ output += `@ CDATANode ${this.location.treeInspectWithLabel()}\n`;
1207
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
1208
+ output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
1209
+ output += `├── children: ${this.inspectArray(this.children, "│ ")}`;
1210
+ output += `└── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
1094
1211
 
1095
1212
  return output
1096
1213
  }
@@ -1108,6 +1225,10 @@ export interface WhitespaceNodeProps extends BaseNodeProps {
1108
1225
  export class WhitespaceNode extends Node {
1109
1226
  readonly value: Token | null;
1110
1227
 
1228
+ static get type(): NodeType {
1229
+ return "AST_WHITESPACE_NODE"
1230
+ }
1231
+
1111
1232
  static from(data: SerializedWhitespaceNode): WhitespaceNode {
1112
1233
  return new WhitespaceNode({
1113
1234
  type: data.type,
@@ -1156,8 +1277,6 @@ export class WhitespaceNode extends Node {
1156
1277
  output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
1157
1278
  output += `└── value: ${this.value ? this.value.treeInspect() : "∅"}\n`;
1158
1279
 
1159
- // output += "\n";
1160
-
1161
1280
  return output
1162
1281
  }
1163
1282
  }
@@ -1189,6 +1308,10 @@ export class ERBContentNode extends Node {
1189
1308
  readonly parsed: boolean;
1190
1309
  readonly valid: boolean;
1191
1310
 
1311
+ static get type(): NodeType {
1312
+ return "AST_ERB_CONTENT_NODE"
1313
+ }
1314
+
1192
1315
  static from(data: SerializedERBContentNode): ERBContentNode {
1193
1316
  return new ERBContentNode({
1194
1317
  type: data.type,
@@ -1257,8 +1380,6 @@ export class ERBContentNode extends Node {
1257
1380
  output += `├── parsed: ${typeof this.parsed === 'boolean' ? String(this.parsed) : "∅"}\n`;
1258
1381
  output += `└── valid: ${typeof this.valid === 'boolean' ? String(this.valid) : "∅"}\n`;
1259
1382
 
1260
- // output += "\n";
1261
-
1262
1383
  return output
1263
1384
  }
1264
1385
  }
@@ -1281,6 +1402,10 @@ export class ERBEndNode extends Node {
1281
1402
  readonly content: Token | null;
1282
1403
  readonly tag_closing: Token | null;
1283
1404
 
1405
+ static get type(): NodeType {
1406
+ return "AST_ERB_END_NODE"
1407
+ }
1408
+
1284
1409
  static from(data: SerializedERBEndNode): ERBEndNode {
1285
1410
  return new ERBEndNode({
1286
1411
  type: data.type,
@@ -1337,8 +1462,6 @@ export class ERBEndNode extends Node {
1337
1462
  output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
1338
1463
  output += `└── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
1339
1464
 
1340
- // output += "\n";
1341
-
1342
1465
  return output
1343
1466
  }
1344
1467
  }
@@ -1364,6 +1487,10 @@ export class ERBElseNode extends Node {
1364
1487
  readonly tag_closing: Token | null;
1365
1488
  readonly statements: Node[];
1366
1489
 
1490
+ static get type(): NodeType {
1491
+ return "AST_ERB_ELSE_NODE"
1492
+ }
1493
+
1367
1494
  static from(data: SerializedERBElseNode): ERBElseNode {
1368
1495
  return new ERBElseNode({
1369
1496
  type: data.type,
@@ -1426,8 +1553,6 @@ export class ERBElseNode extends Node {
1426
1553
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
1427
1554
  output += `└── statements: ${this.inspectArray(this.statements, " ")}`;
1428
1555
 
1429
- // output += "\n";
1430
-
1431
1556
  return output
1432
1557
  }
1433
1558
  }
@@ -1439,7 +1564,7 @@ export interface SerializedERBIfNode extends SerializedNode {
1439
1564
  tag_closing: SerializedToken | null;
1440
1565
  statements: SerializedNode[];
1441
1566
  subsequent: SerializedNode | null;
1442
- end_node: SerializedNode | null;
1567
+ end_node: SerializedERBEndNode | null;
1443
1568
  }
1444
1569
 
1445
1570
  export interface ERBIfNodeProps extends BaseNodeProps {
@@ -1448,7 +1573,7 @@ export interface ERBIfNodeProps extends BaseNodeProps {
1448
1573
  tag_closing: Token | null;
1449
1574
  statements: Node[];
1450
1575
  subsequent: Node | null;
1451
- end_node: Node | null;
1576
+ end_node: ERBEndNode | null;
1452
1577
  }
1453
1578
 
1454
1579
  export class ERBIfNode extends Node {
@@ -1457,7 +1582,11 @@ export class ERBIfNode extends Node {
1457
1582
  readonly tag_closing: Token | null;
1458
1583
  readonly statements: Node[];
1459
1584
  readonly subsequent: Node | null;
1460
- readonly end_node: Node | null;
1585
+ readonly end_node: ERBEndNode | null;
1586
+
1587
+ static get type(): NodeType {
1588
+ return "AST_ERB_IF_NODE"
1589
+ }
1461
1590
 
1462
1591
  static from(data: SerializedERBIfNode): ERBIfNode {
1463
1592
  return new ERBIfNode({
@@ -1468,8 +1597,8 @@ export class ERBIfNode extends Node {
1468
1597
  content: data.content ? Token.from(data.content) : null,
1469
1598
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
1470
1599
  statements: (data.statements || []).map(node => fromSerializedNode(node)),
1471
- subsequent: data.subsequent ? fromSerializedNode((data.subsequent as any)) : null,
1472
- end_node: data.end_node ? fromSerializedNode((data.end_node as any)) : null,
1600
+ subsequent: data.subsequent ? fromSerializedNode((data.subsequent)) : null,
1601
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
1473
1602
  })
1474
1603
  }
1475
1604
 
@@ -1533,8 +1662,6 @@ export class ERBIfNode extends Node {
1533
1662
  output += `├── subsequent: ${this.inspectNode(this.subsequent, "│ ")}`;
1534
1663
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
1535
1664
 
1536
- // output += "\n";
1537
-
1538
1665
  return output
1539
1666
  }
1540
1667
  }
@@ -1545,7 +1672,7 @@ export interface SerializedERBBlockNode extends SerializedNode {
1545
1672
  content: SerializedToken | null;
1546
1673
  tag_closing: SerializedToken | null;
1547
1674
  body: SerializedNode[];
1548
- end_node: SerializedNode | null;
1675
+ end_node: SerializedERBEndNode | null;
1549
1676
  }
1550
1677
 
1551
1678
  export interface ERBBlockNodeProps extends BaseNodeProps {
@@ -1553,7 +1680,7 @@ export interface ERBBlockNodeProps extends BaseNodeProps {
1553
1680
  content: Token | null;
1554
1681
  tag_closing: Token | null;
1555
1682
  body: Node[];
1556
- end_node: Node | null;
1683
+ end_node: ERBEndNode | null;
1557
1684
  }
1558
1685
 
1559
1686
  export class ERBBlockNode extends Node {
@@ -1561,7 +1688,11 @@ export class ERBBlockNode extends Node {
1561
1688
  readonly content: Token | null;
1562
1689
  readonly tag_closing: Token | null;
1563
1690
  readonly body: Node[];
1564
- readonly end_node: Node | null;
1691
+ readonly end_node: ERBEndNode | null;
1692
+
1693
+ static get type(): NodeType {
1694
+ return "AST_ERB_BLOCK_NODE"
1695
+ }
1565
1696
 
1566
1697
  static from(data: SerializedERBBlockNode): ERBBlockNode {
1567
1698
  return new ERBBlockNode({
@@ -1572,7 +1703,7 @@ export class ERBBlockNode extends Node {
1572
1703
  content: data.content ? Token.from(data.content) : null,
1573
1704
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
1574
1705
  body: (data.body || []).map(node => fromSerializedNode(node)),
1575
- end_node: data.end_node ? fromSerializedNode((data.end_node as any)) : null,
1706
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
1576
1707
  })
1577
1708
  }
1578
1709
 
@@ -1631,8 +1762,6 @@ export class ERBBlockNode extends Node {
1631
1762
  output += `├── body: ${this.inspectArray(this.body, "│ ")}`;
1632
1763
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
1633
1764
 
1634
- // output += "\n";
1635
-
1636
1765
  return output
1637
1766
  }
1638
1767
  }
@@ -1658,6 +1787,10 @@ export class ERBWhenNode extends Node {
1658
1787
  readonly tag_closing: Token | null;
1659
1788
  readonly statements: Node[];
1660
1789
 
1790
+ static get type(): NodeType {
1791
+ return "AST_ERB_WHEN_NODE"
1792
+ }
1793
+
1661
1794
  static from(data: SerializedERBWhenNode): ERBWhenNode {
1662
1795
  return new ERBWhenNode({
1663
1796
  type: data.type,
@@ -1720,8 +1853,6 @@ export class ERBWhenNode extends Node {
1720
1853
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
1721
1854
  output += `└── statements: ${this.inspectArray(this.statements, " ")}`;
1722
1855
 
1723
- // output += "\n";
1724
-
1725
1856
  return output
1726
1857
  }
1727
1858
  }
@@ -1733,8 +1864,8 @@ export interface SerializedERBCaseNode extends SerializedNode {
1733
1864
  tag_closing: SerializedToken | null;
1734
1865
  children: SerializedNode[];
1735
1866
  conditions: SerializedNode[];
1736
- else_clause: SerializedNode | null;
1737
- end_node: SerializedNode | null;
1867
+ else_clause: SerializedERBElseNode | null;
1868
+ end_node: SerializedERBEndNode | null;
1738
1869
  }
1739
1870
 
1740
1871
  export interface ERBCaseNodeProps extends BaseNodeProps {
@@ -1743,8 +1874,8 @@ export interface ERBCaseNodeProps extends BaseNodeProps {
1743
1874
  tag_closing: Token | null;
1744
1875
  children: Node[];
1745
1876
  conditions: any[];
1746
- else_clause: Node | null;
1747
- end_node: Node | null;
1877
+ else_clause: ERBElseNode | null;
1878
+ end_node: ERBEndNode | null;
1748
1879
  }
1749
1880
 
1750
1881
  export class ERBCaseNode extends Node {
@@ -1752,9 +1883,13 @@ export class ERBCaseNode extends Node {
1752
1883
  readonly content: Token | null;
1753
1884
  readonly tag_closing: Token | null;
1754
1885
  readonly children: Node[];
1755
- readonly conditions: any[];
1756
- readonly else_clause: Node | null;
1757
- readonly end_node: Node | null;
1886
+ readonly conditions: Node[];
1887
+ readonly else_clause: ERBElseNode | null;
1888
+ readonly end_node: ERBEndNode | null;
1889
+
1890
+ static get type(): NodeType {
1891
+ return "AST_ERB_CASE_NODE"
1892
+ }
1758
1893
 
1759
1894
  static from(data: SerializedERBCaseNode): ERBCaseNode {
1760
1895
  return new ERBCaseNode({
@@ -1766,8 +1901,8 @@ export class ERBCaseNode extends Node {
1766
1901
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
1767
1902
  children: (data.children || []).map(node => fromSerializedNode(node)),
1768
1903
  conditions: (data.conditions || []).map(node => fromSerializedNode(node)),
1769
- else_clause: data.else_clause ? fromSerializedNode((data.else_clause as any)) : null,
1770
- end_node: data.end_node ? fromSerializedNode((data.end_node as any)) : null,
1904
+ else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
1905
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
1771
1906
  })
1772
1907
  }
1773
1908
 
@@ -1836,8 +1971,6 @@ export class ERBCaseNode extends Node {
1836
1971
  output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
1837
1972
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
1838
1973
 
1839
- // output += "\n";
1840
-
1841
1974
  return output
1842
1975
  }
1843
1976
  }
@@ -1849,8 +1982,8 @@ export interface SerializedERBCaseMatchNode extends SerializedNode {
1849
1982
  tag_closing: SerializedToken | null;
1850
1983
  children: SerializedNode[];
1851
1984
  conditions: SerializedNode[];
1852
- else_clause: SerializedNode | null;
1853
- end_node: SerializedNode | null;
1985
+ else_clause: SerializedERBElseNode | null;
1986
+ end_node: SerializedERBEndNode | null;
1854
1987
  }
1855
1988
 
1856
1989
  export interface ERBCaseMatchNodeProps extends BaseNodeProps {
@@ -1859,8 +1992,8 @@ export interface ERBCaseMatchNodeProps extends BaseNodeProps {
1859
1992
  tag_closing: Token | null;
1860
1993
  children: Node[];
1861
1994
  conditions: any[];
1862
- else_clause: Node | null;
1863
- end_node: Node | null;
1995
+ else_clause: ERBElseNode | null;
1996
+ end_node: ERBEndNode | null;
1864
1997
  }
1865
1998
 
1866
1999
  export class ERBCaseMatchNode extends Node {
@@ -1868,9 +2001,13 @@ export class ERBCaseMatchNode extends Node {
1868
2001
  readonly content: Token | null;
1869
2002
  readonly tag_closing: Token | null;
1870
2003
  readonly children: Node[];
1871
- readonly conditions: any[];
1872
- readonly else_clause: Node | null;
1873
- readonly end_node: Node | null;
2004
+ readonly conditions: Node[];
2005
+ readonly else_clause: ERBElseNode | null;
2006
+ readonly end_node: ERBEndNode | null;
2007
+
2008
+ static get type(): NodeType {
2009
+ return "AST_ERB_CASE_MATCH_NODE"
2010
+ }
1874
2011
 
1875
2012
  static from(data: SerializedERBCaseMatchNode): ERBCaseMatchNode {
1876
2013
  return new ERBCaseMatchNode({
@@ -1882,8 +2019,8 @@ export class ERBCaseMatchNode extends Node {
1882
2019
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
1883
2020
  children: (data.children || []).map(node => fromSerializedNode(node)),
1884
2021
  conditions: (data.conditions || []).map(node => fromSerializedNode(node)),
1885
- else_clause: data.else_clause ? fromSerializedNode((data.else_clause as any)) : null,
1886
- end_node: data.end_node ? fromSerializedNode((data.end_node as any)) : null,
2022
+ else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
2023
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
1887
2024
  })
1888
2025
  }
1889
2026
 
@@ -1952,8 +2089,6 @@ export class ERBCaseMatchNode extends Node {
1952
2089
  output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
1953
2090
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
1954
2091
 
1955
- // output += "\n";
1956
-
1957
2092
  return output
1958
2093
  }
1959
2094
  }
@@ -1964,7 +2099,7 @@ export interface SerializedERBWhileNode extends SerializedNode {
1964
2099
  content: SerializedToken | null;
1965
2100
  tag_closing: SerializedToken | null;
1966
2101
  statements: SerializedNode[];
1967
- end_node: SerializedNode | null;
2102
+ end_node: SerializedERBEndNode | null;
1968
2103
  }
1969
2104
 
1970
2105
  export interface ERBWhileNodeProps extends BaseNodeProps {
@@ -1972,7 +2107,7 @@ export interface ERBWhileNodeProps extends BaseNodeProps {
1972
2107
  content: Token | null;
1973
2108
  tag_closing: Token | null;
1974
2109
  statements: Node[];
1975
- end_node: Node | null;
2110
+ end_node: ERBEndNode | null;
1976
2111
  }
1977
2112
 
1978
2113
  export class ERBWhileNode extends Node {
@@ -1980,7 +2115,11 @@ export class ERBWhileNode extends Node {
1980
2115
  readonly content: Token | null;
1981
2116
  readonly tag_closing: Token | null;
1982
2117
  readonly statements: Node[];
1983
- readonly end_node: Node | null;
2118
+ readonly end_node: ERBEndNode | null;
2119
+
2120
+ static get type(): NodeType {
2121
+ return "AST_ERB_WHILE_NODE"
2122
+ }
1984
2123
 
1985
2124
  static from(data: SerializedERBWhileNode): ERBWhileNode {
1986
2125
  return new ERBWhileNode({
@@ -1991,7 +2130,7 @@ export class ERBWhileNode extends Node {
1991
2130
  content: data.content ? Token.from(data.content) : null,
1992
2131
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
1993
2132
  statements: (data.statements || []).map(node => fromSerializedNode(node)),
1994
- end_node: data.end_node ? fromSerializedNode((data.end_node as any)) : null,
2133
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
1995
2134
  })
1996
2135
  }
1997
2136
 
@@ -2050,8 +2189,6 @@ export class ERBWhileNode extends Node {
2050
2189
  output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
2051
2190
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
2052
2191
 
2053
- // output += "\n";
2054
-
2055
2192
  return output
2056
2193
  }
2057
2194
  }
@@ -2062,7 +2199,7 @@ export interface SerializedERBUntilNode extends SerializedNode {
2062
2199
  content: SerializedToken | null;
2063
2200
  tag_closing: SerializedToken | null;
2064
2201
  statements: SerializedNode[];
2065
- end_node: SerializedNode | null;
2202
+ end_node: SerializedERBEndNode | null;
2066
2203
  }
2067
2204
 
2068
2205
  export interface ERBUntilNodeProps extends BaseNodeProps {
@@ -2070,7 +2207,7 @@ export interface ERBUntilNodeProps extends BaseNodeProps {
2070
2207
  content: Token | null;
2071
2208
  tag_closing: Token | null;
2072
2209
  statements: Node[];
2073
- end_node: Node | null;
2210
+ end_node: ERBEndNode | null;
2074
2211
  }
2075
2212
 
2076
2213
  export class ERBUntilNode extends Node {
@@ -2078,7 +2215,11 @@ export class ERBUntilNode extends Node {
2078
2215
  readonly content: Token | null;
2079
2216
  readonly tag_closing: Token | null;
2080
2217
  readonly statements: Node[];
2081
- readonly end_node: Node | null;
2218
+ readonly end_node: ERBEndNode | null;
2219
+
2220
+ static get type(): NodeType {
2221
+ return "AST_ERB_UNTIL_NODE"
2222
+ }
2082
2223
 
2083
2224
  static from(data: SerializedERBUntilNode): ERBUntilNode {
2084
2225
  return new ERBUntilNode({
@@ -2089,7 +2230,7 @@ export class ERBUntilNode extends Node {
2089
2230
  content: data.content ? Token.from(data.content) : null,
2090
2231
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2091
2232
  statements: (data.statements || []).map(node => fromSerializedNode(node)),
2092
- end_node: data.end_node ? fromSerializedNode((data.end_node as any)) : null,
2233
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
2093
2234
  })
2094
2235
  }
2095
2236
 
@@ -2148,8 +2289,6 @@ export class ERBUntilNode extends Node {
2148
2289
  output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
2149
2290
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
2150
2291
 
2151
- // output += "\n";
2152
-
2153
2292
  return output
2154
2293
  }
2155
2294
  }
@@ -2160,7 +2299,7 @@ export interface SerializedERBForNode extends SerializedNode {
2160
2299
  content: SerializedToken | null;
2161
2300
  tag_closing: SerializedToken | null;
2162
2301
  statements: SerializedNode[];
2163
- end_node: SerializedNode | null;
2302
+ end_node: SerializedERBEndNode | null;
2164
2303
  }
2165
2304
 
2166
2305
  export interface ERBForNodeProps extends BaseNodeProps {
@@ -2168,7 +2307,7 @@ export interface ERBForNodeProps extends BaseNodeProps {
2168
2307
  content: Token | null;
2169
2308
  tag_closing: Token | null;
2170
2309
  statements: Node[];
2171
- end_node: Node | null;
2310
+ end_node: ERBEndNode | null;
2172
2311
  }
2173
2312
 
2174
2313
  export class ERBForNode extends Node {
@@ -2176,7 +2315,11 @@ export class ERBForNode extends Node {
2176
2315
  readonly content: Token | null;
2177
2316
  readonly tag_closing: Token | null;
2178
2317
  readonly statements: Node[];
2179
- readonly end_node: Node | null;
2318
+ readonly end_node: ERBEndNode | null;
2319
+
2320
+ static get type(): NodeType {
2321
+ return "AST_ERB_FOR_NODE"
2322
+ }
2180
2323
 
2181
2324
  static from(data: SerializedERBForNode): ERBForNode {
2182
2325
  return new ERBForNode({
@@ -2187,7 +2330,7 @@ export class ERBForNode extends Node {
2187
2330
  content: data.content ? Token.from(data.content) : null,
2188
2331
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2189
2332
  statements: (data.statements || []).map(node => fromSerializedNode(node)),
2190
- end_node: data.end_node ? fromSerializedNode((data.end_node as any)) : null,
2333
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
2191
2334
  })
2192
2335
  }
2193
2336
 
@@ -2246,8 +2389,6 @@ export class ERBForNode extends Node {
2246
2389
  output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
2247
2390
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
2248
2391
 
2249
- // output += "\n";
2250
-
2251
2392
  return output
2252
2393
  }
2253
2394
  }
@@ -2258,7 +2399,7 @@ export interface SerializedERBRescueNode extends SerializedNode {
2258
2399
  content: SerializedToken | null;
2259
2400
  tag_closing: SerializedToken | null;
2260
2401
  statements: SerializedNode[];
2261
- subsequent: SerializedNode | null;
2402
+ subsequent: SerializedERBRescueNode | null;
2262
2403
  }
2263
2404
 
2264
2405
  export interface ERBRescueNodeProps extends BaseNodeProps {
@@ -2266,7 +2407,7 @@ export interface ERBRescueNodeProps extends BaseNodeProps {
2266
2407
  content: Token | null;
2267
2408
  tag_closing: Token | null;
2268
2409
  statements: Node[];
2269
- subsequent: Node | null;
2410
+ subsequent: ERBRescueNode | null;
2270
2411
  }
2271
2412
 
2272
2413
  export class ERBRescueNode extends Node {
@@ -2274,7 +2415,11 @@ export class ERBRescueNode extends Node {
2274
2415
  readonly content: Token | null;
2275
2416
  readonly tag_closing: Token | null;
2276
2417
  readonly statements: Node[];
2277
- readonly subsequent: Node | null;
2418
+ readonly subsequent: ERBRescueNode | null;
2419
+
2420
+ static get type(): NodeType {
2421
+ return "AST_ERB_RESCUE_NODE"
2422
+ }
2278
2423
 
2279
2424
  static from(data: SerializedERBRescueNode): ERBRescueNode {
2280
2425
  return new ERBRescueNode({
@@ -2285,7 +2430,7 @@ export class ERBRescueNode extends Node {
2285
2430
  content: data.content ? Token.from(data.content) : null,
2286
2431
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2287
2432
  statements: (data.statements || []).map(node => fromSerializedNode(node)),
2288
- subsequent: data.subsequent ? fromSerializedNode((data.subsequent as any)) : null,
2433
+ subsequent: data.subsequent ? fromSerializedNode((data.subsequent)) : null,
2289
2434
  })
2290
2435
  }
2291
2436
 
@@ -2344,8 +2489,6 @@ export class ERBRescueNode extends Node {
2344
2489
  output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
2345
2490
  output += `└── subsequent: ${this.inspectNode(this.subsequent, " ")}`;
2346
2491
 
2347
- // output += "\n";
2348
-
2349
2492
  return output
2350
2493
  }
2351
2494
  }
@@ -2371,6 +2514,10 @@ export class ERBEnsureNode extends Node {
2371
2514
  readonly tag_closing: Token | null;
2372
2515
  readonly statements: Node[];
2373
2516
 
2517
+ static get type(): NodeType {
2518
+ return "AST_ERB_ENSURE_NODE"
2519
+ }
2520
+
2374
2521
  static from(data: SerializedERBEnsureNode): ERBEnsureNode {
2375
2522
  return new ERBEnsureNode({
2376
2523
  type: data.type,
@@ -2433,8 +2580,6 @@ export class ERBEnsureNode extends Node {
2433
2580
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
2434
2581
  output += `└── statements: ${this.inspectArray(this.statements, " ")}`;
2435
2582
 
2436
- // output += "\n";
2437
-
2438
2583
  return output
2439
2584
  }
2440
2585
  }
@@ -2445,10 +2590,10 @@ export interface SerializedERBBeginNode extends SerializedNode {
2445
2590
  content: SerializedToken | null;
2446
2591
  tag_closing: SerializedToken | null;
2447
2592
  statements: SerializedNode[];
2448
- rescue_clause: SerializedNode | null;
2449
- else_clause: SerializedNode | null;
2450
- ensure_clause: SerializedNode | null;
2451
- end_node: SerializedNode | null;
2593
+ rescue_clause: SerializedERBRescueNode | null;
2594
+ else_clause: SerializedERBElseNode | null;
2595
+ ensure_clause: SerializedERBEnsureNode | null;
2596
+ end_node: SerializedERBEndNode | null;
2452
2597
  }
2453
2598
 
2454
2599
  export interface ERBBeginNodeProps extends BaseNodeProps {
@@ -2456,10 +2601,10 @@ export interface ERBBeginNodeProps extends BaseNodeProps {
2456
2601
  content: Token | null;
2457
2602
  tag_closing: Token | null;
2458
2603
  statements: Node[];
2459
- rescue_clause: Node | null;
2460
- else_clause: Node | null;
2461
- ensure_clause: Node | null;
2462
- end_node: Node | null;
2604
+ rescue_clause: ERBRescueNode | null;
2605
+ else_clause: ERBElseNode | null;
2606
+ ensure_clause: ERBEnsureNode | null;
2607
+ end_node: ERBEndNode | null;
2463
2608
  }
2464
2609
 
2465
2610
  export class ERBBeginNode extends Node {
@@ -2467,10 +2612,14 @@ export class ERBBeginNode extends Node {
2467
2612
  readonly content: Token | null;
2468
2613
  readonly tag_closing: Token | null;
2469
2614
  readonly statements: Node[];
2470
- readonly rescue_clause: Node | null;
2471
- readonly else_clause: Node | null;
2472
- readonly ensure_clause: Node | null;
2473
- readonly end_node: Node | null;
2615
+ readonly rescue_clause: ERBRescueNode | null;
2616
+ readonly else_clause: ERBElseNode | null;
2617
+ readonly ensure_clause: ERBEnsureNode | null;
2618
+ readonly end_node: ERBEndNode | null;
2619
+
2620
+ static get type(): NodeType {
2621
+ return "AST_ERB_BEGIN_NODE"
2622
+ }
2474
2623
 
2475
2624
  static from(data: SerializedERBBeginNode): ERBBeginNode {
2476
2625
  return new ERBBeginNode({
@@ -2481,10 +2630,10 @@ export class ERBBeginNode extends Node {
2481
2630
  content: data.content ? Token.from(data.content) : null,
2482
2631
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2483
2632
  statements: (data.statements || []).map(node => fromSerializedNode(node)),
2484
- rescue_clause: data.rescue_clause ? fromSerializedNode((data.rescue_clause as any)) : null,
2485
- else_clause: data.else_clause ? fromSerializedNode((data.else_clause as any)) : null,
2486
- ensure_clause: data.ensure_clause ? fromSerializedNode((data.ensure_clause as any)) : null,
2487
- end_node: data.end_node ? fromSerializedNode((data.end_node as any)) : null,
2633
+ rescue_clause: data.rescue_clause ? fromSerializedNode((data.rescue_clause)) : null,
2634
+ else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
2635
+ ensure_clause: data.ensure_clause ? fromSerializedNode((data.ensure_clause)) : null,
2636
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
2488
2637
  })
2489
2638
  }
2490
2639
 
@@ -2558,8 +2707,6 @@ export class ERBBeginNode extends Node {
2558
2707
  output += `├── ensure_clause: ${this.inspectNode(this.ensure_clause, "│ ")}`;
2559
2708
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
2560
2709
 
2561
- // output += "\n";
2562
-
2563
2710
  return output
2564
2711
  }
2565
2712
  }
@@ -2570,8 +2717,8 @@ export interface SerializedERBUnlessNode extends SerializedNode {
2570
2717
  content: SerializedToken | null;
2571
2718
  tag_closing: SerializedToken | null;
2572
2719
  statements: SerializedNode[];
2573
- else_clause: SerializedNode | null;
2574
- end_node: SerializedNode | null;
2720
+ else_clause: SerializedERBElseNode | null;
2721
+ end_node: SerializedERBEndNode | null;
2575
2722
  }
2576
2723
 
2577
2724
  export interface ERBUnlessNodeProps extends BaseNodeProps {
@@ -2579,8 +2726,8 @@ export interface ERBUnlessNodeProps extends BaseNodeProps {
2579
2726
  content: Token | null;
2580
2727
  tag_closing: Token | null;
2581
2728
  statements: Node[];
2582
- else_clause: Node | null;
2583
- end_node: Node | null;
2729
+ else_clause: ERBElseNode | null;
2730
+ end_node: ERBEndNode | null;
2584
2731
  }
2585
2732
 
2586
2733
  export class ERBUnlessNode extends Node {
@@ -2588,8 +2735,12 @@ export class ERBUnlessNode extends Node {
2588
2735
  readonly content: Token | null;
2589
2736
  readonly tag_closing: Token | null;
2590
2737
  readonly statements: Node[];
2591
- readonly else_clause: Node | null;
2592
- readonly end_node: Node | null;
2738
+ readonly else_clause: ERBElseNode | null;
2739
+ readonly end_node: ERBEndNode | null;
2740
+
2741
+ static get type(): NodeType {
2742
+ return "AST_ERB_UNLESS_NODE"
2743
+ }
2593
2744
 
2594
2745
  static from(data: SerializedERBUnlessNode): ERBUnlessNode {
2595
2746
  return new ERBUnlessNode({
@@ -2600,8 +2751,8 @@ export class ERBUnlessNode extends Node {
2600
2751
  content: data.content ? Token.from(data.content) : null,
2601
2752
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2602
2753
  statements: (data.statements || []).map(node => fromSerializedNode(node)),
2603
- else_clause: data.else_clause ? fromSerializedNode((data.else_clause as any)) : null,
2604
- end_node: data.end_node ? fromSerializedNode((data.end_node as any)) : null,
2754
+ else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
2755
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
2605
2756
  })
2606
2757
  }
2607
2758
 
@@ -2665,8 +2816,6 @@ export class ERBUnlessNode extends Node {
2665
2816
  output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
2666
2817
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
2667
2818
 
2668
- // output += "\n";
2669
-
2670
2819
  return output
2671
2820
  }
2672
2821
  }
@@ -2689,6 +2838,10 @@ export class ERBYieldNode extends Node {
2689
2838
  readonly content: Token | null;
2690
2839
  readonly tag_closing: Token | null;
2691
2840
 
2841
+ static get type(): NodeType {
2842
+ return "AST_ERB_YIELD_NODE"
2843
+ }
2844
+
2692
2845
  static from(data: SerializedERBYieldNode): ERBYieldNode {
2693
2846
  return new ERBYieldNode({
2694
2847
  type: data.type,
@@ -2745,8 +2898,6 @@ export class ERBYieldNode extends Node {
2745
2898
  output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
2746
2899
  output += `└── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
2747
2900
 
2748
- // output += "\n";
2749
-
2750
2901
  return output
2751
2902
  }
2752
2903
  }
@@ -2772,6 +2923,10 @@ export class ERBInNode extends Node {
2772
2923
  readonly tag_closing: Token | null;
2773
2924
  readonly statements: Node[];
2774
2925
 
2926
+ static get type(): NodeType {
2927
+ return "AST_ERB_IN_NODE"
2928
+ }
2929
+
2775
2930
  static from(data: SerializedERBInNode): ERBInNode {
2776
2931
  return new ERBInNode({
2777
2932
  type: data.type,
@@ -2834,20 +2989,52 @@ export class ERBInNode extends Node {
2834
2989
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
2835
2990
  output += `└── statements: ${this.inspectArray(this.statements, " ")}`;
2836
2991
 
2837
- // output += "\n";
2838
-
2839
2992
  return output
2840
2993
  }
2841
2994
  }
2842
2995
 
2843
2996
 
2997
+ export type ConcreteNode =
2998
+ 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
2999
+ export function fromSerializedNode(node: SerializedDocumentNode): DocumentNode;
3000
+ export function fromSerializedNode(node: SerializedLiteralNode): LiteralNode;
3001
+ export function fromSerializedNode(node: SerializedHTMLOpenTagNode): HTMLOpenTagNode;
3002
+ export function fromSerializedNode(node: SerializedHTMLCloseTagNode): HTMLCloseTagNode;
3003
+ export function fromSerializedNode(node: SerializedHTMLElementNode): HTMLElementNode;
3004
+ export function fromSerializedNode(node: SerializedHTMLAttributeValueNode): HTMLAttributeValueNode;
3005
+ export function fromSerializedNode(node: SerializedHTMLAttributeNameNode): HTMLAttributeNameNode;
3006
+ export function fromSerializedNode(node: SerializedHTMLAttributeNode): HTMLAttributeNode;
3007
+ export function fromSerializedNode(node: SerializedHTMLTextNode): HTMLTextNode;
3008
+ export function fromSerializedNode(node: SerializedHTMLCommentNode): HTMLCommentNode;
3009
+ export function fromSerializedNode(node: SerializedHTMLDoctypeNode): HTMLDoctypeNode;
3010
+ export function fromSerializedNode(node: SerializedXMLDeclarationNode): XMLDeclarationNode;
3011
+ export function fromSerializedNode(node: SerializedCDATANode): CDATANode;
3012
+ export function fromSerializedNode(node: SerializedWhitespaceNode): WhitespaceNode;
3013
+ export function fromSerializedNode(node: SerializedERBContentNode): ERBContentNode;
3014
+ export function fromSerializedNode(node: SerializedERBEndNode): ERBEndNode;
3015
+ export function fromSerializedNode(node: SerializedERBElseNode): ERBElseNode;
3016
+ export function fromSerializedNode(node: SerializedERBIfNode): ERBIfNode;
3017
+ export function fromSerializedNode(node: SerializedERBBlockNode): ERBBlockNode;
3018
+ export function fromSerializedNode(node: SerializedERBWhenNode): ERBWhenNode;
3019
+ export function fromSerializedNode(node: SerializedERBCaseNode): ERBCaseNode;
3020
+ export function fromSerializedNode(node: SerializedERBCaseMatchNode): ERBCaseMatchNode;
3021
+ export function fromSerializedNode(node: SerializedERBWhileNode): ERBWhileNode;
3022
+ export function fromSerializedNode(node: SerializedERBUntilNode): ERBUntilNode;
3023
+ export function fromSerializedNode(node: SerializedERBForNode): ERBForNode;
3024
+ export function fromSerializedNode(node: SerializedERBRescueNode): ERBRescueNode;
3025
+ export function fromSerializedNode(node: SerializedERBEnsureNode): ERBEnsureNode;
3026
+ export function fromSerializedNode(node: SerializedERBBeginNode): ERBBeginNode;
3027
+ export function fromSerializedNode(node: SerializedERBUnlessNode): ERBUnlessNode;
3028
+ export function fromSerializedNode(node: SerializedERBYieldNode): ERBYieldNode;
3029
+ export function fromSerializedNode(node: SerializedERBInNode): ERBInNode;
3030
+ export function fromSerializedNode(node: SerializedNode): Node;
3031
+
2844
3032
  export function fromSerializedNode(node: SerializedNode): Node {
2845
3033
  switch (node.type) {
2846
3034
  case "AST_DOCUMENT_NODE": return DocumentNode.from(node as SerializedDocumentNode);
2847
3035
  case "AST_LITERAL_NODE": return LiteralNode.from(node as SerializedLiteralNode);
2848
3036
  case "AST_HTML_OPEN_TAG_NODE": return HTMLOpenTagNode.from(node as SerializedHTMLOpenTagNode);
2849
3037
  case "AST_HTML_CLOSE_TAG_NODE": return HTMLCloseTagNode.from(node as SerializedHTMLCloseTagNode);
2850
- case "AST_HTML_SELF_CLOSE_TAG_NODE": return HTMLSelfCloseTagNode.from(node as SerializedHTMLSelfCloseTagNode);
2851
3038
  case "AST_HTML_ELEMENT_NODE": return HTMLElementNode.from(node as SerializedHTMLElementNode);
2852
3039
  case "AST_HTML_ATTRIBUTE_VALUE_NODE": return HTMLAttributeValueNode.from(node as SerializedHTMLAttributeValueNode);
2853
3040
  case "AST_HTML_ATTRIBUTE_NAME_NODE": return HTMLAttributeNameNode.from(node as SerializedHTMLAttributeNameNode);
@@ -2855,6 +3042,8 @@ export function fromSerializedNode(node: SerializedNode): Node {
2855
3042
  case "AST_HTML_TEXT_NODE": return HTMLTextNode.from(node as SerializedHTMLTextNode);
2856
3043
  case "AST_HTML_COMMENT_NODE": return HTMLCommentNode.from(node as SerializedHTMLCommentNode);
2857
3044
  case "AST_HTML_DOCTYPE_NODE": return HTMLDoctypeNode.from(node as SerializedHTMLDoctypeNode);
3045
+ case "AST_XML_DECLARATION_NODE": return XMLDeclarationNode.from(node as SerializedXMLDeclarationNode);
3046
+ case "AST_CDATA_NODE": return CDATANode.from(node as SerializedCDATANode);
2858
3047
  case "AST_WHITESPACE_NODE": return WhitespaceNode.from(node as SerializedWhitespaceNode);
2859
3048
  case "AST_ERB_CONTENT_NODE": return ERBContentNode.from(node as SerializedERBContentNode);
2860
3049
  case "AST_ERB_END_NODE": return ERBEndNode.from(node as SerializedERBEndNode);
@@ -2884,7 +3073,6 @@ export type NodeType =
2884
3073
  | "AST_LITERAL_NODE"
2885
3074
  | "AST_HTML_OPEN_TAG_NODE"
2886
3075
  | "AST_HTML_CLOSE_TAG_NODE"
2887
- | "AST_HTML_SELF_CLOSE_TAG_NODE"
2888
3076
  | "AST_HTML_ELEMENT_NODE"
2889
3077
  | "AST_HTML_ATTRIBUTE_VALUE_NODE"
2890
3078
  | "AST_HTML_ATTRIBUTE_NAME_NODE"
@@ -2892,6 +3080,8 @@ export type NodeType =
2892
3080
  | "AST_HTML_TEXT_NODE"
2893
3081
  | "AST_HTML_COMMENT_NODE"
2894
3082
  | "AST_HTML_DOCTYPE_NODE"
3083
+ | "AST_XML_DECLARATION_NODE"
3084
+ | "AST_CDATA_NODE"
2895
3085
  | "AST_WHITESPACE_NODE"
2896
3086
  | "AST_ERB_CONTENT_NODE"
2897
3087
  | "AST_ERB_END_NODE"
@@ -2951,8 +3141,3 @@ export const ERBNodeClasses = [
2951
3141
  ERBYieldNode,
2952
3142
  ERBInNode,
2953
3143
  ]
2954
-
2955
- export function isERBNode(node: Node): node is ERBNode {
2956
-
2957
- return node.constructor.name.startsWith("ERB")
2958
- }