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
@@ -28,6 +28,8 @@ module Herb
28
28
 
29
29
  attr_reader render_nodes: bool
30
30
 
31
+ attr_reader ruby_version: String?
32
+
31
33
  attr_reader strict: bool
32
34
 
33
35
  attr_reader strict_locals: bool
@@ -76,11 +78,11 @@ module Herb
76
78
 
77
79
  DEFAULT_TRANSFORM_CONDITIONALS: bool
78
80
 
79
- # : (?action_view_helpers: bool, ?analyze: bool, ?arena_stats: bool, ?dot_notation_tags: bool, ?erb_openers: Array[String], ?herb_directives: bool, ?html: bool, ?iteration_nodes: bool, ?max_errors: Integer?, ?prism_nodes: bool, ?prism_nodes_deep: bool, ?prism_program: bool, ?render_nodes: bool, ?strict: bool, ?strict_locals: bool, ?timeout: Numeric, ?track_locations: bool, ?track_whitespace: bool, ?transform_conditionals: bool) -> void
80
- def initialize: (?action_view_helpers: bool, ?analyze: bool, ?arena_stats: bool, ?dot_notation_tags: bool, ?erb_openers: Array[String], ?herb_directives: bool, ?html: bool, ?iteration_nodes: bool, ?max_errors: Integer?, ?prism_nodes: bool, ?prism_nodes_deep: bool, ?prism_program: bool, ?render_nodes: bool, ?strict: bool, ?strict_locals: bool, ?timeout: Numeric, ?track_locations: bool, ?track_whitespace: bool, ?transform_conditionals: bool) -> void
81
+ # : (?action_view_helpers: bool, ?analyze: bool, ?arena_stats: bool, ?dot_notation_tags: bool, ?erb_openers: Array[String], ?herb_directives: bool, ?html: bool, ?iteration_nodes: bool, ?max_errors: Integer?, ?prism_nodes: bool, ?prism_nodes_deep: bool, ?prism_program: bool, ?render_nodes: bool, ?ruby_version: String?, ?strict: bool, ?strict_locals: bool, ?timeout: Numeric, ?track_locations: bool, ?track_whitespace: bool, ?transform_conditionals: bool) -> void
82
+ def initialize: (?action_view_helpers: bool, ?analyze: bool, ?arena_stats: bool, ?dot_notation_tags: bool, ?erb_openers: Array[String], ?herb_directives: bool, ?html: bool, ?iteration_nodes: bool, ?max_errors: Integer?, ?prism_nodes: bool, ?prism_nodes_deep: bool, ?prism_program: bool, ?render_nodes: bool, ?ruby_version: String?, ?strict: bool, ?strict_locals: bool, ?timeout: Numeric, ?track_locations: bool, ?track_whitespace: bool, ?transform_conditionals: bool) -> void
81
83
 
82
- # : () -> Hash[Symbol, (bool | Numeric | Array[String] | nil)]
83
- def to_h: () -> Hash[Symbol, bool | Numeric | Array[String] | nil]
84
+ # : () -> Hash[Symbol, (bool | Numeric | String | Array[String] | nil)]
85
+ def to_h: () -> Hash[Symbol, bool | Numeric | String | Array[String] | nil]
84
86
 
85
87
  # : () -> String
86
88
  def inspect: () -> String
data/sig/herb.rbs CHANGED
@@ -1,8 +1,8 @@
1
1
  # Generated from lib/herb.rb with RBS::Inline
2
2
 
3
3
  module Herb
4
- # : (String input, ?track_whitespace: bool, ?track_locations: bool, ?analyze: bool, ?strict: bool, ?action_view_helpers: bool, ?transform_conditionals: bool, ?dot_notation_tags: bool, ?render_nodes: bool, ?strict_locals: bool, ?herb_directives: bool, ?iteration_nodes: bool, ?prism_nodes: bool, ?prism_nodes_deep: bool, ?prism_program: bool, ?html: bool, ?erb_openers: Array[String], ?arena_stats: bool) -> ParseResult
5
- def self.parse: (String input, ?track_whitespace: bool, ?track_locations: bool, ?analyze: bool, ?strict: bool, ?action_view_helpers: bool, ?transform_conditionals: bool, ?dot_notation_tags: bool, ?render_nodes: bool, ?strict_locals: bool, ?herb_directives: bool, ?iteration_nodes: bool, ?prism_nodes: bool, ?prism_nodes_deep: bool, ?prism_program: bool, ?html: bool, ?erb_openers: Array[String], ?arena_stats: bool) -> ParseResult
4
+ # : (String input, ?track_whitespace: bool, ?track_locations: bool, ?analyze: bool, ?strict: bool, ?action_view_helpers: bool, ?transform_conditionals: bool, ?dot_notation_tags: bool, ?render_nodes: bool, ?strict_locals: bool, ?herb_directives: bool, ?iteration_nodes: bool, ?prism_nodes: bool, ?prism_nodes_deep: bool, ?prism_program: bool, ?html: bool, ?erb_openers: Array[String], ?ruby_version: String?, ?arena_stats: bool) -> ParseResult
5
+ def self.parse: (String input, ?track_whitespace: bool, ?track_locations: bool, ?analyze: bool, ?strict: bool, ?action_view_helpers: bool, ?transform_conditionals: bool, ?dot_notation_tags: bool, ?render_nodes: bool, ?strict_locals: bool, ?herb_directives: bool, ?iteration_nodes: bool, ?prism_nodes: bool, ?prism_nodes_deep: bool, ?prism_program: bool, ?html: bool, ?erb_openers: Array[String], ?ruby_version: String?, ?arena_stats: bool) -> ParseResult
6
6
 
7
7
  # : (String input, ?erb_openers: Array[String], ?arena_stats: bool) -> LexResult
8
8
  def self.lex: (String input, ?erb_openers: Array[String], ?arena_stats: bool) -> LexResult
@@ -4,10 +4,12 @@
4
4
  #include "../../include/lib/hb_array.h"
5
5
  #include "../../include/lib/hb_buffer.h"
6
6
  #include "../../include/lib/hb_string.h"
7
+ #include "../../include/prism/prism_helpers.h"
7
8
  #include "../../include/util/html_util.h"
8
9
  #include "../../include/util/util.h"
9
10
 
10
11
  #include <prism.h>
12
+ #include <stdio.h>
11
13
  #include <stdlib.h>
12
14
  #include <string.h>
13
15
 
@@ -39,14 +41,14 @@ static void compute_position_pair(
39
41
  position_T* out_end
40
42
  ) {
41
43
  *out_start = prism_location_to_position_with_offset(location, original_source, erb_content_offset, source);
42
- pm_location_t end_location = { .start = location->end, .end = location->end };
44
+ pm_location_t end_location = { .start = herb_prism_location_end(*location), .length = 0 };
43
45
  *out_end = prism_location_to_position_with_offset(&end_location, original_source, erb_content_offset, source);
44
46
  }
45
47
 
46
48
  static void extract_key_name_location(pm_node_t* key, pm_location_t* out_name_loc) {
47
49
  if (key->type == PM_SYMBOL_NODE) {
48
50
  pm_symbol_node_t* symbol = (pm_symbol_node_t*) key;
49
- *out_name_loc = symbol->value_loc;
51
+ *out_name_loc = symbol->content_loc;
50
52
  } else if (key->type == PM_STRING_NODE) {
51
53
  pm_string_node_t* string_node = (pm_string_node_t*) key;
52
54
  *out_name_loc = string_node->content_loc;
@@ -69,7 +71,7 @@ static void compute_separator_info(
69
71
  *out_separator_end =
70
72
  prism_location_to_position_with_offset(&assoc->value->location, original_source, erb_content_offset, source);
71
73
 
72
- if (assoc->operator_loc.start != NULL) {
74
+ if (herb_prism_location_assigned(assoc->operator_loc)) {
73
75
  *out_separator_string = " => ";
74
76
  *out_separator_type = TOKEN_EQUALS;
75
77
  *out_separator_start = key_end;
@@ -78,8 +80,8 @@ static void compute_separator_info(
78
80
  *out_separator_type = TOKEN_COLON;
79
81
 
80
82
  pm_location_t colon_loc = {
81
- .start = assoc->key->location.end - 1,
82
- .end = assoc->key->location.end - 1,
83
+ .start = herb_prism_location_end(assoc->key->location) - 1,
84
+ .length = 0,
83
85
  };
84
86
 
85
87
  *out_separator_start =
@@ -102,7 +104,7 @@ static void extract_delimited_locations(
102
104
  pm_symbol_node_t* symbol_node = (pm_symbol_node_t*) node;
103
105
  *out_opening = &symbol_node->opening_loc;
104
106
  *out_closing = &symbol_node->closing_loc;
105
- *out_content = &symbol_node->value_loc;
107
+ *out_content = &symbol_node->content_loc;
106
108
  } else {
107
109
  *out_opening = NULL;
108
110
  *out_closing = NULL;
@@ -127,7 +129,8 @@ static void compute_value_positions(
127
129
 
128
130
  extract_delimited_locations(value_node, &opening_loc, &closing_loc, &content_loc);
129
131
 
130
- if (opening_loc && opening_loc->start != NULL && closing_loc && closing_loc->start != NULL) {
132
+ if (opening_loc && herb_prism_location_assigned(*opening_loc) && closing_loc
133
+ && herb_prism_location_assigned(*closing_loc)) {
131
134
  compute_position_pair(
132
135
  &*opening_loc,
133
136
  source,
@@ -167,7 +170,7 @@ static void fill_attribute_positions(
167
170
  );
168
171
 
169
172
  position_T key_end;
170
- pm_location_t key_end_loc = { .start = assoc->key->location.end, .end = assoc->key->location.end };
173
+ pm_location_t key_end_loc = { .start = herb_prism_location_end(assoc->key->location), .length = 0 };
171
174
  key_end = prism_location_to_position_with_offset(&key_end_loc, original_source, erb_content_offset, source);
172
175
 
173
176
  compute_separator_info(
@@ -246,6 +249,7 @@ static char* join_static_string_array(pm_array_node_t* array, hb_allocator_T* al
246
249
  static AST_NODE_T* create_attribute_from_value(
247
250
  const char* name_string,
248
251
  pm_node_t* value_node,
252
+ const uint8_t* source,
249
253
  attribute_positions_T* positions,
250
254
  hb_allocator_T* allocator,
251
255
  bool is_nested
@@ -281,8 +285,8 @@ static AST_NODE_T* create_attribute_from_value(
281
285
 
282
286
  return (AST_NODE_T*) create_html_attribute_node_precise(name_string, "false", positions, allocator);
283
287
  } else if (value_node->type == PM_INTEGER_NODE) {
284
- size_t value_length = value_node->location.end - value_node->location.start;
285
- char* value_string = hb_allocator_strndup(allocator, (const char*) value_node->location.start, value_length);
288
+ char* value_string =
289
+ hb_allocator_strndup(allocator, (const char*) (source + value_node->location.start), value_node->location.length);
286
290
  if (!value_string) { return NULL; }
287
291
 
288
292
  AST_HTML_ATTRIBUTE_NODE_T* attribute =
@@ -294,15 +298,17 @@ static AST_NODE_T* create_attribute_from_value(
294
298
  return (AST_NODE_T*) create_html_attribute_with_interpolated_value(
295
299
  name_string,
296
300
  (pm_interpolated_string_node_t*) value_node,
301
+ source,
297
302
  positions->name_start,
298
303
  positions->value_end,
299
304
  allocator
300
305
  );
301
306
  } else {
302
- size_t value_length = value_node->location.end - value_node->location.start;
303
- char* raw_content = hb_allocator_strndup(allocator, (const char*) value_node->location.start, value_length);
307
+ size_t value_length = value_node->location.length;
308
+ char* raw_content =
309
+ hb_allocator_strndup(allocator, (const char*) (source + value_node->location.start), value_length);
304
310
 
305
- if (raw_content && value_node->location.start) {
311
+ if (raw_content && herb_prism_location_assigned(value_node->location)) {
306
312
  char* ruby_content = raw_content;
307
313
  hb_buffer_T wrapper;
308
314
  bool wrapped = false;
@@ -488,8 +494,14 @@ AST_NODE_T* extract_html_attribute_from_assoc(
488
494
  fill_attribute_positions(assoc, source, original_source, erb_content_offset, &positions);
489
495
 
490
496
  char* dashed_name = convert_underscores_to_dashes(name_string);
491
- AST_NODE_T* attribute_node =
492
- create_attribute_from_value(dashed_name ? dashed_name : name_string, assoc->value, &positions, allocator, false);
497
+ AST_NODE_T* attribute_node = create_attribute_from_value(
498
+ dashed_name ? dashed_name : name_string,
499
+ assoc->value,
500
+ source,
501
+ &positions,
502
+ allocator,
503
+ false
504
+ );
493
505
 
494
506
  if (dashed_name) { free(dashed_name); }
495
507
  hb_allocator_dealloc(allocator, name_string);
@@ -516,8 +528,9 @@ hb_array_T* extract_html_attributes_from_keyword_hash(
516
528
  pm_assoc_splat_node_t* splat = (pm_assoc_splat_node_t*) element;
517
529
 
518
530
  if (splat->value) {
519
- size_t value_length = splat->value->location.end - splat->value->location.start;
520
- char* value_source = hb_allocator_strndup(allocator, (const char*) splat->value->location.start, value_length);
531
+ size_t value_length = splat->value->location.length;
532
+ char* value_source =
533
+ hb_allocator_strndup(allocator, (const char*) (source + splat->value->location.start), value_length);
521
534
 
522
535
  if (value_source) {
523
536
  hb_buffer_T wrapped;
@@ -560,9 +573,9 @@ hb_array_T* extract_html_attributes_from_keyword_hash(
560
573
  pm_assoc_splat_node_t* splat = (pm_assoc_splat_node_t*) hash_element;
561
574
 
562
575
  if (splat->value) {
563
- size_t value_length = splat->value->location.end - splat->value->location.start;
576
+ size_t value_length = splat->value->location.length;
564
577
  char* value_source =
565
- hb_allocator_strndup(allocator, (const char*) splat->value->location.start, value_length);
578
+ hb_allocator_strndup(allocator, (const char*) (source + splat->value->location.start), value_length);
566
579
 
567
580
  if (value_source) {
568
581
  hb_buffer_T wrapped;
@@ -612,8 +625,14 @@ hb_array_T* extract_html_attributes_from_keyword_hash(
612
625
  attribute_positions_T hash_positions;
613
626
  fill_attribute_positions(hash_assoc, source, original_source, erb_content_offset, &hash_positions);
614
627
 
615
- AST_NODE_T* attribute =
616
- create_attribute_from_value(attribute_key_string, hash_assoc->value, &hash_positions, allocator, true);
628
+ AST_NODE_T* attribute = create_attribute_from_value(
629
+ attribute_key_string,
630
+ hash_assoc->value,
631
+ source,
632
+ &hash_positions,
633
+ allocator,
634
+ true
635
+ );
617
636
 
618
637
  if (attribute) { hb_array_append(attributes, attribute); }
619
638
  hb_allocator_dealloc(allocator, attribute_key_string);
@@ -16,41 +16,41 @@
16
16
  bool detect_image_tag(pm_call_node_t* call_node, pm_parser_t* parser) {
17
17
  if (!call_node || !call_node->name) { return false; }
18
18
 
19
- pm_constant_t* constant = pm_constant_pool_id_to_constant(&parser->constant_pool, call_node->name);
19
+ const pm_constant_t* constant = pm_parser_constant(parser, call_node->name);
20
20
 
21
- return constant && constant->length == 9 && strncmp((const char*) constant->start, "image_tag", 9) == 0;
21
+ return constant && pm_constant_length(constant) == 9 && strncmp((const char*) pm_constant_start(constant), "image_tag", 9) == 0;
22
22
  }
23
23
 
24
24
  bool detect_javascript_include_tag(pm_call_node_t* call_node, pm_parser_t* parser) {
25
25
  if (!call_node || !call_node->name) { return false; }
26
26
 
27
- pm_constant_t* constant = pm_constant_pool_id_to_constant(&parser->constant_pool, call_node->name);
27
+ const pm_constant_t* constant = pm_parser_constant(parser, call_node->name);
28
28
 
29
- return constant && constant->length == 22 && strncmp((const char*) constant->start, "javascript_include_tag", 22) == 0;
29
+ return constant && pm_constant_length(constant) == 22 && strncmp((const char*) pm_constant_start(constant), "javascript_include_tag", 22) == 0;
30
30
  }
31
31
 
32
32
  bool detect_stylesheet_link_tag(pm_call_node_t* call_node, pm_parser_t* parser) {
33
33
  if (!call_node || !call_node->name) { return false; }
34
34
 
35
- pm_constant_t* constant = pm_constant_pool_id_to_constant(&parser->constant_pool, call_node->name);
35
+ const pm_constant_t* constant = pm_parser_constant(parser, call_node->name);
36
36
 
37
- return constant && constant->length == 19 && strncmp((const char*) constant->start, "stylesheet_link_tag", 19) == 0;
37
+ return constant && pm_constant_length(constant) == 19 && strncmp((const char*) pm_constant_start(constant), "stylesheet_link_tag", 19) == 0;
38
38
  }
39
39
 
40
40
  bool detect_javascript_tag(pm_call_node_t* call_node, pm_parser_t* parser) {
41
41
  if (!call_node || !call_node->name) { return false; }
42
42
 
43
- pm_constant_t* constant = pm_constant_pool_id_to_constant(&parser->constant_pool, call_node->name);
43
+ const pm_constant_t* constant = pm_parser_constant(parser, call_node->name);
44
44
 
45
- return constant && constant->length == 14 && strncmp((const char*) constant->start, "javascript_tag", 14) == 0;
45
+ return constant && pm_constant_length(constant) == 14 && strncmp((const char*) pm_constant_start(constant), "javascript_tag", 14) == 0;
46
46
  }
47
47
 
48
48
  bool detect_content_tag(pm_call_node_t* call_node, pm_parser_t* parser) {
49
49
  if (!call_node || !call_node->name) { return false; }
50
50
 
51
- pm_constant_t* constant = pm_constant_pool_id_to_constant(&parser->constant_pool, call_node->name);
51
+ const pm_constant_t* constant = pm_parser_constant(parser, call_node->name);
52
52
 
53
- return constant && constant->length == 11 && strncmp((const char*) constant->start, "content_tag", 11) == 0;
53
+ return constant && pm_constant_length(constant) == 11 && strncmp((const char*) pm_constant_start(constant), "content_tag", 11) == 0;
54
54
  }
55
55
 
56
56
  bool detect_tag(pm_call_node_t* call_node, pm_parser_t* parser) {
@@ -60,17 +60,17 @@ bool detect_tag(pm_call_node_t* call_node, pm_parser_t* parser) {
60
60
  pm_call_node_t* receiver_node = (pm_call_node_t*) call_node->receiver;
61
61
  if (!receiver_node->name) { return false; }
62
62
 
63
- pm_constant_t* constant = pm_constant_pool_id_to_constant(&parser->constant_pool, receiver_node->name);
63
+ const pm_constant_t* constant = pm_parser_constant(parser, receiver_node->name);
64
64
 
65
- return constant && constant->length == 3 && strncmp((const char*) constant->start, "tag", 3) == 0;
65
+ return constant && pm_constant_length(constant) == 3 && strncmp((const char*) pm_constant_start(constant), "tag", 3) == 0;
66
66
  }
67
67
 
68
68
  bool detect_turbo_frame_tag(pm_call_node_t* call_node, pm_parser_t* parser) {
69
69
  if (!call_node || !call_node->name) { return false; }
70
70
 
71
- pm_constant_t* constant = pm_constant_pool_id_to_constant(&parser->constant_pool, call_node->name);
71
+ const pm_constant_t* constant = pm_parser_constant(parser, call_node->name);
72
72
 
73
- return constant && constant->length == 15 && strncmp((const char*) constant->start, "turbo_frame_tag", 15) == 0;
73
+ return constant && pm_constant_length(constant) == 15 && strncmp((const char*) pm_constant_start(constant), "turbo_frame_tag", 15) == 0;
74
74
  }
75
75
 
76
76
  // ==========================================================================
@@ -133,14 +133,17 @@ extern bool is_ruby_introspection_method(hb_string_T method_name);
133
133
  static char* extract_tag_tag_name(pm_call_node_t* call_node, pm_parser_t* parser, hb_allocator_T* allocator) {
134
134
  if (!call_node || !call_node->name) { return NULL; }
135
135
 
136
- pm_constant_t* constant = pm_constant_pool_id_to_constant(&parser->constant_pool, call_node->name);
136
+ const pm_constant_t* constant = pm_parser_constant(parser, call_node->name);
137
137
  if (!constant) { return NULL; }
138
138
 
139
- if (is_ruby_introspection_method(hb_string_from_data((const char*) constant->start, constant->length))) { return NULL; }
139
+ const char* constant_start = (const char*) pm_constant_start(constant);
140
+ size_t constant_length = pm_constant_length(constant);
140
141
 
141
- char* name = hb_allocator_strndup(allocator, (const char*) constant->start, constant->length);
142
+ if (is_ruby_introspection_method(hb_string_from_data(constant_start, constant_length))) { return NULL; }
142
143
 
143
- for (size_t i = 0; i < constant->length && name[i] != '\0'; i++) {
144
+ char* name = hb_allocator_strndup(allocator, constant_start, constant_length);
145
+
146
+ for (size_t i = 0; i < constant_length && name[i] != '\0'; i++) {
144
147
  if (name[i] == '_') { name[i] = '-'; }
145
148
  }
146
149
 
@@ -182,9 +185,7 @@ static char* extract_stylesheet_link_tag_content(pm_call_node_t* _call_node, pm_
182
185
  return NULL;
183
186
  }
184
187
 
185
- static char* extract_javascript_tag_content(pm_call_node_t* call_node, pm_parser_t* _parser, hb_allocator_T* allocator) {
186
- (void) _parser;
187
-
188
+ static char* extract_javascript_tag_content(pm_call_node_t* call_node, pm_parser_t* parser, hb_allocator_T* allocator) {
188
189
  if (!call_node || !call_node->arguments) { return NULL; }
189
190
 
190
191
  pm_arguments_node_t* arguments = call_node->arguments;
@@ -200,17 +201,16 @@ static char* extract_javascript_tag_content(pm_call_node_t* call_node, pm_parser
200
201
  return hb_allocator_strndup(allocator, (const char*) pm_string_source(&string_node->unescaped), length);
201
202
  }
202
203
 
203
- size_t source_length = first_argument->location.end - first_argument->location.start;
204
- return hb_allocator_strndup(allocator, (const char*) first_argument->location.start, source_length);
204
+ const uint8_t* source = pm_parser_start(parser);
205
+ size_t source_length = first_argument->location.length;
206
+ return hb_allocator_strndup(allocator, (const char*) (source + first_argument->location.start), source_length);
205
207
  }
206
208
 
207
- static char* extract_content_tag_content(pm_call_node_t* call_node, pm_parser_t* _parser, hb_allocator_T* allocator) {
208
- (void) _parser;
209
-
209
+ static char* extract_content_tag_content(pm_call_node_t* call_node, pm_parser_t* parser, hb_allocator_T* allocator) {
210
210
  if (!call_node) { return NULL; }
211
211
 
212
212
 
213
- char* block_content = extract_inline_block_content(call_node, allocator);
213
+ char* block_content = extract_inline_block_content(call_node, parser, allocator);
214
214
  if (block_content) { return block_content; }
215
215
 
216
216
 
@@ -228,10 +228,11 @@ static char* extract_content_tag_content(pm_call_node_t* call_node, pm_parser_t*
228
228
  return hb_allocator_strndup(allocator, (const char*) pm_string_source(&string_node->unescaped), length);
229
229
  }
230
230
 
231
- size_t source_length = argument->location.end - argument->location.start;
231
+ const uint8_t* source = pm_parser_start(parser);
232
+ size_t source_length = argument->location.length;
232
233
 
233
234
 
234
- return hb_allocator_strndup(allocator, (const char*) argument->location.start, source_length);
235
+ return hb_allocator_strndup(allocator, (const char*) (source + argument->location.start), source_length);
235
236
 
236
237
  }
237
238
  }
@@ -241,19 +242,17 @@ static char* extract_content_tag_content(pm_call_node_t* call_node, pm_parser_t*
241
242
  }
242
243
 
243
244
  static char* extract_tag_content(pm_call_node_t* call_node, pm_parser_t* parser, hb_allocator_T* allocator) {
244
- (void) parser;
245
-
246
245
  if (!call_node) { return NULL; }
247
246
 
248
247
  if (call_node->name) {
249
- pm_constant_t* constant = pm_constant_pool_id_to_constant(&parser->constant_pool, call_node->name);
248
+ const pm_constant_t* constant = pm_parser_constant(parser, call_node->name);
250
249
 
251
- if (constant && is_ruby_introspection_method(hb_string_from_data((const char*) constant->start, constant->length))) {
250
+ if (constant && is_ruby_introspection_method(hb_string_from_data((const char*) pm_constant_start(constant), pm_constant_length(constant)))) {
252
251
  return NULL;
253
252
  }
254
253
  }
255
254
 
256
- char* block_content = extract_inline_block_content(call_node, allocator);
255
+ char* block_content = extract_inline_block_content(call_node, parser, allocator);
257
256
  if (block_content) { return block_content; }
258
257
 
259
258
 
@@ -271,10 +270,11 @@ static char* extract_tag_content(pm_call_node_t* call_node, pm_parser_t* parser,
271
270
  return hb_allocator_strndup(allocator, (const char*) pm_string_source(&string_node->unescaped), length);
272
271
  }
273
272
 
274
- size_t source_length = argument->location.end - argument->location.start;
273
+ const uint8_t* source = pm_parser_start(parser);
274
+ size_t source_length = argument->location.length;
275
275
 
276
276
 
277
- return hb_allocator_strndup(allocator, (const char*) argument->location.start, source_length);
277
+ return hb_allocator_strndup(allocator, (const char*) (source + argument->location.start), source_length);
278
278
 
279
279
  }
280
280
  }
@@ -5,7 +5,7 @@
5
5
  #include <stdbool.h>
6
6
  #include <string.h>
7
7
 
8
- char* extract_image_tag_src(pm_call_node_t* call_node, pm_parser_t* _parser, hb_allocator_T* allocator) {
8
+ char* extract_image_tag_src(pm_call_node_t* call_node, pm_parser_t* parser, hb_allocator_T* allocator) {
9
9
  if (!call_node || !call_node->arguments) { return NULL; }
10
10
 
11
11
  pm_arguments_node_t* arguments = call_node->arguments;
@@ -20,9 +20,13 @@ char* extract_image_tag_src(pm_call_node_t* call_node, pm_parser_t* _parser, hb_
20
20
  return hb_allocator_strndup(allocator, (const char*) pm_string_source(&string_node->unescaped), length);
21
21
  }
22
22
 
23
- size_t source_length = first_argument->location.end - first_argument->location.start;
23
+ const uint8_t* source = pm_parser_start(parser);
24
24
 
25
- return hb_allocator_strndup(allocator, (const char*) first_argument->location.start, source_length);
25
+ return hb_allocator_strndup(
26
+ allocator,
27
+ (const char*) (source + first_argument->location.start),
28
+ first_argument->location.length
29
+ );
26
30
  }
27
31
 
28
32
  bool image_tag_source_is_url(const char* source, size_t length) {
@@ -6,7 +6,6 @@
6
6
  #include <string.h>
7
7
 
8
8
  char* extract_javascript_include_tag_src(pm_call_node_t* call_node, pm_parser_t* parser, hb_allocator_T* allocator) {
9
- (void) parser;
10
9
 
11
10
  if (!call_node || !call_node->arguments) { return NULL; }
12
11
 
@@ -22,8 +21,12 @@ char* extract_javascript_include_tag_src(pm_call_node_t* call_node, pm_parser_t*
22
21
  return hb_allocator_strndup(allocator, (const char*) pm_string_source(&string_node->unescaped), length);
23
22
  }
24
23
 
25
- size_t source_length = first_argument->location.end - first_argument->location.start;
26
- return hb_allocator_strndup(allocator, (const char*) first_argument->location.start, source_length);
24
+ const uint8_t* source = pm_parser_start(parser);
25
+ return hb_allocator_strndup(
26
+ allocator,
27
+ (const char*) (source + first_argument->location.start),
28
+ first_argument->location.length
29
+ );
27
30
  }
28
31
 
29
32
  bool javascript_include_tag_source_is_url(const char* source, size_t length) {
@@ -25,9 +25,10 @@ char* wrap_in_url_for(const char* source, size_t source_length, hb_allocator_T*
25
25
  bool detect_link_to(pm_call_node_t* call_node, pm_parser_t* parser) {
26
26
  if (!call_node || !call_node->name) { return false; }
27
27
 
28
- pm_constant_t* constant = pm_constant_pool_id_to_constant(&parser->constant_pool, call_node->name);
28
+ const pm_constant_t* constant = pm_parser_constant(parser, call_node->name);
29
29
 
30
- return constant && constant->length == 7 && strncmp((const char*) constant->start, "link_to", 7) == 0;
30
+ return constant && pm_constant_length(constant) == 7
31
+ && strncmp((const char*) pm_constant_start(constant), "link_to", 7) == 0;
31
32
  }
32
33
 
33
34
  bool is_route_helper_node(pm_node_t* node, pm_parser_t* parser) {
@@ -36,11 +37,11 @@ bool is_route_helper_node(pm_node_t* node, pm_parser_t* parser) {
36
37
  pm_call_node_t* call = (pm_call_node_t*) node;
37
38
  if (!call->name) { return false; }
38
39
 
39
- pm_constant_t* constant = pm_constant_pool_id_to_constant(&parser->constant_pool, call->name);
40
- if (!constant || constant->length < 5) { return false; }
40
+ const pm_constant_t* constant = pm_parser_constant(parser, call->name);
41
+ if (!constant || pm_constant_length(constant) < 5) { return false; }
41
42
 
42
- const char* name = (const char*) constant->start;
43
- size_t length = constant->length;
43
+ const char* name = (const char*) pm_constant_start(constant);
44
+ size_t length = pm_constant_length(constant);
44
45
 
45
46
  return (length >= 5 && strncmp(name + length - 5, "_path", 5) == 0)
46
47
  || (length >= 4 && strncmp(name + length - 4, "_url", 4) == 0);
@@ -54,11 +55,9 @@ char* extract_link_to_tag_name(pm_call_node_t* call_node, pm_parser_t* parser, h
54
55
  }
55
56
 
56
57
  char* extract_link_to_content(pm_call_node_t* call_node, pm_parser_t* parser, hb_allocator_T* allocator) {
57
- (void) parser;
58
-
59
58
  if (!call_node) { return NULL; }
60
59
 
61
- char* block_content = extract_inline_block_content(call_node, allocator);
60
+ char* block_content = extract_inline_block_content(call_node, parser, allocator);
62
61
  if (block_content) { return block_content; }
63
62
 
64
63
  if (!call_node->arguments) { return NULL; }
@@ -76,7 +75,8 @@ char* extract_link_to_content(pm_call_node_t* call_node, pm_parser_t* parser, hb
76
75
  return hb_allocator_strndup(allocator, (const char*) pm_string_source(&string_node->unescaped), length);
77
76
  }
78
77
 
79
- size_t source_length = first_argument->location.end - first_argument->location.start;
78
+ const uint8_t* source = pm_parser_start(parser);
79
+ size_t source_length = first_argument->location.length;
80
80
 
81
81
  // Format: "<expression>.to_s"
82
82
  if (arguments->arguments.size == 1) {
@@ -85,21 +85,21 @@ char* extract_link_to_content(pm_call_node_t* call_node, pm_parser_t* parser, hb
85
85
  size_t total_length = source_length + suffix_len;
86
86
  char* ruby_expression = hb_allocator_alloc(allocator, total_length + 1);
87
87
 
88
- memcpy(ruby_expression, (const char*) first_argument->location.start, source_length);
88
+ memcpy(ruby_expression, (const char*) (source + first_argument->location.start), source_length);
89
89
  memcpy(ruby_expression + source_length, suffix, suffix_len);
90
90
  ruby_expression[total_length] = '\0';
91
91
 
92
92
  return ruby_expression;
93
93
  }
94
94
 
95
- return hb_allocator_strndup(allocator, (const char*) first_argument->location.start, source_length);
95
+ return hb_allocator_strndup(allocator, (const char*) (source + first_argument->location.start), source_length);
96
96
  }
97
97
 
98
98
  char* extract_link_to_href(pm_call_node_t* call_node, pm_parser_t* parser, hb_allocator_T* allocator) {
99
- (void) parser;
100
-
101
99
  if (!call_node || !call_node->arguments) { return NULL; }
102
100
 
101
+ const uint8_t* source = pm_parser_start(parser);
102
+
103
103
  pm_arguments_node_t* arguments = call_node->arguments;
104
104
  bool has_inline_block = call_node->block && call_node->block->type == PM_BLOCK_NODE;
105
105
 
@@ -112,13 +112,13 @@ char* extract_link_to_href(pm_call_node_t* call_node, pm_parser_t* parser, hb_al
112
112
  return hb_allocator_strndup(allocator, (const char*) pm_string_source(&string_node->unescaped), length);
113
113
  }
114
114
 
115
- size_t source_length = first_argument->location.end - first_argument->location.start;
115
+ size_t source_length = first_argument->location.length;
116
116
 
117
117
  if (is_route_helper_node(first_argument, parser)) {
118
- return hb_allocator_strndup(allocator, (const char*) first_argument->location.start, source_length);
118
+ return hb_allocator_strndup(allocator, (const char*) (source + first_argument->location.start), source_length);
119
119
  }
120
120
 
121
- return wrap_in_url_for((const char*) first_argument->location.start, source_length, allocator);
121
+ return wrap_in_url_for((const char*) (source + first_argument->location.start), source_length, allocator);
122
122
  }
123
123
 
124
124
  // Format: "url_for(<expression>)"
@@ -127,13 +127,13 @@ char* extract_link_to_href(pm_call_node_t* call_node, pm_parser_t* parser, hb_al
127
127
 
128
128
  if (first_argument->type == PM_STRING_NODE || first_argument->type == PM_NIL_NODE) { return NULL; }
129
129
 
130
- size_t source_length = first_argument->location.end - first_argument->location.start;
130
+ size_t source_length = first_argument->location.length;
131
131
 
132
132
  if (is_route_helper_node(first_argument, parser)) {
133
- return hb_allocator_strndup(allocator, (const char*) first_argument->location.start, source_length);
133
+ return hb_allocator_strndup(allocator, (const char*) (source + first_argument->location.start), source_length);
134
134
  }
135
135
 
136
- return wrap_in_url_for((const char*) first_argument->location.start, source_length, allocator);
136
+ return wrap_in_url_for((const char*) (source + first_argument->location.start), source_length, allocator);
137
137
  }
138
138
 
139
139
  if (arguments->arguments.size < 2) { return NULL; }
@@ -146,13 +146,13 @@ char* extract_link_to_href(pm_call_node_t* call_node, pm_parser_t* parser, hb_al
146
146
  return hb_allocator_strndup(allocator, (const char*) pm_string_source(&string_node->unescaped), length);
147
147
  }
148
148
 
149
- size_t source_length = second_argument->location.end - second_argument->location.start;
149
+ size_t source_length = second_argument->location.length;
150
150
 
151
151
  if (!is_route_helper_node(second_argument, parser)) {
152
- return wrap_in_url_for((const char*) second_argument->location.start, source_length, allocator);
152
+ return wrap_in_url_for((const char*) (source + second_argument->location.start), source_length, allocator);
153
153
  }
154
154
 
155
- return hb_allocator_strndup(allocator, (const char*) second_argument->location.start, source_length);
155
+ return hb_allocator_strndup(allocator, (const char*) (source + second_argument->location.start), source_length);
156
156
  }
157
157
 
158
158
  bool link_to_supports_block(void) {
@@ -59,7 +59,7 @@ size_t get_tag_helper_handlers_count(void) {
59
59
  return handlers_count;
60
60
  }
61
61
 
62
- char* extract_inline_block_content(pm_call_node_t* call_node, hb_allocator_T* allocator) {
62
+ char* extract_inline_block_content(pm_call_node_t* call_node, pm_parser_t* parser, hb_allocator_T* allocator) {
63
63
  if (!call_node || !call_node->block || call_node->block->type != PM_BLOCK_NODE) { return NULL; }
64
64
 
65
65
  pm_block_node_t* block_node = (pm_block_node_t*) call_node->block;
@@ -78,6 +78,10 @@ char* extract_inline_block_content(pm_call_node_t* call_node, hb_allocator_T* al
78
78
  return hb_allocator_strndup(allocator, (const char*) pm_string_source(&string_node->unescaped), length);
79
79
  }
80
80
 
81
- size_t source_length = statement->location.end - statement->location.start;
82
- return hb_allocator_strndup(allocator, (const char*) statement->location.start, source_length);
81
+ const uint8_t* source = pm_parser_start(parser);
82
+ return hb_allocator_strndup(
83
+ allocator,
84
+ (const char*) (source + statement->location.start),
85
+ statement->location.length
86
+ );
83
87
  }
@@ -304,6 +304,7 @@ AST_HTML_ATTRIBUTE_NODE_T* create_html_attribute_with_ruby_literal(
304
304
 
305
305
  static AST_HTML_ATTRIBUTE_VALUE_NODE_T* create_interpolated_attribute_value(
306
306
  pm_interpolated_string_node_t* interpolated_node,
307
+ const uint8_t* source,
307
308
  position_T start_position,
308
309
  position_T end_position,
309
310
  hb_allocator_T* allocator
@@ -338,19 +339,10 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* create_interpolated_attribute_value(
338
339
  }
339
340
  } else if (part->type == PM_EMBEDDED_STATEMENTS_NODE) {
340
341
  pm_embedded_statements_node_t* embedded = (pm_embedded_statements_node_t*) part;
341
- const uint8_t* content_start;
342
- const uint8_t* content_end;
343
-
344
- if (embedded->statements) {
345
- content_start = embedded->statements->base.location.start;
346
- content_end = embedded->statements->base.location.end;
347
- } else {
348
- content_start = part->location.start;
349
- content_end = part->location.end;
350
- }
342
+ pm_location_t content_location = embedded->statements ? embedded->statements->base.location : part->location;
351
343
 
352
- size_t ruby_length = content_end - content_start;
353
- char* ruby_content = hb_allocator_strndup(allocator, (const char*) content_start, ruby_length);
344
+ char* ruby_content =
345
+ hb_allocator_strndup(allocator, (const char*) (source + content_location.start), content_location.length);
354
346
 
355
347
  if (ruby_content) {
356
348
  AST_RUBY_LITERAL_NODE_T* ruby_node = ast_ruby_literal_node_init(
@@ -386,6 +378,7 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* create_interpolated_attribute_value(
386
378
  AST_HTML_ATTRIBUTE_NODE_T* create_html_attribute_with_interpolated_value(
387
379
  const char* name_string,
388
380
  pm_interpolated_string_node_t* interpolated_node,
381
+ const uint8_t* source,
389
382
  position_T start_position,
390
383
  position_T end_position,
391
384
  hb_allocator_T* allocator
@@ -396,7 +389,7 @@ AST_HTML_ATTRIBUTE_NODE_T* create_html_attribute_with_interpolated_value(
396
389
  create_attribute_name_node(name_string, start_position, end_position, allocator);
397
390
 
398
391
  AST_HTML_ATTRIBUTE_VALUE_NODE_T* value_node =
399
- create_interpolated_attribute_value(interpolated_node, start_position, end_position, allocator);
392
+ create_interpolated_attribute_value(interpolated_node, source, start_position, end_position, allocator);
400
393
 
401
394
  token_T* equals_token = create_synthetic_token(allocator, "=", TOKEN_EQUALS, start_position, end_position);
402
395