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/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>
@@ -72,8 +72,8 @@ UNEXPECTED_ERROR_T* unexpected_error_init(const char* description, const char* e
72
72
  return unexpected_error;
73
73
  }
74
74
 
75
- void append_unexpected_error(const char* description, const char* expected, const char* found, position_T start, position_T end, array_T* errors) {
76
- 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));
77
77
  }
78
78
 
79
79
  UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error_init(token_type_T expected_type, token_T* found, position_T start, position_T end) {
@@ -81,9 +81,9 @@ UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error_init(token_type_T expected_type
81
81
 
82
82
  error_init(&unexpected_token_error->base, UNEXPECTED_TOKEN_ERROR, start, end);
83
83
 
84
- 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).";
85
85
 
86
- size_t message_size = 333;
86
+ size_t message_size = 319;
87
87
  char* message = (char*) malloc(message_size);
88
88
 
89
89
  if (message) {
@@ -108,7 +108,7 @@ UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error_init(token_type_T expected_type
108
108
  unexpected_token_error->base.message = herb_strdup(message);
109
109
  free(message);
110
110
  } else {
111
- 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).");
112
112
  }
113
113
 
114
114
  unexpected_token_error->expected_type = expected_type;
@@ -116,8 +116,8 @@ UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error_init(token_type_T expected_type
116
116
  return unexpected_token_error;
117
117
  }
118
118
 
119
- void append_unexpected_token_error(token_type_T expected_type, token_T* found, position_T start, position_T end, array_T* errors) {
120
- 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));
121
121
  }
122
122
 
123
123
  MISSING_OPENING_TAG_ERROR_T* missing_opening_tag_error_init(token_T* closing_tag, position_T start, position_T end) {
@@ -125,9 +125,9 @@ MISSING_OPENING_TAG_ERROR_T* missing_opening_tag_error_init(token_T* closing_tag
125
125
 
126
126
  error_init(&missing_opening_tag_error->base, MISSING_OPENING_TAG_ERROR, start, end);
127
127
 
128
- 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.";
129
129
 
130
- size_t message_size = 231;
130
+ size_t message_size = 235;
131
131
  char* message = (char*) malloc(message_size);
132
132
 
133
133
  if (message) {
@@ -147,15 +147,15 @@ MISSING_OPENING_TAG_ERROR_T* missing_opening_tag_error_init(token_T* closing_tag
147
147
  missing_opening_tag_error->base.message = herb_strdup(message);
148
148
  free(message);
149
149
  } else {
150
- 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.");
151
151
  }
152
152
 
153
153
  missing_opening_tag_error->closing_tag = token_copy(closing_tag);
154
154
  return missing_opening_tag_error;
155
155
  }
156
156
 
157
- void append_missing_opening_tag_error(token_T* closing_tag, position_T start, position_T end, array_T* errors) {
158
- 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));
159
159
  }
160
160
 
161
161
  MISSING_CLOSING_TAG_ERROR_T* missing_closing_tag_error_init(token_T* opening_tag, position_T start, position_T end) {
@@ -163,9 +163,9 @@ MISSING_CLOSING_TAG_ERROR_T* missing_closing_tag_error_init(token_T* opening_tag
163
163
 
164
164
  error_init(&missing_closing_tag_error->base, MISSING_CLOSING_TAG_ERROR, start, end);
165
165
 
166
- 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.";
167
167
 
168
- size_t message_size = 365;
168
+ size_t message_size = 369;
169
169
  char* message = (char*) malloc(message_size);
170
170
 
171
171
  if (message) {
@@ -190,15 +190,15 @@ MISSING_CLOSING_TAG_ERROR_T* missing_closing_tag_error_init(token_T* opening_tag
190
190
  missing_closing_tag_error->base.message = herb_strdup(message);
191
191
  free(message);
192
192
  } else {
193
- 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.");
194
194
  }
195
195
 
196
196
  missing_closing_tag_error->opening_tag = token_copy(opening_tag);
197
197
  return missing_closing_tag_error;
198
198
  }
199
199
 
200
- void append_missing_closing_tag_error(token_T* opening_tag, position_T start, position_T end, array_T* errors) {
201
- 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));
202
202
  }
203
203
 
204
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) {
@@ -206,9 +206,9 @@ TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error_init(token_T* opening_tag,
206
206
 
207
207
  error_init(&tag_names_mismatch_error->base, TAG_NAMES_MISMATCH_ERROR, start, end);
208
208
 
209
- 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).";
210
210
 
211
- size_t message_size = 386;
211
+ size_t message_size = 358;
212
212
  char* message = (char*) malloc(message_size);
213
213
 
214
214
  if (message) {
@@ -235,7 +235,7 @@ TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error_init(token_T* opening_tag,
235
235
  tag_names_mismatch_error->base.message = herb_strdup(message);
236
236
  free(message);
237
237
  } else {
238
- 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).");
239
239
  }
240
240
 
241
241
  tag_names_mismatch_error->opening_tag = token_copy(opening_tag);
@@ -243,8 +243,8 @@ TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error_init(token_T* opening_tag,
243
243
  return tag_names_mismatch_error;
244
244
  }
245
245
 
246
- void append_tag_names_mismatch_error(token_T* opening_tag, token_T* closing_tag, position_T start, position_T end, array_T* errors) {
247
- 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));
248
248
  }
249
249
 
250
250
  QUOTES_MISMATCH_ERROR_T* quotes_mismatch_error_init(token_T* opening_quote, token_T* closing_quote, position_T start, position_T end) {
@@ -252,9 +252,9 @@ QUOTES_MISMATCH_ERROR_T* quotes_mismatch_error_init(token_T* opening_quote, toke
252
252
 
253
253
  error_init(&quotes_mismatch_error->base, QUOTES_MISMATCH_ERROR, start, end);
254
254
 
255
- 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).";
256
256
 
257
- size_t message_size = 343;
257
+ size_t message_size = 329;
258
258
  char* message = (char*) malloc(message_size);
259
259
 
260
260
  if (message) {
@@ -279,7 +279,7 @@ QUOTES_MISMATCH_ERROR_T* quotes_mismatch_error_init(token_T* opening_quote, toke
279
279
  quotes_mismatch_error->base.message = herb_strdup(message);
280
280
  free(message);
281
281
  } else {
282
- 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).");
283
283
  }
284
284
 
285
285
  quotes_mismatch_error->opening_quote = token_copy(opening_quote);
@@ -287,8 +287,8 @@ QUOTES_MISMATCH_ERROR_T* quotes_mismatch_error_init(token_T* opening_quote, toke
287
287
  return quotes_mismatch_error;
288
288
  }
289
289
 
290
- void append_quotes_mismatch_error(token_T* opening_quote, token_T* closing_quote, position_T start, position_T end, array_T* errors) {
291
- 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));
292
292
  }
293
293
 
294
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) {
@@ -340,8 +340,8 @@ VOID_ELEMENT_CLOSING_TAG_ERROR_T* void_element_closing_tag_error_init(token_T* t
340
340
  return void_element_closing_tag_error;
341
341
  }
342
342
 
343
- 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) {
344
- 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));
345
345
  }
346
346
 
347
347
  UNCLOSED_ELEMENT_ERROR_T* unclosed_element_error_init(token_T* opening_tag, position_T start, position_T end) {
@@ -349,9 +349,9 @@ UNCLOSED_ELEMENT_ERROR_T* unclosed_element_error_init(token_T* opening_tag, posi
349
349
 
350
350
  error_init(&unclosed_element_error->base, UNCLOSED_ELEMENT_ERROR, start, end);
351
351
 
352
- 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.";
353
353
 
354
- size_t message_size = 236;
354
+ size_t message_size = 222;
355
355
  char* message = (char*) malloc(message_size);
356
356
 
357
357
  if (message) {
@@ -371,15 +371,15 @@ UNCLOSED_ELEMENT_ERROR_T* unclosed_element_error_init(token_T* opening_tag, posi
371
371
  unclosed_element_error->base.message = herb_strdup(message);
372
372
  free(message);
373
373
  } else {
374
- 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.");
375
375
  }
376
376
 
377
377
  unclosed_element_error->opening_tag = token_copy(opening_tag);
378
378
  return unclosed_element_error;
379
379
  }
380
380
 
381
- void append_unclosed_element_error(token_T* opening_tag, position_T start, position_T end, array_T* errors) {
382
- 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));
383
383
  }
384
384
 
385
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) {
@@ -421,8 +421,80 @@ RUBY_PARSE_ERROR_T* ruby_parse_error_init(const char* error_message, const char*
421
421
  return ruby_parse_error;
422
422
  }
423
423
 
424
- 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) {
425
- 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));
426
498
  }
427
499
 
428
500
  const char* error_type_to_string(ERROR_T* error) {
@@ -436,6 +508,8 @@ const char* error_type_to_string(ERROR_T* error) {
436
508
  case VOID_ELEMENT_CLOSING_TAG_ERROR: return "VOID_ELEMENT_CLOSING_TAG_ERROR";
437
509
  case UNCLOSED_ELEMENT_ERROR: return "UNCLOSED_ELEMENT_ERROR";
438
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";
439
513
  }
440
514
 
441
515
  return "Unknown error_type_T";
@@ -452,6 +526,8 @@ const char* error_human_type(ERROR_T* error) {
452
526
  case VOID_ELEMENT_CLOSING_TAG_ERROR: return "VoidElementClosingTagError";
453
527
  case UNCLOSED_ELEMENT_ERROR: return "UnclosedElementError";
454
528
  case RUBY_PARSE_ERROR: return "RubyParseError";
529
+ case ERB_CONTROL_FLOW_SCOPE_ERROR: return "ERBControlFlowScopeError";
530
+ case MISSINGERB_END_TAG_ERROR: return "MissingERBEndTagError";
455
531
  }
456
532
 
457
533
  return "Unknown error_type_T";
@@ -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
  }