herb 0.11.1 → 0.11.2

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 (247) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +4 -2
  3. data/config.yml +6 -0
  4. data/ext/herb/extconf.rb +8 -31
  5. data/ext/herb/nodes.c +75 -75
  6. data/ext/herb/parser_options_helpers.c +26 -0
  7. data/lib/herb/analysis/partial_index.rb +1 -1
  8. data/lib/herb/analysis/partial_resolution.rb +27 -0
  9. data/lib/herb/ast/helpers.rb +1 -1
  10. data/lib/herb/configuration.rb +11 -1
  11. data/lib/herb/dev/classifier.rb +1 -1
  12. data/lib/herb/engine/compiler.rb +5 -8
  13. data/lib/herb/engine/slots/dynamics_compiler.rb +53 -14
  14. data/lib/herb/engine/slots/subtree_compiler.rb +1 -1
  15. data/lib/herb/engine/slots/visitor.rb +32 -4
  16. data/lib/herb/engine/visitors/instrumentation_visitor.rb +18 -6
  17. data/lib/herb/parser_options.rb +6 -3
  18. data/lib/herb/project.rb +19 -8
  19. data/lib/herb/version.rb +1 -1
  20. data/lib/herb.rb +1 -1
  21. data/sig/herb/analysis/partial_resolution.rbs +8 -0
  22. data/sig/herb/configuration.rbs +3 -0
  23. data/sig/herb/engine/slots/dynamics_compiler.rbs +24 -7
  24. data/sig/herb/engine/slots/visitor.rbs +14 -0
  25. data/sig/herb/engine/visitors/instrumentation_visitor.rbs +5 -1
  26. data/sig/herb/parser_options.rbs +6 -4
  27. data/sig/herb.rbs +2 -2
  28. data/src/analyze/action_view/attribute_extraction_helpers.c +40 -21
  29. data/src/analyze/action_view/generated_handlers.c +36 -36
  30. data/src/analyze/action_view/image_tag.c +7 -3
  31. data/src/analyze/action_view/javascript_include_tag.c +6 -3
  32. data/src/analyze/action_view/link_to.c +23 -23
  33. data/src/analyze/action_view/registry.c +7 -3
  34. data/src/analyze/action_view/tag_helper_node_builders.c +6 -13
  35. data/src/analyze/action_view/tag_helpers.c +139 -90
  36. data/src/analyze/action_view/turbo_frame_tag.c +5 -4
  37. data/src/analyze/analyze.c +35 -19
  38. data/src/analyze/analyze_helpers.c +161 -188
  39. data/src/analyze/analyzed_ruby.c +8 -7
  40. data/src/analyze/control_type.c +29 -22
  41. data/src/analyze/herb_directives.c +16 -20
  42. data/src/analyze/iteration_nodes.c +69 -24
  43. data/src/analyze/parse_errors.c +32 -22
  44. data/src/analyze/postfix_conditionals.c +23 -13
  45. data/src/analyze/prism_annotate.c +29 -28
  46. data/src/analyze/render_nodes.c +51 -41
  47. data/src/analyze/strict_locals.c +14 -15
  48. data/src/analyze/ternary_conditionals.c +14 -10
  49. data/src/herb.c +10 -8
  50. data/src/include/analyze/action_view/tag_helper_handler.h +1 -1
  51. data/src/include/analyze/action_view/tag_helper_node_builders.h +1 -0
  52. data/src/include/analyze/action_view/tag_helpers.h +1 -1
  53. data/src/include/analyze/analyze.h +3 -2
  54. data/src/include/analyze/analyzed_ruby.h +4 -2
  55. data/src/include/analyze/helpers.h +6 -6
  56. data/src/include/herb.h +3 -2
  57. data/src/include/parser/parser_options.h +5 -0
  58. data/src/include/prism/prism_context.h +12 -12
  59. data/src/include/prism/prism_helpers.h +30 -0
  60. data/src/include/prism_version.h +11 -0
  61. data/src/include/version.h +1 -1
  62. data/src/parser/parser_helpers.c +1 -2
  63. data/src/parser.c +6 -7
  64. data/src/parser_options_defaults.c +1 -0
  65. data/src/prism/prism_helpers.c +84 -50
  66. data/src/prism/ruby_parser.c +20 -20
  67. data/templates/ext/herb/nodes.c.erb +5 -5
  68. data/templates/ext/herb/parser_options_helpers.c.erb +33 -0
  69. data/templates/java/nodes.c.erb +6 -6
  70. data/templates/java/parser_options_helpers.c.erb +41 -2
  71. data/templates/java/parser_options_helpers.h.erb +2 -1
  72. data/templates/javascript/packages/node/extension/nodes.cpp.erb +5 -5
  73. data/templates/javascript/packages/node/extension/parser_options_helpers.cpp.erb +34 -2
  74. data/templates/javascript/packages/node/extension/parser_options_helpers.h.erb +1 -1
  75. data/templates/lib/herb/parser_options.rb.erb +1 -1
  76. data/templates/rust/src/prism/generated_deserialize.rs.erb +90 -44
  77. data/templates/rust/src/prism/generated_prettyprint.rs.erb +18 -27
  78. data/templates/src/analyze/action_view/generated_handlers.c.erb +23 -22
  79. data/templates/src/include/parser/parser_options.h.erb +10 -0
  80. data/templates/src/include/prism_version.h.erb +17 -0
  81. data/templates/src/parser_options_defaults.c.erb +1 -1
  82. data/templates/template.rb +17 -2
  83. data/templates/wasm/nodes.cpp.erb +5 -5
  84. data/templates/wasm/parser_options_helpers.cpp.erb +24 -0
  85. data/vendor/prism/Rakefile +76 -7
  86. data/vendor/prism/config.yml +174 -161
  87. data/vendor/prism/include/prism/arena.h +45 -0
  88. data/vendor/prism/include/prism/arena.hpp +42 -0
  89. data/vendor/prism/include/prism/ast.h +2738 -611
  90. data/vendor/prism/include/prism/ast.hpp +641 -0
  91. data/vendor/prism/include/prism/buffer.h +60 -0
  92. data/vendor/prism/include/prism/buffer.hpp +55 -0
  93. data/vendor/prism/include/prism/comments.h +72 -0
  94. data/vendor/prism/include/prism/compiler/accel.h +26 -0
  95. data/vendor/prism/include/prism/compiler/align.h +36 -0
  96. data/vendor/prism/include/prism/compiler/assume.h +25 -0
  97. data/vendor/prism/include/prism/compiler/branch.h +26 -0
  98. data/vendor/prism/include/prism/compiler/bswap.h +46 -0
  99. data/vendor/prism/include/prism/compiler/cplusplus.hpp +16 -0
  100. data/vendor/prism/include/prism/compiler/endianness.h +34 -0
  101. data/vendor/prism/include/prism/compiler/exceptions.hpp +17 -0
  102. data/vendor/prism/include/prism/compiler/exported.h +24 -0
  103. data/vendor/prism/include/prism/compiler/fallthrough.h +22 -0
  104. data/vendor/prism/include/prism/compiler/filesystem.h +32 -0
  105. data/vendor/prism/include/prism/compiler/flex_array.h +19 -0
  106. data/vendor/prism/include/prism/compiler/force_inline.h +21 -0
  107. data/vendor/prism/include/prism/compiler/format.h +27 -0
  108. data/vendor/prism/include/prism/compiler/inline.h +17 -0
  109. data/vendor/prism/include/prism/compiler/lifetimebound.hpp +25 -0
  110. data/vendor/prism/include/prism/compiler/nodiscard.h +22 -0
  111. data/vendor/prism/include/prism/compiler/nonnull.h +18 -0
  112. data/vendor/prism/include/prism/compiler/unused.h +18 -0
  113. data/vendor/prism/include/prism/constant_pool.h +106 -0
  114. data/vendor/prism/include/prism/diagnostic.h +55 -402
  115. data/vendor/prism/include/prism/errors_format.h +61 -0
  116. data/vendor/prism/include/prism/excludes.h +29 -0
  117. data/vendor/prism/include/prism/integer.h +41 -0
  118. data/vendor/prism/include/prism/internal/allocator.h +68 -0
  119. data/vendor/prism/include/prism/internal/allocator_debug.h +88 -0
  120. data/vendor/prism/include/prism/internal/arena.h +108 -0
  121. data/vendor/prism/include/prism/internal/bit.h +42 -0
  122. data/vendor/prism/include/prism/internal/buffer.h +94 -0
  123. data/vendor/prism/include/prism/internal/char.h +145 -0
  124. data/vendor/prism/include/prism/internal/comments.h +54 -0
  125. data/vendor/prism/include/prism/internal/constant_pool.h +152 -0
  126. data/vendor/prism/include/prism/internal/diagnostic.h +389 -0
  127. data/vendor/prism/include/prism/{encoding.h → internal/encoding.h} +27 -68
  128. data/vendor/prism/include/prism/internal/integer.h +68 -0
  129. data/vendor/prism/include/prism/internal/isinf.h +16 -0
  130. data/vendor/prism/include/prism/internal/line_offset_list.h +34 -0
  131. data/vendor/prism/include/prism/{util/pm_list.h → internal/list.h} +11 -52
  132. data/vendor/prism/include/prism/internal/magic_comments.h +23 -0
  133. data/vendor/prism/include/prism/internal/memchr.h +15 -0
  134. data/vendor/prism/include/prism/internal/node.h +42 -0
  135. data/vendor/prism/include/prism/internal/options.h +232 -0
  136. data/vendor/prism/include/prism/internal/parser.h +1015 -0
  137. data/vendor/prism/include/prism/internal/regexp.h +26 -0
  138. data/vendor/prism/include/prism/internal/serialize.h +39 -0
  139. data/vendor/prism/include/prism/internal/source.h +72 -0
  140. data/vendor/prism/include/prism/internal/static_literals.h +60 -0
  141. data/vendor/prism/include/prism/internal/stringy.h +30 -0
  142. data/vendor/prism/include/prism/{util/pm_strncasecmp.h → internal/strncasecmp.h} +3 -17
  143. data/vendor/prism/include/prism/{util/pm_strpbrk.h → internal/strpbrk.h} +7 -20
  144. data/vendor/prism/include/prism/internal/tokens.h +11 -0
  145. data/vendor/prism/include/prism/internal/xxh3.h +16 -0
  146. data/vendor/prism/include/prism/json.h +40 -0
  147. data/vendor/prism/include/prism/line_offset_list.h +69 -0
  148. data/vendor/prism/include/prism/magic_comments.h +53 -0
  149. data/vendor/prism/include/prism/node.h +59 -49
  150. data/vendor/prism/include/prism/node.hpp +272 -0
  151. data/vendor/prism/include/prism/node_type.hpp +38 -0
  152. data/vendor/prism/include/prism/options.h +154 -279
  153. data/vendor/prism/include/prism/options.hpp +43 -0
  154. data/vendor/prism/include/prism/parser.h +367 -870
  155. data/vendor/prism/include/prism/parser.hpp +274 -0
  156. data/vendor/prism/include/prism/prettyprint.h +14 -9
  157. data/vendor/prism/include/prism/serialize.h +123 -0
  158. data/vendor/prism/include/prism/source.h +163 -0
  159. data/vendor/prism/include/prism/stream.h +36 -0
  160. data/vendor/prism/include/prism/string_query.h +82 -0
  161. data/vendor/prism/include/prism/stringy.h +61 -0
  162. data/vendor/prism/include/prism/stringy.hpp +31 -0
  163. data/vendor/prism/include/prism/version.h +20 -3
  164. data/vendor/prism/include/prism.h +35 -320
  165. data/vendor/prism/include/prism.hpp +24 -0
  166. data/vendor/prism/src/arena.c +122 -0
  167. data/vendor/prism/src/{util/pm_buffer.c → buffer.c} +53 -21
  168. data/vendor/prism/src/{util/pm_char.c → char.c} +28 -57
  169. data/vendor/prism/src/comments.c +455 -0
  170. data/vendor/prism/src/constant_pool.c +406 -0
  171. data/vendor/prism/src/diagnostic.c +120 -68
  172. data/vendor/prism/src/encoding.c +8 -3
  173. data/vendor/prism/src/errors_format.c +519 -0
  174. data/vendor/prism/src/{util/pm_integer.c → integer.c} +38 -22
  175. data/vendor/prism/src/json.c +5733 -0
  176. data/vendor/prism/src/line_offset_list.c +100 -0
  177. data/vendor/prism/src/list.c +24 -0
  178. data/vendor/prism/src/{util/pm_memchr.c → memchr.c} +8 -6
  179. data/vendor/prism/src/node.c +3465 -7787
  180. data/vendor/prism/src/options.c +161 -54
  181. data/vendor/prism/src/parser.c +371 -0
  182. data/vendor/prism/src/prettyprint.c +421 -354
  183. data/vendor/prism/src/prism.c +8522 -7280
  184. data/vendor/prism/src/regexp.c +960 -45
  185. data/vendor/prism/src/serialize.c +2434 -2048
  186. data/vendor/prism/src/source.c +524 -0
  187. data/vendor/prism/src/static_literals.c +303 -360
  188. data/vendor/prism/src/string_query.c +180 -0
  189. data/vendor/prism/src/stringy.c +61 -0
  190. data/vendor/prism/src/{util/pm_strncasecmp.c → strncasecmp.c} +5 -4
  191. data/vendor/prism/src/strpbrk.c +447 -0
  192. data/vendor/prism/src/{token_type.c → tokens.c} +39 -18
  193. data/vendor/prism/src/xxh3.c +292 -0
  194. data/vendor/prism/templates/ext/prism/api_node.c.erb +58 -44
  195. data/vendor/prism/templates/include/prism/ast.h.erb +67 -17
  196. data/vendor/prism/templates/include/prism/ast.hpp.erb +31 -0
  197. data/vendor/prism/templates/include/prism/internal/diagnostic.h.erb +60 -0
  198. data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/AbstractNodeVisitor.java.erb +1 -1
  199. data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/Loader.java.erb +232 -133
  200. data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/Nodes.java.erb +62 -23
  201. data/vendor/prism/templates/javascript/src/deserialize.js.erb +153 -146
  202. data/vendor/prism/templates/javascript/src/nodes.js.erb +4 -9
  203. data/vendor/prism/templates/lib/prism/compiler.rb.erb +14 -5
  204. data/vendor/prism/templates/lib/prism/dispatcher.rb.erb +20 -12
  205. data/vendor/prism/templates/lib/prism/dot_visitor.rb.erb +37 -11
  206. data/vendor/prism/templates/lib/prism/dsl.rb.erb +43 -4
  207. data/vendor/prism/templates/lib/prism/inspect_visitor.rb.erb +26 -10
  208. data/vendor/prism/templates/lib/prism/mutation_compiler.rb.erb +5 -2
  209. data/vendor/prism/templates/lib/prism/node.rb.erb +283 -105
  210. data/vendor/prism/templates/lib/prism/reflection.rb.erb +11 -2
  211. data/vendor/prism/templates/lib/prism/serialize.rb.erb +291 -134
  212. data/vendor/prism/templates/lib/prism/visitor.rb.erb +18 -0
  213. data/vendor/prism/templates/src/diagnostic.c.erb +114 -63
  214. data/vendor/prism/templates/src/json.c.erb +130 -0
  215. data/vendor/prism/templates/src/node.c.erb +79 -236
  216. data/vendor/prism/templates/src/prettyprint.c.erb +24 -13
  217. data/vendor/prism/templates/src/serialize.c.erb +369 -183
  218. data/vendor/prism/templates/src/{token_type.c.erb → tokens.c.erb} +22 -11
  219. data/vendor/prism/templates/template.rb +193 -91
  220. metadata +100 -42
  221. data/vendor/prism/include/prism/defines.h +0 -260
  222. data/vendor/prism/include/prism/pack.h +0 -163
  223. data/vendor/prism/include/prism/regexp.h +0 -43
  224. data/vendor/prism/include/prism/static_literals.h +0 -121
  225. data/vendor/prism/include/prism/util/pm_buffer.h +0 -236
  226. data/vendor/prism/include/prism/util/pm_char.h +0 -204
  227. data/vendor/prism/include/prism/util/pm_constant_pool.h +0 -218
  228. data/vendor/prism/include/prism/util/pm_integer.h +0 -130
  229. data/vendor/prism/include/prism/util/pm_memchr.h +0 -29
  230. data/vendor/prism/include/prism/util/pm_newline_list.h +0 -113
  231. data/vendor/prism/include/prism/util/pm_string.h +0 -200
  232. data/vendor/prism/src/pack.c +0 -509
  233. data/vendor/prism/src/util/pm_constant_pool.c +0 -342
  234. data/vendor/prism/src/util/pm_list.c +0 -49
  235. data/vendor/prism/src/util/pm_newline_list.c +0 -125
  236. data/vendor/prism/src/util/pm_string.c +0 -381
  237. data/vendor/prism/src/util/pm_strpbrk.c +0 -206
  238. data/vendor/prism/templates/include/prism/diagnostic.h.erb +0 -130
  239. data/vendor/prism/templates/rbi/prism/dsl.rbi.erb +0 -68
  240. data/vendor/prism/templates/rbi/prism/node.rbi.erb +0 -167
  241. data/vendor/prism/templates/rbi/prism/visitor.rbi.erb +0 -18
  242. data/vendor/prism/templates/sig/prism/_private/dot_visitor.rbs.erb +0 -45
  243. data/vendor/prism/templates/sig/prism/dsl.rbs.erb +0 -31
  244. data/vendor/prism/templates/sig/prism/mutation_compiler.rbs.erb +0 -7
  245. data/vendor/prism/templates/sig/prism/node.rbs.erb +0 -136
  246. data/vendor/prism/templates/sig/prism/visitor.rbs.erb +0 -17
  247. 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>
@@ -204,10 +205,10 @@ static void set_prism_node(AST_NODE_T* node, herb_prism_node_T prism_ref) {
204
205
  }
205
206
  }
206
207
 
207
- static size_t prism_node_start(pm_parser_t* parser, hb_narray_T* node_list, size_t index) {
208
+ static size_t prism_node_start(hb_narray_T* node_list, size_t index) {
208
209
  pm_node_t* prism_node = *(pm_node_t**) hb_narray_get(node_list, index);
209
210
 
210
- return (size_t) (prism_node->location.start - parser->start);
211
+ return prism_node->location.start;
211
212
  }
212
213
 
213
214
  static herb_prism_node_T find_prism_node_for_herb_node(
@@ -229,17 +230,17 @@ static herb_prism_node_T find_prism_node_for_herb_node(
229
230
  while (low < high) {
230
231
  size_t middle = low + (high - low) / 2;
231
232
 
232
- if (prism_node_start(parser, node_list, middle) < content_from) {
233
+ if (prism_node_start(node_list, middle) < content_from) {
233
234
  low = middle + 1;
234
235
  } else {
235
236
  high = middle;
236
237
  }
237
238
  }
238
239
 
239
- if (low >= hb_narray_size(node_list) || prism_node_start(parser, node_list, low) >= content_to) { return result; }
240
+ if (low >= hb_narray_size(node_list) || prism_node_start(node_list, low) >= content_to) { return result; }
240
241
 
241
242
  pm_node_t* prism_node = *(pm_node_t**) hb_narray_get(node_list, low);
242
- size_t prism_end = (size_t) (prism_node->location.end - parser->start);
243
+ size_t prism_end = (size_t) prism_node->location.start + prism_node->location.length;
243
244
 
244
245
  result.node = prism_node;
245
246
  result.parser = parser;
@@ -332,23 +333,21 @@ void herb_annotate_prism_nodes(
332
333
  return;
333
334
  }
334
335
 
335
- memset(&context->pm_opts, 0, sizeof(pm_options_t));
336
- pm_options_line_set(&context->pm_opts, 1);
337
- pm_options_partial_script_set(&context->pm_opts, true);
338
- pm_parser_init(
339
- &context->parser,
340
- (const uint8_t*) context->ruby_buf.value,
341
- context->ruby_buf.length,
342
- &context->pm_opts
343
- );
344
- 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);
345
344
 
346
345
  if (!context->root || context->root->type != PM_PROGRAM_NODE) {
347
- pm_node_destroy(&context->parser, context->root);
348
346
  context->root = NULL;
349
347
 
350
- pm_parser_free(&context->parser);
351
- 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);
352
351
 
353
352
  hb_buffer_free(&context->ruby_buf);
354
353
  hb_allocator_dealloc(allocator, context);
@@ -361,7 +360,7 @@ void herb_annotate_prism_nodes(
361
360
  if (prism_program) {
362
361
  herb_prism_node_T program_ref = {
363
362
  .node = context->root,
364
- .parser = &context->parser,
363
+ .parser = context->parser,
365
364
  };
366
365
 
367
366
  document->prism_node = program_ref;
@@ -393,18 +392,20 @@ void herb_annotate_prism_nodes(
393
392
  }
394
393
  }
395
394
 
396
- memset(&context->structural_pm_opts, 0, sizeof(pm_options_t));
397
- pm_options_line_set(&context->structural_pm_opts, 1);
398
- 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);
399
400
 
400
- pm_parser_init(
401
- &context->structural_parser,
401
+ context->structural_parser = pm_parser_new(
402
+ context->structural_arena,
402
403
  (const uint8_t*) context->structural_buf.value,
403
404
  context->structural_buf.length,
404
- &context->structural_pm_opts
405
+ context->structural_pm_opts
405
406
  );
406
407
 
407
- context->structural_root = pm_parse(&context->structural_parser);
408
+ context->structural_root = pm_parse(context->structural_parser);
408
409
  context->has_structural = true;
409
410
 
410
411
  if (context->structural_root && context->structural_root->type == PM_PROGRAM_NODE) {
@@ -416,8 +417,8 @@ void herb_annotate_prism_nodes(
416
417
  }
417
418
 
418
419
  prism_annotate_context_T annotate_context = {
419
- .parser = &context->parser,
420
- .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,
421
422
  .node_list = &node_list,
422
423
  .structural_node_list = prism_nodes_deep ? &node_list : &structural_node_list,
423
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(
@@ -8,6 +8,7 @@
8
8
  #include "../include/lib/hb_array.h"
9
9
  #include "../include/lib/hb_string.h"
10
10
  #include "../include/prism/herb_prism_node.h"
11
+ #include "../include/prism/prism_helpers.h"
11
12
  #include "../include/visitor.h"
12
13
 
13
14
  #include <prism.h>
@@ -26,7 +27,7 @@ static pm_node_t* find_ternary_statement(analyzed_ruby_T* analyzed) {
26
27
  if (statement->type != PM_IF_NODE) { return NULL; }
27
28
  pm_if_node_t* if_node = (pm_if_node_t*) statement;
28
29
 
29
- if (if_node->if_keyword_loc.start == NULL && if_node->subsequent != NULL) { return statement; }
30
+ if (!herb_prism_location_assigned(if_node->if_keyword_loc) && if_node->subsequent != NULL) { return statement; }
30
31
 
31
32
  return NULL;
32
33
  }
@@ -49,11 +50,11 @@ static body_info_T extract_statements_body_info(
49
50
  pm_node_t* first = statements->body.nodes[0];
50
51
  pm_node_t* last = statements->body.nodes[statements->body.size - 1];
51
52
 
52
- const uint8_t* start = first->location.start;
53
- const uint8_t* end = last->location.end;
53
+ const uint8_t* parser_start = pm_parser_start(analyzed->parser);
54
+ size_t source_length = (size_t) (pm_parser_end(analyzed->parser) - parser_start);
54
55
 
55
- const uint8_t* parser_start = analyzed->parser.start;
56
- size_t source_length = (size_t) (analyzed->parser.end - parser_start);
56
+ const uint8_t* start = herb_prism_location_start_pointer(parser_start, first->location);
57
+ const uint8_t* end = herb_prism_location_end_pointer(parser_start, last->location);
57
58
 
58
59
  if (start < parser_start || end > parser_start + source_length) { return info; }
59
60
 
@@ -83,14 +84,16 @@ static body_info_T extract_statements_body_info(
83
84
  return info;
84
85
  }
85
86
 
86
- static char* extract_condition_source(pm_if_node_t* if_node, hb_allocator_T* allocator) {
87
+ static char* extract_condition_source(const uint8_t* source, pm_if_node_t* if_node, hb_allocator_T* allocator) {
87
88
  pm_node_t* predicate = if_node->predicate;
88
89
 
89
90
  if (!predicate) { return NULL; }
90
91
 
91
- size_t length = (size_t) (predicate->location.end - predicate->location.start);
92
-
93
- return hb_allocator_strndup(allocator, (const char*) predicate->location.start, length);
92
+ return hb_allocator_strndup(
93
+ allocator,
94
+ (const char*) (source + predicate->location.start),
95
+ predicate->location.length
96
+ );
94
97
  }
95
98
 
96
99
  static bool append_branch_statement(
@@ -156,7 +159,8 @@ AST_NODE_T* transform_ternary_expression(
156
159
  pm_else_node_t* else_node = (pm_else_node_t*) if_node->subsequent;
157
160
  if (!else_node) { return NULL; }
158
161
 
159
- char* condition_source = extract_condition_source(if_node, allocator);
162
+ char* condition_source =
163
+ extract_condition_source(pm_parser_start(erb_node->analyzed_ruby->parser), if_node, allocator);
160
164
  if (!condition_source) { return NULL; }
161
165
 
162
166
  position_T start = erb_node->base.location.start;
data/src/herb.c CHANGED
@@ -7,6 +7,7 @@
7
7
  #include "include/lib/hb_allocator.h"
8
8
  #include "include/lib/hb_array.h"
9
9
  #include "include/parser/parser.h"
10
+ #include "include/prism_version.h"
10
11
  #include "include/version.h"
11
12
  #include "include/visitor.h"
12
13
 
@@ -127,7 +128,7 @@ HERB_EXPORTED_FUNCTION const char* herb_version(void) {
127
128
  }
128
129
 
129
130
  HERB_EXPORTED_FUNCTION const char* herb_prism_version(void) {
130
- return PRISM_VERSION;
131
+ return HERB_PRISM_VERSION;
131
132
  }
132
133
 
133
134
  HERB_EXPORTED_FUNCTION herb_ruby_parse_result_T* herb_parse_ruby(const char* source, size_t length) {
@@ -136,9 +137,11 @@ HERB_EXPORTED_FUNCTION herb_ruby_parse_result_T* herb_parse_ruby(const char* sou
136
137
  herb_ruby_parse_result_T* result = malloc(sizeof(herb_ruby_parse_result_T));
137
138
  if (!result) { return NULL; }
138
139
 
139
- memset(&result->options, 0, sizeof(pm_options_t));
140
- pm_parser_init(&result->parser, (const uint8_t*) source, length, &result->options);
141
- result->root = pm_parse(&result->parser);
140
+ result->arena = pm_arena_new();
141
+ result->options = pm_options_new();
142
+ pm_options_line_set(result->options, 0);
143
+ result->parser = pm_parser_new(result->arena, (const uint8_t*) source, length, result->options);
144
+ result->root = pm_parse(result->parser);
142
145
 
143
146
  return result;
144
147
  }
@@ -146,9 +149,8 @@ HERB_EXPORTED_FUNCTION herb_ruby_parse_result_T* herb_parse_ruby(const char* sou
146
149
  HERB_EXPORTED_FUNCTION void herb_free_ruby_parse_result(herb_ruby_parse_result_T* result) {
147
150
  if (!result) { return; }
148
151
 
149
- if (result->root) { pm_node_destroy(&result->parser, result->root); }
150
-
151
- pm_parser_free(&result->parser);
152
- pm_options_free(&result->options);
152
+ pm_parser_free(result->parser);
153
+ pm_arena_free(result->arena);
154
+ pm_options_free(result->options);
153
155
  free(result);
154
156
  }