@herb-tools/node 0.8.10 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/binding.gyp +27 -8
  2. package/dist/herb-node.cjs +41 -12
  3. package/dist/herb-node.cjs.map +1 -1
  4. package/dist/herb-node.esm.js +8 -1
  5. package/dist/herb-node.esm.js.map +1 -1
  6. package/dist/types/node-backend.d.ts +3 -1
  7. package/extension/error_helpers.cpp +598 -73
  8. package/extension/error_helpers.h +20 -3
  9. package/extension/extension_helpers.cpp +40 -35
  10. package/extension/extension_helpers.h +2 -2
  11. package/extension/herb.cpp +194 -64
  12. package/extension/libherb/analyze/action_view/attribute_extraction_helpers.c +303 -0
  13. package/extension/libherb/analyze/action_view/attribute_extraction_helpers.h +36 -0
  14. package/extension/libherb/analyze/action_view/content_tag.c +78 -0
  15. package/extension/libherb/analyze/action_view/link_to.c +167 -0
  16. package/extension/libherb/analyze/action_view/registry.c +83 -0
  17. package/extension/libherb/analyze/action_view/tag.c +70 -0
  18. package/extension/libherb/analyze/action_view/tag_helper_handler.h +43 -0
  19. package/extension/libherb/analyze/action_view/tag_helper_node_builders.c +305 -0
  20. package/extension/libherb/analyze/action_view/tag_helper_node_builders.h +70 -0
  21. package/extension/libherb/analyze/action_view/tag_helpers.c +815 -0
  22. package/extension/libherb/analyze/action_view/tag_helpers.h +38 -0
  23. package/extension/libherb/analyze/action_view/turbo_frame_tag.c +88 -0
  24. package/extension/libherb/analyze/analyze.c +885 -0
  25. package/extension/libherb/{include → analyze}/analyze.h +14 -4
  26. package/extension/libherb/{analyzed_ruby.c → analyze/analyzed_ruby.c} +13 -11
  27. package/extension/libherb/{analyzed_ruby.h → analyze/analyzed_ruby.h} +3 -3
  28. package/extension/libherb/analyze/builders.c +343 -0
  29. package/extension/libherb/analyze/builders.h +27 -0
  30. package/extension/libherb/analyze/conditional_elements.c +594 -0
  31. package/extension/libherb/analyze/conditional_elements.h +9 -0
  32. package/extension/libherb/analyze/conditional_open_tags.c +640 -0
  33. package/extension/libherb/analyze/conditional_open_tags.h +9 -0
  34. package/extension/libherb/analyze/control_type.c +250 -0
  35. package/extension/libherb/analyze/control_type.h +14 -0
  36. package/extension/libherb/{analyze_helpers.c → analyze/helpers.c} +48 -23
  37. package/extension/libherb/{analyze_helpers.h → analyze/helpers.h} +4 -2
  38. package/extension/libherb/analyze/invalid_structures.c +193 -0
  39. package/extension/libherb/analyze/invalid_structures.h +11 -0
  40. package/extension/libherb/{analyze_missing_end.c → analyze/missing_end.c} +33 -22
  41. package/extension/libherb/analyze/parse_errors.c +84 -0
  42. package/extension/libherb/analyze/prism_annotate.c +399 -0
  43. package/extension/libherb/analyze/prism_annotate.h +16 -0
  44. package/extension/libherb/analyze/render_nodes.c +761 -0
  45. package/extension/libherb/analyze/render_nodes.h +11 -0
  46. package/extension/libherb/{analyze_transform.c → analyze/transform.c} +24 -3
  47. package/extension/libherb/ast_node.c +17 -7
  48. package/extension/libherb/ast_node.h +11 -5
  49. package/extension/libherb/ast_nodes.c +760 -388
  50. package/extension/libherb/ast_nodes.h +155 -39
  51. package/extension/libherb/ast_pretty_print.c +265 -7
  52. package/extension/libherb/ast_pretty_print.h +6 -1
  53. package/extension/libherb/element_source.h +3 -8
  54. package/extension/libherb/errors.c +1455 -520
  55. package/extension/libherb/errors.h +207 -56
  56. package/extension/libherb/extract.c +145 -49
  57. package/extension/libherb/extract.h +21 -5
  58. package/extension/libherb/herb.c +52 -34
  59. package/extension/libherb/herb.h +18 -6
  60. package/extension/libherb/herb_prism_node.h +13 -0
  61. package/extension/libherb/html_util.c +241 -12
  62. package/extension/libherb/html_util.h +7 -2
  63. package/extension/libherb/include/analyze/action_view/attribute_extraction_helpers.h +36 -0
  64. package/extension/libherb/include/analyze/action_view/tag_helper_handler.h +43 -0
  65. package/extension/libherb/include/analyze/action_view/tag_helper_node_builders.h +70 -0
  66. package/extension/libherb/include/analyze/action_view/tag_helpers.h +38 -0
  67. package/extension/libherb/{analyze.h → include/analyze/analyze.h} +14 -4
  68. package/extension/libherb/include/{analyzed_ruby.h → analyze/analyzed_ruby.h} +3 -3
  69. package/extension/libherb/include/analyze/builders.h +27 -0
  70. package/extension/libherb/include/analyze/conditional_elements.h +9 -0
  71. package/extension/libherb/include/analyze/conditional_open_tags.h +9 -0
  72. package/extension/libherb/include/analyze/control_type.h +14 -0
  73. package/extension/libherb/include/{analyze_helpers.h → analyze/helpers.h} +4 -2
  74. package/extension/libherb/include/analyze/invalid_structures.h +11 -0
  75. package/extension/libherb/include/analyze/prism_annotate.h +16 -0
  76. package/extension/libherb/include/analyze/render_nodes.h +11 -0
  77. package/extension/libherb/include/ast_node.h +11 -5
  78. package/extension/libherb/include/ast_nodes.h +155 -39
  79. package/extension/libherb/include/ast_pretty_print.h +6 -1
  80. package/extension/libherb/include/element_source.h +3 -8
  81. package/extension/libherb/include/errors.h +207 -56
  82. package/extension/libherb/include/extract.h +21 -5
  83. package/extension/libherb/include/herb.h +18 -6
  84. package/extension/libherb/include/herb_prism_node.h +13 -0
  85. package/extension/libherb/include/html_util.h +7 -2
  86. package/extension/libherb/include/io.h +3 -1
  87. package/extension/libherb/include/lex_helpers.h +29 -0
  88. package/extension/libherb/include/lexer.h +1 -1
  89. package/extension/libherb/include/lexer_peek_helpers.h +87 -13
  90. package/extension/libherb/include/lexer_struct.h +2 -0
  91. package/extension/libherb/include/location.h +2 -1
  92. package/extension/libherb/include/parser.h +28 -2
  93. package/extension/libherb/include/parser_helpers.h +19 -3
  94. package/extension/libherb/include/pretty_print.h +10 -5
  95. package/extension/libherb/include/prism_context.h +45 -0
  96. package/extension/libherb/include/prism_helpers.h +10 -7
  97. package/extension/libherb/include/prism_serialized.h +12 -0
  98. package/extension/libherb/include/token.h +16 -4
  99. package/extension/libherb/include/token_struct.h +10 -3
  100. package/extension/libherb/include/utf8.h +2 -1
  101. package/extension/libherb/include/util/hb_allocator.h +78 -0
  102. package/extension/libherb/include/util/hb_arena.h +6 -1
  103. package/extension/libherb/include/util/hb_arena_debug.h +12 -1
  104. package/extension/libherb/include/util/hb_array.h +7 -3
  105. package/extension/libherb/include/util/hb_buffer.h +6 -4
  106. package/extension/libherb/include/util/hb_foreach.h +79 -0
  107. package/extension/libherb/include/util/hb_narray.h +8 -4
  108. package/extension/libherb/include/util/hb_string.h +56 -9
  109. package/extension/libherb/include/util.h +6 -3
  110. package/extension/libherb/include/version.h +1 -1
  111. package/extension/libherb/io.c +3 -2
  112. package/extension/libherb/io.h +3 -1
  113. package/extension/libherb/lex_helpers.h +29 -0
  114. package/extension/libherb/lexer.c +42 -30
  115. package/extension/libherb/lexer.h +1 -1
  116. package/extension/libherb/lexer_peek_helpers.c +12 -74
  117. package/extension/libherb/lexer_peek_helpers.h +87 -13
  118. package/extension/libherb/lexer_struct.h +2 -0
  119. package/extension/libherb/location.c +2 -2
  120. package/extension/libherb/location.h +2 -1
  121. package/extension/libherb/main.c +53 -28
  122. package/extension/libherb/parser.c +784 -247
  123. package/extension/libherb/parser.h +28 -2
  124. package/extension/libherb/parser_helpers.c +110 -23
  125. package/extension/libherb/parser_helpers.h +19 -3
  126. package/extension/libherb/parser_match_tags.c +130 -49
  127. package/extension/libherb/pretty_print.c +29 -24
  128. package/extension/libherb/pretty_print.h +10 -5
  129. package/extension/libherb/prism_context.h +45 -0
  130. package/extension/libherb/prism_helpers.c +30 -27
  131. package/extension/libherb/prism_helpers.h +10 -7
  132. package/extension/libherb/prism_serialized.h +12 -0
  133. package/extension/libherb/ruby_parser.c +2 -0
  134. package/extension/libherb/token.c +151 -66
  135. package/extension/libherb/token.h +16 -4
  136. package/extension/libherb/token_matchers.c +0 -1
  137. package/extension/libherb/token_struct.h +10 -3
  138. package/extension/libherb/utf8.c +7 -6
  139. package/extension/libherb/utf8.h +2 -1
  140. package/extension/libherb/util/hb_allocator.c +341 -0
  141. package/extension/libherb/util/hb_allocator.h +78 -0
  142. package/extension/libherb/util/hb_arena.c +81 -56
  143. package/extension/libherb/util/hb_arena.h +6 -1
  144. package/extension/libherb/util/hb_arena_debug.c +32 -17
  145. package/extension/libherb/util/hb_arena_debug.h +12 -1
  146. package/extension/libherb/util/hb_array.c +30 -15
  147. package/extension/libherb/util/hb_array.h +7 -3
  148. package/extension/libherb/util/hb_buffer.c +17 -21
  149. package/extension/libherb/util/hb_buffer.h +6 -4
  150. package/extension/libherb/util/hb_foreach.h +79 -0
  151. package/extension/libherb/util/hb_narray.c +22 -7
  152. package/extension/libherb/util/hb_narray.h +8 -4
  153. package/extension/libherb/util/hb_string.c +49 -35
  154. package/extension/libherb/util/hb_string.h +56 -9
  155. package/extension/libherb/util.c +21 -11
  156. package/extension/libherb/util.h +6 -3
  157. package/extension/libherb/version.h +1 -1
  158. package/extension/libherb/visitor.c +68 -1
  159. package/extension/nodes.cpp +593 -6
  160. package/extension/nodes.h +10 -1
  161. package/package.json +12 -8
  162. package/src/node-backend.ts +11 -1
  163. package/dist/types/index-cjs.d.cts +0 -1
  164. package/extension/libherb/analyze.c +0 -1608
  165. package/extension/libherb/element_source.c +0 -12
  166. package/extension/libherb/include/util/hb_system.h +0 -9
  167. package/extension/libherb/util/hb_system.c +0 -30
  168. package/extension/libherb/util/hb_system.h +0 -9
  169. package/src/index-cjs.cts +0 -22
  170. /package/dist/types/{index-esm.d.mts → index.d.ts} +0 -0
  171. /package/src/{index-esm.mts → index.ts} +0 -0
@@ -1,5 +1,5 @@
1
1
  // NOTE: This file is generated by the templates/template.rb script and should not
2
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.8.10/templates/src/include/errors.h.erb
2
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.1/templates/src/include/errors.h.erb
3
3
 
4
4
  #ifndef HERB_ERRORS_H
5
5
  #define HERB_ERRORS_H
@@ -8,8 +8,10 @@
8
8
  #include "location.h"
9
9
  #include "position.h"
10
10
  #include "token.h"
11
+ #include "util/hb_allocator.h"
11
12
  #include "util/hb_array.h"
12
13
  #include "util/hb_buffer.h"
14
+ #include "util/hb_string.h"
13
15
 
14
16
  typedef enum {
15
17
  UNEXPECTED_ERROR,
@@ -17,28 +19,45 @@ typedef enum {
17
19
  MISSING_OPENING_TAG_ERROR,
18
20
  MISSING_CLOSING_TAG_ERROR,
19
21
  TAG_NAMES_MISMATCH_ERROR,
20
- QUOTES_MISMATCH_ERROR,
21
22
  VOID_ELEMENT_CLOSING_TAG_ERROR,
22
23
  UNCLOSED_ELEMENT_ERROR,
23
24
  RUBY_PARSE_ERROR,
24
25
  ERB_CONTROL_FLOW_SCOPE_ERROR,
25
- MISSINGERB_END_TAG_ERROR,
26
+ MISSING_ERB_END_TAG_ERROR,
26
27
  ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR,
27
28
  ERB_CASE_WITH_CONDITIONS_ERROR,
29
+ CONDITIONAL_ELEMENT_MULTIPLE_TAGS_ERROR,
30
+ CONDITIONAL_ELEMENT_CONDITION_MISMATCH_ERROR,
31
+ INVALID_COMMENT_CLOSING_TAG_ERROR,
32
+ OMITTED_CLOSING_TAG_ERROR,
33
+ UNCLOSED_OPEN_TAG_ERROR,
34
+ UNCLOSED_CLOSE_TAG_ERROR,
35
+ UNCLOSED_QUOTE_ERROR,
36
+ MISSING_ATTRIBUTE_VALUE_ERROR,
37
+ UNCLOSED_ERB_TAG_ERROR,
38
+ STRAY_ERB_CLOSING_TAG_ERROR,
39
+ NESTED_ERB_TAG_ERROR,
40
+ RENDER_AMBIGUOUS_LOCALS_ERROR,
41
+ RENDER_MISSING_LOCALS_ERROR,
42
+ RENDER_NO_ARGUMENTS_ERROR,
43
+ RENDER_CONFLICTING_PARTIAL_ERROR,
44
+ RENDER_INVALID_AS_OPTION_ERROR,
45
+ RENDER_OBJECT_AND_COLLECTION_ERROR,
46
+ RENDER_LAYOUT_WITHOUT_BLOCK_ERROR,
28
47
  } error_type_T;
29
48
 
30
49
  typedef struct ERROR_STRUCT {
31
50
  error_type_T type;
32
51
  location_T location;
33
- char* message;
52
+ hb_string_T message;
34
53
  } ERROR_T;
35
54
 
36
55
 
37
56
  typedef struct {
38
57
  ERROR_T base;
39
- const char* description;
40
- const char* expected;
41
- const char* found;
58
+ hb_string_T description;
59
+ hb_string_T expected;
60
+ hb_string_T found;
42
61
  } UNEXPECTED_ERROR_T;
43
62
 
44
63
  typedef struct {
@@ -63,17 +82,11 @@ typedef struct {
63
82
  token_T* closing_tag;
64
83
  } TAG_NAMES_MISMATCH_ERROR_T;
65
84
 
66
- typedef struct {
67
- ERROR_T base;
68
- token_T* opening_quote;
69
- token_T* closing_quote;
70
- } QUOTES_MISMATCH_ERROR_T;
71
-
72
85
  typedef struct {
73
86
  ERROR_T base;
74
87
  token_T* tag_name;
75
- const char* expected;
76
- const char* found;
88
+ hb_string_T expected;
89
+ hb_string_T found;
77
90
  } VOID_ELEMENT_CLOSING_TAG_ERROR_T;
78
91
 
79
92
  typedef struct {
@@ -83,20 +96,20 @@ typedef struct {
83
96
 
84
97
  typedef struct {
85
98
  ERROR_T base;
86
- const char* error_message;
87
- const char* diagnostic_id;
88
- const char* level;
99
+ hb_string_T error_message;
100
+ hb_string_T diagnostic_id;
101
+ hb_string_T level;
89
102
  } RUBY_PARSE_ERROR_T;
90
103
 
91
104
  typedef struct {
92
105
  ERROR_T base;
93
- const char* keyword;
106
+ hb_string_T keyword;
94
107
  } ERB_CONTROL_FLOW_SCOPE_ERROR_T;
95
108
 
96
109
  typedef struct {
97
110
  ERROR_T base;
98
- const char* keyword;
99
- } MISSINGERB_END_TAG_ERROR_T;
111
+ hb_string_T keyword;
112
+ } MISSING_ERB_END_TAG_ERROR_T;
100
113
 
101
114
  typedef struct {
102
115
  ERROR_T base;
@@ -108,50 +121,188 @@ typedef struct {
108
121
  /* no additional fields */
109
122
  } ERB_CASE_WITH_CONDITIONS_ERROR_T;
110
123
 
111
- UNEXPECTED_ERROR_T* unexpected_error_init(const char* description, const char* expected, const char* found, position_T start, position_T end);
112
- void append_unexpected_error(const char* description, const char* expected, const char* found, position_T start, position_T end, hb_array_T* errors);
113
- UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error_init(token_type_T expected_type, token_T* found, position_T start, position_T end);
114
- void append_unexpected_token_error(token_type_T expected_type, token_T* found, position_T start, position_T end, hb_array_T* errors);
115
- MISSING_OPENING_TAG_ERROR_T* missing_opening_tag_error_init(token_T* closing_tag, position_T start, position_T end);
116
- void append_missing_opening_tag_error(token_T* closing_tag, position_T start, position_T end, hb_array_T* errors);
117
- MISSING_CLOSING_TAG_ERROR_T* missing_closing_tag_error_init(token_T* opening_tag, position_T start, position_T end);
118
- void append_missing_closing_tag_error(token_T* opening_tag, position_T start, position_T end, hb_array_T* errors);
119
- TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error_init(token_T* opening_tag, token_T* closing_tag, position_T start, position_T end);
120
- void append_tag_names_mismatch_error(token_T* opening_tag, token_T* closing_tag, position_T start, position_T end, hb_array_T* errors);
121
- QUOTES_MISMATCH_ERROR_T* quotes_mismatch_error_init(token_T* opening_quote, token_T* closing_quote, position_T start, position_T end);
122
- void append_quotes_mismatch_error(token_T* opening_quote, token_T* closing_quote, position_T start, position_T end, hb_array_T* errors);
123
- 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);
124
- 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);
125
- UNCLOSED_ELEMENT_ERROR_T* unclosed_element_error_init(token_T* opening_tag, position_T start, position_T end);
126
- void append_unclosed_element_error(token_T* opening_tag, position_T start, position_T end, hb_array_T* errors);
127
- 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);
128
- 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);
129
- ERB_CONTROL_FLOW_SCOPE_ERROR_T* erb_control_flow_scope_error_init(const char* keyword, position_T start, position_T end);
130
- void append_erb_control_flow_scope_error(const char* keyword, position_T start, position_T end, hb_array_T* errors);
131
- MISSINGERB_END_TAG_ERROR_T* missingerb_end_tag_error_init(const char* keyword, position_T start, position_T end);
132
- void append_missingerb_end_tag_error(const char* keyword, position_T start, position_T end, hb_array_T* errors);
133
- ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T* erb_multiple_blocks_in_tag_error_init(position_T start, position_T end);
134
- void append_erb_multiple_blocks_in_tag_error(position_T start, position_T end, hb_array_T* errors);
135
- ERB_CASE_WITH_CONDITIONS_ERROR_T* erb_case_with_conditions_error_init(position_T start, position_T end);
136
- void append_erb_case_with_conditions_error(position_T start, position_T end, hb_array_T* errors);
124
+ typedef struct {
125
+ ERROR_T base;
126
+ size_t line;
127
+ size_t column;
128
+ } CONDITIONAL_ELEMENT_MULTIPLE_TAGS_ERROR_T;
129
+
130
+ typedef struct {
131
+ ERROR_T base;
132
+ hb_string_T tag_name;
133
+ hb_string_T open_condition;
134
+ size_t open_line;
135
+ size_t open_column;
136
+ hb_string_T close_condition;
137
+ size_t close_line;
138
+ size_t close_column;
139
+ } CONDITIONAL_ELEMENT_CONDITION_MISMATCH_ERROR_T;
140
+
141
+ typedef struct {
142
+ ERROR_T base;
143
+ token_T* closing_tag;
144
+ } INVALID_COMMENT_CLOSING_TAG_ERROR_T;
145
+
146
+ typedef struct {
147
+ ERROR_T base;
148
+ token_T* opening_tag;
149
+ position_T insertion_point;
150
+ } OMITTED_CLOSING_TAG_ERROR_T;
151
+
152
+ typedef struct {
153
+ ERROR_T base;
154
+ token_T* tag_name;
155
+ } UNCLOSED_OPEN_TAG_ERROR_T;
156
+
157
+ typedef struct {
158
+ ERROR_T base;
159
+ token_T* tag_name;
160
+ } UNCLOSED_CLOSE_TAG_ERROR_T;
161
+
162
+ typedef struct {
163
+ ERROR_T base;
164
+ token_T* opening_quote;
165
+ } UNCLOSED_QUOTE_ERROR_T;
166
+
167
+ typedef struct {
168
+ ERROR_T base;
169
+ hb_string_T attribute_name;
170
+ } MISSING_ATTRIBUTE_VALUE_ERROR_T;
171
+
172
+ typedef struct {
173
+ ERROR_T base;
174
+ token_T* opening_tag;
175
+ } UNCLOSED_ERB_TAG_ERROR_T;
176
+
177
+ typedef struct {
178
+ ERROR_T base;
179
+ /* no additional fields */
180
+ } STRAY_ERB_CLOSING_TAG_ERROR_T;
181
+
182
+ typedef struct {
183
+ ERROR_T base;
184
+ token_T* opening_tag;
185
+ size_t nested_tag_line;
186
+ size_t nested_tag_column;
187
+ } NESTED_ERB_TAG_ERROR_T;
188
+
189
+ typedef struct {
190
+ ERROR_T base;
191
+ hb_string_T partial;
192
+ } RENDER_AMBIGUOUS_LOCALS_ERROR_T;
193
+
194
+ typedef struct {
195
+ ERROR_T base;
196
+ hb_string_T partial;
197
+ hb_string_T keywords;
198
+ } RENDER_MISSING_LOCALS_ERROR_T;
199
+
200
+ typedef struct {
201
+ ERROR_T base;
202
+ /* no additional fields */
203
+ } RENDER_NO_ARGUMENTS_ERROR_T;
204
+
205
+ typedef struct {
206
+ ERROR_T base;
207
+ hb_string_T positional_partial;
208
+ hb_string_T keyword_partial;
209
+ } RENDER_CONFLICTING_PARTIAL_ERROR_T;
210
+
211
+ typedef struct {
212
+ ERROR_T base;
213
+ hb_string_T as_value;
214
+ } RENDER_INVALID_AS_OPTION_ERROR_T;
215
+
216
+ typedef struct {
217
+ ERROR_T base;
218
+ /* no additional fields */
219
+ } RENDER_OBJECT_AND_COLLECTION_ERROR_T;
220
+
221
+ typedef struct {
222
+ ERROR_T base;
223
+ hb_string_T layout;
224
+ } RENDER_LAYOUT_WITHOUT_BLOCK_ERROR_T;
225
+
226
+ UNEXPECTED_ERROR_T* unexpected_error_init(hb_string_T description, hb_string_T expected, hb_string_T found, position_T start, position_T end, hb_allocator_T* allocator);
227
+ void append_unexpected_error(hb_string_T description, hb_string_T expected, hb_string_T found, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
228
+ UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error_init(token_type_T expected_type, token_T* found, position_T start, position_T end, hb_allocator_T* allocator);
229
+ void append_unexpected_token_error(token_type_T expected_type, token_T* found, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
230
+ MISSING_OPENING_TAG_ERROR_T* missing_opening_tag_error_init(token_T* closing_tag, position_T start, position_T end, hb_allocator_T* allocator);
231
+ void append_missing_opening_tag_error(token_T* closing_tag, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
232
+ MISSING_CLOSING_TAG_ERROR_T* missing_closing_tag_error_init(token_T* opening_tag, position_T start, position_T end, hb_allocator_T* allocator);
233
+ void append_missing_closing_tag_error(token_T* opening_tag, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
234
+ TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error_init(token_T* opening_tag, token_T* closing_tag, position_T start, position_T end, hb_allocator_T* allocator);
235
+ void append_tag_names_mismatch_error(token_T* opening_tag, token_T* closing_tag, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
236
+ VOID_ELEMENT_CLOSING_TAG_ERROR_T* void_element_closing_tag_error_init(token_T* tag_name, hb_string_T expected, hb_string_T found, position_T start, position_T end, hb_allocator_T* allocator);
237
+ void append_void_element_closing_tag_error(token_T* tag_name, hb_string_T expected, hb_string_T found, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
238
+ UNCLOSED_ELEMENT_ERROR_T* unclosed_element_error_init(token_T* opening_tag, position_T start, position_T end, hb_allocator_T* allocator);
239
+ void append_unclosed_element_error(token_T* opening_tag, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
240
+ RUBY_PARSE_ERROR_T* ruby_parse_error_init(hb_string_T error_message, hb_string_T diagnostic_id, hb_string_T level, position_T start, position_T end, hb_allocator_T* allocator);
241
+ void append_ruby_parse_error(hb_string_T error_message, hb_string_T diagnostic_id, hb_string_T level, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
242
+ ERB_CONTROL_FLOW_SCOPE_ERROR_T* erb_control_flow_scope_error_init(hb_string_T keyword, position_T start, position_T end, hb_allocator_T* allocator);
243
+ void append_erb_control_flow_scope_error(hb_string_T keyword, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
244
+ MISSING_ERB_END_TAG_ERROR_T* missing_erb_end_tag_error_init(hb_string_T keyword, position_T start, position_T end, hb_allocator_T* allocator);
245
+ void append_missing_erb_end_tag_error(hb_string_T keyword, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
246
+ ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T* erb_multiple_blocks_in_tag_error_init(position_T start, position_T end, hb_allocator_T* allocator);
247
+ void append_erb_multiple_blocks_in_tag_error(position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
248
+ ERB_CASE_WITH_CONDITIONS_ERROR_T* erb_case_with_conditions_error_init(position_T start, position_T end, hb_allocator_T* allocator);
249
+ void append_erb_case_with_conditions_error(position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
250
+ CONDITIONAL_ELEMENT_MULTIPLE_TAGS_ERROR_T* conditional_element_multiple_tags_error_init(size_t line, size_t column, position_T start, position_T end, hb_allocator_T* allocator);
251
+ void append_conditional_element_multiple_tags_error(size_t line, size_t column, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
252
+ CONDITIONAL_ELEMENT_CONDITION_MISMATCH_ERROR_T* conditional_element_condition_mismatch_error_init(hb_string_T tag_name, hb_string_T open_condition, size_t open_line, size_t open_column, hb_string_T close_condition, size_t close_line, size_t close_column, position_T start, position_T end, hb_allocator_T* allocator);
253
+ void append_conditional_element_condition_mismatch_error(hb_string_T tag_name, hb_string_T open_condition, size_t open_line, size_t open_column, hb_string_T close_condition, size_t close_line, size_t close_column, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
254
+ INVALID_COMMENT_CLOSING_TAG_ERROR_T* invalid_comment_closing_tag_error_init(token_T* closing_tag, position_T start, position_T end, hb_allocator_T* allocator);
255
+ void append_invalid_comment_closing_tag_error(token_T* closing_tag, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
256
+ OMITTED_CLOSING_TAG_ERROR_T* omitted_closing_tag_error_init(token_T* opening_tag, position_T insertion_point, position_T start, position_T end, hb_allocator_T* allocator);
257
+ void append_omitted_closing_tag_error(token_T* opening_tag, position_T insertion_point, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
258
+ UNCLOSED_OPEN_TAG_ERROR_T* unclosed_open_tag_error_init(token_T* tag_name, position_T start, position_T end, hb_allocator_T* allocator);
259
+ void append_unclosed_open_tag_error(token_T* tag_name, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
260
+ UNCLOSED_CLOSE_TAG_ERROR_T* unclosed_close_tag_error_init(token_T* tag_name, position_T start, position_T end, hb_allocator_T* allocator);
261
+ void append_unclosed_close_tag_error(token_T* tag_name, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
262
+ UNCLOSED_QUOTE_ERROR_T* unclosed_quote_error_init(token_T* opening_quote, position_T start, position_T end, hb_allocator_T* allocator);
263
+ void append_unclosed_quote_error(token_T* opening_quote, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
264
+ MISSING_ATTRIBUTE_VALUE_ERROR_T* missing_attribute_value_error_init(hb_string_T attribute_name, position_T start, position_T end, hb_allocator_T* allocator);
265
+ void append_missing_attribute_value_error(hb_string_T attribute_name, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
266
+ UNCLOSED_ERB_TAG_ERROR_T* unclosed_erb_tag_error_init(token_T* opening_tag, position_T start, position_T end, hb_allocator_T* allocator);
267
+ void append_unclosed_erb_tag_error(token_T* opening_tag, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
268
+ STRAY_ERB_CLOSING_TAG_ERROR_T* stray_erb_closing_tag_error_init(position_T start, position_T end, hb_allocator_T* allocator);
269
+ void append_stray_erb_closing_tag_error(position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
270
+ NESTED_ERB_TAG_ERROR_T* nested_erb_tag_error_init(token_T* opening_tag, size_t nested_tag_line, size_t nested_tag_column, position_T start, position_T end, hb_allocator_T* allocator);
271
+ void append_nested_erb_tag_error(token_T* opening_tag, size_t nested_tag_line, size_t nested_tag_column, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
272
+ RENDER_AMBIGUOUS_LOCALS_ERROR_T* render_ambiguous_locals_error_init(hb_string_T partial, position_T start, position_T end, hb_allocator_T* allocator);
273
+ void append_render_ambiguous_locals_error(hb_string_T partial, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
274
+ RENDER_MISSING_LOCALS_ERROR_T* render_missing_locals_error_init(hb_string_T partial, hb_string_T keywords, position_T start, position_T end, hb_allocator_T* allocator);
275
+ void append_render_missing_locals_error(hb_string_T partial, hb_string_T keywords, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
276
+ RENDER_NO_ARGUMENTS_ERROR_T* render_no_arguments_error_init(position_T start, position_T end, hb_allocator_T* allocator);
277
+ void append_render_no_arguments_error(position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
278
+ RENDER_CONFLICTING_PARTIAL_ERROR_T* render_conflicting_partial_error_init(hb_string_T positional_partial, hb_string_T keyword_partial, position_T start, position_T end, hb_allocator_T* allocator);
279
+ void append_render_conflicting_partial_error(hb_string_T positional_partial, hb_string_T keyword_partial, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
280
+ RENDER_INVALID_AS_OPTION_ERROR_T* render_invalid_as_option_error_init(hb_string_T as_value, position_T start, position_T end, hb_allocator_T* allocator);
281
+ void append_render_invalid_as_option_error(hb_string_T as_value, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
282
+ RENDER_OBJECT_AND_COLLECTION_ERROR_T* render_object_and_collection_error_init(position_T start, position_T end, hb_allocator_T* allocator);
283
+ void append_render_object_and_collection_error(position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
284
+ RENDER_LAYOUT_WITHOUT_BLOCK_ERROR_T* render_layout_without_block_error_init(hb_string_T layout, position_T start, position_T end, hb_allocator_T* allocator);
285
+ void append_render_layout_without_block_error(hb_string_T layout, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
137
286
 
138
287
  void error_init(ERROR_T* error, error_type_T type, position_T start, position_T end);
139
288
 
140
289
  size_t error_sizeof(void);
141
290
  error_type_T error_type(ERROR_T* error);
142
291
 
143
- char* error_message(ERROR_T* error);
292
+ hb_string_T error_message(ERROR_T* error);
144
293
 
145
- const char* error_type_to_string(ERROR_T* error);
146
- const char* error_human_type(ERROR_T* error);
294
+ hb_string_T error_type_to_string(ERROR_T* error);
295
+ hb_string_T error_human_type(ERROR_T* error);
147
296
 
148
- void error_free(ERROR_T* error);
297
+ void error_free(ERROR_T* error, hb_allocator_T* allocator);
149
298
 
150
- void error_pretty_print(ERROR_T* error, size_t indent, size_t relative_indent, hb_buffer_T* buffer);
299
+ #ifndef HERB_EXCLUDE_PRETTYPRINT
300
+ void error_pretty_print(ERROR_T* error, size_t indent, size_t relative_indent, hb_buffer_T* buffer);
151
301
 
152
- void error_pretty_print_array(
153
- const char* name, hb_array_T* array, size_t indent, size_t relative_indent, bool last_property,
154
- hb_buffer_T* buffer
155
- );
302
+ void error_pretty_print_array(
303
+ const char* name, hb_array_T* array, size_t indent, size_t relative_indent, bool last_property,
304
+ hb_buffer_T* buffer
305
+ );
306
+ #endif
156
307
 
157
308
  #endif
@@ -1,42 +1,96 @@
1
1
  #include "include/herb.h"
2
- #include "include/io.h"
3
- #include "include/lexer.h"
2
+ #include "include/util/hb_allocator.h"
4
3
  #include "include/util/hb_array.h"
5
4
  #include "include/util/hb_buffer.h"
5
+ #include "include/util/hb_string.h"
6
6
  #include "include/util/string.h"
7
7
 
8
8
  #include <assert.h>
9
9
  #include <stdlib.h>
10
10
  #include <string.h>
11
11
 
12
- void herb_extract_ruby_to_buffer(const char* source, hb_buffer_T* output) {
13
- hb_array_T* tokens = herb_lex(source);
12
+ const herb_extract_ruby_options_T HERB_EXTRACT_RUBY_DEFAULT_OPTIONS = { .semicolons = true,
13
+ .comments = false,
14
+ .preserve_positions = true };
15
+
16
+ void herb_extract_ruby_to_buffer_with_options(
17
+ const char* source,
18
+ hb_buffer_T* output,
19
+ const herb_extract_ruby_options_T* options,
20
+ hb_allocator_T* allocator
21
+ ) {
22
+ herb_extract_ruby_options_T extract_options = options ? *options : HERB_EXTRACT_RUBY_DEFAULT_OPTIONS;
23
+
24
+ hb_array_T* tokens = herb_lex(source, allocator);
14
25
  bool skip_erb_content = false;
15
26
  bool is_comment_tag = false;
27
+ bool is_erb_comment_tag = false;
28
+ bool need_newline = false;
16
29
 
17
30
  for (size_t i = 0; i < hb_array_size(tokens); i++) {
18
31
  const token_T* token = hb_array_get(tokens, i);
19
32
 
20
33
  switch (token->type) {
21
34
  case TOKEN_NEWLINE: {
22
- hb_buffer_append(output, token->value);
35
+ hb_buffer_append_string(output, token->value);
36
+ need_newline = false;
23
37
  break;
24
38
  }
25
39
 
26
40
  case TOKEN_ERB_START: {
27
- if (string_equals(token->value, "<%#")) {
28
- skip_erb_content = true;
29
- is_comment_tag = true;
30
- } else if (string_equals(token->value, "<%%") || string_equals(token->value, "<%%=")
31
- || string_equals(token->value, "<%graphql")) {
41
+ is_erb_comment_tag = hb_string_equals(token->value, hb_string("<%#"));
42
+
43
+ if (is_erb_comment_tag) {
44
+ if (extract_options.comments) {
45
+ skip_erb_content = false;
46
+ is_comment_tag = false;
47
+
48
+ if (extract_options.preserve_positions) {
49
+ bool is_multiline = false;
50
+
51
+ if (i + 1 < hb_array_size(tokens)) {
52
+ const token_T* next = hb_array_get(tokens, i + 1);
53
+
54
+ if (next->type == TOKEN_ERB_CONTENT && !hb_string_is_null(next->value)
55
+ && memchr(next->value.data, '\n', next->value.length) != NULL) {
56
+ is_multiline = true;
57
+ }
58
+ }
59
+
60
+ if (is_multiline) {
61
+ hb_buffer_append_char(output, '#');
62
+ hb_buffer_append_whitespace(output, 2);
63
+ } else {
64
+ hb_buffer_append_whitespace(output, 2);
65
+ hb_buffer_append_char(output, '#');
66
+ }
67
+ } else {
68
+ if (need_newline) { hb_buffer_append_char(output, '\n'); }
69
+ hb_buffer_append_char(output, '#');
70
+ need_newline = true;
71
+ }
72
+ } else {
73
+ skip_erb_content = true;
74
+ is_comment_tag = true;
75
+ if (extract_options.preserve_positions) { hb_buffer_append_whitespace(output, range_length(token->range)); }
76
+ }
77
+ } else if (hb_string_equals(token->value, hb_string("<%%")) || hb_string_equals(token->value, hb_string("<%%="))
78
+ || hb_string_equals(token->value, hb_string("<%graphql"))) {
32
79
  skip_erb_content = true;
33
80
  is_comment_tag = false;
81
+ if (extract_options.preserve_positions) { hb_buffer_append_whitespace(output, range_length(token->range)); }
34
82
  } else {
35
83
  skip_erb_content = false;
36
84
  is_comment_tag = false;
85
+
86
+ if (extract_options.preserve_positions) {
87
+ hb_buffer_append_whitespace(output, range_length(token->range));
88
+ } else if (need_newline) {
89
+ hb_buffer_append_char(output, '\n');
90
+ need_newline = false;
91
+ }
37
92
  }
38
93
 
39
- hb_buffer_append_whitespace(output, range_length(token->range));
40
94
  break;
41
95
  }
42
96
 
@@ -44,26 +98,65 @@ void herb_extract_ruby_to_buffer(const char* source, hb_buffer_T* output) {
44
98
  if (skip_erb_content == false) {
45
99
  bool is_inline_comment = false;
46
100
 
47
- if (!is_comment_tag && token->value != NULL) {
48
- const char* content = token->value;
101
+ if (!extract_options.comments && !is_comment_tag && !hb_string_is_empty(token->value)) {
102
+ hb_string_T trimmed = hb_string_trim_start(token->value);
49
103
 
50
- while (*content == ' ' || *content == '\t') {
51
- content++;
52
- }
53
-
54
- if (*content == '#' && token->location.start.line == token->location.end.line) {
104
+ if (!hb_string_is_empty(trimmed) && trimmed.data[0] == '#'
105
+ && token->location.start.line == token->location.end.line) {
55
106
  is_comment_tag = true;
56
107
  is_inline_comment = true;
57
108
  }
58
109
  }
59
110
 
60
111
  if (is_inline_comment) {
61
- hb_buffer_append_whitespace(output, range_length(token->range));
112
+ if (extract_options.preserve_positions) { hb_buffer_append_whitespace(output, range_length(token->range)); }
113
+ } else if (is_erb_comment_tag && !hb_string_is_null(token->value)) {
114
+ const char* content = token->value.data;
115
+ size_t content_remaining = token->value.length;
116
+
117
+ while (content_remaining > 0) {
118
+ if (*content == '\n') {
119
+ hb_buffer_append_char(output, '\n');
120
+ content++;
121
+ content_remaining--;
122
+
123
+ if (content_remaining > 0 && extract_options.preserve_positions && *content == ' ') {
124
+ content++;
125
+ content_remaining--;
126
+ }
127
+
128
+ hb_buffer_append_char(output, '#');
129
+ } else {
130
+ hb_buffer_append_char(output, *content);
131
+ content++;
132
+ content_remaining--;
133
+ }
134
+ }
135
+
136
+ if (!extract_options.preserve_positions) { need_newline = true; }
62
137
  } else {
63
- hb_buffer_append(output, token->value);
138
+ hb_buffer_append_string(output, token->value);
139
+
140
+ if (!extract_options.preserve_positions) { need_newline = true; }
64
141
  }
65
142
  } else {
66
- hb_buffer_append_whitespace(output, range_length(token->range));
143
+ if (is_erb_comment_tag && extract_options.preserve_positions && !hb_string_is_null(token->value)) {
144
+ const char* content = token->value.data;
145
+ size_t content_remaining = token->value.length;
146
+
147
+ while (content_remaining > 0) {
148
+ if (*content == '\n') {
149
+ hb_buffer_append_char(output, '\n');
150
+ } else {
151
+ hb_buffer_append_char(output, ' ');
152
+ }
153
+
154
+ content++;
155
+ content_remaining--;
156
+ }
157
+ } else if (extract_options.preserve_positions) {
158
+ hb_buffer_append_whitespace(output, range_length(token->range));
159
+ }
67
160
  }
68
161
 
69
162
  break;
@@ -71,31 +164,43 @@ void herb_extract_ruby_to_buffer(const char* source, hb_buffer_T* output) {
71
164
 
72
165
  case TOKEN_ERB_END: {
73
166
  bool was_comment = is_comment_tag;
167
+ bool was_erb_comment = is_erb_comment_tag;
74
168
  skip_erb_content = false;
75
169
  is_comment_tag = false;
170
+ is_erb_comment_tag = false;
76
171
 
77
- if (was_comment) {
78
- hb_buffer_append_whitespace(output, range_length(token->range));
79
- break;
172
+ if (extract_options.preserve_positions) {
173
+ if (was_comment) {
174
+ hb_buffer_append_whitespace(output, range_length(token->range));
175
+ } else if (was_erb_comment && extract_options.comments) {
176
+ hb_buffer_append_whitespace(output, range_length(token->range));
177
+ } else if (extract_options.semicolons) {
178
+ hb_buffer_append_char(output, ' ');
179
+ hb_buffer_append_char(output, ';');
180
+ hb_buffer_append_whitespace(output, range_length(token->range) - 2);
181
+ } else {
182
+ hb_buffer_append_whitespace(output, range_length(token->range));
183
+ }
80
184
  }
81
185
 
82
- hb_buffer_append_char(output, ' ');
83
- hb_buffer_append_char(output, ';');
84
- hb_buffer_append_whitespace(output, range_length(token->range) - 2);
85
186
  break;
86
187
  }
87
188
 
88
189
  default: {
89
- hb_buffer_append_whitespace(output, range_length(token->range));
190
+ if (extract_options.preserve_positions) { hb_buffer_append_whitespace(output, range_length(token->range)); }
90
191
  }
91
192
  }
92
193
  }
93
194
 
94
- herb_free_tokens(&tokens);
195
+ herb_free_tokens(&tokens, allocator);
196
+ }
197
+
198
+ void herb_extract_ruby_to_buffer(const char* source, hb_buffer_T* output, hb_allocator_T* allocator) {
199
+ herb_extract_ruby_to_buffer_with_options(source, output, NULL, allocator);
95
200
  }
96
201
 
97
- void herb_extract_html_to_buffer(const char* source, hb_buffer_T* output) {
98
- hb_array_T* tokens = herb_lex(source);
202
+ void herb_extract_html_to_buffer(const char* source, hb_buffer_T* output, hb_allocator_T* allocator) {
203
+ hb_array_T* tokens = herb_lex(source, allocator);
99
204
 
100
205
  for (size_t i = 0; i < hb_array_size(tokens); i++) {
101
206
  const token_T* token = hb_array_get(tokens, i);
@@ -104,44 +209,35 @@ void herb_extract_html_to_buffer(const char* source, hb_buffer_T* output) {
104
209
  case TOKEN_ERB_START:
105
210
  case TOKEN_ERB_CONTENT:
106
211
  case TOKEN_ERB_END: hb_buffer_append_whitespace(output, range_length(token->range)); break;
107
- default: hb_buffer_append(output, token->value);
212
+ default: hb_buffer_append_string(output, token->value);
108
213
  }
109
214
  }
110
215
 
111
- herb_free_tokens(&tokens);
216
+ herb_free_tokens(&tokens, allocator);
112
217
  }
113
218
 
114
- char* herb_extract_ruby_with_semicolons(const char* source) {
219
+ char* herb_extract_ruby_with_semicolons(const char* source, hb_allocator_T* allocator) {
115
220
  if (!source) { return NULL; }
116
221
 
117
222
  hb_buffer_T output;
118
- hb_buffer_init(&output, strlen(source));
223
+ hb_buffer_init(&output, strlen(source), allocator);
119
224
 
120
- herb_extract_ruby_to_buffer(source, &output);
225
+ herb_extract_ruby_to_buffer(source, &output, allocator);
121
226
 
122
227
  return output.value;
123
228
  }
124
229
 
125
- char* herb_extract(const char* source, const herb_extract_language_T language) {
230
+ char* herb_extract(const char* source, const herb_extract_language_T language, hb_allocator_T* allocator) {
126
231
  if (!source) { return NULL; }
127
232
 
128
233
  hb_buffer_T output;
129
- hb_buffer_init(&output, strlen(source));
234
+ hb_buffer_init(&output, strlen(source), allocator);
130
235
 
131
236
  switch (language) {
132
- case HERB_EXTRACT_LANGUAGE_RUBY: herb_extract_ruby_to_buffer(source, &output); break;
133
- case HERB_EXTRACT_LANGUAGE_HTML: herb_extract_html_to_buffer(source, &output); break;
237
+ case HERB_EXTRACT_LANGUAGE_RUBY: herb_extract_ruby_to_buffer(source, &output, allocator); break;
238
+ case HERB_EXTRACT_LANGUAGE_HTML: herb_extract_html_to_buffer(source, &output, allocator); break;
134
239
  default: assert(0 && "invalid extract language");
135
240
  }
136
241
 
137
242
  return output.value;
138
243
  }
139
-
140
- char* herb_extract_from_file(const char* path, const herb_extract_language_T language) {
141
- char* source = herb_read_file(path);
142
- char* output = herb_extract(source, language);
143
-
144
- free(source);
145
-
146
- return output;
147
- }