herb 0.7.5 → 0.8.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.
Files changed (161) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +8 -5
  3. data/config.yml +26 -6
  4. data/ext/herb/error_helpers.c +57 -3
  5. data/ext/herb/error_helpers.h +1 -1
  6. data/ext/herb/extconf.rb +1 -0
  7. data/ext/herb/extension.c +10 -24
  8. data/ext/herb/extension_helpers.c +3 -3
  9. data/ext/herb/extension_helpers.h +1 -1
  10. data/ext/herb/nodes.c +72 -37
  11. data/herb.gemspec +0 -2
  12. data/lib/herb/ast/helpers.rb +11 -0
  13. data/lib/herb/ast/node.rb +15 -6
  14. data/lib/herb/ast/nodes.rb +609 -392
  15. data/lib/herb/cli.rb +31 -0
  16. data/lib/herb/colors.rb +82 -0
  17. data/lib/herb/engine/compiler.rb +140 -14
  18. data/lib/herb/engine/debug_visitor.rb +1 -5
  19. data/lib/herb/engine/parser_error_overlay.rb +1 -1
  20. data/lib/herb/engine.rb +8 -14
  21. data/lib/herb/errors.rb +166 -56
  22. data/lib/herb/location.rb +2 -2
  23. data/lib/herb/project.rb +86 -21
  24. data/lib/herb/token.rb +14 -2
  25. data/lib/herb/version.rb +1 -1
  26. data/lib/herb.rb +1 -0
  27. data/sig/herb/ast/helpers.rbs +3 -0
  28. data/sig/herb/ast/node.rbs +12 -5
  29. data/sig/herb/ast/nodes.rbs +124 -62
  30. data/sig/herb/colors.rbs +35 -0
  31. data/sig/herb/engine/compiler.rbs +23 -1
  32. data/sig/herb/errors.rbs +74 -20
  33. data/sig/herb/token.rbs +8 -0
  34. data/sig/herb_c_extension.rbs +1 -1
  35. data/sig/serialized_ast_errors.rbs +8 -0
  36. data/src/analyze.c +420 -171
  37. data/src/analyze_helpers.c +5 -0
  38. data/src/analyze_missing_end.c +147 -0
  39. data/src/analyze_transform.c +196 -0
  40. data/src/analyzed_ruby.c +23 -2
  41. data/src/ast_node.c +5 -5
  42. data/src/ast_nodes.c +179 -179
  43. data/src/ast_pretty_print.c +232 -232
  44. data/src/element_source.c +7 -6
  45. data/src/errors.c +246 -126
  46. data/src/extract.c +92 -34
  47. data/src/herb.c +37 -49
  48. data/src/html_util.c +34 -96
  49. data/src/include/analyze.h +10 -2
  50. data/src/include/analyze_helpers.h +3 -0
  51. data/src/include/analyzed_ruby.h +4 -2
  52. data/src/include/ast_node.h +2 -2
  53. data/src/include/ast_nodes.h +67 -66
  54. data/src/include/ast_pretty_print.h +2 -2
  55. data/src/include/element_source.h +3 -1
  56. data/src/include/errors.h +30 -14
  57. data/src/include/extract.h +4 -4
  58. data/src/include/herb.h +6 -7
  59. data/src/include/html_util.h +4 -5
  60. data/src/include/lexer.h +1 -3
  61. data/src/include/lexer_peek_helpers.h +14 -14
  62. data/src/include/lexer_struct.h +3 -2
  63. data/src/include/macros.h +4 -0
  64. data/src/include/parser.h +12 -6
  65. data/src/include/parser_helpers.h +25 -15
  66. data/src/include/pretty_print.h +38 -28
  67. data/src/include/token.h +5 -8
  68. data/src/include/utf8.h +3 -2
  69. data/src/include/util/hb_arena.h +31 -0
  70. data/src/include/util/hb_arena_debug.h +8 -0
  71. data/src/include/util/hb_array.h +33 -0
  72. data/src/include/util/hb_buffer.h +34 -0
  73. data/src/include/util/hb_string.h +29 -0
  74. data/src/include/util/hb_system.h +9 -0
  75. data/src/include/util.h +3 -14
  76. data/src/include/version.h +1 -1
  77. data/src/include/visitor.h +1 -1
  78. data/src/io.c +7 -4
  79. data/src/lexer.c +61 -88
  80. data/src/lexer_peek_helpers.c +35 -37
  81. data/src/main.c +19 -23
  82. data/src/parser.c +282 -201
  83. data/src/parser_helpers.c +46 -40
  84. data/src/parser_match_tags.c +316 -0
  85. data/src/pretty_print.c +82 -106
  86. data/src/token.c +18 -65
  87. data/src/utf8.c +4 -4
  88. data/src/util/hb_arena.c +179 -0
  89. data/src/util/hb_arena_debug.c +237 -0
  90. data/src/{array.c → util/hb_array.c} +26 -27
  91. data/src/util/hb_buffer.c +203 -0
  92. data/src/util/hb_string.c +85 -0
  93. data/src/util/hb_system.c +30 -0
  94. data/src/util.c +29 -99
  95. data/src/visitor.c +54 -54
  96. data/templates/ext/herb/error_helpers.c.erb +3 -3
  97. data/templates/ext/herb/error_helpers.h.erb +1 -1
  98. data/templates/ext/herb/nodes.c.erb +11 -6
  99. data/templates/java/error_helpers.c.erb +75 -0
  100. data/templates/java/error_helpers.h.erb +20 -0
  101. data/templates/java/nodes.c.erb +97 -0
  102. data/templates/java/nodes.h.erb +23 -0
  103. data/templates/java/org/herb/ast/Errors.java.erb +121 -0
  104. data/templates/java/org/herb/ast/NodeVisitor.java.erb +14 -0
  105. data/templates/java/org/herb/ast/Nodes.java.erb +220 -0
  106. data/templates/java/org/herb/ast/Visitor.java.erb +56 -0
  107. data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +8 -8
  108. data/templates/javascript/packages/node/extension/error_helpers.h.erb +1 -1
  109. data/templates/javascript/packages/node/extension/nodes.cpp.erb +9 -9
  110. data/templates/javascript/packages/node/extension/nodes.h.erb +1 -1
  111. data/templates/lib/herb/ast/nodes.rb.erb +28 -16
  112. data/templates/lib/herb/errors.rb.erb +17 -12
  113. data/templates/rust/src/ast/nodes.rs.erb +220 -0
  114. data/templates/rust/src/errors.rs.erb +216 -0
  115. data/templates/rust/src/nodes.rs.erb +374 -0
  116. data/templates/src/analyze_missing_end.c.erb +36 -0
  117. data/templates/src/analyze_transform.c.erb +24 -0
  118. data/templates/src/ast_nodes.c.erb +14 -14
  119. data/templates/src/ast_pretty_print.c.erb +36 -36
  120. data/templates/src/errors.c.erb +31 -31
  121. data/templates/src/include/ast_nodes.h.erb +10 -9
  122. data/templates/src/include/ast_pretty_print.h.erb +2 -2
  123. data/templates/src/include/errors.h.erb +6 -6
  124. data/templates/src/parser_match_tags.c.erb +38 -0
  125. data/templates/src/visitor.c.erb +4 -4
  126. data/templates/template.rb +22 -3
  127. data/templates/wasm/error_helpers.cpp.erb +9 -9
  128. data/templates/wasm/error_helpers.h.erb +1 -1
  129. data/templates/wasm/nodes.cpp.erb +9 -9
  130. data/templates/wasm/nodes.h.erb +1 -1
  131. data/vendor/prism/Rakefile +4 -1
  132. data/vendor/prism/config.yml +2 -1
  133. data/vendor/prism/include/prism/ast.h +31 -1
  134. data/vendor/prism/include/prism/diagnostic.h +1 -0
  135. data/vendor/prism/include/prism/version.h +3 -3
  136. data/vendor/prism/src/diagnostic.c +3 -1
  137. data/vendor/prism/src/prism.c +130 -71
  138. data/vendor/prism/src/util/pm_string.c +6 -8
  139. data/vendor/prism/templates/include/prism/ast.h.erb +2 -0
  140. data/vendor/prism/templates/java/org/prism/Loader.java.erb +2 -2
  141. data/vendor/prism/templates/javascript/src/deserialize.js.erb +2 -2
  142. data/vendor/prism/templates/lib/prism/serialize.rb.erb +2 -2
  143. data/vendor/prism/templates/sig/prism.rbs.erb +4 -0
  144. data/vendor/prism/templates/src/diagnostic.c.erb +1 -0
  145. metadata +34 -20
  146. data/lib/herb/libherb/array.rb +0 -51
  147. data/lib/herb/libherb/ast_node.rb +0 -50
  148. data/lib/herb/libherb/buffer.rb +0 -56
  149. data/lib/herb/libherb/extract_result.rb +0 -20
  150. data/lib/herb/libherb/lex_result.rb +0 -32
  151. data/lib/herb/libherb/libherb.rb +0 -52
  152. data/lib/herb/libherb/parse_result.rb +0 -20
  153. data/lib/herb/libherb/token.rb +0 -46
  154. data/lib/herb/libherb.rb +0 -35
  155. data/src/buffer.c +0 -241
  156. data/src/include/array.h +0 -33
  157. data/src/include/buffer.h +0 -39
  158. data/src/include/json.h +0 -28
  159. data/src/include/memory.h +0 -12
  160. data/src/json.c +0 -205
  161. data/src/memory.c +0 -53
data/src/parser_helpers.c CHANGED
@@ -1,36 +1,36 @@
1
1
  #include "include/parser_helpers.h"
2
- #include "include/array.h"
3
2
  #include "include/ast_node.h"
4
3
  #include "include/ast_nodes.h"
5
- #include "include/buffer.h"
6
4
  #include "include/errors.h"
7
5
  #include "include/html_util.h"
8
6
  #include "include/lexer.h"
9
7
  #include "include/parser.h"
10
8
  #include "include/token.h"
11
9
  #include "include/token_matchers.h"
10
+ #include "include/util/hb_array.h"
11
+ #include "include/util/hb_buffer.h"
12
+ #include "include/util/hb_string.h"
12
13
 
13
14
  #include <stdio.h>
14
- #include <strings.h>
15
15
 
16
16
  void parser_push_open_tag(const parser_T* parser, token_T* tag_name) {
17
17
  token_T* copy = token_copy(tag_name);
18
- array_push(parser->open_tags_stack, copy);
18
+ hb_array_push(parser->open_tags_stack, copy);
19
19
  }
20
20
 
21
- bool parser_check_matching_tag(const parser_T* parser, const char* tag_name) {
22
- if (array_size(parser->open_tags_stack) == 0) { return false; }
21
+ bool parser_check_matching_tag(const parser_T* parser, hb_string_T tag_name) {
22
+ if (hb_array_size(parser->open_tags_stack) == 0) { return false; }
23
23
 
24
- token_T* top_token = array_last(parser->open_tags_stack);
24
+ token_T* top_token = hb_array_last(parser->open_tags_stack);
25
25
  if (top_token == NULL || top_token->value == NULL) { return false; };
26
26
 
27
- return (strcasecmp(top_token->value, tag_name) == 0);
27
+ return hb_string_equals(hb_string(top_token->value), tag_name);
28
28
  }
29
29
 
30
30
  token_T* parser_pop_open_tag(const parser_T* parser) {
31
- if (array_size(parser->open_tags_stack) == 0) { return NULL; }
31
+ if (hb_array_size(parser->open_tags_stack) == 0) { return NULL; }
32
32
 
33
- return array_pop(parser->open_tags_stack);
33
+ return hb_array_pop(parser->open_tags_stack);
34
34
  }
35
35
 
36
36
  /**
@@ -42,13 +42,14 @@ token_T* parser_pop_open_tag(const parser_T* parser) {
42
42
  bool parser_in_svg_context(const parser_T* parser) {
43
43
  if (!parser || !parser->open_tags_stack) { return false; }
44
44
 
45
- size_t stack_size = array_size(parser->open_tags_stack);
45
+ size_t stack_size = hb_array_size(parser->open_tags_stack);
46
46
 
47
47
  for (size_t i = 0; i < stack_size; i++) {
48
- token_T* tag = (token_T*) array_get(parser->open_tags_stack, i);
48
+ token_T* tag = (token_T*) hb_array_get(parser->open_tags_stack, i);
49
49
 
50
50
  if (tag && tag->value) {
51
- if (strcasecmp(tag->value, "svg") == 0) { return true; }
51
+ hb_string_T tag_value_string = hb_string(tag->value);
52
+ if (hb_string_equals(tag_value_string, hb_string("svg"))) { return true; }
52
53
  }
53
54
  }
54
55
 
@@ -57,24 +58,24 @@ bool parser_in_svg_context(const parser_T* parser) {
57
58
 
58
59
  // ===== Foreign Content Handling =====
59
60
 
60
- foreign_content_type_T parser_get_foreign_content_type(const char* tag_name) {
61
- if (tag_name == NULL) { return FOREIGN_CONTENT_UNKNOWN; }
61
+ foreign_content_type_T parser_get_foreign_content_type(hb_string_T tag_name) {
62
+ if (hb_string_is_empty(tag_name)) { return FOREIGN_CONTENT_UNKNOWN; }
62
63
 
63
- if (strcasecmp(tag_name, "script") == 0) { return FOREIGN_CONTENT_SCRIPT; }
64
- if (strcasecmp(tag_name, "style") == 0) { return FOREIGN_CONTENT_STYLE; }
64
+ if (hb_string_equals(tag_name, hb_string("script"))) { return FOREIGN_CONTENT_SCRIPT; }
65
+ if (hb_string_equals(tag_name, hb_string("style"))) { return FOREIGN_CONTENT_STYLE; }
65
66
 
66
67
  return FOREIGN_CONTENT_UNKNOWN;
67
68
  }
68
69
 
69
- bool parser_is_foreign_content_tag(const char* tag_name) {
70
+ bool parser_is_foreign_content_tag(hb_string_T tag_name) {
70
71
  return parser_get_foreign_content_type(tag_name) != FOREIGN_CONTENT_UNKNOWN;
71
72
  }
72
73
 
73
- const char* parser_get_foreign_content_closing_tag(foreign_content_type_T type) {
74
+ hb_string_T parser_get_foreign_content_closing_tag(foreign_content_type_T type) {
74
75
  switch (type) {
75
- case FOREIGN_CONTENT_SCRIPT: return "script";
76
- case FOREIGN_CONTENT_STYLE: return "style";
77
- default: return NULL;
76
+ case FOREIGN_CONTENT_SCRIPT: return hb_string("script");
77
+ case FOREIGN_CONTENT_STYLE: return hb_string("style");
78
+ default: return hb_string("");
78
79
  }
79
80
  }
80
81
 
@@ -92,7 +93,12 @@ void parser_exit_foreign_content(parser_T* parser) {
92
93
  parser->foreign_content_type = FOREIGN_CONTENT_UNKNOWN;
93
94
  }
94
95
 
95
- void parser_append_unexpected_error(parser_T* parser, const char* description, const char* expected, array_T* errors) {
96
+ void parser_append_unexpected_error(
97
+ parser_T* parser,
98
+ const char* description,
99
+ const char* expected,
100
+ hb_array_T* errors
101
+ ) {
96
102
  token_T* token = parser_advance(parser);
97
103
 
98
104
  append_unexpected_error(
@@ -107,7 +113,7 @@ void parser_append_unexpected_error(parser_T* parser, const char* description, c
107
113
  token_free(token);
108
114
  }
109
115
 
110
- void parser_append_unexpected_token_error(parser_T* parser, token_type_T expected_type, array_T* errors) {
116
+ void parser_append_unexpected_token_error(parser_T* parser, token_type_T expected_type, hb_array_T* errors) {
111
117
  append_unexpected_token_error(
112
118
  expected_type,
113
119
  parser->current_token,
@@ -119,17 +125,17 @@ void parser_append_unexpected_token_error(parser_T* parser, token_type_T expecte
119
125
 
120
126
  void parser_append_literal_node_from_buffer(
121
127
  const parser_T* parser,
122
- buffer_T* buffer,
123
- array_T* children,
128
+ hb_buffer_T* buffer,
129
+ hb_array_T* children,
124
130
  position_T start
125
131
  ) {
126
- if (buffer_length(buffer) == 0) { return; }
132
+ if (hb_buffer_length(buffer) == 0) { return; }
127
133
 
128
134
  AST_LITERAL_NODE_T* literal =
129
- ast_literal_node_init(buffer_value(buffer), start, parser->current_token->location.start, NULL);
135
+ ast_literal_node_init(hb_buffer_value(buffer), start, parser->current_token->location.start, NULL);
130
136
 
131
- if (children != NULL) { array_append(children, literal); }
132
- buffer_clear(buffer);
137
+ if (children != NULL) { hb_array_append(children, literal); }
138
+ hb_buffer_clear(buffer);
133
139
  }
134
140
 
135
141
  token_T* parser_advance(parser_T* parser) {
@@ -143,7 +149,7 @@ token_T* parser_consume_if_present(parser_T* parser, const token_type_T type) {
143
149
  return parser_advance(parser);
144
150
  }
145
151
 
146
- token_T* parser_consume_expected(parser_T* parser, const token_type_T expected_type, array_T* array) {
152
+ token_T* parser_consume_expected(parser_T* parser, const token_type_T expected_type, hb_array_T* array) {
147
153
  token_T* token = parser_consume_if_present(parser, expected_type);
148
154
 
149
155
  if (token == NULL) {
@@ -157,8 +163,8 @@ token_T* parser_consume_expected(parser_T* parser, const token_type_T expected_t
157
163
 
158
164
  AST_HTML_ELEMENT_NODE_T* parser_handle_missing_close_tag(
159
165
  AST_HTML_OPEN_TAG_NODE_T* open_tag,
160
- array_T* body,
161
- array_T* errors
166
+ hb_array_T* body,
167
+ hb_array_T* errors
162
168
  ) {
163
169
  append_missing_closing_tag_error(
164
170
  open_tag->tag_name,
@@ -183,10 +189,10 @@ AST_HTML_ELEMENT_NODE_T* parser_handle_missing_close_tag(
183
189
  void parser_handle_mismatched_tags(
184
190
  const parser_T* parser,
185
191
  const AST_HTML_CLOSE_TAG_NODE_T* close_tag,
186
- array_T* errors
192
+ hb_array_T* errors
187
193
  ) {
188
- if (array_size(parser->open_tags_stack) > 0) {
189
- token_T* expected_tag = array_last(parser->open_tags_stack);
194
+ if (hb_array_size(parser->open_tags_stack) > 0) {
195
+ token_T* expected_tag = hb_array_last(parser->open_tags_stack);
190
196
  token_T* actual_tag = close_tag->tag_name;
191
197
 
192
198
  append_tag_names_mismatch_error(
@@ -206,10 +212,10 @@ void parser_handle_mismatched_tags(
206
212
  }
207
213
  }
208
214
 
209
- bool parser_is_expected_closing_tag_name(const char* tag_name, foreign_content_type_T expected_type) {
210
- const char* expected_tag_name = parser_get_foreign_content_closing_tag(expected_type);
215
+ bool parser_is_expected_closing_tag_name(hb_string_T tag_name, foreign_content_type_T expected_type) {
216
+ hb_string_T expected_tag_name = parser_get_foreign_content_closing_tag(expected_type);
211
217
 
212
- if (expected_tag_name == NULL || tag_name == NULL) { return false; }
218
+ if (hb_string_is_empty(tag_name) || hb_string_is_empty(expected_tag_name)) { return false; }
213
219
 
214
- return strcmp(tag_name, expected_tag_name) == 0;
220
+ return hb_string_equals(expected_tag_name, tag_name);
215
221
  }
@@ -0,0 +1,316 @@
1
+ // NOTE: This file is generated by the templates/template.rb script and should not
2
+ // be modified manually. See /home/runner/work/herb/herb/templates/src/parser_match_tags.c.erb
3
+
4
+ #include "include/parser.h"
5
+ #include "include/ast_nodes.h"
6
+ #include "include/util/hb_array.h"
7
+ #include "include/visitor.h"
8
+
9
+ bool match_tags_visitor(const AST_NODE_T* node, void* data) {
10
+ hb_array_T* errors = (hb_array_T*) data;
11
+
12
+ if (node == NULL) { return false; }
13
+
14
+ switch (node->type) {
15
+
16
+ case AST_DOCUMENT_NODE: {
17
+ const AST_DOCUMENT_NODE_T* document_node = (const AST_DOCUMENT_NODE_T*) node;
18
+
19
+ if (document_node->children != NULL) {
20
+ match_tags_in_node_array(document_node->children, errors);
21
+ }
22
+ } break;
23
+
24
+
25
+
26
+ case AST_HTML_OPEN_TAG_NODE: {
27
+ const AST_HTML_OPEN_TAG_NODE_T* html_open_tag_node = (const AST_HTML_OPEN_TAG_NODE_T*) node;
28
+
29
+ if (html_open_tag_node->children != NULL) {
30
+ match_tags_in_node_array(html_open_tag_node->children, errors);
31
+ }
32
+ } break;
33
+
34
+
35
+ case AST_HTML_CLOSE_TAG_NODE: {
36
+ const AST_HTML_CLOSE_TAG_NODE_T* html_close_tag_node = (const AST_HTML_CLOSE_TAG_NODE_T*) node;
37
+
38
+ if (html_close_tag_node->children != NULL) {
39
+ match_tags_in_node_array(html_close_tag_node->children, errors);
40
+ }
41
+ } break;
42
+
43
+
44
+ case AST_HTML_ELEMENT_NODE: {
45
+ const AST_HTML_ELEMENT_NODE_T* html_element_node = (const AST_HTML_ELEMENT_NODE_T*) node;
46
+
47
+ if (html_element_node->body != NULL) {
48
+ match_tags_in_node_array(html_element_node->body, errors);
49
+ }
50
+ if (html_element_node->open_tag != NULL) {
51
+ herb_visit_node((AST_NODE_T*) html_element_node->open_tag, match_tags_visitor, errors);
52
+ }
53
+ if (html_element_node->close_tag != NULL) {
54
+ herb_visit_node((AST_NODE_T*) html_element_node->close_tag, match_tags_visitor, errors);
55
+ }
56
+ } break;
57
+
58
+
59
+ case AST_HTML_ATTRIBUTE_VALUE_NODE: {
60
+ const AST_HTML_ATTRIBUTE_VALUE_NODE_T* html_attribute_value_node = (const AST_HTML_ATTRIBUTE_VALUE_NODE_T*) node;
61
+
62
+ if (html_attribute_value_node->children != NULL) {
63
+ match_tags_in_node_array(html_attribute_value_node->children, errors);
64
+ }
65
+ } break;
66
+
67
+
68
+ case AST_HTML_ATTRIBUTE_NAME_NODE: {
69
+ const AST_HTML_ATTRIBUTE_NAME_NODE_T* html_attribute_name_node = (const AST_HTML_ATTRIBUTE_NAME_NODE_T*) node;
70
+
71
+ if (html_attribute_name_node->children != NULL) {
72
+ match_tags_in_node_array(html_attribute_name_node->children, errors);
73
+ }
74
+ } break;
75
+
76
+
77
+ case AST_HTML_ATTRIBUTE_NODE: {
78
+ const AST_HTML_ATTRIBUTE_NODE_T* html_attribute_node = (const AST_HTML_ATTRIBUTE_NODE_T*) node;
79
+
80
+ if (html_attribute_node->name != NULL) {
81
+ herb_visit_node((AST_NODE_T*) html_attribute_node->name, match_tags_visitor, errors);
82
+ }
83
+ if (html_attribute_node->value != NULL) {
84
+ herb_visit_node((AST_NODE_T*) html_attribute_node->value, match_tags_visitor, errors);
85
+ }
86
+ } break;
87
+
88
+
89
+
90
+ case AST_HTML_COMMENT_NODE: {
91
+ const AST_HTML_COMMENT_NODE_T* html_comment_node = (const AST_HTML_COMMENT_NODE_T*) node;
92
+
93
+ if (html_comment_node->children != NULL) {
94
+ match_tags_in_node_array(html_comment_node->children, errors);
95
+ }
96
+ } break;
97
+
98
+
99
+ case AST_HTML_DOCTYPE_NODE: {
100
+ const AST_HTML_DOCTYPE_NODE_T* html_doctype_node = (const AST_HTML_DOCTYPE_NODE_T*) node;
101
+
102
+ if (html_doctype_node->children != NULL) {
103
+ match_tags_in_node_array(html_doctype_node->children, errors);
104
+ }
105
+ } break;
106
+
107
+
108
+ case AST_XML_DECLARATION_NODE: {
109
+ const AST_XML_DECLARATION_NODE_T* xml_declaration_node = (const AST_XML_DECLARATION_NODE_T*) node;
110
+
111
+ if (xml_declaration_node->children != NULL) {
112
+ match_tags_in_node_array(xml_declaration_node->children, errors);
113
+ }
114
+ } break;
115
+
116
+
117
+ case AST_CDATA_NODE: {
118
+ const AST_CDATA_NODE_T* cdata_node = (const AST_CDATA_NODE_T*) node;
119
+
120
+ if (cdata_node->children != NULL) {
121
+ match_tags_in_node_array(cdata_node->children, errors);
122
+ }
123
+ } break;
124
+
125
+
126
+
127
+
128
+
129
+ case AST_ERB_ELSE_NODE: {
130
+ const AST_ERB_ELSE_NODE_T* erb_else_node = (const AST_ERB_ELSE_NODE_T*) node;
131
+
132
+ if (erb_else_node->statements != NULL) {
133
+ match_tags_in_node_array(erb_else_node->statements, errors);
134
+ }
135
+ } break;
136
+
137
+
138
+ case AST_ERB_IF_NODE: {
139
+ const AST_ERB_IF_NODE_T* erb_if_node = (const AST_ERB_IF_NODE_T*) node;
140
+
141
+ if (erb_if_node->statements != NULL) {
142
+ match_tags_in_node_array(erb_if_node->statements, errors);
143
+ }
144
+ if (erb_if_node->subsequent != NULL) {
145
+ herb_visit_node((AST_NODE_T*) erb_if_node->subsequent, match_tags_visitor, errors);
146
+ }
147
+ if (erb_if_node->end_node != NULL) {
148
+ herb_visit_node((AST_NODE_T*) erb_if_node->end_node, match_tags_visitor, errors);
149
+ }
150
+ } break;
151
+
152
+
153
+ case AST_ERB_BLOCK_NODE: {
154
+ const AST_ERB_BLOCK_NODE_T* erb_block_node = (const AST_ERB_BLOCK_NODE_T*) node;
155
+
156
+ if (erb_block_node->body != NULL) {
157
+ match_tags_in_node_array(erb_block_node->body, errors);
158
+ }
159
+ if (erb_block_node->end_node != NULL) {
160
+ herb_visit_node((AST_NODE_T*) erb_block_node->end_node, match_tags_visitor, errors);
161
+ }
162
+ } break;
163
+
164
+
165
+ case AST_ERB_WHEN_NODE: {
166
+ const AST_ERB_WHEN_NODE_T* erb_when_node = (const AST_ERB_WHEN_NODE_T*) node;
167
+
168
+ if (erb_when_node->statements != NULL) {
169
+ match_tags_in_node_array(erb_when_node->statements, errors);
170
+ }
171
+ } break;
172
+
173
+
174
+ case AST_ERB_CASE_NODE: {
175
+ const AST_ERB_CASE_NODE_T* erb_case_node = (const AST_ERB_CASE_NODE_T*) node;
176
+
177
+ if (erb_case_node->children != NULL) {
178
+ match_tags_in_node_array(erb_case_node->children, errors);
179
+ }
180
+ if (erb_case_node->conditions != NULL) {
181
+ match_tags_in_node_array(erb_case_node->conditions, errors);
182
+ }
183
+ if (erb_case_node->else_clause != NULL) {
184
+ herb_visit_node((AST_NODE_T*) erb_case_node->else_clause, match_tags_visitor, errors);
185
+ }
186
+ if (erb_case_node->end_node != NULL) {
187
+ herb_visit_node((AST_NODE_T*) erb_case_node->end_node, match_tags_visitor, errors);
188
+ }
189
+ } break;
190
+
191
+
192
+ case AST_ERB_CASE_MATCH_NODE: {
193
+ const AST_ERB_CASE_MATCH_NODE_T* erb_case_match_node = (const AST_ERB_CASE_MATCH_NODE_T*) node;
194
+
195
+ if (erb_case_match_node->children != NULL) {
196
+ match_tags_in_node_array(erb_case_match_node->children, errors);
197
+ }
198
+ if (erb_case_match_node->conditions != NULL) {
199
+ match_tags_in_node_array(erb_case_match_node->conditions, errors);
200
+ }
201
+ if (erb_case_match_node->else_clause != NULL) {
202
+ herb_visit_node((AST_NODE_T*) erb_case_match_node->else_clause, match_tags_visitor, errors);
203
+ }
204
+ if (erb_case_match_node->end_node != NULL) {
205
+ herb_visit_node((AST_NODE_T*) erb_case_match_node->end_node, match_tags_visitor, errors);
206
+ }
207
+ } break;
208
+
209
+
210
+ case AST_ERB_WHILE_NODE: {
211
+ const AST_ERB_WHILE_NODE_T* erb_while_node = (const AST_ERB_WHILE_NODE_T*) node;
212
+
213
+ if (erb_while_node->statements != NULL) {
214
+ match_tags_in_node_array(erb_while_node->statements, errors);
215
+ }
216
+ if (erb_while_node->end_node != NULL) {
217
+ herb_visit_node((AST_NODE_T*) erb_while_node->end_node, match_tags_visitor, errors);
218
+ }
219
+ } break;
220
+
221
+
222
+ case AST_ERB_UNTIL_NODE: {
223
+ const AST_ERB_UNTIL_NODE_T* erb_until_node = (const AST_ERB_UNTIL_NODE_T*) node;
224
+
225
+ if (erb_until_node->statements != NULL) {
226
+ match_tags_in_node_array(erb_until_node->statements, errors);
227
+ }
228
+ if (erb_until_node->end_node != NULL) {
229
+ herb_visit_node((AST_NODE_T*) erb_until_node->end_node, match_tags_visitor, errors);
230
+ }
231
+ } break;
232
+
233
+
234
+ case AST_ERB_FOR_NODE: {
235
+ const AST_ERB_FOR_NODE_T* erb_for_node = (const AST_ERB_FOR_NODE_T*) node;
236
+
237
+ if (erb_for_node->statements != NULL) {
238
+ match_tags_in_node_array(erb_for_node->statements, errors);
239
+ }
240
+ if (erb_for_node->end_node != NULL) {
241
+ herb_visit_node((AST_NODE_T*) erb_for_node->end_node, match_tags_visitor, errors);
242
+ }
243
+ } break;
244
+
245
+
246
+ case AST_ERB_RESCUE_NODE: {
247
+ const AST_ERB_RESCUE_NODE_T* erb_rescue_node = (const AST_ERB_RESCUE_NODE_T*) node;
248
+
249
+ if (erb_rescue_node->statements != NULL) {
250
+ match_tags_in_node_array(erb_rescue_node->statements, errors);
251
+ }
252
+ if (erb_rescue_node->subsequent != NULL) {
253
+ herb_visit_node((AST_NODE_T*) erb_rescue_node->subsequent, match_tags_visitor, errors);
254
+ }
255
+ } break;
256
+
257
+
258
+ case AST_ERB_ENSURE_NODE: {
259
+ const AST_ERB_ENSURE_NODE_T* erb_ensure_node = (const AST_ERB_ENSURE_NODE_T*) node;
260
+
261
+ if (erb_ensure_node->statements != NULL) {
262
+ match_tags_in_node_array(erb_ensure_node->statements, errors);
263
+ }
264
+ } break;
265
+
266
+
267
+ case AST_ERB_BEGIN_NODE: {
268
+ const AST_ERB_BEGIN_NODE_T* erb_begin_node = (const AST_ERB_BEGIN_NODE_T*) node;
269
+
270
+ if (erb_begin_node->statements != NULL) {
271
+ match_tags_in_node_array(erb_begin_node->statements, errors);
272
+ }
273
+ if (erb_begin_node->rescue_clause != NULL) {
274
+ herb_visit_node((AST_NODE_T*) erb_begin_node->rescue_clause, match_tags_visitor, errors);
275
+ }
276
+ if (erb_begin_node->else_clause != NULL) {
277
+ herb_visit_node((AST_NODE_T*) erb_begin_node->else_clause, match_tags_visitor, errors);
278
+ }
279
+ if (erb_begin_node->ensure_clause != NULL) {
280
+ herb_visit_node((AST_NODE_T*) erb_begin_node->ensure_clause, match_tags_visitor, errors);
281
+ }
282
+ if (erb_begin_node->end_node != NULL) {
283
+ herb_visit_node((AST_NODE_T*) erb_begin_node->end_node, match_tags_visitor, errors);
284
+ }
285
+ } break;
286
+
287
+
288
+ case AST_ERB_UNLESS_NODE: {
289
+ const AST_ERB_UNLESS_NODE_T* erb_unless_node = (const AST_ERB_UNLESS_NODE_T*) node;
290
+
291
+ if (erb_unless_node->statements != NULL) {
292
+ match_tags_in_node_array(erb_unless_node->statements, errors);
293
+ }
294
+ if (erb_unless_node->else_clause != NULL) {
295
+ herb_visit_node((AST_NODE_T*) erb_unless_node->else_clause, match_tags_visitor, errors);
296
+ }
297
+ if (erb_unless_node->end_node != NULL) {
298
+ herb_visit_node((AST_NODE_T*) erb_unless_node->end_node, match_tags_visitor, errors);
299
+ }
300
+ } break;
301
+
302
+
303
+
304
+ case AST_ERB_IN_NODE: {
305
+ const AST_ERB_IN_NODE_T* erb_in_node = (const AST_ERB_IN_NODE_T*) node;
306
+
307
+ if (erb_in_node->statements != NULL) {
308
+ match_tags_in_node_array(erb_in_node->statements, errors);
309
+ }
310
+ } break;
311
+
312
+ default: break;
313
+ }
314
+
315
+ return false;
316
+ }