herb 0.11.0-aarch64-linux-gnu → 0.11.2-aarch64-linux-gnu

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +4 -2
  3. data/config.yml +9 -0
  4. data/ext/herb/extconf.rb +8 -31
  5. data/ext/herb/nodes.c +90 -73
  6. data/ext/herb/parser_options_helpers.c +26 -0
  7. data/lib/herb/3.2/herb.so +0 -0
  8. data/lib/herb/3.3/herb.so +0 -0
  9. data/lib/herb/3.4/herb.so +0 -0
  10. data/lib/herb/4.0/herb.so +0 -0
  11. data/lib/herb/analysis/partial_index.rb +1 -1
  12. data/lib/herb/analysis/partial_resolution.rb +27 -0
  13. data/lib/herb/ast/helpers.rb +1 -1
  14. data/lib/herb/ast/nodes.rb +32 -6
  15. data/lib/herb/bootstrap.rb +6 -2
  16. data/lib/herb/configuration.rb +11 -1
  17. data/lib/herb/dev/classifier.rb +1 -1
  18. data/lib/herb/dev/runner.rb +6 -1
  19. data/lib/herb/engine/compiler.rb +52 -19
  20. data/lib/herb/engine/slots/dynamics_compiler.rb +63 -14
  21. data/lib/herb/engine/slots/markers.rb +24 -0
  22. data/lib/herb/engine/slots/state_compiler.rb +1 -2
  23. data/lib/herb/engine/slots/subtree_compiler.rb +1 -1
  24. data/lib/herb/engine/slots/visitor.rb +71 -32
  25. data/lib/herb/engine/visitors/instrumentation_visitor.rb +18 -6
  26. data/lib/herb/engine.rb +0 -2
  27. data/lib/herb/parser_options.rb +6 -3
  28. data/lib/herb/project.rb +19 -8
  29. data/lib/herb/version.rb +1 -1
  30. data/lib/herb.rb +1 -1
  31. data/sig/herb/analysis/partial_resolution.rbs +8 -0
  32. data/sig/herb/ast/nodes.rbs +10 -4
  33. data/sig/herb/bootstrap.rbs +2 -0
  34. data/sig/herb/configuration.rbs +3 -0
  35. data/sig/herb/dev/runner.rbs +3 -0
  36. data/sig/herb/engine/compiler.rbs +14 -3
  37. data/sig/herb/engine/slots/dynamics_compiler.rbs +27 -7
  38. data/sig/herb/engine/slots/markers.rbs +14 -0
  39. data/sig/herb/engine/slots/visitor.rbs +31 -13
  40. data/sig/herb/engine/visitors/instrumentation_visitor.rbs +5 -1
  41. data/sig/herb/parser_options.rbs +6 -4
  42. data/sig/herb.rbs +2 -2
  43. data/sig/serialized_ast_nodes.rbs +1 -0
  44. data/src/analyze/action_view/attribute_extraction_helpers.c +40 -21
  45. data/src/analyze/action_view/generated_handlers.c +36 -36
  46. data/src/analyze/action_view/image_tag.c +7 -3
  47. data/src/analyze/action_view/javascript_include_tag.c +6 -3
  48. data/src/analyze/action_view/link_to.c +23 -23
  49. data/src/analyze/action_view/registry.c +7 -3
  50. data/src/analyze/action_view/tag_helper_node_builders.c +12 -16
  51. data/src/analyze/action_view/tag_helpers.c +215 -110
  52. data/src/analyze/action_view/turbo_frame_tag.c +5 -4
  53. data/src/analyze/analyze.c +41 -45
  54. data/src/analyze/analyze_helpers.c +240 -405
  55. data/src/analyze/analyzed_ruby.c +10 -7
  56. data/src/analyze/builders.c +1 -0
  57. data/src/analyze/control_type.c +46 -29
  58. data/src/analyze/herb_directives.c +16 -20
  59. data/src/analyze/iteration_nodes.c +69 -24
  60. data/src/analyze/parse_errors.c +32 -22
  61. data/src/analyze/postfix_conditionals.c +23 -13
  62. data/src/analyze/prism_annotate.c +56 -32
  63. data/src/analyze/render_nodes.c +51 -41
  64. data/src/analyze/strict_locals.c +14 -15
  65. data/src/analyze/ternary_conditionals.c +14 -10
  66. data/src/ast/ast_nodes.c +3 -1
  67. data/src/ast/ast_pretty_print.c +5 -1
  68. data/src/extract.c +204 -143
  69. data/src/herb.c +10 -8
  70. data/src/include/analyze/action_view/tag_helper_handler.h +1 -1
  71. data/src/include/analyze/action_view/tag_helper_node_builders.h +1 -0
  72. data/src/include/analyze/action_view/tag_helpers.h +1 -1
  73. data/src/include/analyze/analyze.h +3 -24
  74. data/src/include/analyze/analyzed_ruby.h +29 -2
  75. data/src/include/analyze/helpers.h +7 -27
  76. data/src/include/ast/ast_nodes.h +2 -1
  77. data/src/include/herb.h +3 -2
  78. data/src/include/lexer/lexer.h +1 -0
  79. data/src/include/parser/parser_options.h +5 -0
  80. data/src/include/prism/herb_prism_node.h +6 -1
  81. data/src/include/prism/prism_context.h +12 -12
  82. data/src/include/prism/prism_helpers.h +30 -0
  83. data/src/include/prism_version.h +11 -0
  84. data/src/include/version.h +1 -1
  85. data/src/lexer.c +32 -0
  86. data/src/parser/parser_helpers.c +1 -2
  87. data/src/parser.c +6 -7
  88. data/src/parser_options_defaults.c +1 -0
  89. data/src/prism/prism_helpers.c +167 -42
  90. data/src/prism/ruby_parser.c +20 -20
  91. data/templates/ext/herb/nodes.c.erb +5 -5
  92. data/templates/ext/herb/parser_options_helpers.c.erb +33 -0
  93. data/templates/java/nodes.c.erb +6 -6
  94. data/templates/java/parser_options_helpers.c.erb +41 -2
  95. data/templates/java/parser_options_helpers.h.erb +2 -1
  96. data/templates/javascript/packages/core/src/nodes.ts.erb +21 -1
  97. data/templates/javascript/packages/node/extension/nodes.cpp.erb +5 -5
  98. data/templates/javascript/packages/node/extension/parser_options_helpers.cpp.erb +34 -2
  99. data/templates/javascript/packages/node/extension/parser_options_helpers.h.erb +1 -1
  100. data/templates/lib/herb/parser_options.rb.erb +1 -1
  101. data/templates/rust/src/ast/nodes.rs.erb +1 -4
  102. data/templates/rust/src/prism/generated_deserialize.rs.erb +90 -44
  103. data/templates/rust/src/prism/generated_prettyprint.rs.erb +18 -27
  104. data/templates/src/analyze/action_view/generated_handlers.c.erb +23 -22
  105. data/templates/src/include/parser/parser_options.h.erb +10 -0
  106. data/templates/src/include/prism_version.h.erb +17 -0
  107. data/templates/src/parser_options_defaults.c.erb +1 -1
  108. data/templates/template.rb +17 -2
  109. data/templates/wasm/nodes.cpp.erb +8 -18
  110. data/templates/wasm/parser_options_helpers.cpp.erb +24 -0
  111. data/vendor/prism/Rakefile +76 -7
  112. data/vendor/prism/config.yml +174 -161
  113. data/vendor/prism/include/prism/arena.h +45 -0
  114. data/vendor/prism/include/prism/arena.hpp +42 -0
  115. data/vendor/prism/include/prism/ast.h +2738 -611
  116. data/vendor/prism/include/prism/ast.hpp +641 -0
  117. data/vendor/prism/include/prism/buffer.h +60 -0
  118. data/vendor/prism/include/prism/buffer.hpp +55 -0
  119. data/vendor/prism/include/prism/comments.h +72 -0
  120. data/vendor/prism/include/prism/compiler/accel.h +26 -0
  121. data/vendor/prism/include/prism/compiler/align.h +36 -0
  122. data/vendor/prism/include/prism/compiler/assume.h +25 -0
  123. data/vendor/prism/include/prism/compiler/branch.h +26 -0
  124. data/vendor/prism/include/prism/compiler/bswap.h +46 -0
  125. data/vendor/prism/include/prism/compiler/cplusplus.hpp +16 -0
  126. data/vendor/prism/include/prism/compiler/endianness.h +34 -0
  127. data/vendor/prism/include/prism/compiler/exceptions.hpp +17 -0
  128. data/vendor/prism/include/prism/compiler/exported.h +24 -0
  129. data/vendor/prism/include/prism/compiler/fallthrough.h +22 -0
  130. data/vendor/prism/include/prism/compiler/filesystem.h +32 -0
  131. data/vendor/prism/include/prism/compiler/flex_array.h +19 -0
  132. data/vendor/prism/include/prism/compiler/force_inline.h +21 -0
  133. data/vendor/prism/include/prism/compiler/format.h +27 -0
  134. data/vendor/prism/include/prism/compiler/inline.h +17 -0
  135. data/vendor/prism/include/prism/compiler/lifetimebound.hpp +25 -0
  136. data/vendor/prism/include/prism/compiler/nodiscard.h +22 -0
  137. data/vendor/prism/include/prism/compiler/nonnull.h +18 -0
  138. data/vendor/prism/include/prism/compiler/unused.h +18 -0
  139. data/vendor/prism/include/prism/constant_pool.h +106 -0
  140. data/vendor/prism/include/prism/diagnostic.h +55 -402
  141. data/vendor/prism/include/prism/errors_format.h +61 -0
  142. data/vendor/prism/include/prism/excludes.h +29 -0
  143. data/vendor/prism/include/prism/integer.h +41 -0
  144. data/vendor/prism/include/prism/internal/allocator.h +68 -0
  145. data/vendor/prism/include/prism/internal/allocator_debug.h +88 -0
  146. data/vendor/prism/include/prism/internal/arena.h +108 -0
  147. data/vendor/prism/include/prism/internal/bit.h +42 -0
  148. data/vendor/prism/include/prism/internal/buffer.h +94 -0
  149. data/vendor/prism/include/prism/internal/char.h +145 -0
  150. data/vendor/prism/include/prism/internal/comments.h +54 -0
  151. data/vendor/prism/include/prism/internal/constant_pool.h +152 -0
  152. data/vendor/prism/include/prism/internal/diagnostic.h +389 -0
  153. data/vendor/prism/include/prism/{encoding.h → internal/encoding.h} +27 -68
  154. data/vendor/prism/include/prism/internal/integer.h +68 -0
  155. data/vendor/prism/include/prism/internal/isinf.h +16 -0
  156. data/vendor/prism/include/prism/internal/line_offset_list.h +34 -0
  157. data/vendor/prism/include/prism/{util/pm_list.h → internal/list.h} +11 -52
  158. data/vendor/prism/include/prism/internal/magic_comments.h +23 -0
  159. data/vendor/prism/include/prism/internal/memchr.h +15 -0
  160. data/vendor/prism/include/prism/internal/node.h +42 -0
  161. data/vendor/prism/include/prism/internal/options.h +232 -0
  162. data/vendor/prism/include/prism/internal/parser.h +1015 -0
  163. data/vendor/prism/include/prism/internal/regexp.h +26 -0
  164. data/vendor/prism/include/prism/internal/serialize.h +39 -0
  165. data/vendor/prism/include/prism/internal/source.h +72 -0
  166. data/vendor/prism/include/prism/internal/static_literals.h +60 -0
  167. data/vendor/prism/include/prism/internal/stringy.h +30 -0
  168. data/vendor/prism/include/prism/{util/pm_strncasecmp.h → internal/strncasecmp.h} +3 -17
  169. data/vendor/prism/include/prism/{util/pm_strpbrk.h → internal/strpbrk.h} +7 -20
  170. data/vendor/prism/include/prism/internal/tokens.h +11 -0
  171. data/vendor/prism/include/prism/internal/xxh3.h +16 -0
  172. data/vendor/prism/include/prism/json.h +40 -0
  173. data/vendor/prism/include/prism/line_offset_list.h +69 -0
  174. data/vendor/prism/include/prism/magic_comments.h +53 -0
  175. data/vendor/prism/include/prism/node.h +59 -49
  176. data/vendor/prism/include/prism/node.hpp +272 -0
  177. data/vendor/prism/include/prism/node_type.hpp +38 -0
  178. data/vendor/prism/include/prism/options.h +154 -279
  179. data/vendor/prism/include/prism/options.hpp +43 -0
  180. data/vendor/prism/include/prism/parser.h +367 -870
  181. data/vendor/prism/include/prism/parser.hpp +274 -0
  182. data/vendor/prism/include/prism/prettyprint.h +14 -9
  183. data/vendor/prism/include/prism/serialize.h +123 -0
  184. data/vendor/prism/include/prism/source.h +163 -0
  185. data/vendor/prism/include/prism/stream.h +36 -0
  186. data/vendor/prism/include/prism/string_query.h +82 -0
  187. data/vendor/prism/include/prism/stringy.h +61 -0
  188. data/vendor/prism/include/prism/stringy.hpp +31 -0
  189. data/vendor/prism/include/prism/version.h +20 -3
  190. data/vendor/prism/include/prism.h +35 -320
  191. data/vendor/prism/include/prism.hpp +24 -0
  192. data/vendor/prism/src/arena.c +122 -0
  193. data/vendor/prism/src/{util/pm_buffer.c → buffer.c} +53 -21
  194. data/vendor/prism/src/{util/pm_char.c → char.c} +28 -57
  195. data/vendor/prism/src/comments.c +455 -0
  196. data/vendor/prism/src/constant_pool.c +406 -0
  197. data/vendor/prism/src/diagnostic.c +120 -68
  198. data/vendor/prism/src/encoding.c +8 -3
  199. data/vendor/prism/src/errors_format.c +519 -0
  200. data/vendor/prism/src/{util/pm_integer.c → integer.c} +38 -22
  201. data/vendor/prism/src/json.c +5733 -0
  202. data/vendor/prism/src/line_offset_list.c +100 -0
  203. data/vendor/prism/src/list.c +24 -0
  204. data/vendor/prism/src/{util/pm_memchr.c → memchr.c} +8 -6
  205. data/vendor/prism/src/node.c +3465 -7787
  206. data/vendor/prism/src/options.c +161 -54
  207. data/vendor/prism/src/parser.c +371 -0
  208. data/vendor/prism/src/prettyprint.c +421 -354
  209. data/vendor/prism/src/prism.c +8522 -7280
  210. data/vendor/prism/src/regexp.c +960 -45
  211. data/vendor/prism/src/serialize.c +2434 -2048
  212. data/vendor/prism/src/source.c +524 -0
  213. data/vendor/prism/src/static_literals.c +303 -360
  214. data/vendor/prism/src/string_query.c +180 -0
  215. data/vendor/prism/src/stringy.c +61 -0
  216. data/vendor/prism/src/{util/pm_strncasecmp.c → strncasecmp.c} +5 -4
  217. data/vendor/prism/src/strpbrk.c +447 -0
  218. data/vendor/prism/src/{token_type.c → tokens.c} +39 -18
  219. data/vendor/prism/src/xxh3.c +292 -0
  220. data/vendor/prism/templates/ext/prism/api_node.c.erb +58 -44
  221. data/vendor/prism/templates/include/prism/ast.h.erb +67 -17
  222. data/vendor/prism/templates/include/prism/ast.hpp.erb +31 -0
  223. data/vendor/prism/templates/include/prism/internal/diagnostic.h.erb +60 -0
  224. data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/AbstractNodeVisitor.java.erb +1 -1
  225. data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/Loader.java.erb +232 -133
  226. data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/Nodes.java.erb +62 -23
  227. data/vendor/prism/templates/javascript/src/deserialize.js.erb +153 -146
  228. data/vendor/prism/templates/javascript/src/nodes.js.erb +4 -9
  229. data/vendor/prism/templates/lib/prism/compiler.rb.erb +14 -5
  230. data/vendor/prism/templates/lib/prism/dispatcher.rb.erb +20 -12
  231. data/vendor/prism/templates/lib/prism/dot_visitor.rb.erb +37 -11
  232. data/vendor/prism/templates/lib/prism/dsl.rb.erb +43 -4
  233. data/vendor/prism/templates/lib/prism/inspect_visitor.rb.erb +26 -10
  234. data/vendor/prism/templates/lib/prism/mutation_compiler.rb.erb +5 -2
  235. data/vendor/prism/templates/lib/prism/node.rb.erb +283 -105
  236. data/vendor/prism/templates/lib/prism/reflection.rb.erb +11 -2
  237. data/vendor/prism/templates/lib/prism/serialize.rb.erb +291 -134
  238. data/vendor/prism/templates/lib/prism/visitor.rb.erb +18 -0
  239. data/vendor/prism/templates/src/diagnostic.c.erb +114 -63
  240. data/vendor/prism/templates/src/json.c.erb +130 -0
  241. data/vendor/prism/templates/src/node.c.erb +79 -236
  242. data/vendor/prism/templates/src/prettyprint.c.erb +24 -13
  243. data/vendor/prism/templates/src/serialize.c.erb +369 -183
  244. data/vendor/prism/templates/src/{token_type.c.erb → tokens.c.erb} +22 -11
  245. data/vendor/prism/templates/template.rb +193 -91
  246. metadata +100 -42
  247. data/vendor/prism/include/prism/defines.h +0 -260
  248. data/vendor/prism/include/prism/pack.h +0 -163
  249. data/vendor/prism/include/prism/regexp.h +0 -43
  250. data/vendor/prism/include/prism/static_literals.h +0 -121
  251. data/vendor/prism/include/prism/util/pm_buffer.h +0 -236
  252. data/vendor/prism/include/prism/util/pm_char.h +0 -204
  253. data/vendor/prism/include/prism/util/pm_constant_pool.h +0 -218
  254. data/vendor/prism/include/prism/util/pm_integer.h +0 -130
  255. data/vendor/prism/include/prism/util/pm_memchr.h +0 -29
  256. data/vendor/prism/include/prism/util/pm_newline_list.h +0 -113
  257. data/vendor/prism/include/prism/util/pm_string.h +0 -200
  258. data/vendor/prism/src/pack.c +0 -509
  259. data/vendor/prism/src/util/pm_constant_pool.c +0 -342
  260. data/vendor/prism/src/util/pm_list.c +0 -49
  261. data/vendor/prism/src/util/pm_newline_list.c +0 -125
  262. data/vendor/prism/src/util/pm_string.c +0 -381
  263. data/vendor/prism/src/util/pm_strpbrk.c +0 -206
  264. data/vendor/prism/templates/include/prism/diagnostic.h.erb +0 -130
  265. data/vendor/prism/templates/rbi/prism/dsl.rbi.erb +0 -68
  266. data/vendor/prism/templates/rbi/prism/node.rbi.erb +0 -167
  267. data/vendor/prism/templates/rbi/prism/visitor.rbi.erb +0 -18
  268. data/vendor/prism/templates/sig/prism/_private/dot_visitor.rbs.erb +0 -45
  269. data/vendor/prism/templates/sig/prism/dsl.rbs.erb +0 -31
  270. data/vendor/prism/templates/sig/prism/mutation_compiler.rbs.erb +0 -7
  271. data/vendor/prism/templates/sig/prism/node.rbs.erb +0 -136
  272. data/vendor/prism/templates/sig/prism/visitor.rbs.erb +0 -17
  273. data/vendor/prism/templates/sig/prism.rbs.erb +0 -92
@@ -9,6 +9,7 @@
9
9
  #include "../include/lib/hb_array.h"
10
10
  #include "../include/lib/hb_string.h"
11
11
  #include "../include/prism/herb_prism_node.h"
12
+ #include "../include/prism/prism_helpers.h"
12
13
  #include "../include/visitor.h"
13
14
 
14
15
  #include <prism.h>
@@ -27,11 +28,17 @@ static pm_node_t* find_postfix_conditional_statement(analyzed_ruby_T* analyzed)
27
28
  if (statement->type == PM_IF_NODE) {
28
29
  pm_if_node_t* if_node = (pm_if_node_t*) statement;
29
30
 
30
- if (if_node->if_keyword_loc.start != NULL && if_node->end_keyword_loc.start == NULL) { return statement; }
31
+ if (herb_prism_location_assigned(if_node->if_keyword_loc)
32
+ && !herb_prism_location_assigned(if_node->end_keyword_loc)) {
33
+ return statement;
34
+ }
31
35
  } else if (statement->type == PM_UNLESS_NODE) {
32
36
  pm_unless_node_t* unless_node = (pm_unless_node_t*) statement;
33
37
 
34
- if (unless_node->keyword_loc.start != NULL && unless_node->end_keyword_loc.start == NULL) { return statement; }
38
+ if (herb_prism_location_assigned(unless_node->unless_keyword_loc)
39
+ && !herb_prism_location_assigned(unless_node->end_keyword_loc)) {
40
+ return statement;
41
+ }
35
42
  }
36
43
 
37
44
  return NULL;
@@ -55,11 +62,11 @@ static body_info_T extract_statements_body_info(
55
62
  pm_node_t* first = statements->body.nodes[0];
56
63
  pm_node_t* last = statements->body.nodes[statements->body.size - 1];
57
64
 
58
- const uint8_t* start = first->location.start;
59
- const uint8_t* end = last->location.end;
65
+ const uint8_t* parser_start = pm_parser_start(analyzed->parser);
66
+ size_t source_length = (size_t) (pm_parser_end(analyzed->parser) - parser_start);
60
67
 
61
- const uint8_t* parser_start = analyzed->parser.start;
62
- size_t source_length = (size_t) (analyzed->parser.end - parser_start);
68
+ const uint8_t* start = herb_prism_location_start_pointer(parser_start, first->location);
69
+ const uint8_t* end = herb_prism_location_end_pointer(parser_start, last->location);
63
70
 
64
71
  if (start < parser_start || end > parser_start + source_length) { return info; }
65
72
 
@@ -98,13 +105,13 @@ static body_info_T extract_body_info(
98
105
 
99
106
  hb_allocator_dealloc(allocator, (void*) info.source);
100
107
 
101
- info.source = hb_allocator_strndup(allocator, (const char*) analyzed->parser.start, info.length);
108
+ info.source = hb_allocator_strndup(allocator, (const char*) pm_parser_start(analyzed->parser), info.length);
102
109
  }
103
110
 
104
111
  return info;
105
112
  }
106
113
 
107
- static char* extract_condition_source(pm_node_t* conditional_node, hb_allocator_T* allocator) {
114
+ static char* extract_condition_source(const uint8_t* source, pm_node_t* conditional_node, hb_allocator_T* allocator) {
108
115
  pm_node_t* predicate = NULL;
109
116
 
110
117
  if (conditional_node->type == PM_IF_NODE) {
@@ -115,9 +122,11 @@ static char* extract_condition_source(pm_node_t* conditional_node, hb_allocator_
115
122
 
116
123
  if (!predicate) { return NULL; }
117
124
 
118
- size_t length = (size_t) (predicate->location.end - predicate->location.start);
119
-
120
- return hb_allocator_strndup(allocator, (const char*) predicate->location.start, length);
125
+ return hb_allocator_strndup(
126
+ allocator,
127
+ (const char*) (source + predicate->location.start),
128
+ predicate->location.length
129
+ );
121
130
  }
122
131
 
123
132
  static const char* condition_keyword(pm_node_t* conditional_node) {
@@ -150,7 +159,7 @@ static pm_if_node_t* find_nested_ternary(pm_node_t* conditional_node) {
150
159
 
151
160
  pm_if_node_t* if_node = (pm_if_node_t*) body_node;
152
161
 
153
- if (if_node->if_keyword_loc.start == NULL && if_node->subsequent != NULL) { return if_node; }
162
+ if (!herb_prism_location_assigned(if_node->if_keyword_loc) && if_node->subsequent != NULL) { return if_node; }
154
163
 
155
164
  return NULL;
156
165
  }
@@ -215,7 +224,8 @@ static AST_NODE_T* transform_conditional(
215
224
  static_output_node_type_T static_node_type,
216
225
  hb_allocator_T* allocator
217
226
  ) {
218
- char* condition_source = extract_condition_source(conditional_node, allocator);
227
+ char* condition_source =
228
+ extract_condition_source(pm_parser_start(erb_node->analyzed_ruby->parser), conditional_node, allocator);
219
229
  if (!condition_source) { return NULL; }
220
230
 
221
231
  const char* keyword = condition_keyword(conditional_node);
@@ -8,6 +8,7 @@
8
8
  #include "../include/parser/parser.h"
9
9
  #include "../include/prism/herb_prism_node.h"
10
10
  #include "../include/prism/prism_context.h"
11
+ #include "../include/prism/prism_helpers.h"
11
12
  #include "../include/visitor.h"
12
13
 
13
14
  #include <prism.h>
@@ -170,6 +171,7 @@ static token_T* get_content_token(const AST_NODE_T* node) {
170
171
  switch (node->type) {
171
172
  case AST_ERB_CONTENT_NODE: return ((AST_ERB_CONTENT_NODE_T*) node)->content;
172
173
  case AST_ERB_RENDER_NODE: return ((AST_ERB_RENDER_NODE_T*) node)->content;
174
+ case AST_ERB_YIELD_NODE: return ((AST_ERB_YIELD_NODE_T*) node)->content;
173
175
  case AST_ERB_IF_NODE: return ((AST_ERB_IF_NODE_T*) node)->content;
174
176
  case AST_ERB_BLOCK_NODE: return ((AST_ERB_BLOCK_NODE_T*) node)->content;
175
177
  case AST_ERB_ITERATION_BLOCK_NODE: return ((AST_ERB_ITERATION_BLOCK_NODE_T*) node)->content;
@@ -188,6 +190,7 @@ static void set_prism_node(AST_NODE_T* node, herb_prism_node_T prism_ref) {
188
190
  switch (node->type) {
189
191
  case AST_ERB_CONTENT_NODE: ((AST_ERB_CONTENT_NODE_T*) node)->prism_node = prism_ref; break;
190
192
  case AST_ERB_RENDER_NODE: ((AST_ERB_RENDER_NODE_T*) node)->prism_node = prism_ref; break;
193
+ case AST_ERB_YIELD_NODE: ((AST_ERB_YIELD_NODE_T*) node)->prism_node = prism_ref; break;
191
194
  case AST_ERB_IF_NODE: ((AST_ERB_IF_NODE_T*) node)->prism_node = prism_ref; break;
192
195
  case AST_ERB_BLOCK_NODE: ((AST_ERB_BLOCK_NODE_T*) node)->prism_node = prism_ref; break;
193
196
  case AST_ERB_ITERATION_BLOCK_NODE: ((AST_ERB_ITERATION_BLOCK_NODE_T*) node)->prism_node = prism_ref; break;
@@ -202,6 +205,12 @@ static void set_prism_node(AST_NODE_T* node, herb_prism_node_T prism_ref) {
202
205
  }
203
206
  }
204
207
 
208
+ static size_t prism_node_start(hb_narray_T* node_list, size_t index) {
209
+ pm_node_t* prism_node = *(pm_node_t**) hb_narray_get(node_list, index);
210
+
211
+ return prism_node->location.start;
212
+ }
213
+
205
214
  static herb_prism_node_T find_prism_node_for_herb_node(
206
215
  pm_parser_t* parser,
207
216
  hb_narray_T* node_list,
@@ -215,17 +224,29 @@ static herb_prism_node_T find_prism_node_for_herb_node(
215
224
  uint32_t content_from = content->range.from;
216
225
  uint32_t content_to = content->range.to;
217
226
 
218
- for (size_t i = 0; i < hb_narray_size(node_list); i++) {
219
- pm_node_t* prism_node = *(pm_node_t**) hb_narray_get(node_list, i);
220
- size_t prism_start = (size_t) (prism_node->location.start - parser->start);
227
+ size_t low = 0;
228
+ size_t high = hb_narray_size(node_list);
221
229
 
222
- if (prism_start >= content_from && prism_start < content_to) {
223
- result.node = prism_node;
224
- result.parser = parser;
225
- break;
230
+ while (low < high) {
231
+ size_t middle = low + (high - low) / 2;
232
+
233
+ if (prism_node_start(node_list, middle) < content_from) {
234
+ low = middle + 1;
235
+ } else {
236
+ high = middle;
226
237
  }
227
238
  }
228
239
 
240
+ if (low >= hb_narray_size(node_list) || prism_node_start(node_list, low) >= content_to) { return result; }
241
+
242
+ pm_node_t* prism_node = *(pm_node_t**) hb_narray_get(node_list, low);
243
+ size_t prism_end = (size_t) prism_node->location.start + prism_node->location.length;
244
+
245
+ result.node = prism_node;
246
+ result.parser = parser;
247
+ result.source_start = content_from;
248
+ result.source_end = prism_end > content_to ? (uint32_t) prism_end : content_to;
249
+
229
250
  return result;
230
251
  }
231
252
 
@@ -237,7 +258,8 @@ static bool annotate_visitor(const AST_NODE_T* node, void* data) {
237
258
  pm_parser_t* parser;
238
259
  hb_narray_T* node_list;
239
260
 
240
- if (node->type == AST_ERB_CONTENT_NODE || node->type == AST_ERB_RENDER_NODE || context->prism_nodes_deep) {
261
+ if (node->type == AST_ERB_CONTENT_NODE || node->type == AST_ERB_RENDER_NODE || node->type == AST_ERB_YIELD_NODE
262
+ || context->prism_nodes_deep) {
241
263
  parser = context->parser;
242
264
  node_list = context->node_list;
243
265
  } else {
@@ -253,7 +275,9 @@ static bool annotate_visitor(const AST_NODE_T* node, void* data) {
253
275
  }
254
276
 
255
277
  static bool collect_content_ranges_visitor(const AST_NODE_T* node, void* data) {
256
- if (node->type != AST_ERB_CONTENT_NODE && node->type != AST_ERB_RENDER_NODE) { return true; }
278
+ if (node->type != AST_ERB_CONTENT_NODE && node->type != AST_ERB_RENDER_NODE && node->type != AST_ERB_YIELD_NODE) {
279
+ return true;
280
+ }
257
281
 
258
282
  hb_narray_T* ranges = (hb_narray_T*) data;
259
283
  token_T* content = get_content_token(node);
@@ -309,23 +333,21 @@ void herb_annotate_prism_nodes(
309
333
  return;
310
334
  }
311
335
 
312
- memset(&context->pm_opts, 0, sizeof(pm_options_t));
313
- pm_options_line_set(&context->pm_opts, 1);
314
- pm_options_partial_script_set(&context->pm_opts, true);
315
- pm_parser_init(
316
- &context->parser,
317
- (const uint8_t*) context->ruby_buf.value,
318
- context->ruby_buf.length,
319
- &context->pm_opts
320
- );
321
- context->root = pm_parse(&context->parser);
336
+ context->arena = pm_arena_new();
337
+ context->pm_opts = pm_options_new();
338
+ pm_options_line_set(context->pm_opts, 1);
339
+ pm_options_partial_script_set(context->pm_opts, true);
340
+ herb_prism_options_set_ruby_version(context->pm_opts, options);
341
+ context->parser =
342
+ pm_parser_new(context->arena, (const uint8_t*) context->ruby_buf.value, context->ruby_buf.length, context->pm_opts);
343
+ context->root = pm_parse(context->parser);
322
344
 
323
345
  if (!context->root || context->root->type != PM_PROGRAM_NODE) {
324
- pm_node_destroy(&context->parser, context->root);
325
346
  context->root = NULL;
326
347
 
327
- pm_parser_free(&context->parser);
328
- pm_options_free(&context->pm_opts);
348
+ pm_parser_free(context->parser);
349
+ pm_arena_free(context->arena);
350
+ pm_options_free(context->pm_opts);
329
351
 
330
352
  hb_buffer_free(&context->ruby_buf);
331
353
  hb_allocator_dealloc(allocator, context);
@@ -338,7 +360,7 @@ void herb_annotate_prism_nodes(
338
360
  if (prism_program) {
339
361
  herb_prism_node_T program_ref = {
340
362
  .node = context->root,
341
- .parser = &context->parser,
363
+ .parser = context->parser,
342
364
  };
343
365
 
344
366
  document->prism_node = program_ref;
@@ -370,18 +392,20 @@ void herb_annotate_prism_nodes(
370
392
  }
371
393
  }
372
394
 
373
- memset(&context->structural_pm_opts, 0, sizeof(pm_options_t));
374
- pm_options_line_set(&context->structural_pm_opts, 1);
375
- pm_options_partial_script_set(&context->structural_pm_opts, true);
395
+ context->structural_arena = pm_arena_new();
396
+ context->structural_pm_opts = pm_options_new();
397
+ pm_options_line_set(context->structural_pm_opts, 1);
398
+ pm_options_partial_script_set(context->structural_pm_opts, true);
399
+ herb_prism_options_set_ruby_version(context->structural_pm_opts, options);
376
400
 
377
- pm_parser_init(
378
- &context->structural_parser,
401
+ context->structural_parser = pm_parser_new(
402
+ context->structural_arena,
379
403
  (const uint8_t*) context->structural_buf.value,
380
404
  context->structural_buf.length,
381
- &context->structural_pm_opts
405
+ context->structural_pm_opts
382
406
  );
383
407
 
384
- context->structural_root = pm_parse(&context->structural_parser);
408
+ context->structural_root = pm_parse(context->structural_parser);
385
409
  context->has_structural = true;
386
410
 
387
411
  if (context->structural_root && context->structural_root->type == PM_PROGRAM_NODE) {
@@ -393,8 +417,8 @@ void herb_annotate_prism_nodes(
393
417
  }
394
418
 
395
419
  prism_annotate_context_T annotate_context = {
396
- .parser = &context->parser,
397
- .structural_parser = prism_nodes_deep ? &context->parser : &context->structural_parser,
420
+ .parser = context->parser,
421
+ .structural_parser = prism_nodes_deep ? context->parser : context->structural_parser,
398
422
  .node_list = &node_list,
399
423
  .structural_node_list = prism_nodes_deep ? &node_list : &structural_node_list,
400
424
  .prism_nodes_deep = prism_nodes_deep,
@@ -13,6 +13,8 @@
13
13
  #include "../include/lib/string.h"
14
14
  #include "../include/visitor.h"
15
15
 
16
+ #include "../include/prism/prism_helpers.h"
17
+
16
18
  #include <prism.h>
17
19
  #include <stdbool.h>
18
20
  #include <string.h>
@@ -50,9 +52,10 @@ static bool is_render_call(pm_call_node_t* call_node, pm_parser_t* parser) {
50
52
  if (!call_node || !call_node->name) { return false; }
51
53
  if (call_node->receiver && call_node->receiver->type != PM_SELF_NODE) { return false; }
52
54
 
53
- pm_constant_t* constant = pm_constant_pool_id_to_constant(&parser->constant_pool, call_node->name);
55
+ const pm_constant_t* constant = pm_parser_constant(parser, call_node->name);
54
56
 
55
- return constant && constant->length == 6 && strncmp((const char*) constant->start, "render", 6) == 0;
57
+ return constant && pm_constant_length(constant) == 6
58
+ && strncmp((const char*) pm_constant_start(constant), "render", 6) == 0;
56
59
  }
57
60
 
58
61
  static pm_call_node_t* find_render_call(pm_node_t* node, pm_parser_t* parser) {
@@ -117,11 +120,14 @@ static char* extract_string_value(pm_node_t* node, hb_allocator_T* allocator) {
117
120
  return NULL;
118
121
  }
119
122
 
120
- static char* extract_source_expression(pm_node_t* node, hb_allocator_T* allocator) {
123
+ static char* extract_source_expression(const uint8_t* erb_content_source, pm_node_t* node, hb_allocator_T* allocator) {
121
124
  if (!node) { return NULL; }
122
125
 
123
- size_t length = node->location.end - node->location.start;
124
- return hb_allocator_strndup(allocator, (const char*) node->location.start, length);
126
+ return hb_allocator_strndup(
127
+ allocator,
128
+ (const char*) (erb_content_source + node->location.start),
129
+ node->location.length
130
+ );
125
131
  }
126
132
 
127
133
  static token_T* create_token_from_prism_node(
@@ -137,8 +143,8 @@ static token_T* create_token_from_prism_node(
137
143
  position_T end = { .line = 1, .column = 1 };
138
144
 
139
145
  if (node && source && erb_content_source) {
140
- size_t start_offset_in_erb = (size_t) (node->location.start - erb_content_source);
141
- size_t end_offset_in_erb = (size_t) (node->location.end - erb_content_source);
146
+ size_t start_offset_in_erb = node->location.start;
147
+ size_t end_offset_in_erb = herb_prism_location_end(node->location);
142
148
 
143
149
  size_t total_start = erb_content_offset + start_offset_in_erb;
144
150
  size_t total_end = erb_content_offset + end_offset_in_erb;
@@ -160,6 +166,7 @@ static pm_keyword_hash_node_t* find_keyword_hash(pm_arguments_node_t* arguments)
160
166
  }
161
167
 
162
168
  static keyword_result_T find_keyword_value(
169
+ const uint8_t* erb_content_source,
163
170
  pm_keyword_hash_node_t* keyword_hash,
164
171
  const char* key,
165
172
  hb_allocator_T* allocator
@@ -184,7 +191,7 @@ static keyword_result_T find_keyword_value(
184
191
  if (string_value) {
185
192
  result.value = string_value;
186
193
  } else {
187
- result.value = extract_source_expression(assoc->value, allocator);
194
+ result.value = extract_source_expression(erb_content_source, assoc->value, allocator);
188
195
  }
189
196
 
190
197
  return result;
@@ -228,11 +235,12 @@ static bool extract_assoc_parts(
228
235
  AST_RUBY_LITERAL_NODE_T** value_node
229
236
  ) {
230
237
  char* name = extract_string_value(assoc->key, allocator);
231
- if (!name) { name = extract_source_expression(assoc->key, allocator); }
238
+ if (!name) { name = extract_source_expression(erb_content_source, assoc->key, allocator); }
232
239
  if (!name) { return false; }
233
240
 
234
241
  bool shorthand = assoc->value && assoc->value->type == PM_IMPLICIT_NODE;
235
- char* value = shorthand ? hb_allocator_strdup(allocator, name) : extract_source_expression(assoc->value, allocator);
242
+ char* value = shorthand ? hb_allocator_strdup(allocator, name)
243
+ : extract_source_expression(erb_content_source, assoc->value, allocator);
236
244
 
237
245
  if (!value) {
238
246
  hb_allocator_dealloc(allocator, name);
@@ -254,8 +262,8 @@ static bool extract_assoc_parts(
254
262
  pm_node_t* spanned = shorthand ? assoc->key : assoc->value;
255
263
 
256
264
  if (spanned && source && erb_content_source) {
257
- size_t start_offset = (size_t) (spanned->location.start - erb_content_source);
258
- size_t end_offset = (size_t) (spanned->location.end - erb_content_source);
265
+ size_t start_offset = spanned->location.start;
266
+ size_t end_offset = herb_prism_location_end(spanned->location);
259
267
 
260
268
  if (shorthand && end_offset > start_offset && erb_content_source[end_offset - 1] == ':') { end_offset--; }
261
269
 
@@ -348,7 +356,7 @@ static token_T* extract_keyword_token(
348
356
  const uint8_t* erb_content_source,
349
357
  hb_allocator_T* allocator
350
358
  ) {
351
- keyword_result_T keyword = find_keyword_value(keyword_hash, keyword_name, allocator);
359
+ keyword_result_T keyword = find_keyword_value(erb_content_source, keyword_hash, keyword_name, allocator);
352
360
  if (!keyword.value) { return NULL; }
353
361
 
354
362
  token_T* token = create_token_from_prism_node(
@@ -405,7 +413,7 @@ static void append_unusable_state_entry(
405
413
  hb_allocator_T* allocator
406
414
  ) {
407
415
  pm_node_t* named = element->type == PM_ASSOC_NODE ? ((pm_assoc_node_t*) element)->key : element;
408
- char* name = extract_source_expression(named, allocator);
416
+ char* name = extract_source_expression(erb_content_source, named, allocator);
409
417
 
410
418
  if (!name) { return; }
411
419
 
@@ -423,8 +431,8 @@ static void append_unusable_state_entry(
423
431
  position_T end = start;
424
432
 
425
433
  if (source && erb_content_source) {
426
- size_t start_offset = (size_t) (element->location.start - erb_content_source);
427
- size_t end_offset = (size_t) (element->location.end - erb_content_source);
434
+ size_t start_offset = element->location.start;
435
+ size_t end_offset = herb_prism_location_end(element->location);
428
436
 
429
437
  start = byte_offset_to_position(source, erb_content_offset + start_offset);
430
438
  end = byte_offset_to_position(source, erb_content_offset + end_offset);
@@ -512,8 +520,8 @@ static location_T* prism_node_location(
512
520
  ) {
513
521
  if (!node || !source || !erb_content_source) { return NULL; }
514
522
 
515
- size_t start_offset = (size_t) (node->location.start - erb_content_source);
516
- size_t end_offset = (size_t) (node->location.end - erb_content_source);
523
+ size_t start_offset = node->location.start;
524
+ size_t end_offset = herb_prism_location_end(node->location);
517
525
 
518
526
  return location_create(
519
527
  byte_offset_to_position(source, erb_content_offset + start_offset),
@@ -595,7 +603,7 @@ static AST_ERB_RENDER_NODE_T* create_render_node_from_call(
595
603
  hb_allocator_dealloc(allocator, partial_string);
596
604
  }
597
605
  } else if (first_argument->type != PM_KEYWORD_HASH_NODE) {
598
- char* object_string = extract_source_expression(first_argument, allocator);
606
+ char* object_string = extract_source_expression(erb_content_source, first_argument, allocator);
599
607
 
600
608
  if (object_string) {
601
609
  object = create_token_from_prism_node(
@@ -614,7 +622,7 @@ static AST_ERB_RENDER_NODE_T* create_render_node_from_call(
614
622
 
615
623
  if (keyword_hash) {
616
624
  if (has_positional_partial) {
617
- keyword_result_T partial_kw = find_keyword_value(keyword_hash, "partial", allocator);
625
+ keyword_result_T partial_kw = find_keyword_value(erb_content_source, keyword_hash, "partial", allocator);
618
626
  if (partial_kw.value) { has_keyword_partial = true; }
619
627
 
620
628
  pm_hash_node_t* locals_hash = find_locals_hash(keyword_hash, allocator);
@@ -691,7 +699,7 @@ static AST_ERB_RENDER_NODE_T* create_render_node_from_call(
691
699
  hb_array_T* errors = NULL;
692
700
 
693
701
  if (!has_keyword_partial && partial && keyword_hash) {
694
- keyword_result_T locals_keyword = find_keyword_value(keyword_hash, "locals", allocator);
702
+ keyword_result_T locals_keyword = find_keyword_value(erb_content_source, keyword_hash, "locals", allocator);
695
703
 
696
704
  if (locals_keyword.value) {
697
705
  hb_string_T partial_name = partial->value;
@@ -797,7 +805,7 @@ static AST_ERB_RENDER_NODE_T* create_render_node_from_call(
797
805
  }
798
806
 
799
807
  if (has_positional_partial && has_keyword_partial && keyword_hash) {
800
- keyword_result_T keyword_partial = find_keyword_value(keyword_hash, "partial", allocator);
808
+ keyword_result_T keyword_partial = find_keyword_value(erb_content_source, keyword_hash, "partial", allocator);
801
809
 
802
810
  append_render_conflicting_partial_error(
803
811
  partial->value,
@@ -875,7 +883,7 @@ static AST_ERB_RENDER_NODE_T* create_render_node_from_call(
875
883
  pm_block_node_t* inline_block = find_block_on_render_call(call_node);
876
884
 
877
885
  if (inline_block) {
878
- const uint8_t* content_source = erb_content_source ? erb_content_source : (const uint8_t*) parser->start;
886
+ const uint8_t* content_source = erb_content_source ? erb_content_source : pm_parser_start(parser);
879
887
 
880
888
  if (inline_block->parameters && inline_block->parameters->type == PM_BLOCK_PARAMETERS_NODE) {
881
889
  pm_block_parameters_node_t* block_parameters = (pm_block_parameters_node_t*) inline_block->parameters;
@@ -893,16 +901,18 @@ static AST_ERB_RENDER_NODE_T* create_render_node_from_call(
893
901
  }
894
902
 
895
903
  if (inline_block->body) {
896
- size_t body_length = (size_t) (inline_block->body->location.end - inline_block->body->location.start);
897
- char* body_source =
898
- hb_allocator_strndup(allocator, (const char*) inline_block->body->location.start, body_length);
904
+ char* body_source = hb_allocator_strndup(
905
+ allocator,
906
+ (const char*) (content_source + inline_block->body->location.start),
907
+ inline_block->body->location.length
908
+ );
899
909
 
900
910
  position_T body_start = { .line = 1, .column = 1 };
901
911
  position_T body_end = { .line = 1, .column = 1 };
902
912
 
903
913
  if (source && content_source) {
904
- size_t start_offset = (size_t) (inline_block->body->location.start - content_source);
905
- size_t end_offset = (size_t) (inline_block->body->location.end - content_source);
914
+ size_t start_offset = inline_block->body->location.start;
915
+ size_t end_offset = herb_prism_location_end(inline_block->body->location);
906
916
  body_start = byte_offset_to_position(source, erb_content_offset + start_offset);
907
917
  body_end = byte_offset_to_position(source, erb_content_offset + end_offset);
908
918
  }
@@ -1012,7 +1022,7 @@ static AST_ERB_RENDER_NODE_T* try_transform_content_node(
1012
1022
  if (is_erb_comment_tag(erb_node->tag_opening)) { return NULL; }
1013
1023
  if (token_is_escaped_erb_tag_opening(erb_node->tag_opening)) { return NULL; }
1014
1024
 
1015
- pm_call_node_t* render_call = find_render_call(erb_node->analyzed_ruby->root, &erb_node->analyzed_ruby->parser);
1025
+ pm_call_node_t* render_call = find_render_call(erb_node->analyzed_ruby->root, erb_node->analyzed_ruby->parser);
1016
1026
  if (!render_call) { return NULL; }
1017
1027
 
1018
1028
  size_t erb_content_offset = 0;
@@ -1021,12 +1031,12 @@ static AST_ERB_RENDER_NODE_T* try_transform_content_node(
1021
1031
  erb_content_offset = calculate_byte_offset_from_pos(context->source, erb_node->content->location.start);
1022
1032
  }
1023
1033
 
1024
- const uint8_t* erb_content_source = (const uint8_t*) erb_node->analyzed_ruby->parser.start;
1034
+ const uint8_t* erb_content_source = pm_parser_start(erb_node->analyzed_ruby->parser);
1025
1035
 
1026
1036
  return create_render_node_from_call(
1027
1037
  erb_node,
1028
1038
  render_call,
1029
- &erb_node->analyzed_ruby->parser,
1039
+ erb_node->analyzed_ruby->parser,
1030
1040
  context->source,
1031
1041
  erb_content_offset,
1032
1042
  erb_content_source,
@@ -1046,15 +1056,15 @@ static AST_ERB_RENDER_NODE_T* try_transform_block_node(
1046
1056
  const char* ruby_source = block_node->content->value.data;
1047
1057
  size_t ruby_length = block_node->content->value.length;
1048
1058
 
1049
- pm_parser_t parser;
1050
- pm_parser_init(&parser, (const uint8_t*) ruby_source, ruby_length, NULL);
1051
- pm_node_t* root = pm_parse(&parser);
1059
+ pm_arena_t* arena = pm_arena_new();
1060
+ pm_parser_t* parser = herb_prism_parser_new(arena, (const uint8_t*) ruby_source, ruby_length, context->options);
1061
+ pm_node_t* root = pm_parse(parser);
1052
1062
 
1053
- pm_call_node_t* render_call = find_render_call(root, &parser);
1063
+ pm_call_node_t* render_call = find_render_call(root, parser);
1054
1064
 
1055
1065
  if (!render_call) {
1056
- pm_node_destroy(&parser, root);
1057
- pm_parser_free(&parser);
1066
+ pm_parser_free(parser);
1067
+ pm_arena_free(arena);
1058
1068
  return NULL;
1059
1069
  }
1060
1070
 
@@ -1075,7 +1085,7 @@ static AST_ERB_RENDER_NODE_T* try_transform_block_node(
1075
1085
  erb_content_offset = calculate_byte_offset_from_pos(context->source, block_node->content->location.start);
1076
1086
  }
1077
1087
 
1078
- const uint8_t* erb_content_source = (const uint8_t*) parser.start;
1088
+ const uint8_t* erb_content_source = pm_parser_start(parser);
1079
1089
 
1080
1090
  render_block_fields_T block_fields = {
1081
1091
  .block_body = block_node->body,
@@ -1089,7 +1099,7 @@ static AST_ERB_RENDER_NODE_T* try_transform_block_node(
1089
1099
  AST_ERB_RENDER_NODE_T* render_node = create_render_node_from_call(
1090
1100
  &content_view,
1091
1101
  render_call,
1092
- &parser,
1102
+ parser,
1093
1103
  context->source,
1094
1104
  erb_content_offset,
1095
1105
  erb_content_source,
@@ -1098,8 +1108,8 @@ static AST_ERB_RENDER_NODE_T* try_transform_block_node(
1098
1108
  context->options
1099
1109
  );
1100
1110
 
1101
- pm_node_destroy(&parser, root);
1102
- pm_parser_free(&parser);
1111
+ pm_parser_free(parser);
1112
+ pm_arena_free(arena);
1103
1113
 
1104
1114
  return render_node;
1105
1115
  }
@@ -16,6 +16,7 @@
16
16
  #include "../include/prism/prism_helpers.h"
17
17
 
18
18
  #include <prism.h>
19
+ #include <prism/internal/diagnostic.h>
19
20
  #include <stdbool.h>
20
21
  #include <string.h>
21
22
 
@@ -211,17 +212,16 @@ static AST_ERB_STRICT_LOCALS_NODE_T* create_strict_locals_node(
211
212
  hb_buffer_T synthetic_buffer;
212
213
  if (!build_synthetic_ruby(params_open, params_length, &synthetic_buffer, allocator)) { return NULL; }
213
214
 
214
- pm_parser_t parser;
215
- pm_options_t options = { 0 };
216
- pm_parser_init(
217
- &parser,
215
+ pm_arena_t* arena = pm_arena_new();
216
+ pm_parser_t* parser = herb_prism_parser_new(
217
+ arena,
218
218
  (const uint8_t*) hb_buffer_value(&synthetic_buffer),
219
219
  hb_buffer_length(&synthetic_buffer),
220
- &options
220
+ parser_options
221
221
  );
222
- pm_node_t* root = pm_parse(&parser);
222
+ pm_node_t* root = pm_parse(parser);
223
223
 
224
- const uint8_t* synthetic_start = parser.start;
224
+ const uint8_t* synthetic_start = pm_parser_start(parser);
225
225
 
226
226
  pm_parameters_node_t* params_node = find_parameters_node(root);
227
227
  size_t erb_content_byte_offset = calculate_byte_offset_from_position(source, erb_node->content->location.start);
@@ -230,12 +230,12 @@ static AST_ERB_STRICT_LOCALS_NODE_T* create_strict_locals_node(
230
230
  size_t params_in_content = (size_t) (params_open - content_bytes);
231
231
  size_t prefix_length = strlen(SYNTHETIC_PREFIX);
232
232
 
233
- for (const pm_diagnostic_t* error = (const pm_diagnostic_t*) parser.error_list.head; error != NULL;
234
- error = (const pm_diagnostic_t*) error->node.next) {
233
+ for (const pm_diagnostic_t* error = pm_parser_errors_first(parser); error != NULL;
234
+ error = pm_diagnostic_next(error)) {
235
235
  if (error->diag_id == PM_ERR_DEF_TERM) { continue; }
236
236
 
237
- size_t error_start_in_synthetic = (size_t) (error->location.start - synthetic_start);
238
- size_t error_end_in_synthetic = (size_t) (error->location.end - synthetic_start);
237
+ size_t error_start_in_synthetic = error->location.start;
238
+ size_t error_end_in_synthetic = herb_prism_location_end(error->location);
239
239
 
240
240
  size_t error_content_start =
241
241
  params_in_content + (error_start_in_synthetic > prefix_length ? error_start_in_synthetic - prefix_length : 0);
@@ -258,7 +258,7 @@ static AST_ERB_STRICT_LOCALS_NODE_T* create_strict_locals_node(
258
258
  } else {
259
259
  locals = extract_strict_locals(
260
260
  params_node,
261
- &parser,
261
+ parser,
262
262
  source,
263
263
  erb_content_byte_offset,
264
264
  content_bytes,
@@ -270,9 +270,8 @@ static AST_ERB_STRICT_LOCALS_NODE_T* create_strict_locals_node(
270
270
  );
271
271
  }
272
272
 
273
- pm_node_destroy(&parser, root);
274
- pm_parser_free(&parser);
275
- pm_options_free(&options);
273
+ pm_parser_free(parser);
274
+ pm_arena_free(arena);
276
275
  hb_buffer_free(&synthetic_buffer);
277
276
 
278
277
  return ast_erb_strict_locals_node_init(