herb 0.8.10-arm-linux-gnu → 0.9.1-arm-linux-gnu

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +11 -3
  3. data/README.md +64 -34
  4. data/Rakefile +48 -40
  5. data/config.yml +473 -34
  6. data/ext/herb/error_helpers.c +535 -140
  7. data/ext/herb/error_helpers.h +1 -0
  8. data/ext/herb/extconf.rb +67 -28
  9. data/ext/herb/extension.c +321 -51
  10. data/ext/herb/extension.h +1 -0
  11. data/ext/herb/extension_helpers.c +24 -14
  12. data/ext/herb/extension_helpers.h +2 -2
  13. data/ext/herb/nodes.c +647 -270
  14. data/ext/herb/nodes.h +1 -0
  15. data/herb.gemspec +3 -2
  16. data/lib/herb/3.0/herb.so +0 -0
  17. data/lib/herb/3.1/herb.so +0 -0
  18. data/lib/herb/3.2/herb.so +0 -0
  19. data/lib/herb/3.3/herb.so +0 -0
  20. data/lib/herb/3.4/herb.so +0 -0
  21. data/lib/herb/4.0/herb.so +0 -0
  22. data/lib/herb/ast/helpers.rb +3 -3
  23. data/lib/herb/ast/node.rb +15 -2
  24. data/lib/herb/ast/nodes.rb +1530 -179
  25. data/lib/herb/bootstrap.rb +87 -0
  26. data/lib/herb/cli.rb +341 -31
  27. data/lib/herb/configuration.rb +248 -0
  28. data/lib/herb/defaults.yml +32 -0
  29. data/lib/herb/engine/compiler.rb +78 -11
  30. data/lib/herb/engine/debug_visitor.rb +13 -3
  31. data/lib/herb/engine/error_formatter.rb +13 -9
  32. data/lib/herb/engine/parser_error_overlay.rb +10 -6
  33. data/lib/herb/engine/validator.rb +8 -3
  34. data/lib/herb/engine/validators/nesting_validator.rb +2 -2
  35. data/lib/herb/engine.rb +119 -43
  36. data/lib/herb/errors.rb +808 -88
  37. data/lib/herb/lex_result.rb +1 -0
  38. data/lib/herb/location.rb +7 -3
  39. data/lib/herb/parse_result.rb +12 -2
  40. data/lib/herb/parser_options.rb +62 -0
  41. data/lib/herb/position.rb +1 -0
  42. data/lib/herb/prism_inspect.rb +120 -0
  43. data/lib/herb/project.rb +923 -331
  44. data/lib/herb/range.rb +1 -0
  45. data/lib/herb/token.rb +7 -1
  46. data/lib/herb/version.rb +1 -1
  47. data/lib/herb/visitor.rb +47 -2
  48. data/lib/herb/warnings.rb +6 -1
  49. data/lib/herb.rb +35 -3
  50. data/sig/herb/ast/helpers.rbs +2 -2
  51. data/sig/herb/ast/node.rbs +12 -2
  52. data/sig/herb/ast/nodes.rbs +773 -128
  53. data/sig/herb/bootstrap.rbs +31 -0
  54. data/sig/herb/configuration.rbs +89 -0
  55. data/sig/herb/engine/compiler.rbs +9 -1
  56. data/sig/herb/engine/debug_visitor.rbs +2 -0
  57. data/sig/herb/engine/validator.rbs +5 -1
  58. data/sig/herb/engine.rbs +21 -3
  59. data/sig/herb/errors.rbs +372 -63
  60. data/sig/herb/location.rbs +4 -0
  61. data/sig/herb/parse_result.rbs +4 -2
  62. data/sig/herb/parser_options.rbs +46 -0
  63. data/sig/herb/position.rbs +1 -0
  64. data/sig/herb/prism_inspect.rbs +28 -0
  65. data/sig/herb/range.rbs +1 -0
  66. data/sig/herb/token.rbs +6 -0
  67. data/sig/herb/visitor.rbs +31 -4
  68. data/sig/herb/warnings.rbs +6 -1
  69. data/sig/herb.rbs +14 -0
  70. data/sig/herb_c_extension.rbs +5 -2
  71. data/sig/rubyvm.rbs +5 -0
  72. data/sig/serialized_ast_errors.rbs +82 -6
  73. data/sig/serialized_ast_nodes.rbs +91 -6
  74. data/src/analyze/action_view/attribute_extraction_helpers.c +303 -0
  75. data/src/analyze/action_view/content_tag.c +78 -0
  76. data/src/analyze/action_view/link_to.c +167 -0
  77. data/src/analyze/action_view/registry.c +83 -0
  78. data/src/analyze/action_view/tag.c +70 -0
  79. data/src/analyze/action_view/tag_helper_node_builders.c +305 -0
  80. data/src/analyze/action_view/tag_helpers.c +815 -0
  81. data/src/analyze/action_view/turbo_frame_tag.c +88 -0
  82. data/src/analyze/analyze.c +885 -0
  83. data/src/{analyzed_ruby.c → analyze/analyzed_ruby.c} +13 -11
  84. data/src/analyze/builders.c +343 -0
  85. data/src/analyze/conditional_elements.c +594 -0
  86. data/src/analyze/conditional_open_tags.c +640 -0
  87. data/src/analyze/control_type.c +250 -0
  88. data/src/{analyze_helpers.c → analyze/helpers.c} +48 -23
  89. data/src/analyze/invalid_structures.c +193 -0
  90. data/src/{analyze_missing_end.c → analyze/missing_end.c} +33 -22
  91. data/src/analyze/parse_errors.c +84 -0
  92. data/src/analyze/prism_annotate.c +399 -0
  93. data/src/analyze/render_nodes.c +761 -0
  94. data/src/{analyze_transform.c → analyze/transform.c} +24 -3
  95. data/src/ast_node.c +17 -7
  96. data/src/ast_nodes.c +759 -387
  97. data/src/ast_pretty_print.c +264 -6
  98. data/src/errors.c +1454 -519
  99. data/src/extract.c +145 -49
  100. data/src/herb.c +52 -34
  101. data/src/html_util.c +241 -12
  102. data/src/include/analyze/action_view/attribute_extraction_helpers.h +36 -0
  103. data/src/include/analyze/action_view/tag_helper_handler.h +43 -0
  104. data/src/include/analyze/action_view/tag_helper_node_builders.h +70 -0
  105. data/src/include/analyze/action_view/tag_helpers.h +38 -0
  106. data/src/include/{analyze.h → analyze/analyze.h} +14 -4
  107. data/src/include/{analyzed_ruby.h → analyze/analyzed_ruby.h} +3 -3
  108. data/src/include/analyze/builders.h +27 -0
  109. data/src/include/analyze/conditional_elements.h +9 -0
  110. data/src/include/analyze/conditional_open_tags.h +9 -0
  111. data/src/include/analyze/control_type.h +14 -0
  112. data/src/include/{analyze_helpers.h → analyze/helpers.h} +4 -2
  113. data/src/include/analyze/invalid_structures.h +11 -0
  114. data/src/include/analyze/prism_annotate.h +16 -0
  115. data/src/include/analyze/render_nodes.h +11 -0
  116. data/src/include/ast_node.h +11 -5
  117. data/src/include/ast_nodes.h +154 -38
  118. data/src/include/ast_pretty_print.h +5 -0
  119. data/src/include/element_source.h +3 -8
  120. data/src/include/errors.h +206 -55
  121. data/src/include/extract.h +21 -5
  122. data/src/include/herb.h +18 -6
  123. data/src/include/herb_prism_node.h +13 -0
  124. data/src/include/html_util.h +7 -2
  125. data/src/include/io.h +3 -1
  126. data/src/include/lex_helpers.h +29 -0
  127. data/src/include/lexer.h +1 -1
  128. data/src/include/lexer_peek_helpers.h +87 -13
  129. data/src/include/lexer_struct.h +2 -0
  130. data/src/include/location.h +2 -1
  131. data/src/include/parser.h +28 -2
  132. data/src/include/parser_helpers.h +19 -3
  133. data/src/include/pretty_print.h +10 -5
  134. data/src/include/prism_context.h +45 -0
  135. data/src/include/prism_helpers.h +10 -7
  136. data/src/include/prism_serialized.h +12 -0
  137. data/src/include/token.h +16 -4
  138. data/src/include/token_struct.h +10 -3
  139. data/src/include/utf8.h +2 -1
  140. data/src/include/util/hb_allocator.h +78 -0
  141. data/src/include/util/hb_arena.h +6 -1
  142. data/src/include/util/hb_arena_debug.h +12 -1
  143. data/src/include/util/hb_array.h +7 -3
  144. data/src/include/util/hb_buffer.h +6 -4
  145. data/src/include/util/hb_foreach.h +79 -0
  146. data/src/include/util/hb_narray.h +8 -4
  147. data/src/include/util/hb_string.h +56 -9
  148. data/src/include/util.h +6 -3
  149. data/src/include/version.h +1 -1
  150. data/src/io.c +3 -2
  151. data/src/lexer.c +42 -30
  152. data/src/lexer_peek_helpers.c +12 -74
  153. data/src/location.c +2 -2
  154. data/src/main.c +53 -28
  155. data/src/parser.c +784 -247
  156. data/src/parser_helpers.c +110 -23
  157. data/src/parser_match_tags.c +129 -48
  158. data/src/pretty_print.c +29 -24
  159. data/src/prism_helpers.c +30 -27
  160. data/src/ruby_parser.c +2 -0
  161. data/src/token.c +151 -66
  162. data/src/token_matchers.c +0 -1
  163. data/src/utf8.c +7 -6
  164. data/src/util/hb_allocator.c +341 -0
  165. data/src/util/hb_arena.c +81 -56
  166. data/src/util/hb_arena_debug.c +32 -17
  167. data/src/util/hb_array.c +30 -15
  168. data/src/util/hb_buffer.c +17 -21
  169. data/src/util/hb_narray.c +22 -7
  170. data/src/util/hb_string.c +49 -35
  171. data/src/util.c +21 -11
  172. data/src/visitor.c +67 -0
  173. data/templates/ext/herb/error_helpers.c.erb +24 -11
  174. data/templates/ext/herb/error_helpers.h.erb +1 -0
  175. data/templates/ext/herb/nodes.c.erb +50 -16
  176. data/templates/ext/herb/nodes.h.erb +1 -0
  177. data/templates/java/error_helpers.c.erb +1 -1
  178. data/templates/java/nodes.c.erb +30 -8
  179. data/templates/java/org/herb/ast/Errors.java.erb +24 -1
  180. data/templates/java/org/herb/ast/Nodes.java.erb +80 -21
  181. data/templates/javascript/packages/core/src/errors.ts.erb +16 -3
  182. data/templates/javascript/packages/core/src/node-type-guards.ts.erb +3 -1
  183. data/templates/javascript/packages/core/src/nodes.ts.erb +109 -32
  184. data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +13 -4
  185. data/templates/javascript/packages/node/extension/nodes.cpp.erb +43 -4
  186. data/templates/lib/herb/ast/nodes.rb.erb +95 -32
  187. data/templates/lib/herb/errors.rb.erb +15 -3
  188. data/templates/lib/herb/visitor.rb.erb +2 -2
  189. data/templates/rust/src/ast/nodes.rs.erb +97 -44
  190. data/templates/rust/src/errors.rs.erb +2 -1
  191. data/templates/rust/src/nodes.rs.erb +168 -16
  192. data/templates/rust/src/union_types.rs.erb +60 -0
  193. data/templates/rust/src/visitor.rs.erb +81 -0
  194. data/templates/src/{analyze_missing_end.c.erb → analyze/missing_end.c.erb} +9 -6
  195. data/templates/src/{analyze_transform.c.erb → analyze/transform.c.erb} +2 -2
  196. data/templates/src/ast_nodes.c.erb +34 -26
  197. data/templates/src/ast_pretty_print.c.erb +24 -5
  198. data/templates/src/errors.c.erb +60 -54
  199. data/templates/src/include/ast_nodes.h.erb +6 -2
  200. data/templates/src/include/ast_pretty_print.h.erb +5 -0
  201. data/templates/src/include/errors.h.erb +15 -11
  202. data/templates/src/include/util/hb_foreach.h.erb +20 -0
  203. data/templates/src/parser_match_tags.c.erb +10 -4
  204. data/templates/src/visitor.c.erb +2 -2
  205. data/templates/template.rb +204 -29
  206. data/templates/wasm/error_helpers.cpp.erb +9 -5
  207. data/templates/wasm/nodes.cpp.erb +41 -4
  208. metadata +60 -16
  209. data/src/analyze.c +0 -1608
  210. data/src/element_source.c +0 -12
  211. data/src/include/util/hb_system.h +0 -9
  212. data/src/util/hb_system.c +0 -30
data/src/html_util.c CHANGED
@@ -1,5 +1,5 @@
1
1
  #include "include/html_util.h"
2
- #include "include/util.h"
2
+ #include "include/util/hb_allocator.h"
3
3
  #include "include/util/hb_buffer.h"
4
4
  #include "include/util/hb_string.h"
5
5
 
@@ -10,22 +10,251 @@
10
10
  #include <string.h>
11
11
 
12
12
  // https://developer.mozilla.org/en-US/docs/Glossary/Void_element
13
+ static hb_string_T void_tags[] = HB_STRING_LIST(
14
+ "area",
15
+ "base",
16
+ "br",
17
+ "col",
18
+ "embed",
19
+ "hr",
20
+ "img",
21
+ "input",
22
+ "link",
23
+ "meta",
24
+ "param",
25
+ "source",
26
+ "track",
27
+ "wbr"
28
+ );
29
+
30
+ // https://html.spec.whatwg.org/multipage/syntax.html#optional-tags
31
+ static hb_string_T optional_end_tags[] = HB_STRING_LIST(
32
+ "li",
33
+ "dt",
34
+ "dd",
35
+ "p",
36
+ "rt",
37
+ "rp",
38
+ "optgroup",
39
+ "option",
40
+ "thead",
41
+ "tbody",
42
+ "tfoot",
43
+ "tr",
44
+ "td",
45
+ "th",
46
+ "colgroup"
47
+ );
48
+
49
+ static hb_string_T p_closers[] = HB_STRING_LIST(
50
+ "address",
51
+ "article",
52
+ "aside",
53
+ "blockquote",
54
+ "details",
55
+ "div",
56
+ "dl",
57
+ "fieldset",
58
+ "figcaption",
59
+ "figure",
60
+ "footer",
61
+ "form",
62
+ "h1",
63
+ "h2",
64
+ "h3",
65
+ "h4",
66
+ "h5",
67
+ "h6",
68
+ "header",
69
+ "hgroup",
70
+ "hr",
71
+ "main",
72
+ "menu",
73
+ "nav",
74
+ "ol",
75
+ "p",
76
+ "pre",
77
+ "section",
78
+ "table",
79
+ "ul"
80
+ );
81
+
82
+ static hb_string_T p_parent_closers[] = HB_STRING_LIST(
83
+ "article",
84
+ "aside",
85
+ "blockquote",
86
+ "body",
87
+ "details",
88
+ "div",
89
+ "fieldset",
90
+ "figcaption",
91
+ "figure",
92
+ "footer",
93
+ "form",
94
+ "header",
95
+ "main",
96
+ "nav",
97
+ "section",
98
+ "td",
99
+ "th",
100
+ "li",
101
+ "dd",
102
+ "template"
103
+ );
104
+
13
105
  bool is_void_element(hb_string_T tag_name) {
14
106
  if (hb_string_is_empty(tag_name)) { return false; }
15
107
 
16
- hb_string_T void_tags[14] = {
17
- hb_string("area"), hb_string("base"), hb_string("br"), hb_string("col"), hb_string("embed"),
18
- hb_string("hr"), hb_string("img"), hb_string("input"), hb_string("link"), hb_string("meta"),
19
- hb_string("param"), hb_string("source"), hb_string("track"), hb_string("wbr"),
20
- };
21
-
22
- for (size_t i = 0; i < 14; i++) {
108
+ for (size_t i = 0; i < sizeof(void_tags) / sizeof(void_tags[0]); i++) {
23
109
  if (hb_string_equals_case_insensitive(tag_name, void_tags[i])) { return true; }
24
110
  }
25
111
 
26
112
  return false;
27
113
  }
28
114
 
115
+ bool has_optional_end_tag(hb_string_T tag_name) {
116
+ if (hb_string_is_empty(tag_name)) { return false; }
117
+
118
+ for (size_t i = 0; i < sizeof(optional_end_tags) / sizeof(optional_end_tags[0]); i++) {
119
+ if (hb_string_equals_case_insensitive(tag_name, optional_end_tags[i])) { return true; }
120
+ }
121
+
122
+ return false;
123
+ }
124
+
125
+ static bool tag_in_list(hb_string_T tag_name, hb_string_T* list, size_t count) {
126
+ for (size_t i = 0; i < count; i++) {
127
+ if (hb_string_equals_case_insensitive(tag_name, list[i])) { return true; }
128
+ }
129
+
130
+ return false;
131
+ }
132
+
133
+ bool should_implicitly_close(hb_string_T open_tag_name, hb_string_T next_tag_name) {
134
+ if (hb_string_is_empty(open_tag_name)) { return false; }
135
+
136
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("li"))) {
137
+ return hb_string_equals_case_insensitive(next_tag_name, hb_string("li"));
138
+ }
139
+
140
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("dt"))) {
141
+ return hb_string_equals_case_insensitive(next_tag_name, hb_string("dt"))
142
+ || hb_string_equals_case_insensitive(next_tag_name, hb_string("dd"));
143
+ }
144
+
145
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("dd"))) {
146
+ return hb_string_equals_case_insensitive(next_tag_name, hb_string("dd"))
147
+ || hb_string_equals_case_insensitive(next_tag_name, hb_string("dt"));
148
+ }
149
+
150
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("p"))) {
151
+ return tag_in_list(next_tag_name, p_closers, sizeof(p_closers) / sizeof(p_closers[0]));
152
+ }
153
+
154
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("rt"))) {
155
+ return hb_string_equals_case_insensitive(next_tag_name, hb_string("rt"))
156
+ || hb_string_equals_case_insensitive(next_tag_name, hb_string("rp"));
157
+ }
158
+
159
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("rp"))) {
160
+ return hb_string_equals_case_insensitive(next_tag_name, hb_string("rp"))
161
+ || hb_string_equals_case_insensitive(next_tag_name, hb_string("rt"));
162
+ }
163
+
164
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("optgroup"))) {
165
+ return hb_string_equals_case_insensitive(next_tag_name, hb_string("optgroup"));
166
+ }
167
+
168
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("option"))) {
169
+ return hb_string_equals_case_insensitive(next_tag_name, hb_string("option"))
170
+ || hb_string_equals_case_insensitive(next_tag_name, hb_string("optgroup"));
171
+ }
172
+
173
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("thead"))) {
174
+ return hb_string_equals_case_insensitive(next_tag_name, hb_string("tbody"))
175
+ || hb_string_equals_case_insensitive(next_tag_name, hb_string("tfoot"));
176
+ }
177
+
178
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("tbody"))) {
179
+ return hb_string_equals_case_insensitive(next_tag_name, hb_string("tbody"))
180
+ || hb_string_equals_case_insensitive(next_tag_name, hb_string("tfoot"));
181
+ }
182
+
183
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("tr"))) {
184
+ return hb_string_equals_case_insensitive(next_tag_name, hb_string("tr"));
185
+ }
186
+
187
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("td"))) {
188
+ return hb_string_equals_case_insensitive(next_tag_name, hb_string("td"))
189
+ || hb_string_equals_case_insensitive(next_tag_name, hb_string("th"));
190
+ }
191
+
192
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("th"))) {
193
+ return hb_string_equals_case_insensitive(next_tag_name, hb_string("th"))
194
+ || hb_string_equals_case_insensitive(next_tag_name, hb_string("td"));
195
+ }
196
+
197
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("colgroup"))) {
198
+ return !hb_string_equals_case_insensitive(next_tag_name, hb_string("col"));
199
+ }
200
+
201
+ return false;
202
+ }
203
+
204
+ bool parent_closes_element(hb_string_T open_tag_name, hb_string_T parent_close_tag_name) {
205
+ if (hb_string_is_empty(open_tag_name)) { return false; }
206
+
207
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("li"))) {
208
+ return hb_string_equals_case_insensitive(parent_close_tag_name, hb_string("ul"))
209
+ || hb_string_equals_case_insensitive(parent_close_tag_name, hb_string("ol"))
210
+ || hb_string_equals_case_insensitive(parent_close_tag_name, hb_string("menu"));
211
+ }
212
+
213
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("dt"))
214
+ || hb_string_equals_case_insensitive(open_tag_name, hb_string("dd"))) {
215
+ return hb_string_equals_case_insensitive(parent_close_tag_name, hb_string("dl"));
216
+ }
217
+
218
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("p"))) {
219
+ return tag_in_list(parent_close_tag_name, p_parent_closers, sizeof(p_parent_closers) / sizeof(p_parent_closers[0]));
220
+ }
221
+
222
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("rt"))
223
+ || hb_string_equals_case_insensitive(open_tag_name, hb_string("rp"))) {
224
+ return hb_string_equals_case_insensitive(parent_close_tag_name, hb_string("ruby"));
225
+ }
226
+
227
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("optgroup"))
228
+ || hb_string_equals_case_insensitive(open_tag_name, hb_string("option"))) {
229
+ return hb_string_equals_case_insensitive(parent_close_tag_name, hb_string("select"))
230
+ || hb_string_equals_case_insensitive(parent_close_tag_name, hb_string("datalist"));
231
+ }
232
+
233
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("thead"))
234
+ || hb_string_equals_case_insensitive(open_tag_name, hb_string("tbody"))
235
+ || hb_string_equals_case_insensitive(open_tag_name, hb_string("tfoot"))) {
236
+ return hb_string_equals_case_insensitive(parent_close_tag_name, hb_string("table"));
237
+ }
238
+
239
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("tr"))) {
240
+ return hb_string_equals_case_insensitive(parent_close_tag_name, hb_string("thead"))
241
+ || hb_string_equals_case_insensitive(parent_close_tag_name, hb_string("tbody"))
242
+ || hb_string_equals_case_insensitive(parent_close_tag_name, hb_string("tfoot"))
243
+ || hb_string_equals_case_insensitive(parent_close_tag_name, hb_string("table"));
244
+ }
245
+
246
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("td"))
247
+ || hb_string_equals_case_insensitive(open_tag_name, hb_string("th"))) {
248
+ return hb_string_equals_case_insensitive(parent_close_tag_name, hb_string("tr"));
249
+ }
250
+
251
+ if (hb_string_equals_case_insensitive(open_tag_name, hb_string("colgroup"))) {
252
+ return hb_string_equals_case_insensitive(parent_close_tag_name, hb_string("table"));
253
+ }
254
+
255
+ return false;
256
+ }
257
+
29
258
  /**
30
259
  * @brief Creates a closing HTML tag string like "</tag_name>"
31
260
  *
@@ -41,9 +270,9 @@ bool is_void_element(hb_string_T tag_name) {
41
270
  * free(tag.data);
42
271
  * @endcode
43
272
  */
44
- hb_string_T html_closing_tag_string(hb_string_T tag_name) {
273
+ hb_string_T html_closing_tag_string(hb_string_T tag_name, struct hb_allocator* allocator) {
45
274
  hb_buffer_T buffer;
46
- hb_buffer_init(&buffer, tag_name.length + 3);
275
+ hb_buffer_init(&buffer, tag_name.length + 3, allocator);
47
276
 
48
277
  hb_buffer_append_char(&buffer, '<');
49
278
  hb_buffer_append_char(&buffer, '/');
@@ -67,9 +296,9 @@ hb_string_T html_closing_tag_string(hb_string_T tag_name) {
67
296
  * free(tag);
68
297
  * @endcode
69
298
  */
70
- hb_string_T html_self_closing_tag_string(hb_string_T tag_name) {
299
+ hb_string_T html_self_closing_tag_string(hb_string_T tag_name, struct hb_allocator* allocator) {
71
300
  hb_buffer_T buffer;
72
- hb_buffer_init(&buffer, tag_name.length + 4);
301
+ hb_buffer_init(&buffer, tag_name.length + 4, allocator);
73
302
 
74
303
  hb_buffer_append_char(&buffer, '<');
75
304
  hb_buffer_append_string(&buffer, tag_name);
@@ -0,0 +1,36 @@
1
+ #ifndef ATTRIBUTE_EXTRACTION_HELPERS_H
2
+ #define ATTRIBUTE_EXTRACTION_HELPERS_H
3
+
4
+ #include "../../util/hb_allocator.h"
5
+ #include "tag_helper_handler.h"
6
+ #include "tag_helpers.h"
7
+
8
+ #include <prism.h>
9
+
10
+ AST_HTML_ATTRIBUTE_NODE_T* extract_html_attribute_from_assoc(
11
+ pm_assoc_node_t* assoc,
12
+ const uint8_t* source,
13
+ const char* original_source,
14
+ size_t erb_content_offset,
15
+ hb_allocator_T* allocator
16
+ );
17
+
18
+ hb_array_T* extract_html_attributes_from_keyword_hash(
19
+ pm_keyword_hash_node_t* kw_hash,
20
+ const uint8_t* source,
21
+ const char* original_source,
22
+ size_t erb_content_offset,
23
+ hb_allocator_T* allocator
24
+ );
25
+
26
+ bool has_html_attributes_in_call(pm_call_node_t* call_node);
27
+
28
+ hb_array_T* extract_html_attributes_from_call_node(
29
+ pm_call_node_t* call_node,
30
+ const uint8_t* source,
31
+ const char* original_source,
32
+ size_t erb_content_offset,
33
+ hb_allocator_T* allocator
34
+ );
35
+
36
+ #endif
@@ -0,0 +1,43 @@
1
+ #ifndef TAG_HELPER_HANDLER_H
2
+ #define TAG_HELPER_HANDLER_H
3
+
4
+ #include "../../util/hb_allocator.h"
5
+ #include "../../util/hb_array.h"
6
+ #include "../../util/hb_string.h"
7
+ #include <prism.h>
8
+ #include <stdbool.h>
9
+
10
+ typedef struct {
11
+ char* tag_name;
12
+ pm_call_node_t* call_node;
13
+ hb_array_T* attributes;
14
+ char* content;
15
+ bool content_is_ruby_expression;
16
+ bool has_block;
17
+ hb_allocator_T* allocator;
18
+ } tag_helper_info_T;
19
+
20
+ typedef struct {
21
+ const char* name;
22
+ hb_string_T source;
23
+ bool (*detect)(pm_call_node_t* call_node, pm_parser_t* parser);
24
+ char* (*extract_tag_name)(pm_call_node_t* call_node, pm_parser_t* parser, hb_allocator_T* allocator);
25
+ char* (*extract_content)(pm_call_node_t* call_node, pm_parser_t* parser, hb_allocator_T* allocator);
26
+ hb_array_T* (*extract_attributes)(
27
+ pm_call_node_t* call_node,
28
+ const uint8_t* source,
29
+ const char* original_source,
30
+ size_t erb_content_offset
31
+ );
32
+ bool (*supports_block)(void);
33
+ } tag_helper_handler_T;
34
+
35
+ tag_helper_info_T* tag_helper_info_init(hb_allocator_T* allocator);
36
+ void tag_helper_info_free(tag_helper_info_T** info);
37
+
38
+ tag_helper_handler_T* get_tag_helper_handlers(void);
39
+ size_t get_tag_helper_handlers_count(void);
40
+
41
+ char* extract_inline_block_content(pm_call_node_t* call_node, hb_allocator_T* allocator);
42
+
43
+ #endif
@@ -0,0 +1,70 @@
1
+ #ifndef HERB_ANALYZE_TAG_HELPER_NODE_BUILDERS_H
2
+ #define HERB_ANALYZE_TAG_HELPER_NODE_BUILDERS_H
3
+
4
+ #include "../../ast_nodes.h"
5
+ #include "../../position.h"
6
+ #include "../../token_struct.h"
7
+ #include "../../util/hb_allocator.h"
8
+ #include "../../util/hb_array.h"
9
+
10
+ #include <prism.h>
11
+
12
+ token_T* create_synthetic_token(
13
+ hb_allocator_T* allocator,
14
+ const char* value,
15
+ token_type_T type,
16
+ position_T start,
17
+ position_T end
18
+ );
19
+
20
+ AST_HTML_ATTRIBUTE_NAME_NODE_T* create_attribute_name_node(
21
+ const char* name_string,
22
+ position_T start_position,
23
+ position_T end_position,
24
+ hb_allocator_T* allocator
25
+ );
26
+
27
+ AST_HTML_ATTRIBUTE_NODE_T* create_html_attribute_node(
28
+ const char* name_string,
29
+ const char* value_string,
30
+ position_T start_position,
31
+ position_T end_position,
32
+ hb_allocator_T* allocator
33
+ );
34
+
35
+ AST_HTML_ATTRIBUTE_NODE_T* create_html_attribute_with_ruby_literal(
36
+ const char* name_string,
37
+ const char* ruby_content,
38
+ position_T start_position,
39
+ position_T end_position,
40
+ hb_allocator_T* allocator
41
+ );
42
+
43
+ AST_HTML_ATTRIBUTE_NODE_T* create_html_attribute_with_interpolated_value(
44
+ const char* name_string,
45
+ pm_interpolated_string_node_t* interpolated_node,
46
+ position_T start_position,
47
+ position_T end_position,
48
+ hb_allocator_T* allocator
49
+ );
50
+
51
+ hb_array_T* prepend_attribute(hb_array_T* attributes, AST_NODE_T* attribute, hb_allocator_T* allocator);
52
+
53
+ AST_HTML_ATTRIBUTE_NODE_T* create_href_attribute(
54
+ const char* href,
55
+ bool is_ruby_expression,
56
+ position_T start_position,
57
+ position_T end_position,
58
+ hb_allocator_T* allocator
59
+ );
60
+
61
+ void append_body_content_node(
62
+ hb_array_T* body,
63
+ const char* content,
64
+ bool is_ruby_expression,
65
+ position_T start,
66
+ position_T end,
67
+ hb_allocator_T* allocator
68
+ );
69
+
70
+ #endif
@@ -0,0 +1,38 @@
1
+ #ifndef HERB_ANALYZE_TAG_HELPERS_H
2
+ #define HERB_ANALYZE_TAG_HELPERS_H
3
+
4
+ #include "../../ast_nodes.h"
5
+ #include "../../position.h"
6
+ #include "../../util/hb_array.h"
7
+ #include "../analyze.h"
8
+ #include "tag_helper_handler.h"
9
+
10
+ #include <prism.h>
11
+ #include <stdbool.h>
12
+
13
+ typedef struct {
14
+ const pm_node_t* tag_helper_node;
15
+ const uint8_t* source;
16
+ pm_parser_t* parser;
17
+ tag_helper_info_T* info;
18
+ const tag_helper_handler_T* matched_handler;
19
+ bool found;
20
+ } tag_helper_search_data_T;
21
+
22
+ bool search_tag_helper_node(const pm_node_t* node, void* data);
23
+
24
+ position_T prism_location_to_position_with_offset(
25
+ const pm_location_t* pm_location,
26
+ const char* original_source,
27
+ size_t erb_content_offset,
28
+ const uint8_t* erb_content_source
29
+ );
30
+
31
+ position_T byte_offset_to_position(const char* source, size_t offset);
32
+
33
+ size_t calculate_byte_offset_from_position(const char* source, position_T position);
34
+
35
+ void transform_tag_helper_blocks(const AST_NODE_T* node, analyze_ruby_context_T* context);
36
+ bool transform_tag_helper_nodes(const AST_NODE_T* node, void* data);
37
+
38
+ #endif
@@ -1,14 +1,18 @@
1
1
  #ifndef HERB_ANALYZE_H
2
2
  #define HERB_ANALYZE_H
3
3
 
4
+ #include "../ast_nodes.h"
5
+ #include "../parser.h"
6
+ #include "../util/hb_allocator.h"
7
+ #include "../util/hb_array.h"
4
8
  #include "analyzed_ruby.h"
5
- #include "ast_nodes.h"
6
- #include "util/hb_array.h"
7
9
 
8
10
  typedef struct ANALYZE_RUBY_CONTEXT_STRUCT {
9
11
  AST_DOCUMENT_NODE_T* document;
10
12
  AST_NODE_T* parent;
11
13
  hb_array_T* ruby_context_stack;
14
+ hb_allocator_T* allocator;
15
+ const char* source;
12
16
  } analyze_ruby_context_T;
13
17
 
14
18
  typedef enum {
@@ -36,10 +40,16 @@ typedef enum {
36
40
  typedef struct {
37
41
  int loop_depth;
38
42
  int rescue_depth;
43
+ hb_allocator_T* allocator;
39
44
  } invalid_erb_context_T;
40
45
 
41
- void herb_analyze_parse_errors(AST_DOCUMENT_NODE_T* document, const char* source);
42
- void herb_analyze_parse_tree(AST_DOCUMENT_NODE_T* document, const char* source);
46
+ void herb_analyze_parse_errors(AST_DOCUMENT_NODE_T* document, const char* source, hb_allocator_T* allocator);
47
+ void herb_analyze_parse_tree(
48
+ AST_DOCUMENT_NODE_T* document,
49
+ const char* source,
50
+ const parser_options_T* options,
51
+ hb_allocator_T* allocator
52
+ );
43
53
 
44
54
  hb_array_T* rewrite_node_array(AST_NODE_T* node, hb_array_T* array, analyze_ruby_context_T* context);
45
55
  bool transform_erb_nodes(const AST_NODE_T* node, void* data);
@@ -1,8 +1,8 @@
1
1
  #ifndef HERB_ANALYZED_RUBY_H
2
2
  #define HERB_ANALYZED_RUBY_H
3
3
 
4
- #include "util/hb_array.h"
5
- #include "util/hb_string.h"
4
+ #include "../util/hb_array.h"
5
+ #include "../util/hb_string.h"
6
6
 
7
7
  #include <prism.h>
8
8
 
@@ -35,6 +35,6 @@ typedef struct ANALYZED_RUBY_STRUCT {
35
35
 
36
36
  analyzed_ruby_T* init_analyzed_ruby(hb_string_T source);
37
37
  void free_analyzed_ruby(analyzed_ruby_T* analyzed);
38
- const char* erb_keyword_from_analyzed_ruby(const analyzed_ruby_T* analyzed);
38
+ hb_string_T erb_keyword_from_analyzed_ruby(const analyzed_ruby_T* analyzed);
39
39
 
40
40
  #endif
@@ -0,0 +1,27 @@
1
+ #ifndef HERB_ANALYZE_BUILDERS_H
2
+ #define HERB_ANALYZE_BUILDERS_H
3
+
4
+ #include "../ast_nodes.h"
5
+ #include "../location.h"
6
+ #include "../position.h"
7
+ #include "../util/hb_allocator.h"
8
+ #include "analyze.h"
9
+
10
+ position_T erb_content_end_position(const AST_ERB_CONTENT_NODE_T* erb_node);
11
+
12
+ location_T* compute_then_keyword(
13
+ AST_ERB_CONTENT_NODE_T* erb_node,
14
+ control_type_t control_type,
15
+ hb_allocator_T* allocator
16
+ );
17
+
18
+ AST_NODE_T* create_control_node(
19
+ AST_ERB_CONTENT_NODE_T* erb_node,
20
+ hb_array_T* children,
21
+ AST_NODE_T* subsequent,
22
+ AST_ERB_END_NODE_T* end_node,
23
+ control_type_t control_type,
24
+ hb_allocator_T* allocator
25
+ );
26
+
27
+ #endif
@@ -0,0 +1,9 @@
1
+ #ifndef HERB_ANALYZE_CONDITIONAL_ELEMENTS_H
2
+ #define HERB_ANALYZE_CONDITIONAL_ELEMENTS_H
3
+
4
+ #include "../ast_nodes.h"
5
+ #include "../util/hb_allocator.h"
6
+
7
+ void herb_transform_conditional_elements(AST_DOCUMENT_NODE_T* document, hb_allocator_T* allocator);
8
+
9
+ #endif
@@ -0,0 +1,9 @@
1
+ #ifndef HERB_ANALYZE_CONDITIONAL_OPEN_TAGS_H
2
+ #define HERB_ANALYZE_CONDITIONAL_OPEN_TAGS_H
3
+
4
+ #include "../ast_nodes.h"
5
+ #include "../util/hb_allocator.h"
6
+
7
+ void herb_transform_conditional_open_tags(AST_DOCUMENT_NODE_T* document, hb_allocator_T* allocator);
8
+
9
+ #endif
@@ -0,0 +1,14 @@
1
+ #ifndef HERB_ANALYZE_CONTROL_TYPE_H
2
+ #define HERB_ANALYZE_CONTROL_TYPE_H
3
+
4
+ #include "../ast_nodes.h"
5
+ #include "analyze.h"
6
+
7
+ #include <stdbool.h>
8
+
9
+ control_type_t detect_control_type(AST_ERB_CONTENT_NODE_T* erb_node);
10
+ bool is_subsequent_type(control_type_t parent_type, control_type_t child_type);
11
+ bool is_terminator_type(control_type_t parent_type, control_type_t child_type);
12
+ bool is_compound_control_type(control_type_t type);
13
+
14
+ #endif
@@ -4,8 +4,9 @@
4
4
  #include <prism.h>
5
5
  #include <stdbool.h>
6
6
 
7
+ #include "../ast_node.h"
8
+ #include "../util/hb_allocator.h"
7
9
  #include "analyzed_ruby.h"
8
- #include "ast_node.h"
9
10
 
10
11
  bool has_if_node(analyzed_ruby_T* analyzed);
11
12
  bool has_elsif_node(analyzed_ruby_T* analyzed);
@@ -26,6 +27,7 @@ bool has_ensure_node(analyzed_ruby_T* analyzed);
26
27
  bool has_unless_node(analyzed_ruby_T* analyzed);
27
28
  bool has_yield_node(analyzed_ruby_T* analyzed);
28
29
  bool has_then_keyword(analyzed_ruby_T* analyzed);
30
+ bool has_inline_case_condition(analyzed_ruby_T* analyzed);
29
31
 
30
32
  bool has_error_message(analyzed_ruby_T* anlayzed, const char* message);
31
33
 
@@ -58,6 +60,6 @@ bool search_unexpected_in_nodes(analyzed_ruby_T* analyzed);
58
60
  bool search_unexpected_rescue_nodes(analyzed_ruby_T* analyzed);
59
61
  bool search_unexpected_when_nodes(analyzed_ruby_T* analyzed);
60
62
 
61
- void check_erb_node_for_missing_end(const AST_NODE_T* node);
63
+ void check_erb_node_for_missing_end(const AST_NODE_T* node, hb_allocator_T* allocator);
62
64
 
63
65
  #endif
@@ -0,0 +1,11 @@
1
+ #ifndef HERB_ANALYZE_INVALID_STRUCTURES_H
2
+ #define HERB_ANALYZE_INVALID_STRUCTURES_H
3
+
4
+ #include "../ast_node.h"
5
+ #include "analyze.h"
6
+
7
+ #include <stdbool.h>
8
+
9
+ bool detect_invalid_erb_structures(const AST_NODE_T* node, void* data);
10
+
11
+ #endif
@@ -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
@@ -0,0 +1,11 @@
1
+ #ifndef HERB_ANALYZE_RENDER_NODES_H
2
+ #define HERB_ANALYZE_RENDER_NODES_H
3
+
4
+ #include "../ast_nodes.h"
5
+ #include "analyze.h"
6
+
7
+ #include <stdbool.h>
8
+
9
+ bool transform_render_nodes(const AST_NODE_T* node, void* data);
10
+
11
+ #endif