herb 0.7.4-aarch64-linux-gnu → 0.8.0-aarch64-linux-gnu

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 (176) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +8 -5
  3. data/config.yml +40 -20
  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 +12 -18
  9. data/ext/herb/extension_helpers.h +4 -4
  10. data/ext/herb/nodes.c +72 -37
  11. data/herb.gemspec +0 -2
  12. data/lib/herb/3.0/herb.so +0 -0
  13. data/lib/herb/3.1/herb.so +0 -0
  14. data/lib/herb/3.2/herb.so +0 -0
  15. data/lib/herb/3.3/herb.so +0 -0
  16. data/lib/herb/3.4/herb.so +0 -0
  17. data/lib/herb/ast/helpers.rb +11 -0
  18. data/lib/herb/ast/node.rb +15 -6
  19. data/lib/herb/ast/nodes.rb +609 -392
  20. data/lib/herb/cli.rb +31 -0
  21. data/lib/herb/colors.rb +82 -0
  22. data/lib/herb/engine/compiler.rb +140 -14
  23. data/lib/herb/engine/debug_visitor.rb +1 -5
  24. data/lib/herb/engine/parser_error_overlay.rb +1 -1
  25. data/lib/herb/engine.rb +18 -20
  26. data/lib/herb/errors.rb +166 -56
  27. data/lib/herb/location.rb +2 -2
  28. data/lib/herb/project.rb +86 -21
  29. data/lib/herb/token.rb +14 -2
  30. data/lib/herb/version.rb +1 -1
  31. data/lib/herb.rb +1 -0
  32. data/sig/herb/ast/helpers.rbs +3 -0
  33. data/sig/herb/ast/node.rbs +12 -5
  34. data/sig/herb/ast/nodes.rbs +124 -62
  35. data/sig/herb/colors.rbs +35 -0
  36. data/sig/herb/engine/compiler.rbs +23 -1
  37. data/sig/herb/errors.rbs +74 -20
  38. data/sig/herb/token.rbs +8 -0
  39. data/sig/herb_c_extension.rbs +1 -1
  40. data/sig/serialized_ast_errors.rbs +8 -0
  41. data/src/analyze.c +461 -249
  42. data/src/analyze_helpers.c +5 -0
  43. data/src/analyze_missing_end.c +147 -0
  44. data/src/analyze_transform.c +196 -0
  45. data/src/analyzed_ruby.c +23 -2
  46. data/src/ast_node.c +14 -17
  47. data/src/ast_nodes.c +179 -181
  48. data/src/ast_pretty_print.c +232 -232
  49. data/src/element_source.c +7 -6
  50. data/src/errors.c +272 -152
  51. data/src/extract.c +92 -34
  52. data/src/herb.c +37 -49
  53. data/src/html_util.c +34 -96
  54. data/src/include/analyze.h +10 -2
  55. data/src/include/analyze_helpers.h +3 -0
  56. data/src/include/analyzed_ruby.h +4 -2
  57. data/src/include/ast_node.h +4 -4
  58. data/src/include/ast_nodes.h +68 -67
  59. data/src/include/ast_pretty_print.h +2 -2
  60. data/src/include/element_source.h +3 -1
  61. data/src/include/errors.h +42 -26
  62. data/src/include/extract.h +4 -4
  63. data/src/include/herb.h +6 -7
  64. data/src/include/html_util.h +4 -5
  65. data/src/include/lexer.h +1 -3
  66. data/src/include/lexer_peek_helpers.h +21 -19
  67. data/src/include/lexer_struct.h +12 -10
  68. data/src/include/location.h +10 -13
  69. data/src/include/macros.h +4 -0
  70. data/src/include/parser.h +12 -6
  71. data/src/include/parser_helpers.h +26 -16
  72. data/src/include/position.h +3 -14
  73. data/src/include/pretty_print.h +38 -28
  74. data/src/include/prism_helpers.h +1 -1
  75. data/src/include/range.h +4 -13
  76. data/src/include/token.h +5 -11
  77. data/src/include/token_struct.h +2 -2
  78. data/src/include/utf8.h +3 -2
  79. data/src/include/util/hb_arena.h +31 -0
  80. data/src/include/util/hb_arena_debug.h +8 -0
  81. data/src/include/util/hb_array.h +33 -0
  82. data/src/include/util/hb_buffer.h +34 -0
  83. data/src/include/util/hb_string.h +29 -0
  84. data/src/include/util/hb_system.h +9 -0
  85. data/src/include/util.h +3 -14
  86. data/src/include/version.h +1 -1
  87. data/src/include/visitor.h +1 -1
  88. data/src/io.c +7 -4
  89. data/src/lexer.c +62 -88
  90. data/src/lexer_peek_helpers.c +42 -38
  91. data/src/location.c +9 -37
  92. data/src/main.c +19 -23
  93. data/src/parser.c +373 -313
  94. data/src/parser_helpers.c +60 -54
  95. data/src/parser_match_tags.c +316 -0
  96. data/src/pretty_print.c +88 -117
  97. data/src/prism_helpers.c +7 -7
  98. data/src/range.c +2 -35
  99. data/src/token.c +36 -87
  100. data/src/utf8.c +4 -4
  101. data/src/util/hb_arena.c +179 -0
  102. data/src/util/hb_arena_debug.c +237 -0
  103. data/src/{array.c → util/hb_array.c} +26 -27
  104. data/src/util/hb_buffer.c +203 -0
  105. data/src/util/hb_string.c +85 -0
  106. data/src/util/hb_system.c +30 -0
  107. data/src/util.c +29 -99
  108. data/src/visitor.c +54 -54
  109. data/templates/ext/herb/error_helpers.c.erb +3 -3
  110. data/templates/ext/herb/error_helpers.h.erb +1 -1
  111. data/templates/ext/herb/nodes.c.erb +11 -6
  112. data/templates/java/error_helpers.c.erb +75 -0
  113. data/templates/java/error_helpers.h.erb +20 -0
  114. data/templates/java/nodes.c.erb +97 -0
  115. data/templates/java/nodes.h.erb +23 -0
  116. data/templates/java/org/herb/ast/Errors.java.erb +121 -0
  117. data/templates/java/org/herb/ast/NodeVisitor.java.erb +14 -0
  118. data/templates/java/org/herb/ast/Nodes.java.erb +220 -0
  119. data/templates/java/org/herb/ast/Visitor.java.erb +56 -0
  120. data/templates/javascript/packages/core/src/visitor.ts.erb +29 -1
  121. data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +8 -8
  122. data/templates/javascript/packages/node/extension/error_helpers.h.erb +1 -1
  123. data/templates/javascript/packages/node/extension/nodes.cpp.erb +9 -9
  124. data/templates/javascript/packages/node/extension/nodes.h.erb +1 -1
  125. data/templates/lib/herb/ast/nodes.rb.erb +28 -16
  126. data/templates/lib/herb/errors.rb.erb +17 -12
  127. data/templates/rust/src/ast/nodes.rs.erb +220 -0
  128. data/templates/rust/src/errors.rs.erb +216 -0
  129. data/templates/rust/src/nodes.rs.erb +374 -0
  130. data/templates/src/analyze_missing_end.c.erb +36 -0
  131. data/templates/src/analyze_transform.c.erb +24 -0
  132. data/templates/src/ast_nodes.c.erb +14 -16
  133. data/templates/src/ast_pretty_print.c.erb +36 -36
  134. data/templates/src/errors.c.erb +36 -38
  135. data/templates/src/include/ast_nodes.h.erb +11 -10
  136. data/templates/src/include/ast_pretty_print.h.erb +2 -2
  137. data/templates/src/include/errors.h.erb +9 -9
  138. data/templates/src/parser_match_tags.c.erb +38 -0
  139. data/templates/src/visitor.c.erb +4 -4
  140. data/templates/template.rb +22 -3
  141. data/templates/wasm/error_helpers.cpp.erb +9 -9
  142. data/templates/wasm/error_helpers.h.erb +1 -1
  143. data/templates/wasm/nodes.cpp.erb +9 -9
  144. data/templates/wasm/nodes.h.erb +1 -1
  145. data/vendor/prism/Rakefile +4 -1
  146. data/vendor/prism/config.yml +2 -1
  147. data/vendor/prism/include/prism/ast.h +31 -1
  148. data/vendor/prism/include/prism/diagnostic.h +1 -0
  149. data/vendor/prism/include/prism/version.h +3 -3
  150. data/vendor/prism/src/diagnostic.c +3 -1
  151. data/vendor/prism/src/prism.c +130 -71
  152. data/vendor/prism/src/util/pm_string.c +6 -8
  153. data/vendor/prism/templates/include/prism/ast.h.erb +2 -0
  154. data/vendor/prism/templates/java/org/prism/Loader.java.erb +2 -2
  155. data/vendor/prism/templates/javascript/src/deserialize.js.erb +2 -2
  156. data/vendor/prism/templates/lib/prism/serialize.rb.erb +2 -2
  157. data/vendor/prism/templates/sig/prism.rbs.erb +4 -0
  158. data/vendor/prism/templates/src/diagnostic.c.erb +1 -0
  159. metadata +34 -21
  160. data/lib/herb/libherb/array.rb +0 -51
  161. data/lib/herb/libherb/ast_node.rb +0 -50
  162. data/lib/herb/libherb/buffer.rb +0 -56
  163. data/lib/herb/libherb/extract_result.rb +0 -20
  164. data/lib/herb/libherb/lex_result.rb +0 -32
  165. data/lib/herb/libherb/libherb.rb +0 -52
  166. data/lib/herb/libherb/parse_result.rb +0 -20
  167. data/lib/herb/libherb/token.rb +0 -46
  168. data/lib/herb/libherb.rb +0 -35
  169. data/src/buffer.c +0 -232
  170. data/src/include/array.h +0 -33
  171. data/src/include/buffer.h +0 -39
  172. data/src/include/json.h +0 -28
  173. data/src/include/memory.h +0 -12
  174. data/src/json.c +0 -205
  175. data/src/memory.c +0 -53
  176. data/src/position.c +0 -33
data/src/errors.c CHANGED
@@ -1,13 +1,13 @@
1
1
  // NOTE: This file is generated by the templates/template.rb script and should not
2
2
  // be modified manually. See /home/runner/work/herb/herb/templates/src/errors.c.erb
3
3
 
4
- #include "include/array.h"
5
4
  #include "include/errors.h"
6
5
  #include "include/location.h"
7
6
  #include "include/position.h"
8
7
  #include "include/pretty_print.h"
9
8
  #include "include/token.h"
10
9
  #include "include/util.h"
10
+ #include "include/util/hb_array.h"
11
11
 
12
12
  #include <stdio.h>
13
13
  #include <stdbool.h>
@@ -20,14 +20,15 @@ size_t error_sizeof(void) {
20
20
  return sizeof(struct ERROR_STRUCT);
21
21
  }
22
22
 
23
- void error_init(ERROR_T* error, const error_type_T type, position_T* start, position_T* end) {
23
+ void error_init(ERROR_T* error, const error_type_T type, position_T start, position_T end) {
24
24
  if (!error) { return; }
25
25
 
26
26
  error->type = type;
27
- error->location = location_init(position_copy(start), position_copy(end));
27
+ error->location.start = start;
28
+ error->location.end = end;
28
29
  }
29
30
 
30
- UNEXPECTED_ERROR_T* unexpected_error_init(const char* description, const char* expected, const char* found, position_T* start, position_T* end) {
31
+ UNEXPECTED_ERROR_T* unexpected_error_init(const char* description, const char* expected, const char* found, position_T start, position_T end) {
31
32
  UNEXPECTED_ERROR_T* unexpected_error = malloc(sizeof(UNEXPECTED_ERROR_T));
32
33
 
33
34
  error_init(&unexpected_error->base, UNEXPECTED_ERROR, start, end);
@@ -71,18 +72,18 @@ UNEXPECTED_ERROR_T* unexpected_error_init(const char* description, const char* e
71
72
  return unexpected_error;
72
73
  }
73
74
 
74
- void append_unexpected_error(const char* description, const char* expected, const char* found, position_T* start, position_T* end, array_T* errors) {
75
- array_append(errors, unexpected_error_init(description, expected, found, start, end));
75
+ void append_unexpected_error(const char* description, const char* expected, const char* found, position_T start, position_T end, hb_array_T* errors) {
76
+ hb_array_append(errors, unexpected_error_init(description, expected, found, start, end));
76
77
  }
77
78
 
78
- UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error_init(token_type_T expected_type, token_T* found, position_T* start, position_T* end) {
79
+ UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error_init(token_type_T expected_type, token_T* found, position_T start, position_T end) {
79
80
  UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error = malloc(sizeof(UNEXPECTED_TOKEN_ERROR_T));
80
81
 
81
82
  error_init(&unexpected_token_error->base, UNEXPECTED_TOKEN_ERROR, start, end);
82
83
 
83
- const char* message_template = "Found `%s` when expecting `%s` at (%zu:%zu).";
84
+ const char* message_template = "Found `%s` when expecting `%s` at (%u:%u).";
84
85
 
85
- size_t message_size = 333;
86
+ size_t message_size = 319;
86
87
  char* message = (char*) malloc(message_size);
87
88
 
88
89
  if (message) {
@@ -100,14 +101,14 @@ UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error_init(token_type_T expected_type
100
101
  message_template,
101
102
  truncated_argument_0,
102
103
  truncated_argument_1,
103
- found->location->start->line,
104
- found->location->start->column
104
+ found->location.start.line,
105
+ found->location.start.column
105
106
  );
106
107
 
107
108
  unexpected_token_error->base.message = herb_strdup(message);
108
109
  free(message);
109
110
  } else {
110
- unexpected_token_error->base.message = herb_strdup("Found `%s` when expecting `%s` at (%zu:%zu).");
111
+ unexpected_token_error->base.message = herb_strdup("Found `%s` when expecting `%s` at (%u:%u).");
111
112
  }
112
113
 
113
114
  unexpected_token_error->expected_type = expected_type;
@@ -115,18 +116,18 @@ UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error_init(token_type_T expected_type
115
116
  return unexpected_token_error;
116
117
  }
117
118
 
118
- void append_unexpected_token_error(token_type_T expected_type, token_T* found, position_T* start, position_T* end, array_T* errors) {
119
- array_append(errors, unexpected_token_error_init(expected_type, found, start, end));
119
+ void append_unexpected_token_error(token_type_T expected_type, token_T* found, position_T start, position_T end, hb_array_T* errors) {
120
+ hb_array_append(errors, unexpected_token_error_init(expected_type, found, start, end));
120
121
  }
121
122
 
122
- MISSING_OPENING_TAG_ERROR_T* missing_opening_tag_error_init(token_T* closing_tag, position_T* start, position_T* end) {
123
+ MISSING_OPENING_TAG_ERROR_T* missing_opening_tag_error_init(token_T* closing_tag, position_T start, position_T end) {
123
124
  MISSING_OPENING_TAG_ERROR_T* missing_opening_tag_error = malloc(sizeof(MISSING_OPENING_TAG_ERROR_T));
124
125
 
125
126
  error_init(&missing_opening_tag_error->base, MISSING_OPENING_TAG_ERROR, start, end);
126
127
 
127
- const char* message_template = "Found closing tag `</%s>` at (%zu:%zu) without a matching opening tag.";
128
+ const char* message_template = "Found closing tag `</%s>` at (%u:%u) without a matching opening tag in the same scope.";
128
129
 
129
- size_t message_size = 231;
130
+ size_t message_size = 235;
130
131
  char* message = (char*) malloc(message_size);
131
132
 
132
133
  if (message) {
@@ -139,32 +140,32 @@ MISSING_OPENING_TAG_ERROR_T* missing_opening_tag_error_init(token_T* closing_tag
139
140
  message_size,
140
141
  message_template,
141
142
  truncated_argument_0,
142
- closing_tag->location->start->line,
143
- closing_tag->location->start->column
143
+ closing_tag->location.start.line,
144
+ closing_tag->location.start.column
144
145
  );
145
146
 
146
147
  missing_opening_tag_error->base.message = herb_strdup(message);
147
148
  free(message);
148
149
  } else {
149
- missing_opening_tag_error->base.message = herb_strdup("Found closing tag `</%s>` at (%zu:%zu) without a matching opening tag.");
150
+ missing_opening_tag_error->base.message = herb_strdup("Found closing tag `</%s>` at (%u:%u) without a matching opening tag in the same scope.");
150
151
  }
151
152
 
152
153
  missing_opening_tag_error->closing_tag = token_copy(closing_tag);
153
154
  return missing_opening_tag_error;
154
155
  }
155
156
 
156
- void append_missing_opening_tag_error(token_T* closing_tag, position_T* start, position_T* end, array_T* errors) {
157
- array_append(errors, missing_opening_tag_error_init(closing_tag, start, end));
157
+ void append_missing_opening_tag_error(token_T* closing_tag, position_T start, position_T end, hb_array_T* errors) {
158
+ hb_array_append(errors, missing_opening_tag_error_init(closing_tag, start, end));
158
159
  }
159
160
 
160
- MISSING_CLOSING_TAG_ERROR_T* missing_closing_tag_error_init(token_T* opening_tag, position_T* start, position_T* end) {
161
+ MISSING_CLOSING_TAG_ERROR_T* missing_closing_tag_error_init(token_T* opening_tag, position_T start, position_T end) {
161
162
  MISSING_CLOSING_TAG_ERROR_T* missing_closing_tag_error = malloc(sizeof(MISSING_CLOSING_TAG_ERROR_T));
162
163
 
163
164
  error_init(&missing_closing_tag_error->base, MISSING_CLOSING_TAG_ERROR, start, end);
164
165
 
165
- const char* message_template = "Opening tag `<%s>` at (%zu:%zu) doesn't have a matching closing tag `</%s>`.";
166
+ const char* message_template = "Opening tag `<%s>` at (%u:%u) doesn't have a matching closing tag `</%s>` in the same scope.";
166
167
 
167
- size_t message_size = 365;
168
+ size_t message_size = 369;
168
169
  char* message = (char*) malloc(message_size);
169
170
 
170
171
  if (message) {
@@ -181,33 +182,33 @@ MISSING_CLOSING_TAG_ERROR_T* missing_closing_tag_error_init(token_T* opening_tag
181
182
  message_size,
182
183
  message_template,
183
184
  truncated_argument_0,
184
- opening_tag->location->start->line,
185
- opening_tag->location->start->column,
185
+ opening_tag->location.start.line,
186
+ opening_tag->location.start.column,
186
187
  truncated_argument_3
187
188
  );
188
189
 
189
190
  missing_closing_tag_error->base.message = herb_strdup(message);
190
191
  free(message);
191
192
  } else {
192
- missing_closing_tag_error->base.message = herb_strdup("Opening tag `<%s>` at (%zu:%zu) doesn't have a matching closing tag `</%s>`.");
193
+ missing_closing_tag_error->base.message = herb_strdup("Opening tag `<%s>` at (%u:%u) doesn't have a matching closing tag `</%s>` in the same scope.");
193
194
  }
194
195
 
195
196
  missing_closing_tag_error->opening_tag = token_copy(opening_tag);
196
197
  return missing_closing_tag_error;
197
198
  }
198
199
 
199
- void append_missing_closing_tag_error(token_T* opening_tag, position_T* start, position_T* end, array_T* errors) {
200
- array_append(errors, missing_closing_tag_error_init(opening_tag, start, end));
200
+ void append_missing_closing_tag_error(token_T* opening_tag, position_T start, position_T end, hb_array_T* errors) {
201
+ hb_array_append(errors, missing_closing_tag_error_init(opening_tag, start, end));
201
202
  }
202
203
 
203
- TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error_init(token_T* opening_tag, token_T* closing_tag, position_T* start, position_T* end) {
204
+ TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error_init(token_T* opening_tag, token_T* closing_tag, position_T start, position_T end) {
204
205
  TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error = malloc(sizeof(TAG_NAMES_MISMATCH_ERROR_T));
205
206
 
206
207
  error_init(&tag_names_mismatch_error->base, TAG_NAMES_MISMATCH_ERROR, start, end);
207
208
 
208
- const char* message_template = "Opening tag `<%s>` at (%zu:%zu) closed with `</%s>` at (%zu:%zu).";
209
+ const char* message_template = "Opening tag `<%s>` at (%u:%u) closed with `</%s>` at (%u:%u).";
209
210
 
210
- size_t message_size = 386;
211
+ size_t message_size = 358;
211
212
  char* message = (char*) malloc(message_size);
212
213
 
213
214
  if (message) {
@@ -224,17 +225,17 @@ TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error_init(token_T* opening_tag,
224
225
  message_size,
225
226
  message_template,
226
227
  truncated_argument_0,
227
- opening_tag->location->start->line,
228
- opening_tag->location->start->column,
228
+ opening_tag->location.start.line,
229
+ opening_tag->location.start.column,
229
230
  truncated_argument_3,
230
- closing_tag->location->start->line,
231
- closing_tag->location->start->column
231
+ closing_tag->location.start.line,
232
+ closing_tag->location.start.column
232
233
  );
233
234
 
234
235
  tag_names_mismatch_error->base.message = herb_strdup(message);
235
236
  free(message);
236
237
  } else {
237
- tag_names_mismatch_error->base.message = herb_strdup("Opening tag `<%s>` at (%zu:%zu) closed with `</%s>` at (%zu:%zu).");
238
+ tag_names_mismatch_error->base.message = herb_strdup("Opening tag `<%s>` at (%u:%u) closed with `</%s>` at (%u:%u).");
238
239
  }
239
240
 
240
241
  tag_names_mismatch_error->opening_tag = token_copy(opening_tag);
@@ -242,18 +243,18 @@ TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error_init(token_T* opening_tag,
242
243
  return tag_names_mismatch_error;
243
244
  }
244
245
 
245
- void append_tag_names_mismatch_error(token_T* opening_tag, token_T* closing_tag, position_T* start, position_T* end, array_T* errors) {
246
- array_append(errors, tag_names_mismatch_error_init(opening_tag, closing_tag, start, end));
246
+ void append_tag_names_mismatch_error(token_T* opening_tag, token_T* closing_tag, position_T start, position_T end, hb_array_T* errors) {
247
+ hb_array_append(errors, tag_names_mismatch_error_init(opening_tag, closing_tag, start, end));
247
248
  }
248
249
 
249
- QUOTES_MISMATCH_ERROR_T* quotes_mismatch_error_init(token_T* opening_quote, token_T* closing_quote, position_T* start, position_T* end) {
250
+ QUOTES_MISMATCH_ERROR_T* quotes_mismatch_error_init(token_T* opening_quote, token_T* closing_quote, position_T start, position_T end) {
250
251
  QUOTES_MISMATCH_ERROR_T* quotes_mismatch_error = malloc(sizeof(QUOTES_MISMATCH_ERROR_T));
251
252
 
252
253
  error_init(&quotes_mismatch_error->base, QUOTES_MISMATCH_ERROR, start, end);
253
254
 
254
- const char* message_template = "String opened with %s but closed with %s at (%zu:%zu).";
255
+ const char* message_template = "String opened with %s but closed with %s at (%u:%u).";
255
256
 
256
- size_t message_size = 343;
257
+ size_t message_size = 329;
257
258
  char* message = (char*) malloc(message_size);
258
259
 
259
260
  if (message) {
@@ -271,14 +272,14 @@ QUOTES_MISMATCH_ERROR_T* quotes_mismatch_error_init(token_T* opening_quote, toke
271
272
  message_template,
272
273
  truncated_argument_0,
273
274
  truncated_argument_1,
274
- closing_quote->location->start->line,
275
- closing_quote->location->start->column
275
+ closing_quote->location.start.line,
276
+ closing_quote->location.start.column
276
277
  );
277
278
 
278
279
  quotes_mismatch_error->base.message = herb_strdup(message);
279
280
  free(message);
280
281
  } else {
281
- quotes_mismatch_error->base.message = herb_strdup("String opened with %s but closed with %s at (%zu:%zu).");
282
+ quotes_mismatch_error->base.message = herb_strdup("String opened with %s but closed with %s at (%u:%u).");
282
283
  }
283
284
 
284
285
  quotes_mismatch_error->opening_quote = token_copy(opening_quote);
@@ -286,11 +287,11 @@ QUOTES_MISMATCH_ERROR_T* quotes_mismatch_error_init(token_T* opening_quote, toke
286
287
  return quotes_mismatch_error;
287
288
  }
288
289
 
289
- void append_quotes_mismatch_error(token_T* opening_quote, token_T* closing_quote, position_T* start, position_T* end, array_T* errors) {
290
- array_append(errors, quotes_mismatch_error_init(opening_quote, closing_quote, start, end));
290
+ void append_quotes_mismatch_error(token_T* opening_quote, token_T* closing_quote, position_T start, position_T end, hb_array_T* errors) {
291
+ hb_array_append(errors, quotes_mismatch_error_init(opening_quote, closing_quote, start, end));
291
292
  }
292
293
 
293
- VOID_ELEMENT_CLOSING_TAG_ERROR_T* void_element_closing_tag_error_init(token_T* tag_name, const char* expected, const char* found, position_T* start, position_T* end) {
294
+ VOID_ELEMENT_CLOSING_TAG_ERROR_T* void_element_closing_tag_error_init(token_T* tag_name, const char* expected, const char* found, position_T start, position_T end) {
294
295
  VOID_ELEMENT_CLOSING_TAG_ERROR_T* void_element_closing_tag_error = malloc(sizeof(VOID_ELEMENT_CLOSING_TAG_ERROR_T));
295
296
 
296
297
  error_init(&void_element_closing_tag_error->base, VOID_ELEMENT_CLOSING_TAG_ERROR, start, end);
@@ -339,18 +340,18 @@ VOID_ELEMENT_CLOSING_TAG_ERROR_T* void_element_closing_tag_error_init(token_T* t
339
340
  return void_element_closing_tag_error;
340
341
  }
341
342
 
342
- void append_void_element_closing_tag_error(token_T* tag_name, const char* expected, const char* found, position_T* start, position_T* end, array_T* errors) {
343
- array_append(errors, void_element_closing_tag_error_init(tag_name, expected, found, start, end));
343
+ void append_void_element_closing_tag_error(token_T* tag_name, const char* expected, const char* found, position_T start, position_T end, hb_array_T* errors) {
344
+ hb_array_append(errors, void_element_closing_tag_error_init(tag_name, expected, found, start, end));
344
345
  }
345
346
 
346
- UNCLOSED_ELEMENT_ERROR_T* unclosed_element_error_init(token_T* opening_tag, position_T* start, position_T* end) {
347
+ UNCLOSED_ELEMENT_ERROR_T* unclosed_element_error_init(token_T* opening_tag, position_T start, position_T end) {
347
348
  UNCLOSED_ELEMENT_ERROR_T* unclosed_element_error = malloc(sizeof(UNCLOSED_ELEMENT_ERROR_T));
348
349
 
349
350
  error_init(&unclosed_element_error->base, UNCLOSED_ELEMENT_ERROR, start, end);
350
351
 
351
- const char* message_template = "Tag `<%s>` opened at (%zu:%zu) was never closed before the end of document.";
352
+ const char* message_template = "Tag `<%s>` opened at (%u:%u) was never closed before the end of document.";
352
353
 
353
- size_t message_size = 236;
354
+ size_t message_size = 222;
354
355
  char* message = (char*) malloc(message_size);
355
356
 
356
357
  if (message) {
@@ -363,25 +364,25 @@ UNCLOSED_ELEMENT_ERROR_T* unclosed_element_error_init(token_T* opening_tag, posi
363
364
  message_size,
364
365
  message_template,
365
366
  truncated_argument_0,
366
- opening_tag->location->start->line,
367
- opening_tag->location->start->column
367
+ opening_tag->location.start.line,
368
+ opening_tag->location.start.column
368
369
  );
369
370
 
370
371
  unclosed_element_error->base.message = herb_strdup(message);
371
372
  free(message);
372
373
  } else {
373
- unclosed_element_error->base.message = herb_strdup("Tag `<%s>` opened at (%zu:%zu) was never closed before the end of document.");
374
+ unclosed_element_error->base.message = herb_strdup("Tag `<%s>` opened at (%u:%u) was never closed before the end of document.");
374
375
  }
375
376
 
376
377
  unclosed_element_error->opening_tag = token_copy(opening_tag);
377
378
  return unclosed_element_error;
378
379
  }
379
380
 
380
- void append_unclosed_element_error(token_T* opening_tag, position_T* start, position_T* end, array_T* errors) {
381
- array_append(errors, unclosed_element_error_init(opening_tag, start, end));
381
+ void append_unclosed_element_error(token_T* opening_tag, position_T start, position_T end, hb_array_T* errors) {
382
+ hb_array_append(errors, unclosed_element_error_init(opening_tag, start, end));
382
383
  }
383
384
 
384
- RUBY_PARSE_ERROR_T* ruby_parse_error_init(const char* error_message, const char* diagnostic_id, const char* level, position_T* start, position_T* end) {
385
+ RUBY_PARSE_ERROR_T* ruby_parse_error_init(const char* error_message, const char* diagnostic_id, const char* level, position_T start, position_T end) {
385
386
  RUBY_PARSE_ERROR_T* ruby_parse_error = malloc(sizeof(RUBY_PARSE_ERROR_T));
386
387
 
387
388
  error_init(&ruby_parse_error->base, RUBY_PARSE_ERROR, start, end);
@@ -420,8 +421,80 @@ RUBY_PARSE_ERROR_T* ruby_parse_error_init(const char* error_message, const char*
420
421
  return ruby_parse_error;
421
422
  }
422
423
 
423
- void append_ruby_parse_error(const char* error_message, const char* diagnostic_id, const char* level, position_T* start, position_T* end, array_T* errors) {
424
- array_append(errors, ruby_parse_error_init(error_message, diagnostic_id, level, start, end));
424
+ void append_ruby_parse_error(const char* error_message, const char* diagnostic_id, const char* level, position_T start, position_T end, hb_array_T* errors) {
425
+ hb_array_append(errors, ruby_parse_error_init(error_message, diagnostic_id, level, start, end));
426
+ }
427
+
428
+ ERB_CONTROL_FLOW_SCOPE_ERROR_T* erb_control_flow_scope_error_init(const char* keyword, position_T start, position_T end) {
429
+ ERB_CONTROL_FLOW_SCOPE_ERROR_T* erb_control_flow_scope_error = malloc(sizeof(ERB_CONTROL_FLOW_SCOPE_ERROR_T));
430
+
431
+ error_init(&erb_control_flow_scope_error->base, ERB_CONTROL_FLOW_SCOPE_ERROR, start, end);
432
+
433
+ const char* message_template = "%s appears outside its control flow block. Keep ERB control flow statements together within the same HTML scope (tag, attribute, or content).";
434
+
435
+ size_t message_size = 270;
436
+ char* message = (char*) malloc(message_size);
437
+
438
+ if (message) {
439
+ char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
440
+ strncpy(truncated_argument_0, keyword, ERROR_MESSAGES_TRUNCATED_LENGTH);
441
+ truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
442
+
443
+ snprintf(
444
+ message,
445
+ message_size,
446
+ message_template,
447
+ truncated_argument_0
448
+ );
449
+
450
+ erb_control_flow_scope_error->base.message = herb_strdup(message);
451
+ free(message);
452
+ } else {
453
+ erb_control_flow_scope_error->base.message = herb_strdup("%s appears outside its control flow block. Keep ERB control flow statements together within the same HTML scope (tag, attribute, or content).");
454
+ }
455
+
456
+ erb_control_flow_scope_error->keyword = herb_strdup(keyword);
457
+ return erb_control_flow_scope_error;
458
+ }
459
+
460
+ void append_erb_control_flow_scope_error(const char* keyword, position_T start, position_T end, hb_array_T* errors) {
461
+ hb_array_append(errors, erb_control_flow_scope_error_init(keyword, start, end));
462
+ }
463
+
464
+ MISSINGERB_END_TAG_ERROR_T* missingerb_end_tag_error_init(const char* keyword, position_T start, position_T end) {
465
+ MISSINGERB_END_TAG_ERROR_T* missingerb_end_tag_error = malloc(sizeof(MISSINGERB_END_TAG_ERROR_T));
466
+
467
+ error_init(&missingerb_end_tag_error->base, MISSINGERB_END_TAG_ERROR, start, end);
468
+
469
+ const char* message_template = "%s started here but never closed with an end tag. The end tag may be in a different scope.";
470
+
471
+ size_t message_size = 219;
472
+ char* message = (char*) malloc(message_size);
473
+
474
+ if (message) {
475
+ char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
476
+ strncpy(truncated_argument_0, keyword, ERROR_MESSAGES_TRUNCATED_LENGTH);
477
+ truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
478
+
479
+ snprintf(
480
+ message,
481
+ message_size,
482
+ message_template,
483
+ truncated_argument_0
484
+ );
485
+
486
+ missingerb_end_tag_error->base.message = herb_strdup(message);
487
+ free(message);
488
+ } else {
489
+ missingerb_end_tag_error->base.message = herb_strdup("%s started here but never closed with an end tag. The end tag may be in a different scope.");
490
+ }
491
+
492
+ missingerb_end_tag_error->keyword = herb_strdup(keyword);
493
+ return missingerb_end_tag_error;
494
+ }
495
+
496
+ void append_missingerb_end_tag_error(const char* keyword, position_T start, position_T end, hb_array_T* errors) {
497
+ hb_array_append(errors, missingerb_end_tag_error_init(keyword, start, end));
425
498
  }
426
499
 
427
500
  const char* error_type_to_string(ERROR_T* error) {
@@ -435,6 +508,8 @@ const char* error_type_to_string(ERROR_T* error) {
435
508
  case VOID_ELEMENT_CLOSING_TAG_ERROR: return "VOID_ELEMENT_CLOSING_TAG_ERROR";
436
509
  case UNCLOSED_ELEMENT_ERROR: return "UNCLOSED_ELEMENT_ERROR";
437
510
  case RUBY_PARSE_ERROR: return "RUBY_PARSE_ERROR";
511
+ case ERB_CONTROL_FLOW_SCOPE_ERROR: return "ERB_CONTROL_FLOW_SCOPE_ERROR";
512
+ case MISSINGERB_END_TAG_ERROR: return "MISSINGERB_END_TAG_ERROR";
438
513
  }
439
514
 
440
515
  return "Unknown error_type_T";
@@ -451,6 +526,8 @@ const char* error_human_type(ERROR_T* error) {
451
526
  case VOID_ELEMENT_CLOSING_TAG_ERROR: return "VoidElementClosingTagError";
452
527
  case UNCLOSED_ELEMENT_ERROR: return "UnclosedElementError";
453
528
  case RUBY_PARSE_ERROR: return "RubyParseError";
529
+ case ERB_CONTROL_FLOW_SCOPE_ERROR: return "ERBControlFlowScopeError";
530
+ case MISSINGERB_END_TAG_ERROR: return "MissingERBEndTagError";
454
531
  }
455
532
 
456
533
  return "Unknown error_type_T";
@@ -459,7 +536,6 @@ const char* error_human_type(ERROR_T* error) {
459
536
  void error_free_base_error(ERROR_T* error) {
460
537
  if (error == NULL) { return; }
461
538
 
462
- if (error->location != NULL) { location_free(error->location); }
463
539
  if (error->message != NULL) { free(error->message); }
464
540
 
465
541
  free(error);
@@ -528,6 +604,18 @@ static void error_free_ruby_parse_error(RUBY_PARSE_ERROR_T* ruby_parse_error) {
528
604
  error_free_base_error(&ruby_parse_error->base);
529
605
  }
530
606
 
607
+ static void error_free_erb_control_flow_scope_error(ERB_CONTROL_FLOW_SCOPE_ERROR_T* erb_control_flow_scope_error) {
608
+ if (erb_control_flow_scope_error->keyword != NULL) { free((char*) erb_control_flow_scope_error->keyword); }
609
+
610
+ error_free_base_error(&erb_control_flow_scope_error->base);
611
+ }
612
+
613
+ static void error_free_missingerb_end_tag_error(MISSINGERB_END_TAG_ERROR_T* missingerb_end_tag_error) {
614
+ if (missingerb_end_tag_error->keyword != NULL) { free((char*) missingerb_end_tag_error->keyword); }
615
+
616
+ error_free_base_error(&missingerb_end_tag_error->base);
617
+ }
618
+
531
619
  void error_free(ERROR_T* error) {
532
620
  if (!error) { return; }
533
621
 
@@ -541,189 +629,219 @@ void error_free(ERROR_T* error) {
541
629
  case VOID_ELEMENT_CLOSING_TAG_ERROR: error_free_void_element_closing_tag_error((VOID_ELEMENT_CLOSING_TAG_ERROR_T*) error); break;
542
630
  case UNCLOSED_ELEMENT_ERROR: error_free_unclosed_element_error((UNCLOSED_ELEMENT_ERROR_T*) error); break;
543
631
  case RUBY_PARSE_ERROR: error_free_ruby_parse_error((RUBY_PARSE_ERROR_T*) error); break;
632
+ case ERB_CONTROL_FLOW_SCOPE_ERROR: error_free_erb_control_flow_scope_error((ERB_CONTROL_FLOW_SCOPE_ERROR_T*) error); break;
633
+ case MISSINGERB_END_TAG_ERROR: error_free_missingerb_end_tag_error((MISSINGERB_END_TAG_ERROR_T*) error); break;
544
634
  }
545
635
  }
546
636
 
547
637
  void error_pretty_print_array(
548
- const char* name, array_T* array, const size_t indent, const size_t relative_indent, const bool last_property,
549
- buffer_T* buffer
638
+ const char* name, hb_array_T* array, const size_t indent, const size_t relative_indent, const bool last_property,
639
+ hb_buffer_T* buffer
550
640
  ) {
551
641
  if (array == NULL) {
552
- pretty_print_property(name, "∅", indent, relative_indent, last_property, buffer);
642
+ pretty_print_property(hb_string(name), hb_string("∅"), indent, relative_indent, last_property, buffer);
553
643
 
554
644
  return;
555
645
  }
556
646
 
557
- if (array_size(array) == 0) {
558
- pretty_print_property(name, "[]", indent, relative_indent, last_property, buffer);
647
+ if (hb_array_size(array) == 0) {
648
+ pretty_print_property(hb_string(name), hb_string("[]"), indent, relative_indent, last_property, buffer);
559
649
 
560
650
  return;
561
651
  }
562
652
 
563
- pretty_print_label(name, indent, relative_indent, last_property, buffer);
653
+ pretty_print_label(hb_string(name), indent, relative_indent, last_property, buffer);
564
654
 
565
- buffer_append(buffer, "(");
655
+ hb_buffer_append(buffer, "(");
566
656
 
567
657
  char count[16];
568
- sprintf(count, "%zu", array_size(array));
569
- buffer_append(buffer, count);
570
- buffer_append(buffer, ")\n");
658
+ sprintf(count, "%zu", hb_array_size(array));
659
+ hb_buffer_append(buffer, count);
660
+ hb_buffer_append(buffer, ")\n");
571
661
 
572
662
  if (indent < 20) {
573
- for (size_t i = 0; i < array_size(array); i++) {
574
- ERROR_T* child = array_get(array, i);
663
+ for (size_t i = 0; i < hb_array_size(array); i++) {
664
+ ERROR_T* child = hb_array_get(array, i);
575
665
  pretty_print_indent(buffer, indent);
576
666
  pretty_print_indent(buffer, relative_indent + 1);
577
667
 
578
- if (i == array_size(array) - 1) {
579
- buffer_append(buffer, "└── ");
668
+ if (i == hb_array_size(array) - 1) {
669
+ hb_buffer_append(buffer, "└── ");
580
670
  } else {
581
- buffer_append(buffer, "├── ");
671
+ hb_buffer_append(buffer, "├── ");
582
672
  }
583
673
 
584
674
  error_pretty_print(child, indent + 1, relative_indent + 1, buffer);
585
675
 
586
- if (i != array_size(array) - 1) { pretty_print_newline(indent + 1, relative_indent, buffer); }
676
+ if (i != hb_array_size(array) - 1) { pretty_print_newline(indent + 1, relative_indent, buffer); }
587
677
  }
588
678
  }
589
679
  }
590
680
 
591
- static void error_pretty_print_unexpected_error(UNEXPECTED_ERROR_T* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
681
+ static void error_pretty_print_unexpected_error(UNEXPECTED_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
682
+ if (!error) { return; }
683
+
684
+ hb_buffer_append(buffer, "@ ");
685
+ hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
686
+ hb_buffer_append(buffer, " ");
687
+
688
+ pretty_print_location(error->base.location, buffer);
689
+ hb_buffer_append(buffer, "\n");
690
+
691
+ pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
692
+ pretty_print_quoted_property(hb_string("description"), hb_string(error->description), indent, relative_indent, false, buffer);
693
+ pretty_print_quoted_property(hb_string("expected"), hb_string(error->expected), indent, relative_indent, false, buffer);
694
+ pretty_print_quoted_property(hb_string("found"), hb_string(error->found), indent, relative_indent, true, buffer);
695
+ }
696
+
697
+ static void error_pretty_print_unexpected_token_error(UNEXPECTED_TOKEN_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
698
+ if (!error) { return; }
699
+
700
+ hb_buffer_append(buffer, "@ ");
701
+ hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
702
+ hb_buffer_append(buffer, " ");
703
+
704
+ pretty_print_location(error->base.location, buffer);
705
+ hb_buffer_append(buffer, "\n");
706
+
707
+ pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
708
+ pretty_print_property(hb_string(token_type_to_string(error->expected_type)), hb_string("expected_type"), indent, relative_indent, false, buffer);
709
+ pretty_print_token_property(error->found, hb_string("found"), indent, relative_indent, true, buffer);
710
+ }
711
+
712
+ static void error_pretty_print_missing_opening_tag_error(MISSING_OPENING_TAG_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
592
713
  if (!error) { return; }
593
714
 
594
- buffer_append(buffer, "@ ");
595
- buffer_append(buffer, error_human_type((ERROR_T*) error));
596
- buffer_append(buffer, " ");
715
+ hb_buffer_append(buffer, "@ ");
716
+ hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
717
+ hb_buffer_append(buffer, " ");
597
718
 
598
719
  pretty_print_location(error->base.location, buffer);
599
- buffer_append(buffer, "\n");
720
+ hb_buffer_append(buffer, "\n");
600
721
 
601
- pretty_print_quoted_property("message", error->base.message, indent, relative_indent, false, buffer);
602
- pretty_print_quoted_property("description", error->description, indent, relative_indent, false, buffer);
603
- pretty_print_quoted_property("expected", error->expected, indent, relative_indent, false, buffer);
604
- pretty_print_quoted_property("found", error->found, indent, relative_indent, true, buffer);
722
+ pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
723
+ pretty_print_token_property(error->closing_tag, hb_string("closing_tag"), indent, relative_indent, true, buffer);
605
724
  }
606
725
 
607
- static void error_pretty_print_unexpected_token_error(UNEXPECTED_TOKEN_ERROR_T* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
726
+ static void error_pretty_print_missing_closing_tag_error(MISSING_CLOSING_TAG_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
608
727
  if (!error) { return; }
609
728
 
610
- buffer_append(buffer, "@ ");
611
- buffer_append(buffer, error_human_type((ERROR_T*) error));
612
- buffer_append(buffer, " ");
729
+ hb_buffer_append(buffer, "@ ");
730
+ hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
731
+ hb_buffer_append(buffer, " ");
613
732
 
614
733
  pretty_print_location(error->base.location, buffer);
615
- buffer_append(buffer, "\n");
734
+ hb_buffer_append(buffer, "\n");
616
735
 
617
- pretty_print_quoted_property("message", error->base.message, indent, relative_indent, false, buffer);
618
- pretty_print_property(token_type_to_string(error->expected_type), "expected_type", indent, relative_indent, false, buffer);
619
- pretty_print_token_property(error->found, "found", indent, relative_indent, true, buffer);
736
+ pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
737
+ pretty_print_token_property(error->opening_tag, hb_string("opening_tag"), indent, relative_indent, true, buffer);
620
738
  }
621
739
 
622
- static void error_pretty_print_missing_opening_tag_error(MISSING_OPENING_TAG_ERROR_T* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
740
+ static void error_pretty_print_tag_names_mismatch_error(TAG_NAMES_MISMATCH_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
623
741
  if (!error) { return; }
624
742
 
625
- buffer_append(buffer, "@ ");
626
- buffer_append(buffer, error_human_type((ERROR_T*) error));
627
- buffer_append(buffer, " ");
743
+ hb_buffer_append(buffer, "@ ");
744
+ hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
745
+ hb_buffer_append(buffer, " ");
628
746
 
629
747
  pretty_print_location(error->base.location, buffer);
630
- buffer_append(buffer, "\n");
748
+ hb_buffer_append(buffer, "\n");
631
749
 
632
- pretty_print_quoted_property("message", error->base.message, indent, relative_indent, false, buffer);
633
- pretty_print_token_property(error->closing_tag, "closing_tag", indent, relative_indent, true, buffer);
750
+ pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
751
+ pretty_print_token_property(error->opening_tag, hb_string("opening_tag"), indent, relative_indent, false, buffer);
752
+ pretty_print_token_property(error->closing_tag, hb_string("closing_tag"), indent, relative_indent, true, buffer);
634
753
  }
635
754
 
636
- static void error_pretty_print_missing_closing_tag_error(MISSING_CLOSING_TAG_ERROR_T* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
755
+ static void error_pretty_print_quotes_mismatch_error(QUOTES_MISMATCH_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
637
756
  if (!error) { return; }
638
757
 
639
- buffer_append(buffer, "@ ");
640
- buffer_append(buffer, error_human_type((ERROR_T*) error));
641
- buffer_append(buffer, " ");
758
+ hb_buffer_append(buffer, "@ ");
759
+ hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
760
+ hb_buffer_append(buffer, " ");
642
761
 
643
762
  pretty_print_location(error->base.location, buffer);
644
- buffer_append(buffer, "\n");
763
+ hb_buffer_append(buffer, "\n");
645
764
 
646
- pretty_print_quoted_property("message", error->base.message, indent, relative_indent, false, buffer);
647
- pretty_print_token_property(error->opening_tag, "opening_tag", indent, relative_indent, true, buffer);
765
+ pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
766
+ pretty_print_token_property(error->opening_quote, hb_string("opening_quote"), indent, relative_indent, false, buffer);
767
+ pretty_print_token_property(error->closing_quote, hb_string("closing_quote"), indent, relative_indent, true, buffer);
648
768
  }
649
769
 
650
- static void error_pretty_print_tag_names_mismatch_error(TAG_NAMES_MISMATCH_ERROR_T* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
770
+ static void error_pretty_print_void_element_closing_tag_error(VOID_ELEMENT_CLOSING_TAG_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
651
771
  if (!error) { return; }
652
772
 
653
- buffer_append(buffer, "@ ");
654
- buffer_append(buffer, error_human_type((ERROR_T*) error));
655
- buffer_append(buffer, " ");
773
+ hb_buffer_append(buffer, "@ ");
774
+ hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
775
+ hb_buffer_append(buffer, " ");
656
776
 
657
777
  pretty_print_location(error->base.location, buffer);
658
- buffer_append(buffer, "\n");
778
+ hb_buffer_append(buffer, "\n");
659
779
 
660
- pretty_print_quoted_property("message", error->base.message, indent, relative_indent, false, buffer);
661
- pretty_print_token_property(error->opening_tag, "opening_tag", indent, relative_indent, false, buffer);
662
- pretty_print_token_property(error->closing_tag, "closing_tag", indent, relative_indent, true, buffer);
780
+ pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
781
+ pretty_print_token_property(error->tag_name, hb_string("tag_name"), indent, relative_indent, false, buffer);
782
+ pretty_print_quoted_property(hb_string("expected"), hb_string(error->expected), indent, relative_indent, false, buffer);
783
+ pretty_print_quoted_property(hb_string("found"), hb_string(error->found), indent, relative_indent, true, buffer);
663
784
  }
664
785
 
665
- static void error_pretty_print_quotes_mismatch_error(QUOTES_MISMATCH_ERROR_T* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
786
+ static void error_pretty_print_unclosed_element_error(UNCLOSED_ELEMENT_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
666
787
  if (!error) { return; }
667
788
 
668
- buffer_append(buffer, "@ ");
669
- buffer_append(buffer, error_human_type((ERROR_T*) error));
670
- buffer_append(buffer, " ");
789
+ hb_buffer_append(buffer, "@ ");
790
+ hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
791
+ hb_buffer_append(buffer, " ");
671
792
 
672
793
  pretty_print_location(error->base.location, buffer);
673
- buffer_append(buffer, "\n");
794
+ hb_buffer_append(buffer, "\n");
674
795
 
675
- pretty_print_quoted_property("message", error->base.message, indent, relative_indent, false, buffer);
676
- pretty_print_token_property(error->opening_quote, "opening_quote", indent, relative_indent, false, buffer);
677
- pretty_print_token_property(error->closing_quote, "closing_quote", indent, relative_indent, true, buffer);
796
+ pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
797
+ pretty_print_token_property(error->opening_tag, hb_string("opening_tag"), indent, relative_indent, true, buffer);
678
798
  }
679
799
 
680
- static void error_pretty_print_void_element_closing_tag_error(VOID_ELEMENT_CLOSING_TAG_ERROR_T* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
800
+ static void error_pretty_print_ruby_parse_error(RUBY_PARSE_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
681
801
  if (!error) { return; }
682
802
 
683
- buffer_append(buffer, "@ ");
684
- buffer_append(buffer, error_human_type((ERROR_T*) error));
685
- buffer_append(buffer, " ");
803
+ hb_buffer_append(buffer, "@ ");
804
+ hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
805
+ hb_buffer_append(buffer, " ");
686
806
 
687
807
  pretty_print_location(error->base.location, buffer);
688
- buffer_append(buffer, "\n");
808
+ hb_buffer_append(buffer, "\n");
689
809
 
690
- pretty_print_quoted_property("message", error->base.message, indent, relative_indent, false, buffer);
691
- pretty_print_token_property(error->tag_name, "tag_name", indent, relative_indent, false, buffer);
692
- pretty_print_quoted_property("expected", error->expected, indent, relative_indent, false, buffer);
693
- pretty_print_quoted_property("found", error->found, indent, relative_indent, true, buffer);
810
+ pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
811
+ pretty_print_quoted_property(hb_string("error_message"), hb_string(error->error_message), indent, relative_indent, false, buffer);
812
+ pretty_print_quoted_property(hb_string("diagnostic_id"), hb_string(error->diagnostic_id), indent, relative_indent, false, buffer);
813
+ pretty_print_quoted_property(hb_string("level"), hb_string(error->level), indent, relative_indent, true, buffer);
694
814
  }
695
815
 
696
- static void error_pretty_print_unclosed_element_error(UNCLOSED_ELEMENT_ERROR_T* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
816
+ static void error_pretty_print_erb_control_flow_scope_error(ERB_CONTROL_FLOW_SCOPE_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
697
817
  if (!error) { return; }
698
818
 
699
- buffer_append(buffer, "@ ");
700
- buffer_append(buffer, error_human_type((ERROR_T*) error));
701
- buffer_append(buffer, " ");
819
+ hb_buffer_append(buffer, "@ ");
820
+ hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
821
+ hb_buffer_append(buffer, " ");
702
822
 
703
823
  pretty_print_location(error->base.location, buffer);
704
- buffer_append(buffer, "\n");
824
+ hb_buffer_append(buffer, "\n");
705
825
 
706
- pretty_print_quoted_property("message", error->base.message, indent, relative_indent, false, buffer);
707
- pretty_print_token_property(error->opening_tag, "opening_tag", indent, relative_indent, true, buffer);
826
+ pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
827
+ pretty_print_quoted_property(hb_string("keyword"), hb_string(error->keyword), indent, relative_indent, true, buffer);
708
828
  }
709
829
 
710
- static void error_pretty_print_ruby_parse_error(RUBY_PARSE_ERROR_T* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
830
+ static void error_pretty_print_missingerb_end_tag_error(MISSINGERB_END_TAG_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
711
831
  if (!error) { return; }
712
832
 
713
- buffer_append(buffer, "@ ");
714
- buffer_append(buffer, error_human_type((ERROR_T*) error));
715
- buffer_append(buffer, " ");
833
+ hb_buffer_append(buffer, "@ ");
834
+ hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
835
+ hb_buffer_append(buffer, " ");
716
836
 
717
837
  pretty_print_location(error->base.location, buffer);
718
- buffer_append(buffer, "\n");
838
+ hb_buffer_append(buffer, "\n");
719
839
 
720
- pretty_print_quoted_property("message", error->base.message, indent, relative_indent, false, buffer);
721
- pretty_print_quoted_property("error_message", error->error_message, indent, relative_indent, false, buffer);
722
- pretty_print_quoted_property("diagnostic_id", error->diagnostic_id, indent, relative_indent, false, buffer);
723
- pretty_print_quoted_property("level", error->level, indent, relative_indent, true, buffer);
840
+ pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
841
+ pretty_print_quoted_property(hb_string("keyword"), hb_string(error->keyword), indent, relative_indent, true, buffer);
724
842
  }
725
843
 
726
- void error_pretty_print(ERROR_T* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
844
+ void error_pretty_print(ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
727
845
  if (!error) { return; }
728
846
 
729
847
  switch (error->type) {
@@ -736,5 +854,7 @@ void error_pretty_print(ERROR_T* error, const size_t indent, const size_t relati
736
854
  case VOID_ELEMENT_CLOSING_TAG_ERROR: error_pretty_print_void_element_closing_tag_error((VOID_ELEMENT_CLOSING_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
737
855
  case UNCLOSED_ELEMENT_ERROR: error_pretty_print_unclosed_element_error((UNCLOSED_ELEMENT_ERROR_T*) error, indent, relative_indent, buffer); break;
738
856
  case RUBY_PARSE_ERROR: error_pretty_print_ruby_parse_error((RUBY_PARSE_ERROR_T*) error, indent, relative_indent, buffer); break;
857
+ case ERB_CONTROL_FLOW_SCOPE_ERROR: error_pretty_print_erb_control_flow_scope_error((ERB_CONTROL_FLOW_SCOPE_ERROR_T*) error, indent, relative_indent, buffer); break;
858
+ case MISSINGERB_END_TAG_ERROR: error_pretty_print_missingerb_end_tag_error((MISSINGERB_END_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
739
859
  }
740
860
  }