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
@@ -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/ast/ast_nodes.c CHANGED
@@ -712,7 +712,7 @@ AST_ERB_STRICT_LOCALS_NODE_T* ast_erb_strict_locals_node_init(token_T* tag_openi
712
712
  return erb_strict_locals_node;
713
713
  }
714
714
 
715
- AST_ERB_YIELD_NODE_T* ast_erb_yield_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, position_T start_position, position_T end_position, hb_array_T* errors, hb_allocator_T* allocator) {
715
+ AST_ERB_YIELD_NODE_T* ast_erb_yield_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, herb_prism_node_T prism_node, position_T start_position, position_T end_position, hb_array_T* errors, hb_allocator_T* allocator) {
716
716
  AST_ERB_YIELD_NODE_T* erb_yield_node = hb_allocator_alloc(allocator, sizeof(AST_ERB_YIELD_NODE_T));
717
717
 
718
718
  if (!erb_yield_node) { return NULL; }
@@ -722,6 +722,7 @@ AST_ERB_YIELD_NODE_T* ast_erb_yield_node_init(token_T* tag_opening, token_T* con
722
722
  erb_yield_node->tag_opening = tag_opening;
723
723
  erb_yield_node->content = content;
724
724
  erb_yield_node->tag_closing = tag_closing;
725
+ erb_yield_node->prism_node = prism_node;
725
726
 
726
727
  return erb_yield_node;
727
728
  }
@@ -1628,6 +1629,7 @@ static void ast_free_erb_yield_node(AST_ERB_YIELD_NODE_T* erb_yield_node, hb_all
1628
1629
  if (erb_yield_node->tag_opening != NULL) { token_free(erb_yield_node->tag_opening, allocator); }
1629
1630
  if (erb_yield_node->content != NULL) { token_free(erb_yield_node->content, allocator); }
1630
1631
  if (erb_yield_node->tag_closing != NULL) { token_free(erb_yield_node->tag_closing, allocator); }
1632
+ /* prism_node is a borrowed reference into the prism context, not freed here */
1631
1633
 
1632
1634
  ast_free_base_node(&erb_yield_node->base, allocator);
1633
1635
  }
@@ -1228,7 +1228,11 @@ void ast_pretty_print_node(AST_NODE_T* node, const size_t indent, const size_t r
1228
1228
  pretty_print_errors(node, indent, relative_indent, false, buffer);
1229
1229
  pretty_print_token_property(erb_yield_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
1230
1230
  pretty_print_token_property(erb_yield_node->content, hb_string("content"), indent, relative_indent, false, buffer);
1231
- pretty_print_token_property(erb_yield_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, true, buffer);
1231
+ pretty_print_token_property(erb_yield_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
1232
+ if (erb_yield_node->prism_node.node != NULL) {
1233
+ pretty_print_label(hb_string("prism_node"), indent, relative_indent, true, buffer);
1234
+ hb_buffer_append(buffer, " (pm_node_t*)\n");
1235
+ }
1232
1236
  } break;
1233
1237
 
1234
1238
  case AST_ERB_IN_NODE: {
data/src/extract.c CHANGED
@@ -1,9 +1,12 @@
1
1
  #include "include/herb.h"
2
+ #include "include/lexer/lexer.h"
3
+ #include "include/lexer/token.h"
2
4
  #include "include/lib/hb_allocator.h"
3
5
  #include "include/lib/hb_array.h"
4
6
  #include "include/lib/hb_buffer.h"
5
7
  #include "include/lib/hb_string.h"
6
8
  #include "include/lib/string.h"
9
+ #include "include/util/util.h"
7
10
 
8
11
  #include <assert.h>
9
12
  #include <stdlib.h>
@@ -16,192 +19,250 @@ const herb_extract_ruby_options_T HERB_EXTRACT_RUBY_DEFAULT_OPTIONS = { .semicol
16
19
  .erb_openers = NULL,
17
20
  .erb_opener_count = 0 };
18
21
 
19
- void herb_extract_ruby_to_buffer_with_options(
20
- const char* source,
21
- hb_buffer_T* output,
22
- const herb_extract_ruby_options_T* options,
23
- hb_allocator_T* allocator
24
- ) {
25
- herb_extract_ruby_options_T extract_options = options ? *options : HERB_EXTRACT_RUBY_DEFAULT_OPTIONS;
22
+ typedef struct {
23
+ herb_extract_ruby_options_T options;
24
+ hb_buffer_T* output;
25
+ bool skip_erb_content;
26
+ bool is_comment_tag;
27
+ bool is_erb_comment_tag;
28
+ bool need_newline;
29
+ } extract_ruby_state_T;
26
30
 
27
- parser_options_T lex_options = HERB_DEFAULT_PARSER_OPTIONS;
28
- lex_options.erb_openers = extract_options.erb_openers;
29
- lex_options.erb_opener_count = extract_options.erb_opener_count;
31
+ static void extract_ruby_data(extract_ruby_state_T* state, const char* data, uint32_t from, uint32_t to) {
32
+ uint32_t run_start = from;
30
33
 
31
- hb_array_T* tokens = herb_lex_with_options(source, &lex_options, allocator);
32
- bool skip_erb_content = false;
33
- bool is_comment_tag = false;
34
- bool is_erb_comment_tag = false;
35
- bool need_newline = false;
34
+ for (uint32_t position = from; position < to; position++) {
35
+ if (!is_newline(data[position])) { continue; }
36
36
 
37
- for (size_t i = 0; i < hb_array_size(tokens); i++) {
38
- const token_T* token = hb_array_get(tokens, i);
37
+ if (state->options.preserve_positions) { hb_buffer_append_whitespace(state->output, position - run_start); }
39
38
 
40
- switch (token->type) {
41
- case TOKEN_NEWLINE: {
42
- hb_buffer_append_string(output, token->value);
43
- need_newline = false;
44
- break;
45
- }
39
+ hb_buffer_append_char(state->output, data[position]);
40
+ state->need_newline = false;
41
+ run_start = position + 1;
42
+ }
46
43
 
47
- case TOKEN_ERB_START: {
48
- is_erb_comment_tag = hb_string_equals(token->value, hb_string("<%#"));
44
+ if (state->options.preserve_positions) { hb_buffer_append_whitespace(state->output, to - run_start); }
45
+ }
49
46
 
50
- if (is_erb_comment_tag) {
51
- if (extract_options.comments) {
52
- skip_erb_content = false;
53
- is_comment_tag = false;
47
+ static void extract_ruby_token(extract_ruby_state_T* state, const token_T* token, const token_T* next) {
48
+ switch (token->type) {
49
+ case TOKEN_NEWLINE: {
50
+ hb_buffer_append_string(state->output, token->value);
51
+ state->need_newline = false;
52
+ break;
53
+ }
54
54
 
55
- if (extract_options.preserve_positions) {
56
- bool is_multiline = false;
55
+ case TOKEN_ERB_START: {
56
+ state->is_erb_comment_tag = hb_string_equals(token->value, hb_string("<%#"));
57
57
 
58
- if (i + 1 < hb_array_size(tokens)) {
59
- const token_T* next = hb_array_get(tokens, i + 1);
58
+ if (state->is_erb_comment_tag) {
59
+ if (state->options.comments) {
60
+ state->skip_erb_content = false;
61
+ state->is_comment_tag = false;
60
62
 
61
- if (next->type == TOKEN_ERB_CONTENT && !hb_string_is_null(next->value)
62
- && memchr(next->value.data, '\n', next->value.length) != NULL) {
63
- is_multiline = true;
64
- }
65
- }
63
+ if (state->options.preserve_positions) {
64
+ bool is_multiline = false;
66
65
 
67
- if (is_multiline) {
68
- hb_buffer_append_char(output, '#');
69
- hb_buffer_append_whitespace(output, 2);
70
- } else {
71
- hb_buffer_append_whitespace(output, 2);
72
- hb_buffer_append_char(output, '#');
73
- }
66
+ if (next && next->type == TOKEN_ERB_CONTENT && !hb_string_is_null(next->value)
67
+ && memchr(next->value.data, '\n', next->value.length) != NULL) {
68
+ is_multiline = true;
69
+ }
70
+
71
+ if (is_multiline) {
72
+ hb_buffer_append_char(state->output, '#');
73
+ hb_buffer_append_whitespace(state->output, 2);
74
74
  } else {
75
- if (need_newline) { hb_buffer_append_char(output, '\n'); }
76
- hb_buffer_append_char(output, '#');
77
- need_newline = true;
75
+ hb_buffer_append_whitespace(state->output, 2);
76
+ hb_buffer_append_char(state->output, '#');
78
77
  }
79
78
  } else {
80
- skip_erb_content = true;
81
- is_comment_tag = true;
82
- if (extract_options.preserve_positions) { hb_buffer_append_whitespace(output, range_length(token->range)); }
79
+ if (state->need_newline) { hb_buffer_append_char(state->output, '\n'); }
80
+ hb_buffer_append_char(state->output, '#');
81
+ state->need_newline = true;
83
82
  }
84
- } else if (hb_string_equals(token->value, hb_string("<%%")) || hb_string_equals(token->value, hb_string("<%%="))
85
- || (erb_opening_is_custom(token->value) && !extract_options.custom_tags)) {
86
- skip_erb_content = true;
87
- is_comment_tag = false;
88
- if (extract_options.preserve_positions) { hb_buffer_append_whitespace(output, range_length(token->range)); }
89
83
  } else {
90
- skip_erb_content = false;
91
- is_comment_tag = false;
92
-
93
- if (extract_options.preserve_positions) {
94
- hb_buffer_append_whitespace(output, range_length(token->range));
95
- } else if (need_newline) {
96
- hb_buffer_append_char(output, '\n');
97
- need_newline = false;
84
+ state->skip_erb_content = true;
85
+ state->is_comment_tag = true;
86
+ if (state->options.preserve_positions) {
87
+ hb_buffer_append_whitespace(state->output, range_length(token->range));
98
88
  }
99
89
  }
100
-
101
- break;
90
+ } else if (hb_string_equals(token->value, hb_string("<%%")) || hb_string_equals(token->value, hb_string("<%%="))
91
+ || (erb_opening_is_custom(token->value) && !state->options.custom_tags)) {
92
+ state->skip_erb_content = true;
93
+ state->is_comment_tag = false;
94
+ if (state->options.preserve_positions) {
95
+ hb_buffer_append_whitespace(state->output, range_length(token->range));
96
+ }
97
+ } else {
98
+ state->skip_erb_content = false;
99
+ state->is_comment_tag = false;
100
+
101
+ if (state->options.preserve_positions) {
102
+ hb_buffer_append_whitespace(state->output, range_length(token->range));
103
+ } else if (state->need_newline) {
104
+ hb_buffer_append_char(state->output, '\n');
105
+ state->need_newline = false;
106
+ }
102
107
  }
103
108
 
104
- case TOKEN_ERB_CONTENT: {
105
- if (skip_erb_content == false) {
106
- bool is_inline_comment = false;
109
+ break;
110
+ }
107
111
 
108
- if (!extract_options.comments && !is_comment_tag && !hb_string_is_empty(token->value)) {
109
- hb_string_T trimmed = hb_string_trim_start(token->value);
112
+ case TOKEN_ERB_CONTENT: {
113
+ if (state->skip_erb_content == false) {
114
+ bool is_inline_comment = false;
110
115
 
111
- if (!hb_string_is_empty(trimmed) && trimmed.data[0] == '#'
112
- && token->location.start.line == token->location.end.line) {
113
- is_comment_tag = true;
114
- is_inline_comment = true;
115
- }
116
- }
116
+ if (!state->options.comments && !state->is_comment_tag && !hb_string_is_empty(token->value)) {
117
+ hb_string_T trimmed = hb_string_trim_start(token->value);
117
118
 
118
- if (is_inline_comment) {
119
- if (extract_options.preserve_positions) { hb_buffer_append_whitespace(output, range_length(token->range)); }
120
- } else if (is_erb_comment_tag && !hb_string_is_null(token->value)) {
121
- const char* content = token->value.data;
122
- size_t content_remaining = token->value.length;
119
+ if (!hb_string_is_empty(trimmed) && trimmed.data[0] == '#'
120
+ && token->location.start.line == token->location.end.line) {
121
+ state->is_comment_tag = true;
122
+ is_inline_comment = true;
123
+ }
124
+ }
123
125
 
124
- while (content_remaining > 0) {
125
- if (*content == '\n') {
126
- hb_buffer_append_char(output, '\n');
127
- content++;
128
- content_remaining--;
126
+ if (is_inline_comment) {
127
+ if (state->options.preserve_positions) {
128
+ hb_buffer_append_whitespace(state->output, range_length(token->range));
129
+ }
130
+ } else if (state->is_erb_comment_tag && !hb_string_is_null(token->value)) {
131
+ const char* content = token->value.data;
132
+ size_t content_remaining = token->value.length;
129
133
 
130
- if (content_remaining > 0 && extract_options.preserve_positions && *content == ' ') {
131
- content++;
132
- content_remaining--;
133
- }
134
+ while (content_remaining > 0) {
135
+ if (*content == '\n') {
136
+ hb_buffer_append_char(state->output, '\n');
137
+ content++;
138
+ content_remaining--;
134
139
 
135
- hb_buffer_append_char(output, '#');
136
- } else {
137
- hb_buffer_append_char(output, *content);
140
+ if (content_remaining > 0 && state->options.preserve_positions && *content == ' ') {
138
141
  content++;
139
142
  content_remaining--;
140
143
  }
141
- }
142
-
143
- if (!extract_options.preserve_positions) { need_newline = true; }
144
- } else {
145
- hb_buffer_append_string(output, token->value);
146
-
147
- if (!extract_options.preserve_positions) { need_newline = true; }
148
- }
149
- } else {
150
- if (is_erb_comment_tag && extract_options.preserve_positions && !hb_string_is_null(token->value)) {
151
- const char* content = token->value.data;
152
- size_t content_remaining = token->value.length;
153
-
154
- while (content_remaining > 0) {
155
- if (*content == '\n') {
156
- hb_buffer_append_char(output, '\n');
157
- } else {
158
- hb_buffer_append_char(output, ' ');
159
- }
160
144
 
145
+ hb_buffer_append_char(state->output, '#');
146
+ } else {
147
+ hb_buffer_append_char(state->output, *content);
161
148
  content++;
162
149
  content_remaining--;
163
150
  }
164
- } else if (extract_options.preserve_positions) {
165
- hb_buffer_append_whitespace(output, range_length(token->range));
166
151
  }
167
- }
168
152
 
169
- break;
170
- }
153
+ if (!state->options.preserve_positions) { state->need_newline = true; }
154
+ } else {
155
+ hb_buffer_append_string(state->output, token->value);
171
156
 
172
- case TOKEN_ERB_END: {
173
- bool was_comment = is_comment_tag;
174
- bool was_erb_comment = is_erb_comment_tag;
175
- skip_erb_content = false;
176
- is_comment_tag = false;
177
- is_erb_comment_tag = false;
178
-
179
- if (extract_options.preserve_positions) {
180
- if (was_comment) {
181
- hb_buffer_append_whitespace(output, range_length(token->range));
182
- } else if (was_erb_comment && extract_options.comments) {
183
- hb_buffer_append_whitespace(output, range_length(token->range));
184
- } else if (extract_options.semicolons) {
185
- size_t length = range_length(token->range);
186
-
187
- if (length >= 2) { hb_buffer_append_char(output, ' '); }
188
- if (length >= 1) { hb_buffer_append_char(output, ';'); }
189
- if (length >= 2) { hb_buffer_append_whitespace(output, length - 2); }
190
- } else {
191
- hb_buffer_append_whitespace(output, range_length(token->range));
192
- }
157
+ if (!state->options.preserve_positions) { state->need_newline = true; }
193
158
  }
159
+ } else {
160
+ if (state->is_erb_comment_tag && state->options.preserve_positions && !hb_string_is_null(token->value)) {
161
+ const char* content = token->value.data;
162
+ size_t content_remaining = token->value.length;
163
+
164
+ while (content_remaining > 0) {
165
+ if (*content == '\n') {
166
+ hb_buffer_append_char(state->output, '\n');
167
+ } else {
168
+ hb_buffer_append_char(state->output, ' ');
169
+ }
194
170
 
195
- break;
171
+ content++;
172
+ content_remaining--;
173
+ }
174
+ } else if (state->options.preserve_positions) {
175
+ hb_buffer_append_whitespace(state->output, range_length(token->range));
176
+ }
196
177
  }
197
178
 
198
- default: {
199
- if (extract_options.preserve_positions) { hb_buffer_append_whitespace(output, range_length(token->range)); }
179
+ break;
180
+ }
181
+
182
+ case TOKEN_ERB_END: {
183
+ bool was_comment = state->is_comment_tag;
184
+ bool was_erb_comment = state->is_erb_comment_tag;
185
+ state->skip_erb_content = false;
186
+ state->is_comment_tag = false;
187
+ state->is_erb_comment_tag = false;
188
+
189
+ if (state->options.preserve_positions) {
190
+ if (was_comment) {
191
+ hb_buffer_append_whitespace(state->output, range_length(token->range));
192
+ } else if (was_erb_comment && state->options.comments) {
193
+ hb_buffer_append_whitespace(state->output, range_length(token->range));
194
+ } else if (state->options.semicolons) {
195
+ size_t length = range_length(token->range);
196
+
197
+ if (length >= 2) { hb_buffer_append_char(state->output, ' '); }
198
+ if (length >= 1) { hb_buffer_append_char(state->output, ';'); }
199
+ if (length >= 2) { hb_buffer_append_whitespace(state->output, length - 2); }
200
+ } else {
201
+ hb_buffer_append_whitespace(state->output, range_length(token->range));
202
+ }
200
203
  }
204
+
205
+ break;
206
+ }
207
+
208
+ default: {
209
+ if (state->options.preserve_positions) { hb_buffer_append_whitespace(state->output, range_length(token->range)); }
201
210
  }
202
211
  }
212
+ }
203
213
 
204
- herb_free_tokens(&tokens, allocator);
214
+ void herb_extract_ruby_to_buffer_with_options(
215
+ const char* source,
216
+ hb_buffer_T* output,
217
+ const herb_extract_ruby_options_T* options,
218
+ hb_allocator_T* allocator
219
+ ) {
220
+ extract_ruby_state_T state = {
221
+ .options = options ? *options : HERB_EXTRACT_RUBY_DEFAULT_OPTIONS,
222
+ .output = output,
223
+ .skip_erb_content = false,
224
+ .is_comment_tag = false,
225
+ .is_erb_comment_tag = false,
226
+ .need_newline = false,
227
+ };
228
+
229
+ parser_options_T lex_options = HERB_DEFAULT_PARSER_OPTIONS;
230
+ lex_options.erb_openers = state.options.erb_openers;
231
+ lex_options.erb_opener_count = state.options.erb_opener_count;
232
+
233
+ lexer_T lexer = { 0 };
234
+ lexer_init(&lexer, source ? source : "", allocator);
235
+ lexer_apply_erb_openers(&lexer, &lex_options);
236
+
237
+ const char* data = lexer.source.data;
238
+ uint32_t length = (uint32_t) lexer.source.length;
239
+ token_T* pending = NULL;
240
+
241
+ while (true) {
242
+ if (!pending && lexer.state == STATE_DATA) {
243
+ uint32_t position = lexer.current_position;
244
+
245
+ while (position < length && !(data[position] == '<' && data[position + 1] == '%')) {
246
+ position++;
247
+ }
248
+
249
+ extract_ruby_data(&state, data, lexer.current_position, position);
250
+ lexer_skip_data_to(&lexer, position);
251
+ }
252
+
253
+ token_T* token = pending ? pending : lexer_next_token(&lexer);
254
+ pending = NULL;
255
+
256
+ if (token->type == TOKEN_EOF) {
257
+ token_free(token, allocator);
258
+ break;
259
+ }
260
+
261
+ if (token->type == TOKEN_ERB_START) { pending = lexer_next_token(&lexer); }
262
+
263
+ extract_ruby_token(&state, token, pending);
264
+ token_free(token, allocator);
265
+ }
205
266
  }
206
267
 
207
268
  void herb_extract_ruby_to_buffer(const char* source, hb_buffer_T* output, hb_allocator_T* allocator) {
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
  }
@@ -38,7 +38,7 @@ void tag_helper_info_free(tag_helper_info_T** info);
38
38
  const tag_helper_handler_T* const* get_tag_helper_handlers(void);
39
39
  size_t get_tag_helper_handlers_count(void);
40
40
 
41
- char* extract_inline_block_content(pm_call_node_t* call_node, hb_allocator_T* allocator);
41
+ char* extract_inline_block_content(pm_call_node_t* call_node, pm_parser_t* parser, hb_allocator_T* allocator);
42
42
 
43
43
  struct AST_NODE_STRUCT;
44
44
  bool wrap_javascript_tag_body_visitor(const struct AST_NODE_STRUCT* node, void* data);
@@ -58,6 +58,7 @@ AST_HTML_ATTRIBUTE_NODE_T* create_html_attribute_with_ruby_literal(
58
58
  AST_HTML_ATTRIBUTE_NODE_T* create_html_attribute_with_interpolated_value(
59
59
  const char* name_string,
60
60
  pm_interpolated_string_node_t* interpolated_node,
61
+ const uint8_t* source,
61
62
  position_T start_position,
62
63
  position_T end_position,
63
64
  hb_allocator_T* allocator
@@ -19,7 +19,7 @@ typedef struct {
19
19
  bool found;
20
20
  } tag_helper_search_data_T;
21
21
 
22
- bool search_tag_helper_node(const pm_node_t* node, void* data);
22
+ pm_visit_result_t search_tag_helper_node(const pm_node_t* node, void* data);
23
23
 
24
24
  position_T prism_location_to_position_with_offset(
25
25
  const pm_location_t* pm_location,
@@ -10,8 +10,9 @@
10
10
 
11
11
  typedef struct TAG_HELPER_SCOPE_STRUCT {
12
12
  hb_buffer_T buffer;
13
- pm_options_t options;
14
- pm_parser_t parser;
13
+ pm_arena_t* arena;
14
+ pm_options_t* options;
15
+ pm_parser_t* parser;
15
16
  pm_node_t* root;
16
17
  } tag_helper_scope_T;
17
18
 
@@ -26,28 +27,6 @@ typedef struct ANALYZE_RUBY_CONTEXT_STRUCT {
26
27
  const parser_options_T* options;
27
28
  } analyze_ruby_context_T;
28
29
 
29
- typedef enum {
30
- CONTROL_TYPE_IF,
31
- CONTROL_TYPE_ELSIF,
32
- CONTROL_TYPE_ELSE,
33
- CONTROL_TYPE_END,
34
- CONTROL_TYPE_CASE,
35
- CONTROL_TYPE_CASE_MATCH,
36
- CONTROL_TYPE_WHEN,
37
- CONTROL_TYPE_IN,
38
- CONTROL_TYPE_BEGIN,
39
- CONTROL_TYPE_RESCUE,
40
- CONTROL_TYPE_ENSURE,
41
- CONTROL_TYPE_UNLESS,
42
- CONTROL_TYPE_WHILE,
43
- CONTROL_TYPE_UNTIL,
44
- CONTROL_TYPE_FOR,
45
- CONTROL_TYPE_BLOCK,
46
- CONTROL_TYPE_BLOCK_CLOSE,
47
- CONTROL_TYPE_YIELD,
48
- CONTROL_TYPE_UNKNOWN
49
- } control_type_t;
50
-
51
30
  typedef struct {
52
31
  int loop_depth;
53
32
  int rescue_depth;