@herb-tools/node 0.8.9 → 0.9.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 (174) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/binding.gyp +26 -8
  3. package/dist/herb-node.cjs +41 -12
  4. package/dist/herb-node.cjs.map +1 -1
  5. package/dist/herb-node.esm.js +8 -1
  6. package/dist/herb-node.esm.js.map +1 -1
  7. package/dist/types/node-backend.d.ts +3 -1
  8. package/extension/error_helpers.cpp +419 -71
  9. package/extension/error_helpers.h +14 -3
  10. package/extension/extension_helpers.cpp +38 -35
  11. package/extension/extension_helpers.h +2 -2
  12. package/extension/herb.cpp +183 -64
  13. package/extension/libherb/analyze/action_view/attribute_extraction_helpers.c +290 -0
  14. package/extension/libherb/analyze/action_view/attribute_extraction_helpers.h +36 -0
  15. package/extension/libherb/analyze/action_view/content_tag.c +70 -0
  16. package/extension/libherb/analyze/action_view/link_to.c +143 -0
  17. package/extension/libherb/analyze/action_view/registry.c +60 -0
  18. package/extension/libherb/analyze/action_view/tag.c +64 -0
  19. package/extension/libherb/analyze/action_view/tag_helper_handler.h +41 -0
  20. package/extension/libherb/analyze/action_view/tag_helper_node_builders.c +305 -0
  21. package/extension/libherb/analyze/action_view/tag_helper_node_builders.h +70 -0
  22. package/extension/libherb/analyze/action_view/tag_helpers.c +748 -0
  23. package/extension/libherb/analyze/action_view/tag_helpers.h +38 -0
  24. package/extension/libherb/analyze/action_view/turbo_frame_tag.c +88 -0
  25. package/extension/libherb/analyze/analyze.c +882 -0
  26. package/extension/libherb/{include → analyze}/analyze.h +14 -4
  27. package/extension/libherb/{analyzed_ruby.c → analyze/analyzed_ruby.c} +13 -11
  28. package/extension/libherb/{analyzed_ruby.h → analyze/analyzed_ruby.h} +3 -3
  29. package/extension/libherb/analyze/builders.c +343 -0
  30. package/extension/libherb/analyze/builders.h +27 -0
  31. package/extension/libherb/analyze/conditional_elements.c +594 -0
  32. package/extension/libherb/analyze/conditional_elements.h +9 -0
  33. package/extension/libherb/analyze/conditional_open_tags.c +640 -0
  34. package/extension/libherb/analyze/conditional_open_tags.h +9 -0
  35. package/extension/libherb/analyze/control_type.c +250 -0
  36. package/extension/libherb/analyze/control_type.h +14 -0
  37. package/extension/libherb/{analyze_helpers.c → analyze/helpers.c} +79 -31
  38. package/extension/libherb/{analyze_helpers.h → analyze/helpers.h} +22 -17
  39. package/extension/libherb/analyze/invalid_structures.c +193 -0
  40. package/extension/libherb/analyze/invalid_structures.h +11 -0
  41. package/extension/libherb/{analyze_missing_end.c → analyze/missing_end.c} +33 -22
  42. package/extension/libherb/analyze/parse_errors.c +84 -0
  43. package/extension/libherb/analyze/prism_annotate.c +397 -0
  44. package/extension/libherb/analyze/prism_annotate.h +16 -0
  45. package/extension/libherb/{analyze_transform.c → analyze/transform.c} +17 -3
  46. package/extension/libherb/ast_node.c +17 -7
  47. package/extension/libherb/ast_node.h +11 -5
  48. package/extension/libherb/ast_nodes.c +663 -388
  49. package/extension/libherb/ast_nodes.h +118 -39
  50. package/extension/libherb/ast_pretty_print.c +191 -7
  51. package/extension/libherb/ast_pretty_print.h +6 -1
  52. package/extension/libherb/element_source.h +3 -8
  53. package/extension/libherb/errors.c +1100 -507
  54. package/extension/libherb/errors.h +155 -54
  55. package/extension/libherb/extract.c +148 -49
  56. package/extension/libherb/extract.h +21 -5
  57. package/extension/libherb/herb.c +52 -34
  58. package/extension/libherb/herb.h +18 -6
  59. package/extension/libherb/herb_prism_node.h +13 -0
  60. package/extension/libherb/html_util.c +241 -12
  61. package/extension/libherb/html_util.h +7 -2
  62. package/extension/libherb/include/analyze/action_view/attribute_extraction_helpers.h +36 -0
  63. package/extension/libherb/include/analyze/action_view/tag_helper_handler.h +41 -0
  64. package/extension/libherb/include/analyze/action_view/tag_helper_node_builders.h +70 -0
  65. package/extension/libherb/include/analyze/action_view/tag_helpers.h +38 -0
  66. package/extension/libherb/{analyze.h → include/analyze/analyze.h} +14 -4
  67. package/extension/libherb/include/{analyzed_ruby.h → analyze/analyzed_ruby.h} +3 -3
  68. package/extension/libherb/include/analyze/builders.h +27 -0
  69. package/extension/libherb/include/analyze/conditional_elements.h +9 -0
  70. package/extension/libherb/include/analyze/conditional_open_tags.h +9 -0
  71. package/extension/libherb/include/analyze/control_type.h +14 -0
  72. package/extension/libherb/include/{analyze_helpers.h → analyze/helpers.h} +22 -17
  73. package/extension/libherb/include/analyze/invalid_structures.h +11 -0
  74. package/extension/libherb/include/analyze/prism_annotate.h +16 -0
  75. package/extension/libherb/include/ast_node.h +11 -5
  76. package/extension/libherb/include/ast_nodes.h +118 -39
  77. package/extension/libherb/include/ast_pretty_print.h +6 -1
  78. package/extension/libherb/include/element_source.h +3 -8
  79. package/extension/libherb/include/errors.h +155 -54
  80. package/extension/libherb/include/extract.h +21 -5
  81. package/extension/libherb/include/herb.h +18 -6
  82. package/extension/libherb/include/herb_prism_node.h +13 -0
  83. package/extension/libherb/include/html_util.h +7 -2
  84. package/extension/libherb/include/io.h +3 -1
  85. package/extension/libherb/include/lex_helpers.h +29 -0
  86. package/extension/libherb/include/lexer.h +1 -1
  87. package/extension/libherb/include/lexer_peek_helpers.h +87 -13
  88. package/extension/libherb/include/lexer_struct.h +2 -0
  89. package/extension/libherb/include/location.h +2 -1
  90. package/extension/libherb/include/parser.h +27 -2
  91. package/extension/libherb/include/parser_helpers.h +19 -3
  92. package/extension/libherb/include/pretty_print.h +10 -5
  93. package/extension/libherb/include/prism_context.h +45 -0
  94. package/extension/libherb/include/prism_helpers.h +10 -7
  95. package/extension/libherb/include/prism_serialized.h +12 -0
  96. package/extension/libherb/include/token.h +16 -4
  97. package/extension/libherb/include/token_struct.h +10 -3
  98. package/extension/libherb/include/utf8.h +2 -1
  99. package/extension/libherb/include/util/hb_allocator.h +78 -0
  100. package/extension/libherb/include/util/hb_arena.h +6 -1
  101. package/extension/libherb/include/util/hb_arena_debug.h +12 -1
  102. package/extension/libherb/include/util/hb_array.h +7 -3
  103. package/extension/libherb/include/util/hb_buffer.h +6 -4
  104. package/extension/libherb/include/util/hb_foreach.h +79 -0
  105. package/extension/libherb/include/util/hb_narray.h +8 -4
  106. package/extension/libherb/include/util/hb_string.h +56 -9
  107. package/extension/libherb/include/util/string.h +11 -0
  108. package/extension/libherb/include/util.h +6 -3
  109. package/extension/libherb/include/version.h +1 -1
  110. package/extension/libherb/io.c +3 -2
  111. package/extension/libherb/io.h +3 -1
  112. package/extension/libherb/lex_helpers.h +29 -0
  113. package/extension/libherb/lexer.c +42 -30
  114. package/extension/libherb/lexer.h +1 -1
  115. package/extension/libherb/lexer_peek_helpers.c +12 -74
  116. package/extension/libherb/lexer_peek_helpers.h +87 -13
  117. package/extension/libherb/lexer_struct.h +2 -0
  118. package/extension/libherb/location.c +2 -2
  119. package/extension/libherb/location.h +2 -1
  120. package/extension/libherb/main.c +79 -66
  121. package/extension/libherb/parser.c +784 -247
  122. package/extension/libherb/parser.h +27 -2
  123. package/extension/libherb/parser_helpers.c +110 -23
  124. package/extension/libherb/parser_helpers.h +19 -3
  125. package/extension/libherb/parser_match_tags.c +110 -49
  126. package/extension/libherb/pretty_print.c +29 -24
  127. package/extension/libherb/pretty_print.h +10 -5
  128. package/extension/libherb/prism_context.h +45 -0
  129. package/extension/libherb/prism_helpers.c +30 -27
  130. package/extension/libherb/prism_helpers.h +10 -7
  131. package/extension/libherb/prism_serialized.h +12 -0
  132. package/extension/libherb/ruby_parser.c +2 -0
  133. package/extension/libherb/token.c +151 -66
  134. package/extension/libherb/token.h +16 -4
  135. package/extension/libherb/token_matchers.c +0 -1
  136. package/extension/libherb/token_struct.h +10 -3
  137. package/extension/libherb/utf8.c +7 -6
  138. package/extension/libherb/utf8.h +2 -1
  139. package/extension/libherb/util/hb_allocator.c +341 -0
  140. package/extension/libherb/util/hb_allocator.h +78 -0
  141. package/extension/libherb/util/hb_arena.c +81 -56
  142. package/extension/libherb/util/hb_arena.h +6 -1
  143. package/extension/libherb/util/hb_arena_debug.c +32 -17
  144. package/extension/libherb/util/hb_arena_debug.h +12 -1
  145. package/extension/libherb/util/hb_array.c +30 -15
  146. package/extension/libherb/util/hb_array.h +7 -3
  147. package/extension/libherb/util/hb_buffer.c +17 -21
  148. package/extension/libherb/util/hb_buffer.h +6 -4
  149. package/extension/libherb/util/hb_foreach.h +79 -0
  150. package/extension/libherb/util/hb_narray.c +22 -7
  151. package/extension/libherb/util/hb_narray.h +8 -4
  152. package/extension/libherb/util/hb_string.c +49 -35
  153. package/extension/libherb/util/hb_string.h +56 -9
  154. package/extension/libherb/util/string.h +11 -0
  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 +48 -1
  159. package/extension/nodes.cpp +451 -6
  160. package/extension/nodes.h +8 -1
  161. package/extension/prism/include/prism/ast.h +4 -4
  162. package/extension/prism/include/prism/version.h +2 -2
  163. package/extension/prism/src/prism.c +1 -1
  164. package/package.json +12 -8
  165. package/src/node-backend.ts +11 -1
  166. package/dist/types/index-cjs.d.cts +0 -1
  167. package/extension/libherb/analyze.c +0 -1594
  168. package/extension/libherb/element_source.c +0 -12
  169. package/extension/libherb/include/util/hb_system.h +0 -9
  170. package/extension/libherb/util/hb_system.c +0 -30
  171. package/extension/libherb/util/hb_system.h +0 -9
  172. package/src/index-cjs.cts +0 -22
  173. /package/dist/types/{index-esm.d.mts → index.d.ts} +0 -0
  174. /package/src/{index-esm.mts → index.ts} +0 -0
@@ -0,0 +1,397 @@
1
+ #include "../include/analyze/prism_annotate.h"
2
+ #include "../include/ast_node.h"
3
+ #include "../include/ast_nodes.h"
4
+ #include "../include/extract.h"
5
+ #include "../include/herb_prism_node.h"
6
+ #include "../include/prism_context.h"
7
+ #include "../include/util/hb_allocator.h"
8
+ #include "../include/util/hb_buffer.h"
9
+ #include "../include/util/hb_narray.h"
10
+ #include "../include/visitor.h"
11
+
12
+ #include <prism.h>
13
+ #include <string.h>
14
+
15
+ typedef struct {
16
+ uint32_t from;
17
+ uint32_t to;
18
+ } content_range_T;
19
+
20
+ typedef struct {
21
+ pm_parser_t* parser;
22
+ pm_parser_t* structural_parser;
23
+ hb_narray_T* node_list;
24
+ hb_narray_T* structural_node_list;
25
+ bool prism_nodes_deep;
26
+ } prism_annotate_context_T;
27
+
28
+ static void collect_prism_nodes(pm_node_t* node, hb_narray_T* list);
29
+
30
+ static void collect_from_statements(pm_statements_node_t* statements, hb_narray_T* list) {
31
+ if (!statements) { return; }
32
+
33
+ for (size_t i = 0; i < statements->body.size; i++) {
34
+ hb_narray_push(list, &statements->body.nodes[i]);
35
+ collect_prism_nodes(statements->body.nodes[i], list);
36
+ }
37
+ }
38
+
39
+ static void collect_prism_nodes(pm_node_t* node, hb_narray_T* list) {
40
+ if (!node) { return; }
41
+
42
+ switch (PM_NODE_TYPE(node)) {
43
+ case PM_PROGRAM_NODE: {
44
+ collect_from_statements(((pm_program_node_t*) node)->statements, list);
45
+ break;
46
+ }
47
+
48
+ case PM_IF_NODE: {
49
+ pm_if_node_t* if_node = (pm_if_node_t*) node;
50
+ collect_from_statements(if_node->statements, list);
51
+ if (if_node->subsequent) { collect_prism_nodes(if_node->subsequent, list); }
52
+ break;
53
+ }
54
+
55
+ case PM_UNLESS_NODE: {
56
+ pm_unless_node_t* unless_node = (pm_unless_node_t*) node;
57
+ collect_from_statements(unless_node->statements, list);
58
+ if (unless_node->else_clause) { collect_prism_nodes((pm_node_t*) unless_node->else_clause, list); }
59
+ break;
60
+ }
61
+
62
+ case PM_ELSE_NODE: {
63
+ collect_from_statements(((pm_else_node_t*) node)->statements, list);
64
+ break;
65
+ }
66
+
67
+ case PM_WHILE_NODE: {
68
+ collect_from_statements(((pm_while_node_t*) node)->statements, list);
69
+ break;
70
+ }
71
+
72
+ case PM_UNTIL_NODE: {
73
+ collect_from_statements(((pm_until_node_t*) node)->statements, list);
74
+ break;
75
+ }
76
+
77
+ case PM_FOR_NODE: {
78
+ collect_from_statements(((pm_for_node_t*) node)->statements, list);
79
+ break;
80
+ }
81
+
82
+ case PM_CASE_NODE: {
83
+ pm_case_node_t* case_node = (pm_case_node_t*) node;
84
+
85
+ for (size_t i = 0; i < case_node->conditions.size; i++) {
86
+ collect_prism_nodes(case_node->conditions.nodes[i], list);
87
+ }
88
+
89
+ if (case_node->else_clause) { collect_prism_nodes((pm_node_t*) case_node->else_clause, list); }
90
+ break;
91
+ }
92
+
93
+ case PM_CASE_MATCH_NODE: {
94
+ pm_case_match_node_t* case_match_node = (pm_case_match_node_t*) node;
95
+
96
+ for (size_t i = 0; i < case_match_node->conditions.size; i++) {
97
+ collect_prism_nodes(case_match_node->conditions.nodes[i], list);
98
+ }
99
+
100
+ if (case_match_node->else_clause) { collect_prism_nodes((pm_node_t*) case_match_node->else_clause, list); }
101
+ break;
102
+ }
103
+
104
+ case PM_WHEN_NODE: {
105
+ collect_from_statements(((pm_when_node_t*) node)->statements, list);
106
+ break;
107
+ }
108
+
109
+ case PM_IN_NODE: {
110
+ collect_from_statements(((pm_in_node_t*) node)->statements, list);
111
+ break;
112
+ }
113
+
114
+ case PM_BEGIN_NODE: {
115
+ pm_begin_node_t* begin_node = (pm_begin_node_t*) node;
116
+
117
+ collect_from_statements(begin_node->statements, list);
118
+
119
+ if (begin_node->rescue_clause) { collect_prism_nodes((pm_node_t*) begin_node->rescue_clause, list); }
120
+ if (begin_node->else_clause) { collect_prism_nodes((pm_node_t*) begin_node->else_clause, list); }
121
+ if (begin_node->ensure_clause) { collect_prism_nodes((pm_node_t*) begin_node->ensure_clause, list); }
122
+
123
+ break;
124
+ }
125
+
126
+ case PM_RESCUE_NODE: {
127
+ pm_rescue_node_t* rescue_node = (pm_rescue_node_t*) node;
128
+
129
+ collect_from_statements(rescue_node->statements, list);
130
+
131
+ if (rescue_node->subsequent) { collect_prism_nodes((pm_node_t*) rescue_node->subsequent, list); }
132
+ break;
133
+ }
134
+
135
+ case PM_ENSURE_NODE: {
136
+ collect_from_statements(((pm_ensure_node_t*) node)->statements, list);
137
+ break;
138
+ }
139
+
140
+ case PM_CALL_NODE: {
141
+ pm_call_node_t* call_node = (pm_call_node_t*) node;
142
+
143
+ if (call_node->block && PM_NODE_TYPE(call_node->block) == PM_BLOCK_NODE) {
144
+ pm_block_node_t* block = (pm_block_node_t*) call_node->block;
145
+
146
+ if (block->body && PM_NODE_TYPE(block->body) == PM_STATEMENTS_NODE) {
147
+ collect_from_statements((pm_statements_node_t*) block->body, list);
148
+ }
149
+ }
150
+
151
+ break;
152
+ }
153
+
154
+ case PM_LAMBDA_NODE: {
155
+ pm_lambda_node_t* lambda_node = (pm_lambda_node_t*) node;
156
+
157
+ if (lambda_node->body && PM_NODE_TYPE(lambda_node->body) == PM_STATEMENTS_NODE) {
158
+ collect_from_statements((pm_statements_node_t*) lambda_node->body, list);
159
+ }
160
+
161
+ break;
162
+ }
163
+
164
+ default: break;
165
+ }
166
+ }
167
+
168
+ static token_T* get_content_token(const AST_NODE_T* node) {
169
+ switch (node->type) {
170
+ case AST_ERB_CONTENT_NODE: return ((AST_ERB_CONTENT_NODE_T*) node)->content;
171
+ case AST_ERB_IF_NODE: return ((AST_ERB_IF_NODE_T*) node)->content;
172
+ case AST_ERB_BLOCK_NODE: return ((AST_ERB_BLOCK_NODE_T*) node)->content;
173
+ case AST_ERB_CASE_NODE: return ((AST_ERB_CASE_NODE_T*) node)->content;
174
+ case AST_ERB_CASE_MATCH_NODE: return ((AST_ERB_CASE_MATCH_NODE_T*) node)->content;
175
+ case AST_ERB_WHILE_NODE: return ((AST_ERB_WHILE_NODE_T*) node)->content;
176
+ case AST_ERB_UNTIL_NODE: return ((AST_ERB_UNTIL_NODE_T*) node)->content;
177
+ case AST_ERB_FOR_NODE: return ((AST_ERB_FOR_NODE_T*) node)->content;
178
+ case AST_ERB_BEGIN_NODE: return ((AST_ERB_BEGIN_NODE_T*) node)->content;
179
+ case AST_ERB_UNLESS_NODE: return ((AST_ERB_UNLESS_NODE_T*) node)->content;
180
+ default: return NULL;
181
+ }
182
+ }
183
+
184
+ static void set_prism_node(AST_NODE_T* node, herb_prism_node_T prism_ref) {
185
+ switch (node->type) {
186
+ case AST_ERB_CONTENT_NODE: ((AST_ERB_CONTENT_NODE_T*) node)->prism_node = prism_ref; break;
187
+ case AST_ERB_IF_NODE: ((AST_ERB_IF_NODE_T*) node)->prism_node = prism_ref; break;
188
+ case AST_ERB_BLOCK_NODE: ((AST_ERB_BLOCK_NODE_T*) node)->prism_node = prism_ref; break;
189
+ case AST_ERB_CASE_NODE: ((AST_ERB_CASE_NODE_T*) node)->prism_node = prism_ref; break;
190
+ case AST_ERB_CASE_MATCH_NODE: ((AST_ERB_CASE_MATCH_NODE_T*) node)->prism_node = prism_ref; break;
191
+ case AST_ERB_WHILE_NODE: ((AST_ERB_WHILE_NODE_T*) node)->prism_node = prism_ref; break;
192
+ case AST_ERB_UNTIL_NODE: ((AST_ERB_UNTIL_NODE_T*) node)->prism_node = prism_ref; break;
193
+ case AST_ERB_FOR_NODE: ((AST_ERB_FOR_NODE_T*) node)->prism_node = prism_ref; break;
194
+ case AST_ERB_BEGIN_NODE: ((AST_ERB_BEGIN_NODE_T*) node)->prism_node = prism_ref; break;
195
+ case AST_ERB_UNLESS_NODE: ((AST_ERB_UNLESS_NODE_T*) node)->prism_node = prism_ref; break;
196
+ default: break;
197
+ }
198
+ }
199
+
200
+ static herb_prism_node_T find_prism_node_for_herb_node(
201
+ pm_parser_t* parser,
202
+ hb_narray_T* node_list,
203
+ const AST_NODE_T* node
204
+ ) {
205
+ herb_prism_node_T result = HERB_PRISM_NODE_EMPTY;
206
+
207
+ token_T* content = get_content_token(node);
208
+ if (!content || hb_string_is_empty(content->value)) { return result; }
209
+
210
+ uint32_t content_from = content->range.from;
211
+ uint32_t content_to = content->range.to;
212
+
213
+ for (size_t i = 0; i < hb_narray_size(node_list); i++) {
214
+ pm_node_t* prism_node = *(pm_node_t**) hb_narray_get(node_list, i);
215
+ size_t prism_start = (size_t) (prism_node->location.start - parser->start);
216
+
217
+ if (prism_start >= content_from && prism_start < content_to) {
218
+ result.node = prism_node;
219
+ result.parser = parser;
220
+ break;
221
+ }
222
+ }
223
+
224
+ return result;
225
+ }
226
+
227
+ static bool annotate_visitor(const AST_NODE_T* node, void* data) {
228
+ prism_annotate_context_T* context = (prism_annotate_context_T*) data;
229
+
230
+ if (!get_content_token(node)) { return true; }
231
+
232
+ pm_parser_t* parser;
233
+ hb_narray_T* node_list;
234
+
235
+ if (node->type == AST_ERB_CONTENT_NODE || context->prism_nodes_deep) {
236
+ parser = context->parser;
237
+ node_list = context->node_list;
238
+ } else {
239
+ parser = context->structural_parser;
240
+ node_list = context->structural_node_list;
241
+ }
242
+
243
+ herb_prism_node_T prism_ref = find_prism_node_for_herb_node(parser, node_list, node);
244
+
245
+ if (prism_ref.node) { set_prism_node((AST_NODE_T*) node, prism_ref); }
246
+
247
+ return true;
248
+ }
249
+
250
+ static bool collect_content_ranges_visitor(const AST_NODE_T* node, void* data) {
251
+ if (node->type != AST_ERB_CONTENT_NODE) { return true; }
252
+
253
+ hb_narray_T* ranges = (hb_narray_T*) data;
254
+ token_T* content = get_content_token(node);
255
+
256
+ if (!content || hb_string_is_empty(content->value)) { return true; }
257
+
258
+ content_range_T range = { .from = content->range.from, .to = content->range.to };
259
+ hb_narray_push(ranges, &range);
260
+
261
+ return true;
262
+ }
263
+
264
+ void herb_annotate_prism_nodes(
265
+ AST_DOCUMENT_NODE_T* document,
266
+ const char* source,
267
+ bool prism_nodes,
268
+ bool prism_nodes_deep,
269
+ bool prism_program,
270
+ hb_allocator_T* allocator
271
+ ) {
272
+ if (!document || !source) { return; }
273
+
274
+ size_t source_len = strlen(source);
275
+
276
+ herb_prism_context_T* context = hb_allocator_alloc(allocator, sizeof(herb_prism_context_T));
277
+ if (!context) { return; }
278
+
279
+ memset(context, 0, sizeof(herb_prism_context_T));
280
+
281
+ context->allocator = allocator;
282
+ context->has_structural = false;
283
+
284
+ if (!hb_buffer_init(&context->ruby_buf, source_len, allocator)) {
285
+ hb_allocator_dealloc(allocator, context);
286
+ return;
287
+ }
288
+
289
+ herb_extract_ruby_options_T extract_options = {
290
+ .semicolons = true,
291
+ .comments = false,
292
+ .preserve_positions = true,
293
+ };
294
+
295
+ herb_extract_ruby_to_buffer_with_options(source, &context->ruby_buf, &extract_options, allocator);
296
+
297
+ if (!context->ruby_buf.value || context->ruby_buf.length == 0) {
298
+ hb_buffer_free(&context->ruby_buf);
299
+ hb_allocator_dealloc(allocator, context);
300
+ return;
301
+ }
302
+
303
+ memset(&context->pm_opts, 0, sizeof(pm_options_t));
304
+ pm_options_partial_script_set(&context->pm_opts, true);
305
+ pm_parser_init(
306
+ &context->parser,
307
+ (const uint8_t*) context->ruby_buf.value,
308
+ context->ruby_buf.length,
309
+ &context->pm_opts
310
+ );
311
+ context->root = pm_parse(&context->parser);
312
+
313
+ if (!context->root || context->root->type != PM_PROGRAM_NODE) {
314
+ pm_node_destroy(&context->parser, context->root);
315
+ context->root = NULL;
316
+
317
+ pm_parser_free(&context->parser);
318
+ pm_options_free(&context->pm_opts);
319
+
320
+ hb_buffer_free(&context->ruby_buf);
321
+ hb_allocator_dealloc(allocator, context);
322
+
323
+ return;
324
+ }
325
+
326
+ document->prism_context = context;
327
+
328
+ if (prism_program) {
329
+ herb_prism_node_T program_ref = {
330
+ .node = context->root,
331
+ .parser = &context->parser,
332
+ };
333
+
334
+ document->prism_node = program_ref;
335
+ }
336
+
337
+ hb_narray_T node_list;
338
+ hb_narray_pointer_init(&node_list, 32, allocator);
339
+
340
+ hb_narray_T structural_node_list;
341
+ hb_narray_pointer_init(&structural_node_list, 32, allocator);
342
+
343
+ if (prism_nodes) {
344
+ collect_prism_nodes(context->root, &node_list);
345
+
346
+ if (!prism_nodes_deep) {
347
+ hb_narray_T content_ranges;
348
+ hb_narray_init(&content_ranges, sizeof(content_range_T), 32, allocator);
349
+ herb_visit_node((AST_NODE_T*) document, collect_content_ranges_visitor, &content_ranges);
350
+
351
+ if (hb_buffer_init(&context->structural_buf, context->ruby_buf.length, allocator)) {
352
+ memcpy(context->structural_buf.value, context->ruby_buf.value, context->ruby_buf.length);
353
+ context->structural_buf.length = context->ruby_buf.length;
354
+
355
+ for (size_t i = 0; i < hb_narray_size(&content_ranges); i++) {
356
+ content_range_T* range = (content_range_T*) hb_narray_get(&content_ranges, i);
357
+
358
+ for (uint32_t j = range->from; j < range->to && j < context->structural_buf.length; j++) {
359
+ context->structural_buf.value[j] = ' ';
360
+ }
361
+ }
362
+
363
+ memset(&context->structural_pm_opts, 0, sizeof(pm_options_t));
364
+ pm_options_partial_script_set(&context->structural_pm_opts, true);
365
+
366
+ pm_parser_init(
367
+ &context->structural_parser,
368
+ (const uint8_t*) context->structural_buf.value,
369
+ context->structural_buf.length,
370
+ &context->structural_pm_opts
371
+ );
372
+
373
+ context->structural_root = pm_parse(&context->structural_parser);
374
+ context->has_structural = true;
375
+
376
+ if (context->structural_root && context->structural_root->type == PM_PROGRAM_NODE) {
377
+ collect_prism_nodes(context->structural_root, &structural_node_list);
378
+ }
379
+ }
380
+
381
+ hb_narray_deinit(&content_ranges);
382
+ }
383
+
384
+ prism_annotate_context_T annotate_context = {
385
+ .parser = &context->parser,
386
+ .structural_parser = prism_nodes_deep ? &context->parser : &context->structural_parser,
387
+ .node_list = &node_list,
388
+ .structural_node_list = prism_nodes_deep ? &node_list : &structural_node_list,
389
+ .prism_nodes_deep = prism_nodes_deep,
390
+ };
391
+
392
+ herb_visit_node((AST_NODE_T*) document, annotate_visitor, &annotate_context);
393
+ }
394
+
395
+ hb_narray_deinit(&node_list);
396
+ hb_narray_deinit(&structural_node_list);
397
+ }
@@ -0,0 +1,16 @@
1
+ #ifndef HERB_PRISM_ANNOTATE_H
2
+ #define HERB_PRISM_ANNOTATE_H
3
+
4
+ #include "../ast_nodes.h"
5
+ #include "../util/hb_allocator.h"
6
+
7
+ void herb_annotate_prism_nodes(
8
+ AST_DOCUMENT_NODE_T* document,
9
+ const char* source,
10
+ bool prism_nodes,
11
+ bool prism_nodes_deep,
12
+ bool prism_program,
13
+ hb_allocator_T* allocator
14
+ );
15
+
16
+ #endif
@@ -1,8 +1,8 @@
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.9/templates/src/analyze_transform.c.erb
2
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.0/templates/src/analyze/transform.c.erb
3
3
 
4
- #include "include/analyze.h"
5
- #include "include/visitor.h"
4
+ #include "../include/analyze/analyze.h"
5
+ #include "../include/visitor.h"
6
6
 
7
7
  bool transform_erb_nodes(const AST_NODE_T* node, void* data) {
8
8
  analyze_ruby_context_T* context = (analyze_ruby_context_T*) data;
@@ -36,6 +36,13 @@ bool transform_erb_nodes(const AST_NODE_T* node, void* data) {
36
36
  hb_array_free(&old_array);
37
37
  }
38
38
 
39
+ if (node->type == AST_HTML_CONDITIONAL_ELEMENT_NODE) {
40
+ AST_HTML_CONDITIONAL_ELEMENT_NODE_T* html_conditional_element_node = (AST_HTML_CONDITIONAL_ELEMENT_NODE_T*) node;
41
+ hb_array_T* old_array = html_conditional_element_node->body;
42
+ html_conditional_element_node->body = rewrite_node_array((AST_NODE_T*) node, html_conditional_element_node->body, context);
43
+ hb_array_free(&old_array);
44
+ }
45
+
39
46
  if (node->type == AST_HTML_ATTRIBUTE_VALUE_NODE) {
40
47
  AST_HTML_ATTRIBUTE_VALUE_NODE_T* html_attribute_value_node = (AST_HTML_ATTRIBUTE_VALUE_NODE_T*) node;
41
48
  hb_array_T* old_array = html_attribute_value_node->children;
@@ -50,6 +57,13 @@ bool transform_erb_nodes(const AST_NODE_T* node, void* data) {
50
57
  hb_array_free(&old_array);
51
58
  }
52
59
 
60
+ if (node->type == AST_ERB_OPEN_TAG_NODE) {
61
+ AST_ERB_OPEN_TAG_NODE_T* erb_open_tag_node = (AST_ERB_OPEN_TAG_NODE_T*) node;
62
+ hb_array_T* old_array = erb_open_tag_node->children;
63
+ erb_open_tag_node->children = rewrite_node_array((AST_NODE_T*) node, erb_open_tag_node->children, context);
64
+ hb_array_free(&old_array);
65
+ }
66
+
53
67
  if (node->type == AST_HTML_COMMENT_NODE) {
54
68
  AST_HTML_COMMENT_NODE_T* html_comment_node = (AST_HTML_COMMENT_NODE_T*) node;
55
69
  hb_array_T* old_array = html_comment_node->children;
@@ -2,8 +2,9 @@
2
2
  #include "include/ast_nodes.h"
3
3
  #include "include/errors.h"
4
4
  #include "include/position.h"
5
- #include "include/token.h"
6
5
  #include "include/util.h"
6
+ #include "include/util/hb_allocator.h"
7
+ #include "include/util/hb_string.h"
7
8
  #include "include/visitor.h"
8
9
 
9
10
  #include <prism.h>
@@ -14,7 +15,14 @@ size_t ast_node_sizeof(void) {
14
15
  return sizeof(struct AST_NODE_STRUCT);
15
16
  }
16
17
 
17
- void ast_node_init(AST_NODE_T* node, const ast_node_type_T type, position_T start, position_T end, hb_array_T* errors) {
18
+ void ast_node_init(
19
+ AST_NODE_T* node,
20
+ const ast_node_type_T type,
21
+ position_T start,
22
+ position_T end,
23
+ hb_array_T* errors,
24
+ hb_allocator_T* allocator
25
+ ) {
18
26
  if (!node) { return; }
19
27
 
20
28
  node->type = type;
@@ -22,18 +30,20 @@ void ast_node_init(AST_NODE_T* node, const ast_node_type_T type, position_T star
22
30
  node->location.end = end;
23
31
 
24
32
  if (errors == NULL) {
25
- node->errors = hb_array_init(8);
33
+ node->errors = hb_array_init(0, allocator);
26
34
  } else {
27
35
  node->errors = errors;
28
36
  }
29
37
  }
30
38
 
31
- AST_LITERAL_NODE_T* ast_literal_node_init_from_token(const token_T* token) {
32
- AST_LITERAL_NODE_T* literal = malloc(sizeof(AST_LITERAL_NODE_T));
39
+ AST_LITERAL_NODE_T* ast_literal_node_init_from_token(const token_T* token, hb_allocator_T* allocator) {
40
+ AST_LITERAL_NODE_T* literal = hb_allocator_alloc(allocator, sizeof(AST_LITERAL_NODE_T));
33
41
 
34
- ast_node_init(&literal->base, AST_LITERAL_NODE, token->location.start, token->location.end, NULL);
42
+ if (!literal) { return NULL; }
35
43
 
36
- literal->content = herb_strdup(token->value);
44
+ ast_node_init(&literal->base, AST_LITERAL_NODE, token->location.start, token->location.end, NULL, allocator);
45
+
46
+ literal->content = hb_string_copy(token->value, allocator);
37
47
 
38
48
  return literal;
39
49
  }
@@ -5,19 +5,25 @@
5
5
  #include "errors.h"
6
6
  #include "position.h"
7
7
  #include "token_struct.h"
8
+ #include "util/hb_allocator.h"
8
9
 
9
- void ast_node_init(AST_NODE_T* node, ast_node_type_T type, position_T start, position_T end, hb_array_T* errors);
10
- void ast_node_free(AST_NODE_T* node);
10
+ void ast_node_init(
11
+ AST_NODE_T* node,
12
+ ast_node_type_T type,
13
+ position_T start,
14
+ position_T end,
15
+ hb_array_T* errors,
16
+ hb_allocator_T* allocator
17
+ );
18
+ void ast_node_free(AST_NODE_T* node, hb_allocator_T* allocator);
11
19
 
12
- AST_LITERAL_NODE_T* ast_literal_node_init_from_token(const token_T* token);
20
+ AST_LITERAL_NODE_T* ast_literal_node_init_from_token(const token_T* token, hb_allocator_T* allocator);
13
21
 
14
22
  size_t ast_node_sizeof(void);
15
23
  size_t ast_node_child_count(AST_NODE_T* node);
16
24
 
17
25
  ast_node_type_T ast_node_type(const AST_NODE_T* node);
18
26
 
19
- char* ast_node_name(AST_NODE_T* node);
20
-
21
27
  void ast_node_set_start(AST_NODE_T* node, position_T position);
22
28
  void ast_node_set_end(AST_NODE_T* node, position_T position);
23
29