herb 0.10.4 → 0.11.0

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 (784) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +16 -6
  3. data/README.md +36 -119
  4. data/Rakefile +2 -11
  5. data/config/action_view_helpers/actioncable/action_cable_helper/action_cable_meta_tag.yml +12 -8
  6. data/config/action_view_helpers/actionpack/content_security_policy/content_security_policy?.yml +9 -6
  7. data/config/action_view_helpers/actionpack/content_security_policy/content_security_policy_nonce.yml +9 -6
  8. data/config/action_view_helpers/actionpack/polymorphic_routes/polymorphic_path.yml +20 -12
  9. data/config/action_view_helpers/actionpack/polymorphic_routes/polymorphic_url.yml +30 -18
  10. data/config/action_view_helpers/actionpack/request_forgery_protection/form_authenticity_token.yml +15 -9
  11. data/config/action_view_helpers/actionpack/request_forgery_protection/protect_against_forgery?.yml +9 -6
  12. data/config/action_view_helpers/actiontext/content_helper/render_action_text_content.yml +15 -9
  13. data/config/action_view_helpers/actiontext/content_helper/sanitize_action_text_content.yml +15 -9
  14. data/config/action_view_helpers/actiontext/tag_helper/rich_textarea_tag.yml +34 -22
  15. data/config/action_view_helpers/actionview/active_model_helper/error_message.yml +9 -6
  16. data/config/action_view_helpers/actionview/active_model_helper/error_wrapping.yml +9 -6
  17. data/config/action_view_helpers/actionview/active_model_helper/object.yml +9 -6
  18. data/config/action_view_helpers/actionview/asset_tag_helper/apply_stylesheet_media_default.yml +9 -6
  19. data/config/action_view_helpers/actionview/asset_tag_helper/audio_tag.yml +40 -27
  20. data/config/action_view_helpers/actionview/asset_tag_helper/auto_discovery_link_tag.yml +37 -23
  21. data/config/action_view_helpers/actionview/asset_tag_helper/auto_include_nonce.yml +9 -6
  22. data/config/action_view_helpers/actionview/asset_tag_helper/auto_include_nonce_for_scripts.yml +9 -6
  23. data/config/action_view_helpers/actionview/asset_tag_helper/auto_include_nonce_for_styles.yml +9 -6
  24. data/config/action_view_helpers/actionview/asset_tag_helper/favicon_link_tag.yml +32 -22
  25. data/config/action_view_helpers/actionview/asset_tag_helper/image_decoding.yml +9 -6
  26. data/config/action_view_helpers/actionview/asset_tag_helper/image_loading.yml +9 -6
  27. data/config/action_view_helpers/actionview/asset_tag_helper/image_tag.yml +67 -46
  28. data/config/action_view_helpers/actionview/asset_tag_helper/javascript_include_tag.yml +58 -39
  29. data/config/action_view_helpers/actionview/asset_tag_helper/picture_tag.yml +22 -14
  30. data/config/action_view_helpers/actionview/asset_tag_helper/preload_link_tag.yml +45 -30
  31. data/config/action_view_helpers/actionview/asset_tag_helper/preload_links_header.yml +9 -6
  32. data/config/action_view_helpers/actionview/asset_tag_helper/stylesheet_link_tag.yml +49 -30
  33. data/config/action_view_helpers/actionview/asset_tag_helper/video_tag.yml +53 -35
  34. data/config/action_view_helpers/actionview/asset_url_helper/asset_path.yml +16 -10
  35. data/config/action_view_helpers/actionview/asset_url_helper/asset_url.yml +16 -10
  36. data/config/action_view_helpers/actionview/asset_url_helper/audio_path.yml +16 -10
  37. data/config/action_view_helpers/actionview/asset_url_helper/audio_url.yml +16 -10
  38. data/config/action_view_helpers/actionview/asset_url_helper/compute_asset_extname.yml +9 -6
  39. data/config/action_view_helpers/actionview/asset_url_helper/compute_asset_host.yml +9 -6
  40. data/config/action_view_helpers/actionview/asset_url_helper/compute_asset_path.yml +9 -6
  41. data/config/action_view_helpers/actionview/asset_url_helper/font_path.yml +16 -10
  42. data/config/action_view_helpers/actionview/asset_url_helper/font_url.yml +16 -10
  43. data/config/action_view_helpers/actionview/asset_url_helper/image_path.yml +16 -10
  44. data/config/action_view_helpers/actionview/asset_url_helper/image_url.yml +16 -10
  45. data/config/action_view_helpers/actionview/asset_url_helper/javascript_path.yml +16 -10
  46. data/config/action_view_helpers/actionview/asset_url_helper/javascript_url.yml +16 -10
  47. data/config/action_view_helpers/actionview/asset_url_helper/public_compute_asset_path.yml +9 -6
  48. data/config/action_view_helpers/actionview/asset_url_helper/stylesheet_path.yml +16 -10
  49. data/config/action_view_helpers/actionview/asset_url_helper/stylesheet_url.yml +16 -10
  50. data/config/action_view_helpers/actionview/asset_url_helper/video_path.yml +16 -10
  51. data/config/action_view_helpers/actionview/asset_url_helper/video_url.yml +16 -10
  52. data/config/action_view_helpers/actionview/atom_feed_helper/atom_feed.yml +52 -27
  53. data/config/action_view_helpers/actionview/cache_helper/cache.yml +25 -15
  54. data/config/action_view_helpers/actionview/cache_helper/cache_fragment_name.yml +9 -6
  55. data/config/action_view_helpers/actionview/cache_helper/cache_if.yml +20 -12
  56. data/config/action_view_helpers/actionview/cache_helper/cache_unless.yml +20 -12
  57. data/config/action_view_helpers/actionview/cache_helper/caching_predicate.yml +9 -6
  58. data/config/action_view_helpers/actionview/cache_helper/digest_path_from_template.yml +9 -6
  59. data/config/action_view_helpers/actionview/cache_helper/fragment_for.yml +9 -6
  60. data/config/action_view_helpers/actionview/cache_helper/fragment_name_with_digest.yml +9 -6
  61. data/config/action_view_helpers/actionview/cache_helper/read_fragment_for.yml +9 -6
  62. data/config/action_view_helpers/actionview/cache_helper/uncacheable.yml +9 -6
  63. data/config/action_view_helpers/actionview/cache_helper/write_fragment_for.yml +9 -6
  64. data/config/action_view_helpers/actionview/capture_helper/capture.yml +9 -6
  65. data/config/action_view_helpers/actionview/capture_helper/content_for.yml +20 -12
  66. data/config/action_view_helpers/actionview/capture_helper/content_for_predicate.yml +15 -9
  67. data/config/action_view_helpers/actionview/capture_helper/provide.yml +15 -9
  68. data/config/action_view_helpers/actionview/capture_helper/with_output_buffer.yml +9 -6
  69. data/config/action_view_helpers/actionview/content_exfiltration_prevention_helper/prepend_content_exfiltration_prevention.yml +9 -6
  70. data/config/action_view_helpers/actionview/content_exfiltration_prevention_helper/prevent_content_exfiltration.yml +9 -6
  71. data/config/action_view_helpers/actionview/controller_helper/action_name.yml +9 -6
  72. data/config/action_view_helpers/actionview/controller_helper/assign_controller.yml +9 -6
  73. data/config/action_view_helpers/actionview/controller_helper/controller.yml +9 -6
  74. data/config/action_view_helpers/actionview/controller_helper/controller_name.yml +9 -6
  75. data/config/action_view_helpers/actionview/controller_helper/controller_path.yml +9 -6
  76. data/config/action_view_helpers/actionview/controller_helper/cookies.yml +9 -6
  77. data/config/action_view_helpers/actionview/controller_helper/flash.yml +9 -6
  78. data/config/action_view_helpers/actionview/controller_helper/headers.yml +9 -6
  79. data/config/action_view_helpers/actionview/controller_helper/logger.yml +9 -6
  80. data/config/action_view_helpers/actionview/controller_helper/params.yml +9 -6
  81. data/config/action_view_helpers/actionview/controller_helper/request.yml +9 -6
  82. data/config/action_view_helpers/actionview/controller_helper/request_forgery_protection_token.yml +9 -6
  83. data/config/action_view_helpers/actionview/controller_helper/response.yml +9 -6
  84. data/config/action_view_helpers/actionview/controller_helper/session.yml +9 -6
  85. data/config/action_view_helpers/actionview/csp_helper/csp_meta_tag.yml +18 -11
  86. data/config/action_view_helpers/actionview/csrf_helper/csrf_meta_tags.yml +16 -10
  87. data/config/action_view_helpers/actionview/date_helper/date_select.yml +85 -51
  88. data/config/action_view_helpers/actionview/date_helper/datetime_select.yml +65 -39
  89. data/config/action_view_helpers/actionview/date_helper/distance_of_time_in_words.yml +30 -18
  90. data/config/action_view_helpers/actionview/date_helper/relative_time_in_words.yml +35 -21
  91. data/config/action_view_helpers/actionview/date_helper/select_date.yml +50 -30
  92. data/config/action_view_helpers/actionview/date_helper/select_datetime.yml +65 -39
  93. data/config/action_view_helpers/actionview/date_helper/select_day.yml +40 -24
  94. data/config/action_view_helpers/actionview/date_helper/select_hour.yml +50 -30
  95. data/config/action_view_helpers/actionview/date_helper/select_minute.yml +40 -24
  96. data/config/action_view_helpers/actionview/date_helper/select_month.yml +60 -36
  97. data/config/action_view_helpers/actionview/date_helper/select_second.yml +35 -21
  98. data/config/action_view_helpers/actionview/date_helper/select_time.yml +55 -33
  99. data/config/action_view_helpers/actionview/date_helper/select_year.yml +45 -27
  100. data/config/action_view_helpers/actionview/date_helper/time_ago_in_words.yml +21 -13
  101. data/config/action_view_helpers/actionview/date_helper/time_select.yml +60 -36
  102. data/config/action_view_helpers/actionview/date_helper/time_tag.yml +32 -20
  103. data/config/action_view_helpers/actionview/debug_helper/debug.yml +15 -9
  104. data/config/action_view_helpers/actionview/form_builder/button.yml +60 -0
  105. data/config/action_view_helpers/actionview/form_builder/submit.yml +48 -0
  106. data/config/action_view_helpers/actionview/form_helper/apply_form_for_options.yml +9 -6
  107. data/config/action_view_helpers/actionview/form_helper/checkbox.yml +41 -25
  108. data/config/action_view_helpers/actionview/form_helper/color_field.yml +25 -15
  109. data/config/action_view_helpers/actionview/form_helper/date_field.yml +35 -21
  110. data/config/action_view_helpers/actionview/form_helper/datetime_field.yml +41 -25
  111. data/config/action_view_helpers/actionview/form_helper/email_field.yml +25 -15
  112. data/config/action_view_helpers/actionview/form_helper/emitted_hidden_id.yml +9 -6
  113. data/config/action_view_helpers/actionview/form_helper/fields.yml +37 -18
  114. data/config/action_view_helpers/actionview/form_helper/fields_for.yml +33 -15
  115. data/config/action_view_helpers/actionview/form_helper/file_field.yml +45 -27
  116. data/config/action_view_helpers/actionview/form_helper/form_for.yml +45 -24
  117. data/config/action_view_helpers/actionview/form_helper/form_with.yml +56 -30
  118. data/config/action_view_helpers/actionview/form_helper/form_with_generates_ids.yml +9 -6
  119. data/config/action_view_helpers/actionview/form_helper/form_with_generates_remote_forms.yml +9 -6
  120. data/config/action_view_helpers/actionview/form_helper/hidden_field.yml +25 -15
  121. data/config/action_view_helpers/actionview/form_helper/label.yml +52 -27
  122. data/config/action_view_helpers/actionview/form_helper/month_field.yml +25 -15
  123. data/config/action_view_helpers/actionview/form_helper/multipart.yml +9 -6
  124. data/config/action_view_helpers/actionview/form_helper/multiple_file_field_include_hidden.yml +9 -6
  125. data/config/action_view_helpers/actionview/form_helper/number_field.yml +45 -27
  126. data/config/action_view_helpers/actionview/form_helper/password_field.yml +25 -15
  127. data/config/action_view_helpers/actionview/form_helper/radio_button.yml +30 -18
  128. data/config/action_view_helpers/actionview/form_helper/range_field.yml +45 -27
  129. data/config/action_view_helpers/actionview/form_helper/search_field.yml +25 -15
  130. data/config/action_view_helpers/actionview/form_helper/telephone_field.yml +26 -16
  131. data/config/action_view_helpers/actionview/form_helper/text_field.yml +25 -15
  132. data/config/action_view_helpers/actionview/form_helper/textarea.yml +31 -19
  133. data/config/action_view_helpers/actionview/form_helper/time_field.yml +40 -24
  134. data/config/action_view_helpers/actionview/form_helper/url_field.yml +25 -15
  135. data/config/action_view_helpers/actionview/form_helper/week_field.yml +25 -15
  136. data/config/action_view_helpers/actionview/form_options_helper/collection_checkboxes.yml +58 -31
  137. data/config/action_view_helpers/actionview/form_options_helper/collection_radio_buttons.yml +57 -30
  138. data/config/action_view_helpers/actionview/form_options_helper/collection_select.yml +65 -39
  139. data/config/action_view_helpers/actionview/form_options_helper/grouped_collection_select.yml +65 -39
  140. data/config/action_view_helpers/actionview/form_options_helper/grouped_options_for_select.yml +35 -21
  141. data/config/action_view_helpers/actionview/form_options_helper/option_groups_from_collection_for_select.yml +40 -24
  142. data/config/action_view_helpers/actionview/form_options_helper/options_for_select.yml +20 -12
  143. data/config/action_view_helpers/actionview/form_options_helper/options_from_collection_for_select.yml +30 -18
  144. data/config/action_view_helpers/actionview/form_options_helper/select.yml +60 -36
  145. data/config/action_view_helpers/actionview/form_options_helper/time_zone_options_for_select.yml +25 -15
  146. data/config/action_view_helpers/actionview/form_options_helper/time_zone_select.yml +50 -30
  147. data/config/action_view_helpers/actionview/form_options_helper/weekday_options_for_select.yml +30 -18
  148. data/config/action_view_helpers/actionview/form_options_helper/weekday_select.yml +30 -18
  149. data/config/action_view_helpers/actionview/form_tag_helper/button_tag.yml +39 -21
  150. data/config/action_view_helpers/actionview/form_tag_helper/checkbox_tag.yml +33 -21
  151. data/config/action_view_helpers/actionview/form_tag_helper/color_field_tag.yml +26 -17
  152. data/config/action_view_helpers/actionview/form_tag_helper/date_field_tag.yml +27 -17
  153. data/config/action_view_helpers/actionview/form_tag_helper/datetime_field_tag.yml +28 -18
  154. data/config/action_view_helpers/actionview/form_tag_helper/default_enforce_utf8.yml +9 -6
  155. data/config/action_view_helpers/actionview/form_tag_helper/email_field_tag.yml +27 -17
  156. data/config/action_view_helpers/actionview/form_tag_helper/embed_authenticity_token_in_remote_forms.yml +9 -6
  157. data/config/action_view_helpers/actionview/form_tag_helper/field_id.yml +30 -18
  158. data/config/action_view_helpers/actionview/form_tag_helper/field_name.yml +30 -18
  159. data/config/action_view_helpers/actionview/form_tag_helper/field_set_tag.yml +23 -15
  160. data/config/action_view_helpers/actionview/form_tag_helper/file_field_tag.yml +35 -22
  161. data/config/action_view_helpers/actionview/form_tag_helper/form_tag.yml +38 -24
  162. data/config/action_view_helpers/actionview/form_tag_helper/hidden_field_tag.yml +27 -17
  163. data/config/action_view_helpers/actionview/form_tag_helper/image_submit_tag.yml +31 -21
  164. data/config/action_view_helpers/actionview/form_tag_helper/label_tag.yml +33 -17
  165. data/config/action_view_helpers/actionview/form_tag_helper/month_field_tag.yml +27 -17
  166. data/config/action_view_helpers/actionview/form_tag_helper/number_field_tag.yml +47 -29
  167. data/config/action_view_helpers/actionview/form_tag_helper/password_field_tag.yml +27 -17
  168. data/config/action_view_helpers/actionview/form_tag_helper/radio_button_tag.yml +32 -20
  169. data/config/action_view_helpers/actionview/form_tag_helper/range_field_tag.yml +47 -29
  170. data/config/action_view_helpers/actionview/form_tag_helper/search_field_tag.yml +27 -17
  171. data/config/action_view_helpers/actionview/form_tag_helper/select_tag.yml +47 -29
  172. data/config/action_view_helpers/actionview/form_tag_helper/submit_tag.yml +33 -21
  173. data/config/action_view_helpers/actionview/form_tag_helper/telephone_field_tag.yml +28 -18
  174. data/config/action_view_helpers/actionview/form_tag_helper/text_field_tag.yml +27 -17
  175. data/config/action_view_helpers/actionview/form_tag_helper/textarea_tag.yml +31 -20
  176. data/config/action_view_helpers/actionview/form_tag_helper/time_field_tag.yml +27 -17
  177. data/config/action_view_helpers/actionview/form_tag_helper/url_field_tag.yml +27 -17
  178. data/config/action_view_helpers/actionview/form_tag_helper/utf8_enforcer_tag.yml +9 -6
  179. data/config/action_view_helpers/actionview/form_tag_helper/week_field_tag.yml +28 -18
  180. data/config/action_view_helpers/actionview/javascript_helper/escape_javascript.yml +16 -10
  181. data/config/action_view_helpers/actionview/javascript_helper/javascript_cdata_section.yml +9 -6
  182. data/config/action_view_helpers/actionview/javascript_helper/javascript_tag.yml +41 -27
  183. data/config/action_view_helpers/actionview/number_helper/number_to_currency.yml +29 -18
  184. data/config/action_view_helpers/actionview/number_helper/number_to_human.yml +25 -15
  185. data/config/action_view_helpers/actionview/number_helper/number_to_human_size.yml +20 -12
  186. data/config/action_view_helpers/actionview/number_helper/number_to_percentage.yml +20 -12
  187. data/config/action_view_helpers/actionview/number_helper/number_to_phone.yml +33 -20
  188. data/config/action_view_helpers/actionview/number_helper/number_with_delimiter.yml +21 -13
  189. data/config/action_view_helpers/actionview/number_helper/number_with_precision.yml +25 -15
  190. data/config/action_view_helpers/actionview/output_safety_helper/raw.yml +15 -9
  191. data/config/action_view_helpers/actionview/output_safety_helper/safe_join.yml +20 -12
  192. data/config/action_view_helpers/actionview/output_safety_helper/to_sentence.yml +24 -15
  193. data/config/action_view_helpers/actionview/record_identifier/dom_class.yml +20 -12
  194. data/config/action_view_helpers/actionview/record_identifier/dom_id.yml +20 -12
  195. data/config/action_view_helpers/actionview/record_identifier/dom_target.yml +15 -9
  196. data/config/action_view_helpers/actionview/record_identifier/model_name_from_record_or_class.yml +9 -6
  197. data/config/action_view_helpers/actionview/rendering_helper/render.yml +108 -22
  198. data/config/action_view_helpers/actionview/sanitize_helper/sanitize.yml +25 -15
  199. data/config/action_view_helpers/actionview/sanitize_helper/sanitize_css.yml +15 -9
  200. data/config/action_view_helpers/actionview/sanitize_helper/sanitizer_vendor.yml +9 -6
  201. data/config/action_view_helpers/actionview/sanitize_helper/strip_links.yml +15 -9
  202. data/config/action_view_helpers/actionview/sanitize_helper/strip_tags.yml +15 -9
  203. data/config/action_view_helpers/actionview/tag_helper/cdata_section.yml +15 -9
  204. data/config/action_view_helpers/actionview/tag_helper/content_tag.yml +59 -38
  205. data/config/action_view_helpers/actionview/tag_helper/escape_once.yml +15 -9
  206. data/config/action_view_helpers/actionview/tag_helper/tag.yml +54 -31
  207. data/config/action_view_helpers/actionview/tag_helper/token_list.yml +16 -10
  208. data/config/action_view_helpers/actionview/text_helper/concat.yml +15 -9
  209. data/config/action_view_helpers/actionview/text_helper/current_cycle.yml +15 -9
  210. data/config/action_view_helpers/actionview/text_helper/cycle.yml +23 -14
  211. data/config/action_view_helpers/actionview/text_helper/excerpt.yml +33 -20
  212. data/config/action_view_helpers/actionview/text_helper/highlight.yml +37 -18
  213. data/config/action_view_helpers/actionview/text_helper/pluralize.yml +30 -18
  214. data/config/action_view_helpers/actionview/text_helper/reset_cycle.yml +15 -9
  215. data/config/action_view_helpers/actionview/text_helper/safe_concat.yml +9 -6
  216. data/config/action_view_helpers/actionview/text_helper/simple_format.yml +33 -20
  217. data/config/action_view_helpers/actionview/text_helper/truncate.yml +38 -23
  218. data/config/action_view_helpers/actionview/text_helper/word_wrap.yml +25 -15
  219. data/config/action_view_helpers/actionview/translation_helper/debug_missing_translation.yml +9 -6
  220. data/config/action_view_helpers/actionview/translation_helper/localize.yml +26 -16
  221. data/config/action_view_helpers/actionview/translation_helper/translate.yml +31 -19
  222. data/config/action_view_helpers/actionview/url_helper/button_to.yml +57 -33
  223. data/config/action_view_helpers/actionview/url_helper/button_to_generates_button_tag.yml +9 -6
  224. data/config/action_view_helpers/actionview/url_helper/current_page?.yml +25 -15
  225. data/config/action_view_helpers/actionview/url_helper/link_to.yml +76 -53
  226. data/config/action_view_helpers/actionview/url_helper/link_to_if.yml +54 -20
  227. data/config/action_view_helpers/actionview/url_helper/link_to_unless.yml +54 -20
  228. data/config/action_view_helpers/actionview/url_helper/link_to_unless_current.yml +49 -17
  229. data/config/action_view_helpers/actionview/url_helper/mail_to.yml +60 -34
  230. data/config/action_view_helpers/actionview/url_helper/phone_to.yml +40 -22
  231. data/config/action_view_helpers/actionview/url_helper/sms_to.yml +45 -25
  232. data/config/action_view_helpers/actionview/url_helper/url_for.yml +15 -9
  233. data/config/action_view_helpers/importmap-rails/importmap_tags_helper/javascript_import_module_tag.yml +32 -0
  234. data/config/action_view_helpers/importmap-rails/importmap_tags_helper/javascript_importmap_module_preload_tags.yml +39 -0
  235. data/config/action_view_helpers/importmap-rails/importmap_tags_helper/javascript_importmap_tags.yml +35 -0
  236. data/config/action_view_helpers/importmap-rails/importmap_tags_helper/javascript_inline_importmap_tag.yml +32 -0
  237. data/config/action_view_helpers/importmap-rails/importmap_tags_helper/javascript_module_preload_tag.yml +35 -0
  238. data/config/action_view_helpers/turbo-rails/drive_helper/turbo_exempts_page_from_cache.yml +9 -6
  239. data/config/action_view_helpers/turbo-rails/drive_helper/turbo_exempts_page_from_cache_tag.yml +12 -8
  240. data/config/action_view_helpers/turbo-rails/drive_helper/turbo_exempts_page_from_preview.yml +9 -6
  241. data/config/action_view_helpers/turbo-rails/drive_helper/turbo_exempts_page_from_preview_tag.yml +12 -8
  242. data/config/action_view_helpers/turbo-rails/drive_helper/turbo_page_requires_reload.yml +9 -6
  243. data/config/action_view_helpers/turbo-rails/drive_helper/turbo_page_requires_reload_tag.yml +12 -8
  244. data/config/action_view_helpers/turbo-rails/drive_helper/turbo_refresh_method_tag.yml +17 -11
  245. data/config/action_view_helpers/turbo-rails/drive_helper/turbo_refresh_scroll_tag.yml +17 -11
  246. data/config/action_view_helpers/turbo-rails/drive_helper/turbo_refreshes_with.yml +20 -12
  247. data/config/action_view_helpers/turbo-rails/frames_helper/turbo_frame_tag.yml +54 -33
  248. data/config/action_view_helpers/turbo-rails/includes_helper/turbo_include_tags.yml +9 -6
  249. data/config/action_view_helpers/turbo-rails/streams_action_helper/turbo_stream_action_tag.yml +32 -20
  250. data/config/action_view_helpers/turbo-rails/streams_action_helper/turbo_stream_refresh_tag.yml +18 -11
  251. data/config/action_view_helpers/turbo-rails/streams_helper/turbo_stream.yml +9 -6
  252. data/config/action_view_helpers/turbo-rails/streams_helper/turbo_stream_from.yml +28 -18
  253. data/config/html_elements.yml +597 -0
  254. data/config/options.yml +1 -0
  255. data/config/slots/components.yml +52 -0
  256. data/config/state/kind.yml +61 -0
  257. data/config/state/operators.yml +27 -0
  258. data/config/state/predicates.yml +39 -0
  259. data/config/state/transforms.yml +18 -0
  260. data/config/view_context_methods/actionview/base/annotate_rendered_view_with_filenames.yml +4 -4
  261. data/config/view_context_methods/actionview/base/assign.yml +4 -4
  262. data/config/view_context_methods/actionview/base/assigns.yml +4 -4
  263. data/config/view_context_methods/actionview/base/automatically_disable_submit_tag.yml +4 -4
  264. data/config/view_context_methods/actionview/base/compiled_method_container.yml +4 -4
  265. data/config/view_context_methods/actionview/base/config.yml +4 -4
  266. data/config/view_context_methods/actionview/base/default_form_builder.yml +4 -4
  267. data/config/view_context_methods/actionview/base/default_formats.yml +4 -4
  268. data/config/view_context_methods/actionview/base/field_error_proc.yml +4 -4
  269. data/config/view_context_methods/actionview/base/formats.yml +4 -4
  270. data/config/view_context_methods/actionview/base/in_rendering_context.yml +4 -4
  271. data/config/view_context_methods/actionview/base/locale.yml +4 -4
  272. data/config/view_context_methods/actionview/base/lookup_context.yml +4 -4
  273. data/config/view_context_methods/actionview/base/output_buffer.yml +4 -4
  274. data/config/view_context_methods/actionview/base/prefix_partial_path_with_controller_namespace.yml +4 -4
  275. data/config/view_context_methods/actionview/base/remove_hidden_field_autocomplete.yml +4 -4
  276. data/config/view_context_methods/actionview/base/streaming_completion_on_exception.yml +4 -4
  277. data/config/view_context_methods/actionview/base/view_flow.yml +4 -4
  278. data/config/view_context_methods/actionview/base/view_paths.yml +4 -4
  279. data/config/view_context_methods/actionview/base/view_renderer.yml +4 -4
  280. data/config/view_context_methods/actionview/template/local_assigns.yml +4 -4
  281. data/config/view_context_methods/activemodel/conversion/convert_to_model.yml +4 -4
  282. data/config/view_context_methods/activesupport/benchmarkable/benchmark.yml +4 -4
  283. data/config.yml +1240 -790
  284. data/exe/herb +2 -0
  285. data/ext/herb/error_helpers.c +355 -17
  286. data/ext/herb/error_helpers.h +1 -1
  287. data/ext/herb/extconf.rb +4 -2
  288. data/ext/herb/extension.c +137 -89
  289. data/ext/herb/extension_helpers.c +81 -42
  290. data/ext/herb/extension_helpers.h +4 -1
  291. data/ext/herb/nodes.c +826 -358
  292. data/ext/herb/nodes.h +3 -2
  293. data/ext/herb/parser_options_helpers.c +151 -0
  294. data/ext/herb/parser_options_helpers.h +14 -0
  295. data/herb.gemspec +2 -2
  296. data/lib/herb/action_view/helper_registry.rb +1358 -62
  297. data/lib/herb/analysis/partial_declaration.rb +140 -0
  298. data/lib/herb/analysis/partial_index.rb +189 -0
  299. data/lib/herb/analysis/partial_resolution.rb +161 -0
  300. data/lib/herb/analysis/partial_resolver.rb +144 -0
  301. data/lib/herb/analysis/project_index.rb +152 -0
  302. data/lib/herb/{action_view → analysis}/render_analyzer.rb +287 -77
  303. data/lib/herb/analysis/render_graph/ancestor_chain.rb +27 -0
  304. data/lib/herb/analysis/render_graph/builder.rb +376 -0
  305. data/lib/herb/analysis/render_graph/call_frame.rb +9 -0
  306. data/lib/herb/analysis/render_graph/call_site_location.rb +23 -0
  307. data/lib/herb/analysis/render_graph/inferred_signature.rb +21 -0
  308. data/lib/herb/analysis/render_graph/partial_call_site.rb +40 -0
  309. data/lib/herb/analysis/render_graph/partial_context.rb +46 -0
  310. data/lib/herb/analysis/render_graph/template_roots.rb +31 -0
  311. data/lib/herb/analysis/render_graph.rb +285 -0
  312. data/lib/herb/analysis/ruby_locals_index/local.rb +25 -0
  313. data/lib/herb/analysis/ruby_locals_index/named_reference.rb +22 -0
  314. data/lib/herb/analysis/ruby_locals_index/offset_table.rb +44 -0
  315. data/lib/herb/analysis/ruby_locals_index/reference_collector.rb +80 -0
  316. data/lib/herb/analysis/ruby_locals_index/state_locals.rb +49 -0
  317. data/lib/herb/analysis/ruby_locals_index.rb +165 -0
  318. data/lib/herb/analysis/ruby_reference.rb +67 -0
  319. data/lib/herb/analysis/template_dependencies/dependency_collector.rb +179 -0
  320. data/lib/herb/analysis/template_dependencies/node_dependency_collector.rb +309 -0
  321. data/lib/herb/analysis/template_dependencies.rb +562 -0
  322. data/lib/herb/ast/erb_render_node.rb +26 -94
  323. data/lib/herb/ast/helpers.rb +90 -10
  324. data/lib/herb/ast/herb_directive_node.rb +18 -0
  325. data/lib/herb/ast/node.rb +32 -2
  326. data/lib/herb/ast/nodes.rb +1342 -105
  327. data/lib/herb/backend.rb +73 -0
  328. data/lib/herb/bootstrap.rb +3 -7
  329. data/lib/herb/cli.rb +550 -32
  330. data/lib/herb/colors.rb +14 -0
  331. data/lib/herb/configuration.rb +71 -35
  332. data/lib/herb/defaults.yml +2 -1
  333. data/lib/herb/dev/assets.rb +57 -0
  334. data/lib/herb/dev/classifier.rb +84 -0
  335. data/lib/herb/dev/embedded.rb +27 -0
  336. data/lib/herb/dev/pipeline.rb +305 -0
  337. data/lib/herb/dev/protocol.rb +221 -0
  338. data/lib/herb/dev/runner.rb +175 -175
  339. data/lib/herb/dev/server.rb +89 -26
  340. data/lib/herb/dev/server_entry.rb +41 -6
  341. data/lib/herb/dev/watcher.rb +181 -0
  342. data/lib/herb/dev.rb +163 -0
  343. data/lib/herb/diagnostic/formatter.rb +88 -0
  344. data/lib/herb/diagnostic.rb +172 -0
  345. data/lib/herb/diff/operation.rb +36 -0
  346. data/lib/herb/diff/result.rb +62 -0
  347. data/lib/herb/diff.rb +10 -0
  348. data/lib/herb/engine/collector.rb +62 -0
  349. data/lib/herb/engine/compiler.rb +346 -108
  350. data/lib/herb/engine/component_tags/constant_resolver.rb +28 -0
  351. data/lib/herb/engine/component_tags/partial_resolver.rb +54 -0
  352. data/lib/herb/engine/component_tags/resolver.rb +32 -0
  353. data/lib/herb/engine/component_tags/visitor.rb +231 -0
  354. data/lib/herb/engine/css_inliner/inliner.rb +101 -0
  355. data/lib/herb/engine/css_inliner/visitor.rb +174 -0
  356. data/lib/herb/engine/errors.rb +122 -0
  357. data/lib/herb/engine/helpers.rb +82 -0
  358. data/lib/herb/engine/inline_render/inliner.rb +122 -0
  359. data/lib/herb/engine/inline_render/visitor.rb +267 -0
  360. data/lib/herb/engine/runtime/entry.rb +62 -0
  361. data/lib/herb/engine/runtime/error_page.rb +362 -0
  362. data/lib/herb/engine/runtime/html_safe_assertions.rb +217 -0
  363. data/lib/herb/engine/runtime/journal/summary.rb +227 -0
  364. data/lib/herb/engine/runtime/journal.rb +379 -0
  365. data/lib/herb/engine/runtime/middleware.rb +212 -0
  366. data/lib/herb/engine/runtime/observations.rb +73 -0
  367. data/lib/herb/engine/runtime/report.rb +204 -0
  368. data/lib/herb/engine/runtime/session.rb +437 -0
  369. data/lib/herb/engine/runtime.rb +21 -0
  370. data/lib/herb/engine/scoped_style/channel.rb +66 -0
  371. data/lib/herb/engine/scoped_style/collector.rb +74 -0
  372. data/lib/herb/engine/scoped_style/visitor.rb +533 -0
  373. data/lib/herb/engine/slots/annotation.rb +98 -0
  374. data/lib/herb/engine/slots/bindings.rb +61 -0
  375. data/lib/herb/engine/slots/callee.rb +118 -0
  376. data/lib/herb/engine/slots/component_definitions.rb +67 -0
  377. data/lib/herb/engine/slots/components/async.rb +24 -0
  378. data/lib/herb/engine/slots/components/base.rb +132 -0
  379. data/lib/herb/engine/slots/components/deferred.rb +81 -0
  380. data/lib/herb/engine/slots/components/fallback.rb +27 -0
  381. data/lib/herb/engine/slots/components/fragment.rb +99 -0
  382. data/lib/herb/engine/slots/components/lazy.rb +24 -0
  383. data/lib/herb/engine/slots/components.rb +52 -0
  384. data/lib/herb/engine/slots/dependencies/channel.rb +72 -0
  385. data/lib/herb/engine/slots/dependencies.rb +269 -0
  386. data/lib/herb/engine/slots/dynamics_compiler.rb +854 -0
  387. data/lib/herb/engine/slots/identifier.rb +35 -0
  388. data/lib/herb/engine/slots/manifest/channel.rb +74 -0
  389. data/lib/herb/engine/slots/manifest/collector.rb +75 -0
  390. data/lib/herb/engine/slots/markers.rb +128 -0
  391. data/lib/herb/engine/slots/render_bindings.rb +141 -0
  392. data/lib/herb/engine/slots/schema_compiler.rb +94 -0
  393. data/lib/herb/engine/slots/state_anchor.rb +94 -0
  394. data/lib/herb/engine/slots/state_compiler.rb +1326 -0
  395. data/lib/herb/engine/slots/state_directives.rb +854 -0
  396. data/lib/herb/engine/slots/state_kinds.rb +54 -0
  397. data/lib/herb/engine/slots/state_operators.rb +36 -0
  398. data/lib/herb/engine/slots/state_overrides.rb +79 -0
  399. data/lib/herb/engine/slots/state_predicates.rb +65 -0
  400. data/lib/herb/engine/slots/state_transforms.rb +42 -0
  401. data/lib/herb/engine/slots/statics.rb +185 -0
  402. data/lib/herb/engine/slots/subtree.rb +82 -0
  403. data/lib/herb/engine/slots/subtree_compiler.rb +255 -0
  404. data/lib/herb/engine/slots/types.rb +42 -0
  405. data/lib/herb/engine/slots/visitor.rb +2256 -0
  406. data/lib/herb/engine/validators/accessibility_validator.rb +3 -3
  407. data/lib/herb/engine/validators/base.rb +36 -0
  408. data/lib/herb/engine/validators/generator_template_validator.rb +39 -0
  409. data/lib/herb/engine/validators/nesting_validator.rb +3 -3
  410. data/lib/herb/engine/validators/render_validator.rb +13 -33
  411. data/lib/herb/engine/validators/security_validator.rb +3 -17
  412. data/lib/herb/engine/validators.rb +43 -0
  413. data/lib/herb/engine/visitors/auto_close_omitted_tags_visitor.rb +48 -0
  414. data/lib/herb/engine/visitors/content_for_visitor.rb +127 -0
  415. data/lib/herb/engine/{debug_visitor.rb → visitors/debug_visitor.rb} +121 -93
  416. data/lib/herb/engine/visitors/html_safe_assertions_visitor.rb +281 -0
  417. data/lib/herb/engine/visitors/instrumentation_visitor.rb +290 -0
  418. data/lib/herb/engine/visitors/optimize_visitor.rb +728 -0
  419. data/lib/herb/engine/visitors/remove_comments_visitor.rb +106 -0
  420. data/lib/herb/engine/visitors/source_attribution_visitor.rb +177 -0
  421. data/lib/herb/engine.rb +218 -257
  422. data/lib/herb/ensure_installed.rb +43 -0
  423. data/lib/herb/errors.rb +646 -157
  424. data/lib/herb/fingerprint.rb +82 -0
  425. data/lib/herb/html/elements.rb +18 -0
  426. data/lib/herb/html/util.rb +21 -2
  427. data/lib/herb/lex_result.rb +0 -10
  428. data/lib/herb/locate.rb +163 -0
  429. data/lib/herb/location.rb +20 -0
  430. data/lib/herb/parse_result.rb +17 -11
  431. data/lib/herb/parser_options.rb +65 -46
  432. data/lib/herb/position.rb +19 -0
  433. data/lib/herb/prism_inspect.rb +1 -4
  434. data/lib/herb/project.rb +28 -15
  435. data/lib/herb/range.rb +5 -0
  436. data/lib/herb/result.rb +2 -2
  437. data/lib/herb/ruby_program.rb +110 -0
  438. data/lib/herb/source_path.rb +232 -0
  439. data/lib/herb/token.rb +14 -3
  440. data/lib/herb/version.rb +1 -1
  441. data/lib/herb/visitor/context/origin.rb +52 -0
  442. data/lib/herb/visitor/context/replacements.rb +59 -0
  443. data/lib/herb/visitor/context.rb +169 -0
  444. data/lib/herb/visitor/context_aware.rb +45 -0
  445. data/lib/herb/visitor/diagnostics.rb +148 -0
  446. data/lib/herb/visitor/experimental.rb +33 -0
  447. data/lib/herb/visitor/parser_option_requirements.rb +151 -0
  448. data/lib/herb/visitor/stack.rb +192 -0
  449. data/lib/herb/visitor.rb +47 -1
  450. data/lib/herb/warnings.rb +25 -0
  451. data/lib/herb.rb +74 -63
  452. data/sig/herb/action_view/helper_registry.rbs +82 -10
  453. data/sig/herb/analysis/partial_declaration.rbs +80 -0
  454. data/sig/herb/analysis/partial_index.rbs +66 -0
  455. data/sig/herb/analysis/partial_resolution.rbs +57 -0
  456. data/sig/herb/analysis/partial_resolver.rbs +76 -0
  457. data/sig/herb/analysis/project_index.rbs +57 -0
  458. data/sig/herb/{action_view → analysis}/render_analyzer.rbs +25 -4
  459. data/sig/herb/analysis/render_graph/ancestor_chain.rbs +22 -0
  460. data/sig/herb/analysis/render_graph/builder.rbs +180 -0
  461. data/sig/herb/analysis/render_graph/call_frame.rbs +26 -0
  462. data/sig/herb/analysis/render_graph/call_site_location.rbs +28 -0
  463. data/sig/herb/analysis/render_graph/inferred_signature.rbs +27 -0
  464. data/sig/herb/analysis/render_graph/partial_call_site.rbs +36 -0
  465. data/sig/herb/analysis/render_graph/partial_context.rbs +31 -0
  466. data/sig/herb/analysis/render_graph/template_roots.rbs +32 -0
  467. data/sig/herb/analysis/render_graph.rbs +83 -0
  468. data/sig/herb/analysis/ruby_locals_index/local.rbs +21 -0
  469. data/sig/herb/analysis/ruby_locals_index/named_reference.rbs +20 -0
  470. data/sig/herb/analysis/ruby_locals_index/offset_table.rbs +26 -0
  471. data/sig/herb/analysis/ruby_locals_index/reference_collector.rbs +40 -0
  472. data/sig/herb/analysis/ruby_locals_index/state_locals.rbs +19 -0
  473. data/sig/herb/analysis/ruby_locals_index.rbs +62 -0
  474. data/sig/herb/analysis/ruby_reference.rbs +28 -0
  475. data/sig/herb/analysis/template_dependencies/dependency_collector.rbs +52 -0
  476. data/sig/herb/analysis/template_dependencies/node_dependency_collector.rbs +81 -0
  477. data/sig/herb/analysis/template_dependencies.rbs +125 -0
  478. data/sig/herb/ast/erb_render_node.rbs +10 -2
  479. data/sig/herb/ast/helpers.rbs +31 -1
  480. data/sig/herb/ast/herb_directive_node.rbs +13 -0
  481. data/sig/herb/ast/node.rbs +9 -0
  482. data/sig/herb/ast/nodes.rbs +662 -89
  483. data/sig/herb/backend.rbs +52 -0
  484. data/sig/herb/colors.rbs +3 -0
  485. data/sig/herb/configuration.rbs +27 -3
  486. data/sig/herb/dev/assets.rbs +27 -0
  487. data/sig/herb/dev/classifier.rbs +57 -0
  488. data/sig/herb/dev/embedded.rbs +21 -0
  489. data/sig/herb/dev/pipeline.rbs +118 -0
  490. data/sig/herb/dev/protocol.rbs +78 -0
  491. data/sig/herb/dev/runner.rbs +61 -23
  492. data/sig/herb/dev/server.rbs +49 -22
  493. data/sig/herb/dev/server_entry.rbs +46 -21
  494. data/sig/herb/dev/watcher.rbs +84 -0
  495. data/sig/herb/dev.rbs +58 -0
  496. data/sig/herb/diagnostic/formatter.rbs +28 -0
  497. data/sig/herb/diagnostic.rbs +88 -0
  498. data/sig/herb/diff/operation.rbs +36 -0
  499. data/sig/herb/diff/result.rbs +36 -0
  500. data/sig/herb/diff.rbs +6 -0
  501. data/sig/herb/engine/collector.rbs +48 -0
  502. data/sig/herb/engine/compiler.rbs +62 -23
  503. data/sig/herb/engine/component_tags/constant_resolver.rbs +19 -0
  504. data/sig/herb/engine/component_tags/partial_resolver.rbs +30 -0
  505. data/sig/herb/engine/component_tags/resolver.rbs +25 -0
  506. data/sig/herb/engine/component_tags/visitor.rbs +69 -0
  507. data/sig/herb/engine/css_inliner/inliner.rbs +65 -0
  508. data/sig/herb/engine/css_inliner/visitor.rbs +87 -0
  509. data/sig/herb/engine/errors.rbs +68 -0
  510. data/sig/herb/engine/helpers.rbs +28 -0
  511. data/sig/herb/engine/inline_render/inliner.rbs +39 -0
  512. data/sig/herb/engine/inline_render/visitor.rbs +104 -0
  513. data/sig/herb/engine/runtime/entry.rbs +43 -0
  514. data/sig/herb/engine/runtime/error_page.rbs +115 -0
  515. data/sig/herb/engine/runtime/html_safe_assertions.rbs +99 -0
  516. data/sig/herb/engine/runtime/journal/summary.rbs +172 -0
  517. data/sig/herb/engine/runtime/journal.rbs +126 -0
  518. data/sig/herb/engine/runtime/middleware.rbs +96 -0
  519. data/sig/herb/engine/runtime/observations.rbs +38 -0
  520. data/sig/herb/engine/runtime/report.rbs +97 -0
  521. data/sig/herb/engine/runtime/session.rbs +233 -0
  522. data/sig/herb/engine/runtime.rbs +14 -0
  523. data/sig/herb/engine/scoped_style/channel.rbs +45 -0
  524. data/sig/herb/engine/scoped_style/collector.rbs +45 -0
  525. data/sig/herb/engine/scoped_style/visitor.rbs +220 -0
  526. data/sig/herb/engine/slots/annotation.rbs +72 -0
  527. data/sig/herb/engine/slots/bindings.rbs +34 -0
  528. data/sig/herb/engine/slots/callee.rbs +62 -0
  529. data/sig/herb/engine/slots/component_definitions.rbs +19 -0
  530. data/sig/herb/engine/slots/components/async.rbs +20 -0
  531. data/sig/herb/engine/slots/components/base.rbs +60 -0
  532. data/sig/herb/engine/slots/components/deferred.rbs +29 -0
  533. data/sig/herb/engine/slots/components/fallback.rbs +21 -0
  534. data/sig/herb/engine/slots/components/fragment.rbs +34 -0
  535. data/sig/herb/engine/slots/components/lazy.rbs +20 -0
  536. data/sig/herb/engine/slots/components.rbs +30 -0
  537. data/sig/herb/engine/slots/dependencies/channel.rbs +51 -0
  538. data/sig/herb/engine/slots/dependencies.rbs +94 -0
  539. data/sig/herb/engine/slots/dynamics_compiler.rbs +349 -0
  540. data/sig/herb/engine/slots/identifier.rbs +19 -0
  541. data/sig/herb/engine/slots/manifest/channel.rbs +49 -0
  542. data/sig/herb/engine/slots/manifest/collector.rbs +45 -0
  543. data/sig/herb/engine/slots/markers.rbs +85 -0
  544. data/sig/herb/engine/slots/render_bindings.rbs +69 -0
  545. data/sig/herb/engine/slots/schema_compiler.rbs +62 -0
  546. data/sig/herb/engine/slots/state_anchor.rbs +41 -0
  547. data/sig/herb/engine/slots/state_compiler.rbs +258 -0
  548. data/sig/herb/engine/slots/state_directives.rbs +278 -0
  549. data/sig/herb/engine/slots/state_kinds.rbs +24 -0
  550. data/sig/herb/engine/slots/state_operators.rbs +19 -0
  551. data/sig/herb/engine/slots/state_overrides.rbs +33 -0
  552. data/sig/herb/engine/slots/state_predicates.rbs +16 -0
  553. data/sig/herb/engine/slots/state_transforms.rbs +15 -0
  554. data/sig/herb/engine/slots/statics.rbs +67 -0
  555. data/sig/herb/engine/slots/subtree.rbs +49 -0
  556. data/sig/herb/engine/slots/subtree_compiler.rbs +130 -0
  557. data/sig/herb/engine/slots/types.rbs +46 -0
  558. data/sig/herb/engine/slots/visitor.rbs +599 -0
  559. data/sig/herb/engine/validators/accessibility_validator.rbs +1 -1
  560. data/sig/herb/engine/validators/base.rbs +28 -0
  561. data/sig/herb/engine/validators/generator_template_validator.rbs +19 -0
  562. data/sig/herb/engine/validators/nesting_validator.rbs +1 -1
  563. data/sig/herb/engine/validators/render_validator.rbs +2 -6
  564. data/sig/herb/engine/validators/security_validator.rbs +1 -3
  565. data/sig/herb/engine/validators.rbs +21 -0
  566. data/sig/herb/engine/visitors/auto_close_omitted_tags_visitor.rbs +26 -0
  567. data/sig/herb/engine/visitors/content_for_visitor.rbs +52 -0
  568. data/sig/herb/engine/{debug_visitor.rbs → visitors/debug_visitor.rbs} +26 -15
  569. data/sig/herb/engine/visitors/html_safe_assertions_visitor.rbs +100 -0
  570. data/sig/herb/engine/visitors/instrumentation_visitor.rbs +111 -0
  571. data/sig/herb/engine/visitors/optimize_visitor.rbs +246 -0
  572. data/sig/herb/engine/visitors/remove_comments_visitor.rbs +66 -0
  573. data/sig/herb/engine/visitors/source_attribution_visitor.rbs +90 -0
  574. data/sig/herb/engine.rbs +47 -41
  575. data/sig/herb/ensure_installed.rbs +9 -0
  576. data/sig/herb/errors.rbs +293 -0
  577. data/sig/herb/fingerprint.rbs +37 -0
  578. data/sig/herb/html/elements.rbs +19 -0
  579. data/sig/herb/html/util.rbs +15 -1
  580. data/sig/herb/lex_result.rbs +0 -6
  581. data/sig/herb/locate.rbs +89 -0
  582. data/sig/herb/location.rbs +12 -0
  583. data/sig/herb/parse_result.rbs +10 -8
  584. data/sig/herb/parser_options.rbs +47 -21
  585. data/sig/herb/position.rbs +11 -0
  586. data/sig/herb/range.rbs +3 -0
  587. data/sig/herb/ruby_program.rbs +51 -0
  588. data/sig/herb/source_path.rbs +132 -0
  589. data/sig/herb/token.rbs +5 -2
  590. data/sig/herb/visitor/context/origin.rbs +51 -0
  591. data/sig/herb/visitor/context/replacements.rbs +39 -0
  592. data/sig/herb/visitor/context.rbs +83 -0
  593. data/sig/herb/visitor/context_aware.rbs +32 -0
  594. data/sig/herb/visitor/diagnostics.rbs +82 -0
  595. data/sig/herb/visitor/experimental.rbs +23 -0
  596. data/sig/herb/visitor/parser_option_requirements.rbs +76 -0
  597. data/sig/herb/visitor/stack.rbs +91 -0
  598. data/sig/herb/visitor.rbs +22 -0
  599. data/sig/herb/warnings.rbs +10 -0
  600. data/sig/herb.rbs +27 -10
  601. data/sig/serialized_ast_errors.rbs +58 -1
  602. data/sig/serialized_ast_nodes.rbs +58 -2
  603. data/src/analyze/action_view/attribute_extraction_helpers.c +73 -36
  604. data/src/analyze/action_view/generated_handlers.c +37 -1
  605. data/src/analyze/action_view/generated_handlers.h +2 -1
  606. data/src/analyze/action_view/helper_registry.c +1353 -58
  607. data/src/analyze/action_view/registry.c +10 -17
  608. data/src/analyze/action_view/stylesheet_link_tag.c +40 -0
  609. data/src/analyze/action_view/tag_helper_node_builders.c +57 -0
  610. data/src/analyze/action_view/tag_helpers.c +423 -93
  611. data/src/analyze/analyze.c +301 -64
  612. data/src/analyze/analyze_helpers.c +420 -23
  613. data/src/analyze/builders.c +79 -51
  614. data/src/analyze/conditional_elements.c +13 -8
  615. data/src/analyze/conditional_open_tags.c +11 -5
  616. data/src/analyze/control_type.c +16 -1
  617. data/src/analyze/herb_directives.c +701 -0
  618. data/src/analyze/invalid_structures.c +11 -7
  619. data/src/analyze/iteration_nodes.c +306 -0
  620. data/src/analyze/missing_end.c +116 -32
  621. data/src/analyze/parse_errors.c +8 -3
  622. data/src/analyze/postfix_conditionals.c +98 -63
  623. data/src/analyze/prism_annotate.c +13 -4
  624. data/src/analyze/render_nodes.c +345 -123
  625. data/src/analyze/strict_locals.c +30 -26
  626. data/src/analyze/ternary_conditionals.c +95 -70
  627. data/src/analyze/transform.c +43 -1
  628. data/src/ast/ast_node.c +3 -13
  629. data/src/ast/ast_nodes.c +911 -112
  630. data/src/ast/ast_pretty_print.c +161 -2
  631. data/src/diff/herb_diff.c +8 -0
  632. data/src/diff/herb_diff_attributes.c +1 -0
  633. data/src/diff/herb_diff_children.c +4 -3
  634. data/src/diff/herb_diff_helpers.c +7 -1
  635. data/src/diff/herb_diff_nodes.c +186 -71
  636. data/src/diff/herb_hash_tree.c +99 -1
  637. data/src/errors.c +1096 -128
  638. data/src/extract.c +30 -8
  639. data/src/herb.c +30 -11
  640. data/src/include/analyze/action_view/attribute_extraction_helpers.h +1 -1
  641. data/src/include/analyze/action_view/helper_registry.h +28 -4
  642. data/src/include/analyze/action_view/tag_helper_handler.h +1 -1
  643. data/src/include/analyze/action_view/tag_helper_node_builders.h +7 -0
  644. data/src/include/analyze/analyze.h +11 -0
  645. data/src/include/analyze/builders.h +16 -0
  646. data/src/include/analyze/helpers.h +23 -2
  647. data/src/include/analyze/herb_directive_kinds.h +41 -0
  648. data/src/include/analyze/herb_directives.h +14 -0
  649. data/src/include/analyze/iteration_nodes.h +11 -0
  650. data/src/include/analyze/prism_annotate.h +3 -3
  651. data/src/include/analyze/ternary_conditionals.h +2 -0
  652. data/src/include/ast/ast_node.h +1 -5
  653. data/src/include/ast/ast_nodes.h +76 -2
  654. data/src/include/ast/ast_pretty_print.h +1 -1
  655. data/src/include/diff/herb_diff.h +11 -0
  656. data/src/include/errors.h +156 -39
  657. data/src/include/extract.h +11 -0
  658. data/src/include/herb.h +6 -0
  659. data/src/include/lexer/erb_openers.h +29 -0
  660. data/src/include/lexer/lexer_peek_helpers.h +8 -1
  661. data/src/include/lexer/lexer_struct.h +4 -0
  662. data/src/include/lexer/token.h +3 -0
  663. data/src/include/lexer/token_struct.h +8 -6
  664. data/src/include/lib/hb_allocator.h +2 -1
  665. data/src/include/lib/hb_array.h +2 -0
  666. data/src/include/lib/hb_foreach.h +1 -1
  667. data/src/include/lib/hb_string.h +7 -0
  668. data/src/include/parser/dot_notation.h +1 -1
  669. data/src/include/parser/foreign_content_elements.h +32 -0
  670. data/src/include/parser/parser.h +16 -30
  671. data/src/include/parser/parser_helpers.h +13 -11
  672. data/src/include/parser/parser_options.h +41 -0
  673. data/src/include/prism/ruby_parser.h +6 -0
  674. data/src/include/util/html_elements.h +85 -0
  675. data/src/include/util/html_util.h +1 -0
  676. data/src/include/version.h +1 -1
  677. data/src/lexer/lexer_peek_helpers.c +15 -1
  678. data/src/lexer/token.c +83 -1
  679. data/src/lexer.c +196 -12
  680. data/src/lib/hb_allocator.c +2 -0
  681. data/src/lib/hb_array.c +26 -0
  682. data/src/lib/hb_string.c +26 -0
  683. data/src/main.c +1 -1
  684. data/src/parser/dot_notation.c +4 -3
  685. data/src/parser/match_tags.c +66 -1
  686. data/src/parser/parser_helpers.c +69 -37
  687. data/src/parser.c +606 -383
  688. data/src/parser_options_defaults.c +30 -0
  689. data/src/prism/prism_helpers.c +3 -0
  690. data/src/prism/ruby_parser.c +49 -0
  691. data/src/util/html_util.c +11 -58
  692. data/src/visitor.c +77 -1
  693. data/templates/ext/herb/error_helpers.c.erb +1 -1
  694. data/templates/ext/herb/nodes.c.erb +18 -13
  695. data/templates/ext/herb/nodes.h.erb +2 -1
  696. data/templates/ext/herb/parser_options_helpers.c.erb +69 -0
  697. data/templates/ext/herb/parser_options_helpers.h.erb +11 -0
  698. data/templates/java/nodes.c.erb +20 -16
  699. data/templates/java/nodes.h.erb +3 -2
  700. data/templates/java/org/herb/ParserOptions.java.erb +24 -0
  701. data/templates/java/org/herb/ast/HelperRegistry.java.erb +67 -31
  702. data/templates/java/org/herb/ast/HelperType.java.erb +29 -0
  703. data/templates/java/org/herb/ast/Nodes.java.erb +11 -7
  704. data/templates/java/parser_options_helpers.c.erb +45 -0
  705. data/templates/java/parser_options_helpers.h.erb +10 -0
  706. data/templates/javascript/packages/client/src/state-kinds.ts.erb +49 -0
  707. data/templates/javascript/packages/client/src/state-operators.ts.erb +15 -0
  708. data/templates/javascript/packages/client/src/state-predicates.ts.erb +27 -0
  709. data/templates/javascript/packages/client/src/state-transforms.ts.erb +19 -0
  710. data/templates/javascript/packages/core/src/action-view-helpers.ts.erb +47 -0
  711. data/templates/javascript/packages/core/src/built-in-components.ts.erb +67 -0
  712. data/templates/javascript/packages/core/src/errors.ts.erb +9 -3
  713. data/templates/javascript/packages/core/src/foreign-content-elements.ts.erb +18 -0
  714. data/templates/javascript/packages/core/src/html-constants.ts.erb +32 -0
  715. data/templates/javascript/packages/core/src/html-elements.ts.erb +41 -0
  716. data/templates/javascript/packages/core/src/node-type-guards.ts.erb +11 -7
  717. data/templates/javascript/packages/core/src/nodes.ts.erb +82 -19
  718. data/templates/javascript/packages/core/src/parser-options.ts.erb +41 -0
  719. data/templates/javascript/packages/core/src/visitor.ts.erb +1 -1
  720. data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +3 -3
  721. data/templates/javascript/packages/node/extension/nodes.cpp.erb +17 -12
  722. data/templates/javascript/packages/node/extension/nodes.h.erb +3 -3
  723. data/templates/javascript/packages/node/extension/parser_options_helpers.cpp.erb +41 -0
  724. data/templates/javascript/packages/node/extension/parser_options_helpers.h.erb +12 -0
  725. data/templates/lib/herb/action_view/helper_registry.rb.erb +77 -3
  726. data/templates/lib/herb/ast/nodes.rb.erb +16 -6
  727. data/templates/lib/herb/engine/slots/component_definitions.rb.erb +38 -0
  728. data/templates/lib/herb/engine/slots/state_kinds.rb.erb +37 -0
  729. data/templates/lib/herb/engine/slots/state_operators.rb.erb +26 -0
  730. data/templates/lib/herb/engine/slots/state_predicates.rb.erb +39 -0
  731. data/templates/lib/herb/engine/slots/state_transforms.rb.erb +27 -0
  732. data/templates/lib/herb/errors.rb.erb +34 -6
  733. data/templates/lib/herb/html/elements.rb.erb +12 -0
  734. data/templates/lib/herb/parser_options.rb.erb +32 -0
  735. data/templates/lib/herb/visitor.rb.erb +7 -1
  736. data/templates/rust/herb-printer/src/printer_visitor.rs.erb +14 -0
  737. data/templates/rust/src/action_view_helpers.rs.erb +38 -0
  738. data/templates/rust/src/ast/nodes.rs.erb +24 -31
  739. data/templates/rust/src/errors.rs.erb +1 -1
  740. data/templates/rust/src/nodes.rs.erb +58 -26
  741. data/templates/rust/src/parser_options.rs.erb +16 -0
  742. data/templates/rust/src/prism/generated_deserialize.rs.erb +109 -0
  743. data/templates/rust/src/prism/generated_prettyprint.rs.erb +153 -0
  744. data/templates/rust/src/union_types.rs.erb +7 -1
  745. data/templates/rust/src/visitor.rs.erb +1 -1
  746. data/templates/src/analyze/action_view/helper_registry.c.erb +22 -0
  747. data/templates/src/analyze/missing_end.c.erb +13 -5
  748. data/templates/src/ast/ast_nodes.c.erb +41 -2
  749. data/templates/src/diff/herb_diff_nodes.c.erb +44 -8
  750. data/templates/src/errors.c.erb +8 -3
  751. data/templates/src/include/analyze/action_view/helper_registry.h.erb +19 -0
  752. data/templates/src/include/analyze/herb_directive_kinds.h.erb +25 -0
  753. data/templates/src/include/errors.h.erb +3 -1
  754. data/templates/src/include/parser/foreign_content_elements.h.erb +23 -0
  755. data/templates/src/include/parser/parser_options.h.erb +21 -0
  756. data/templates/src/include/util/html_elements.h.erb +28 -0
  757. data/templates/src/parser_options_defaults.c.erb +9 -0
  758. data/templates/template.rb +564 -9
  759. data/templates/wasm/error_helpers.cpp.erb +4 -4
  760. data/templates/wasm/nodes.cpp.erb +12 -12
  761. data/templates/wasm/nodes.h.erb +3 -3
  762. data/templates/wasm/parser_options_helpers.cpp.erb +25 -0
  763. data/templates/wasm/parser_options_helpers.h.erb +12 -0
  764. metadata +306 -27
  765. data/config/action_view_helpers/actionview/form_helper/button.yml +0 -38
  766. data/config/action_view_helpers/actionview/form_helper/submit.yml +0 -35
  767. data/lib/herb/ast.rb +0 -7
  768. data/lib/herb/diff_operation.rb +0 -34
  769. data/lib/herb/diff_result.rb +0 -59
  770. data/lib/herb/engine/error_formatter.rb +0 -432
  771. data/lib/herb/engine/parser_error_overlay.rb +0 -773
  772. data/lib/herb/engine/validation_error_overlay.rb +0 -182
  773. data/lib/herb/engine/validation_errors.rb +0 -65
  774. data/lib/herb/engine/validator.rb +0 -80
  775. data/sig/herb/ast.rbs +0 -6
  776. data/sig/herb/diff_operation.rbs +0 -34
  777. data/sig/herb/diff_result.rbs +0 -34
  778. data/sig/herb/engine/debug.rbs +0 -38
  779. data/sig/herb/engine/error_formatter.rbs +0 -47
  780. data/sig/herb/engine/parser_error_overlay.rbs +0 -41
  781. data/sig/herb/engine/validation_error_overlay.rbs +0 -35
  782. data/sig/herb/engine/validation_errors.rbs +0 -45
  783. data/sig/herb/engine/validator.rbs +0 -41
  784. data/sig/herb_c_extension.rbs +0 -10
data/ext/herb/nodes.c CHANGED
@@ -1,5 +1,5 @@
1
1
  // NOTE: This file is generated by the templates/template.rb script and should not
2
- // be modified manually. See /home/runner/work/herb/herb/templates/ext/herb/nodes.c.erb
2
+ // be modified manually. See templates/ext/herb/nodes.c.erb
3
3
 
4
4
  #include <ruby.h>
5
5
  #include <ruby/encoding.h>
@@ -12,8 +12,8 @@
12
12
  #include "../../src/include/herb.h"
13
13
  #include "../../src/include/lexer/token.h"
14
14
 
15
- VALUE rb_node_from_c_struct(AST_NODE_T* node);
16
- static VALUE rb_nodes_array_from_c_array(hb_array_T* array);
15
+ VALUE rb_node_from_c_struct(AST_NODE_T* node, const parser_options_T* options);
16
+ static VALUE rb_nodes_array_from_c_array(hb_array_T* array, const parser_options_T* options);
17
17
 
18
18
  static VALUE mAST;
19
19
  static VALUE cNode;
@@ -36,6 +36,7 @@ static VALUE cHTMLTextNode;
36
36
  static VALUE cHTMLCommentNode;
37
37
  static VALUE cHTMLDoctypeNode;
38
38
  static VALUE cXMLDeclarationNode;
39
+ static VALUE cXMLProcessingInstructionNode;
39
40
  static VALUE cCDATANode;
40
41
  static VALUE cWhitespaceNode;
41
42
  static VALUE cERBContentNode;
@@ -43,6 +44,7 @@ static VALUE cERBEndNode;
43
44
  static VALUE cERBElseNode;
44
45
  static VALUE cERBIfNode;
45
46
  static VALUE cERBBlockNode;
47
+ static VALUE cERBIterationBlockNode;
46
48
  static VALUE cERBWhenNode;
47
49
  static VALUE cERBCaseNode;
48
50
  static VALUE cERBCaseMatchNode;
@@ -60,6 +62,10 @@ static VALUE cRubyParameterNode;
60
62
  static VALUE cERBStrictLocalsNode;
61
63
  static VALUE cERBYieldNode;
62
64
  static VALUE cERBInNode;
65
+ static VALUE cHerbDirectiveNode;
66
+ static VALUE cHerbStateDeclarationNode;
67
+ static VALUE cHerbStateDirectiveNode;
68
+ static VALUE cERBCommentNode;
63
69
 
64
70
  void rb_init_node_classes(void) {
65
71
  mAST = rb_define_module_under(mHerb, "AST");
@@ -83,6 +89,7 @@ void rb_init_node_classes(void) {
83
89
  cHTMLCommentNode = rb_define_class_under(mAST, "HTMLCommentNode", cNode);
84
90
  cHTMLDoctypeNode = rb_define_class_under(mAST, "HTMLDoctypeNode", cNode);
85
91
  cXMLDeclarationNode = rb_define_class_under(mAST, "XMLDeclarationNode", cNode);
92
+ cXMLProcessingInstructionNode = rb_define_class_under(mAST, "XMLProcessingInstructionNode", cNode);
86
93
  cCDATANode = rb_define_class_under(mAST, "CDATANode", cNode);
87
94
  cWhitespaceNode = rb_define_class_under(mAST, "WhitespaceNode", cNode);
88
95
  cERBContentNode = rb_define_class_under(mAST, "ERBContentNode", cNode);
@@ -90,6 +97,7 @@ void rb_init_node_classes(void) {
90
97
  cERBElseNode = rb_define_class_under(mAST, "ERBElseNode", cNode);
91
98
  cERBIfNode = rb_define_class_under(mAST, "ERBIfNode", cNode);
92
99
  cERBBlockNode = rb_define_class_under(mAST, "ERBBlockNode", cNode);
100
+ cERBIterationBlockNode = rb_define_class_under(mAST, "ERBIterationBlockNode", cNode);
93
101
  cERBWhenNode = rb_define_class_under(mAST, "ERBWhenNode", cNode);
94
102
  cERBCaseNode = rb_define_class_under(mAST, "ERBCaseNode", cNode);
95
103
  cERBCaseMatchNode = rb_define_class_under(mAST, "ERBCaseMatchNode", cNode);
@@ -107,18 +115,27 @@ void rb_init_node_classes(void) {
107
115
  cERBStrictLocalsNode = rb_define_class_under(mAST, "ERBStrictLocalsNode", cNode);
108
116
  cERBYieldNode = rb_define_class_under(mAST, "ERBYieldNode", cNode);
109
117
  cERBInNode = rb_define_class_under(mAST, "ERBInNode", cNode);
118
+ cHerbDirectiveNode = rb_define_class_under(mAST, "HerbDirectiveNode", cNode);
119
+ cHerbStateDeclarationNode = rb_define_class_under(mAST, "HerbStateDeclarationNode", cNode);
120
+ cHerbStateDirectiveNode = rb_define_class_under(mAST, "HerbStateDirectiveNode", cNode);
121
+ cERBCommentNode = rb_define_class_under(mAST, "ERBCommentNode", cNode);
110
122
  }
111
123
 
112
- static VALUE rb_document_node_from_c_struct(AST_DOCUMENT_NODE_T* document_node) {
124
+ static VALUE rb_document_node_from_c_struct(AST_DOCUMENT_NODE_T* document_node, const parser_options_T* options) {
113
125
  if (document_node == NULL) { return Qnil; }
114
126
 
115
127
  AST_NODE_T* node = &document_node->base;
116
128
 
117
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
118
- VALUE location = rb_location_from_c_struct(node->location);
129
+ static VALUE type = 0;
130
+
131
+ if (type == 0) {
132
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
133
+ rb_gc_register_mark_object(type);
134
+ }
135
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
119
136
  VALUE errors = rb_errors_array_from_c_array(node->errors);
120
137
 
121
- VALUE document_node_children = rb_nodes_array_from_c_array(document_node->children);
138
+ VALUE document_node_children = rb_nodes_array_from_c_array(document_node->children, options);
122
139
  /* prism_context is internal parser state, not exposed to Ruby */
123
140
  VALUE document_node_prism_context = Qnil;
124
141
  VALUE document_node_prism_node;
@@ -150,13 +167,18 @@ static VALUE rb_document_node_from_c_struct(AST_DOCUMENT_NODE_T* document_node)
150
167
  return rb_class_new_instance(6, args, cDocumentNode);
151
168
  };
152
169
 
153
- static VALUE rb_literal_node_from_c_struct(AST_LITERAL_NODE_T* literal_node) {
170
+ static VALUE rb_literal_node_from_c_struct(AST_LITERAL_NODE_T* literal_node, const parser_options_T* options) {
154
171
  if (literal_node == NULL) { return Qnil; }
155
172
 
156
173
  AST_NODE_T* node = &literal_node->base;
157
174
 
158
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
159
- VALUE location = rb_location_from_c_struct(node->location);
175
+ static VALUE type = 0;
176
+
177
+ if (type == 0) {
178
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
179
+ rb_gc_register_mark_object(type);
180
+ }
181
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
160
182
  VALUE errors = rb_errors_array_from_c_array(node->errors);
161
183
 
162
184
  VALUE literal_node_content = rb_string_from_hb_string(literal_node->content);
@@ -171,19 +193,24 @@ static VALUE rb_literal_node_from_c_struct(AST_LITERAL_NODE_T* literal_node) {
171
193
  return rb_class_new_instance(4, args, cLiteralNode);
172
194
  };
173
195
 
174
- static VALUE rb_html_open_tag_node_from_c_struct(AST_HTML_OPEN_TAG_NODE_T* html_open_tag_node) {
196
+ static VALUE rb_html_open_tag_node_from_c_struct(AST_HTML_OPEN_TAG_NODE_T* html_open_tag_node, const parser_options_T* options) {
175
197
  if (html_open_tag_node == NULL) { return Qnil; }
176
198
 
177
199
  AST_NODE_T* node = &html_open_tag_node->base;
178
200
 
179
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
180
- VALUE location = rb_location_from_c_struct(node->location);
201
+ static VALUE type = 0;
202
+
203
+ if (type == 0) {
204
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
205
+ rb_gc_register_mark_object(type);
206
+ }
207
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
181
208
  VALUE errors = rb_errors_array_from_c_array(node->errors);
182
209
 
183
- VALUE html_open_tag_node_tag_opening = rb_token_from_c_struct(html_open_tag_node->tag_opening);
184
- VALUE html_open_tag_node_tag_name = rb_token_from_c_struct(html_open_tag_node->tag_name);
185
- VALUE html_open_tag_node_tag_closing = rb_token_from_c_struct(html_open_tag_node->tag_closing);
186
- VALUE html_open_tag_node_children = rb_nodes_array_from_c_array(html_open_tag_node->children);
210
+ VALUE html_open_tag_node_tag_opening = rb_token_from_c_struct(html_open_tag_node->tag_opening, options);
211
+ VALUE html_open_tag_node_tag_name = rb_token_from_c_struct(html_open_tag_node->tag_name, options);
212
+ VALUE html_open_tag_node_tag_closing = rb_token_from_c_struct(html_open_tag_node->tag_closing, options);
213
+ VALUE html_open_tag_node_children = rb_nodes_array_from_c_array(html_open_tag_node->children, options);
187
214
  VALUE html_open_tag_node_is_void = (html_open_tag_node->is_void) ? Qtrue : Qfalse;
188
215
 
189
216
  VALUE args[8] = {
@@ -200,17 +227,22 @@ static VALUE rb_html_open_tag_node_from_c_struct(AST_HTML_OPEN_TAG_NODE_T* html_
200
227
  return rb_class_new_instance(8, args, cHTMLOpenTagNode);
201
228
  };
202
229
 
203
- static VALUE rb_html_conditional_open_tag_node_from_c_struct(AST_HTML_CONDITIONAL_OPEN_TAG_NODE_T* html_conditional_open_tag_node) {
230
+ static VALUE rb_html_conditional_open_tag_node_from_c_struct(AST_HTML_CONDITIONAL_OPEN_TAG_NODE_T* html_conditional_open_tag_node, const parser_options_T* options) {
204
231
  if (html_conditional_open_tag_node == NULL) { return Qnil; }
205
232
 
206
233
  AST_NODE_T* node = &html_conditional_open_tag_node->base;
207
234
 
208
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
209
- VALUE location = rb_location_from_c_struct(node->location);
235
+ static VALUE type = 0;
236
+
237
+ if (type == 0) {
238
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
239
+ rb_gc_register_mark_object(type);
240
+ }
241
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
210
242
  VALUE errors = rb_errors_array_from_c_array(node->errors);
211
243
 
212
- VALUE html_conditional_open_tag_node_conditional = rb_node_from_c_struct((AST_NODE_T*) html_conditional_open_tag_node->conditional);
213
- VALUE html_conditional_open_tag_node_tag_name = rb_token_from_c_struct(html_conditional_open_tag_node->tag_name);
244
+ VALUE html_conditional_open_tag_node_conditional = rb_node_from_c_struct((AST_NODE_T*) html_conditional_open_tag_node->conditional, options);
245
+ VALUE html_conditional_open_tag_node_tag_name = rb_token_from_c_struct(html_conditional_open_tag_node->tag_name, options);
214
246
  VALUE html_conditional_open_tag_node_is_void = (html_conditional_open_tag_node->is_void) ? Qtrue : Qfalse;
215
247
 
216
248
  VALUE args[6] = {
@@ -225,19 +257,24 @@ static VALUE rb_html_conditional_open_tag_node_from_c_struct(AST_HTML_CONDITIONA
225
257
  return rb_class_new_instance(6, args, cHTMLConditionalOpenTagNode);
226
258
  };
227
259
 
228
- static VALUE rb_html_close_tag_node_from_c_struct(AST_HTML_CLOSE_TAG_NODE_T* html_close_tag_node) {
260
+ static VALUE rb_html_close_tag_node_from_c_struct(AST_HTML_CLOSE_TAG_NODE_T* html_close_tag_node, const parser_options_T* options) {
229
261
  if (html_close_tag_node == NULL) { return Qnil; }
230
262
 
231
263
  AST_NODE_T* node = &html_close_tag_node->base;
232
264
 
233
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
234
- VALUE location = rb_location_from_c_struct(node->location);
265
+ static VALUE type = 0;
266
+
267
+ if (type == 0) {
268
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
269
+ rb_gc_register_mark_object(type);
270
+ }
271
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
235
272
  VALUE errors = rb_errors_array_from_c_array(node->errors);
236
273
 
237
- VALUE html_close_tag_node_tag_opening = rb_token_from_c_struct(html_close_tag_node->tag_opening);
238
- VALUE html_close_tag_node_tag_name = rb_token_from_c_struct(html_close_tag_node->tag_name);
239
- VALUE html_close_tag_node_children = rb_nodes_array_from_c_array(html_close_tag_node->children);
240
- VALUE html_close_tag_node_tag_closing = rb_token_from_c_struct(html_close_tag_node->tag_closing);
274
+ VALUE html_close_tag_node_tag_opening = rb_token_from_c_struct(html_close_tag_node->tag_opening, options);
275
+ VALUE html_close_tag_node_tag_name = rb_token_from_c_struct(html_close_tag_node->tag_name, options);
276
+ VALUE html_close_tag_node_children = rb_nodes_array_from_c_array(html_close_tag_node->children, options);
277
+ VALUE html_close_tag_node_tag_closing = rb_token_from_c_struct(html_close_tag_node->tag_closing, options);
241
278
 
242
279
  VALUE args[7] = {
243
280
  type,
@@ -252,16 +289,21 @@ static VALUE rb_html_close_tag_node_from_c_struct(AST_HTML_CLOSE_TAG_NODE_T* htm
252
289
  return rb_class_new_instance(7, args, cHTMLCloseTagNode);
253
290
  };
254
291
 
255
- static VALUE rb_html_omitted_close_tag_node_from_c_struct(AST_HTML_OMITTED_CLOSE_TAG_NODE_T* html_omitted_close_tag_node) {
292
+ static VALUE rb_html_omitted_close_tag_node_from_c_struct(AST_HTML_OMITTED_CLOSE_TAG_NODE_T* html_omitted_close_tag_node, const parser_options_T* options) {
256
293
  if (html_omitted_close_tag_node == NULL) { return Qnil; }
257
294
 
258
295
  AST_NODE_T* node = &html_omitted_close_tag_node->base;
259
296
 
260
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
261
- VALUE location = rb_location_from_c_struct(node->location);
297
+ static VALUE type = 0;
298
+
299
+ if (type == 0) {
300
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
301
+ rb_gc_register_mark_object(type);
302
+ }
303
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
262
304
  VALUE errors = rb_errors_array_from_c_array(node->errors);
263
305
 
264
- VALUE html_omitted_close_tag_node_tag_name = rb_token_from_c_struct(html_omitted_close_tag_node->tag_name);
306
+ VALUE html_omitted_close_tag_node_tag_name = rb_token_from_c_struct(html_omitted_close_tag_node->tag_name, options);
265
307
 
266
308
  VALUE args[4] = {
267
309
  type,
@@ -273,16 +315,21 @@ static VALUE rb_html_omitted_close_tag_node_from_c_struct(AST_HTML_OMITTED_CLOSE
273
315
  return rb_class_new_instance(4, args, cHTMLOmittedCloseTagNode);
274
316
  };
275
317
 
276
- static VALUE rb_html_virtual_close_tag_node_from_c_struct(AST_HTML_VIRTUAL_CLOSE_TAG_NODE_T* html_virtual_close_tag_node) {
318
+ static VALUE rb_html_virtual_close_tag_node_from_c_struct(AST_HTML_VIRTUAL_CLOSE_TAG_NODE_T* html_virtual_close_tag_node, const parser_options_T* options) {
277
319
  if (html_virtual_close_tag_node == NULL) { return Qnil; }
278
320
 
279
321
  AST_NODE_T* node = &html_virtual_close_tag_node->base;
280
322
 
281
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
282
- VALUE location = rb_location_from_c_struct(node->location);
323
+ static VALUE type = 0;
324
+
325
+ if (type == 0) {
326
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
327
+ rb_gc_register_mark_object(type);
328
+ }
329
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
283
330
  VALUE errors = rb_errors_array_from_c_array(node->errors);
284
331
 
285
- VALUE html_virtual_close_tag_node_tag_name = rb_token_from_c_struct(html_virtual_close_tag_node->tag_name);
332
+ VALUE html_virtual_close_tag_node_tag_name = rb_token_from_c_struct(html_virtual_close_tag_node->tag_name, options);
286
333
 
287
334
  VALUE args[4] = {
288
335
  type,
@@ -294,19 +341,24 @@ static VALUE rb_html_virtual_close_tag_node_from_c_struct(AST_HTML_VIRTUAL_CLOSE
294
341
  return rb_class_new_instance(4, args, cHTMLVirtualCloseTagNode);
295
342
  };
296
343
 
297
- static VALUE rb_html_element_node_from_c_struct(AST_HTML_ELEMENT_NODE_T* html_element_node) {
344
+ static VALUE rb_html_element_node_from_c_struct(AST_HTML_ELEMENT_NODE_T* html_element_node, const parser_options_T* options) {
298
345
  if (html_element_node == NULL) { return Qnil; }
299
346
 
300
347
  AST_NODE_T* node = &html_element_node->base;
301
348
 
302
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
303
- VALUE location = rb_location_from_c_struct(node->location);
349
+ static VALUE type = 0;
350
+
351
+ if (type == 0) {
352
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
353
+ rb_gc_register_mark_object(type);
354
+ }
355
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
304
356
  VALUE errors = rb_errors_array_from_c_array(node->errors);
305
357
 
306
- VALUE html_element_node_open_tag = rb_node_from_c_struct((AST_NODE_T*) html_element_node->open_tag);
307
- VALUE html_element_node_tag_name = rb_token_from_c_struct(html_element_node->tag_name);
308
- VALUE html_element_node_body = rb_nodes_array_from_c_array(html_element_node->body);
309
- VALUE html_element_node_close_tag = rb_node_from_c_struct((AST_NODE_T*) html_element_node->close_tag);
358
+ VALUE html_element_node_open_tag = rb_node_from_c_struct((AST_NODE_T*) html_element_node->open_tag, options);
359
+ VALUE html_element_node_tag_name = rb_token_from_c_struct(html_element_node->tag_name, options);
360
+ VALUE html_element_node_body = rb_nodes_array_from_c_array(html_element_node->body, options);
361
+ VALUE html_element_node_close_tag = rb_node_from_c_struct((AST_NODE_T*) html_element_node->close_tag, options);
310
362
  VALUE html_element_node_is_void = (html_element_node->is_void) ? Qtrue : Qfalse;
311
363
  VALUE html_element_node_element_source = rb_string_from_hb_string(html_element_node->element_source);
312
364
 
@@ -325,22 +377,27 @@ static VALUE rb_html_element_node_from_c_struct(AST_HTML_ELEMENT_NODE_T* html_el
325
377
  return rb_class_new_instance(9, args, cHTMLElementNode);
326
378
  };
327
379
 
328
- static VALUE rb_html_conditional_element_node_from_c_struct(AST_HTML_CONDITIONAL_ELEMENT_NODE_T* html_conditional_element_node) {
380
+ static VALUE rb_html_conditional_element_node_from_c_struct(AST_HTML_CONDITIONAL_ELEMENT_NODE_T* html_conditional_element_node, const parser_options_T* options) {
329
381
  if (html_conditional_element_node == NULL) { return Qnil; }
330
382
 
331
383
  AST_NODE_T* node = &html_conditional_element_node->base;
332
384
 
333
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
334
- VALUE location = rb_location_from_c_struct(node->location);
385
+ static VALUE type = 0;
386
+
387
+ if (type == 0) {
388
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
389
+ rb_gc_register_mark_object(type);
390
+ }
391
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
335
392
  VALUE errors = rb_errors_array_from_c_array(node->errors);
336
393
 
337
394
  VALUE html_conditional_element_node_condition = rb_string_from_hb_string(html_conditional_element_node->condition);
338
- VALUE html_conditional_element_node_open_conditional = rb_node_from_c_struct((AST_NODE_T*) html_conditional_element_node->open_conditional);
339
- VALUE html_conditional_element_node_open_tag = rb_node_from_c_struct((AST_NODE_T*) html_conditional_element_node->open_tag);
340
- VALUE html_conditional_element_node_body = rb_nodes_array_from_c_array(html_conditional_element_node->body);
341
- VALUE html_conditional_element_node_close_tag = rb_node_from_c_struct((AST_NODE_T*) html_conditional_element_node->close_tag);
342
- VALUE html_conditional_element_node_close_conditional = rb_node_from_c_struct((AST_NODE_T*) html_conditional_element_node->close_conditional);
343
- VALUE html_conditional_element_node_tag_name = rb_token_from_c_struct(html_conditional_element_node->tag_name);
395
+ VALUE html_conditional_element_node_open_conditional = rb_node_from_c_struct((AST_NODE_T*) html_conditional_element_node->open_conditional, options);
396
+ VALUE html_conditional_element_node_open_tag = rb_node_from_c_struct((AST_NODE_T*) html_conditional_element_node->open_tag, options);
397
+ VALUE html_conditional_element_node_body = rb_nodes_array_from_c_array(html_conditional_element_node->body, options);
398
+ VALUE html_conditional_element_node_close_tag = rb_node_from_c_struct((AST_NODE_T*) html_conditional_element_node->close_tag, options);
399
+ VALUE html_conditional_element_node_close_conditional = rb_node_from_c_struct((AST_NODE_T*) html_conditional_element_node->close_conditional, options);
400
+ VALUE html_conditional_element_node_tag_name = rb_token_from_c_struct(html_conditional_element_node->tag_name, options);
344
401
  VALUE html_conditional_element_node_element_source = rb_string_from_hb_string(html_conditional_element_node->element_source);
345
402
 
346
403
  VALUE args[11] = {
@@ -360,18 +417,23 @@ static VALUE rb_html_conditional_element_node_from_c_struct(AST_HTML_CONDITIONAL
360
417
  return rb_class_new_instance(11, args, cHTMLConditionalElementNode);
361
418
  };
362
419
 
363
- static VALUE rb_html_attribute_value_node_from_c_struct(AST_HTML_ATTRIBUTE_VALUE_NODE_T* html_attribute_value_node) {
420
+ static VALUE rb_html_attribute_value_node_from_c_struct(AST_HTML_ATTRIBUTE_VALUE_NODE_T* html_attribute_value_node, const parser_options_T* options) {
364
421
  if (html_attribute_value_node == NULL) { return Qnil; }
365
422
 
366
423
  AST_NODE_T* node = &html_attribute_value_node->base;
367
424
 
368
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
369
- VALUE location = rb_location_from_c_struct(node->location);
425
+ static VALUE type = 0;
426
+
427
+ if (type == 0) {
428
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
429
+ rb_gc_register_mark_object(type);
430
+ }
431
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
370
432
  VALUE errors = rb_errors_array_from_c_array(node->errors);
371
433
 
372
- VALUE html_attribute_value_node_open_quote = rb_token_from_c_struct(html_attribute_value_node->open_quote);
373
- VALUE html_attribute_value_node_children = rb_nodes_array_from_c_array(html_attribute_value_node->children);
374
- VALUE html_attribute_value_node_close_quote = rb_token_from_c_struct(html_attribute_value_node->close_quote);
434
+ VALUE html_attribute_value_node_open_quote = rb_token_from_c_struct(html_attribute_value_node->open_quote, options);
435
+ VALUE html_attribute_value_node_children = rb_nodes_array_from_c_array(html_attribute_value_node->children, options);
436
+ VALUE html_attribute_value_node_close_quote = rb_token_from_c_struct(html_attribute_value_node->close_quote, options);
375
437
  VALUE html_attribute_value_node_quoted = (html_attribute_value_node->quoted) ? Qtrue : Qfalse;
376
438
 
377
439
  VALUE args[7] = {
@@ -387,16 +449,21 @@ static VALUE rb_html_attribute_value_node_from_c_struct(AST_HTML_ATTRIBUTE_VALUE
387
449
  return rb_class_new_instance(7, args, cHTMLAttributeValueNode);
388
450
  };
389
451
 
390
- static VALUE rb_html_attribute_name_node_from_c_struct(AST_HTML_ATTRIBUTE_NAME_NODE_T* html_attribute_name_node) {
452
+ static VALUE rb_html_attribute_name_node_from_c_struct(AST_HTML_ATTRIBUTE_NAME_NODE_T* html_attribute_name_node, const parser_options_T* options) {
391
453
  if (html_attribute_name_node == NULL) { return Qnil; }
392
454
 
393
455
  AST_NODE_T* node = &html_attribute_name_node->base;
394
456
 
395
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
396
- VALUE location = rb_location_from_c_struct(node->location);
457
+ static VALUE type = 0;
458
+
459
+ if (type == 0) {
460
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
461
+ rb_gc_register_mark_object(type);
462
+ }
463
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
397
464
  VALUE errors = rb_errors_array_from_c_array(node->errors);
398
465
 
399
- VALUE html_attribute_name_node_children = rb_nodes_array_from_c_array(html_attribute_name_node->children);
466
+ VALUE html_attribute_name_node_children = rb_nodes_array_from_c_array(html_attribute_name_node->children, options);
400
467
 
401
468
  VALUE args[4] = {
402
469
  type,
@@ -408,18 +475,23 @@ static VALUE rb_html_attribute_name_node_from_c_struct(AST_HTML_ATTRIBUTE_NAME_N
408
475
  return rb_class_new_instance(4, args, cHTMLAttributeNameNode);
409
476
  };
410
477
 
411
- static VALUE rb_html_attribute_node_from_c_struct(AST_HTML_ATTRIBUTE_NODE_T* html_attribute_node) {
478
+ static VALUE rb_html_attribute_node_from_c_struct(AST_HTML_ATTRIBUTE_NODE_T* html_attribute_node, const parser_options_T* options) {
412
479
  if (html_attribute_node == NULL) { return Qnil; }
413
480
 
414
481
  AST_NODE_T* node = &html_attribute_node->base;
415
482
 
416
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
417
- VALUE location = rb_location_from_c_struct(node->location);
483
+ static VALUE type = 0;
484
+
485
+ if (type == 0) {
486
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
487
+ rb_gc_register_mark_object(type);
488
+ }
489
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
418
490
  VALUE errors = rb_errors_array_from_c_array(node->errors);
419
491
 
420
- VALUE html_attribute_node_name = rb_node_from_c_struct((AST_NODE_T*) html_attribute_node->name);
421
- VALUE html_attribute_node_equals = rb_token_from_c_struct(html_attribute_node->equals);
422
- VALUE html_attribute_node_value = rb_node_from_c_struct((AST_NODE_T*) html_attribute_node->value);
492
+ VALUE html_attribute_node_name = rb_node_from_c_struct((AST_NODE_T*) html_attribute_node->name, options);
493
+ VALUE html_attribute_node_equals = rb_token_from_c_struct(html_attribute_node->equals, options);
494
+ VALUE html_attribute_node_value = rb_node_from_c_struct((AST_NODE_T*) html_attribute_node->value, options);
423
495
 
424
496
  VALUE args[6] = {
425
497
  type,
@@ -433,13 +505,18 @@ static VALUE rb_html_attribute_node_from_c_struct(AST_HTML_ATTRIBUTE_NODE_T* htm
433
505
  return rb_class_new_instance(6, args, cHTMLAttributeNode);
434
506
  };
435
507
 
436
- static VALUE rb_ruby_literal_node_from_c_struct(AST_RUBY_LITERAL_NODE_T* ruby_literal_node) {
508
+ static VALUE rb_ruby_literal_node_from_c_struct(AST_RUBY_LITERAL_NODE_T* ruby_literal_node, const parser_options_T* options) {
437
509
  if (ruby_literal_node == NULL) { return Qnil; }
438
510
 
439
511
  AST_NODE_T* node = &ruby_literal_node->base;
440
512
 
441
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
442
- VALUE location = rb_location_from_c_struct(node->location);
513
+ static VALUE type = 0;
514
+
515
+ if (type == 0) {
516
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
517
+ rb_gc_register_mark_object(type);
518
+ }
519
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
443
520
  VALUE errors = rb_errors_array_from_c_array(node->errors);
444
521
 
445
522
  VALUE ruby_literal_node_content = rb_string_from_hb_string(ruby_literal_node->content);
@@ -454,13 +531,18 @@ static VALUE rb_ruby_literal_node_from_c_struct(AST_RUBY_LITERAL_NODE_T* ruby_li
454
531
  return rb_class_new_instance(4, args, cRubyLiteralNode);
455
532
  };
456
533
 
457
- static VALUE rb_ruby_html_attributes_splat_node_from_c_struct(AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE_T* ruby_html_attributes_splat_node) {
534
+ static VALUE rb_ruby_html_attributes_splat_node_from_c_struct(AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE_T* ruby_html_attributes_splat_node, const parser_options_T* options) {
458
535
  if (ruby_html_attributes_splat_node == NULL) { return Qnil; }
459
536
 
460
537
  AST_NODE_T* node = &ruby_html_attributes_splat_node->base;
461
538
 
462
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
463
- VALUE location = rb_location_from_c_struct(node->location);
539
+ static VALUE type = 0;
540
+
541
+ if (type == 0) {
542
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
543
+ rb_gc_register_mark_object(type);
544
+ }
545
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
464
546
  VALUE errors = rb_errors_array_from_c_array(node->errors);
465
547
 
466
548
  VALUE ruby_html_attributes_splat_node_content = rb_string_from_hb_string(ruby_html_attributes_splat_node->content);
@@ -477,20 +559,25 @@ static VALUE rb_ruby_html_attributes_splat_node_from_c_struct(AST_RUBY_HTML_ATTR
477
559
  return rb_class_new_instance(5, args, cRubyHTMLAttributesSplatNode);
478
560
  };
479
561
 
480
- static VALUE rb_erb_open_tag_node_from_c_struct(AST_ERB_OPEN_TAG_NODE_T* erb_open_tag_node) {
562
+ static VALUE rb_erb_open_tag_node_from_c_struct(AST_ERB_OPEN_TAG_NODE_T* erb_open_tag_node, const parser_options_T* options) {
481
563
  if (erb_open_tag_node == NULL) { return Qnil; }
482
564
 
483
565
  AST_NODE_T* node = &erb_open_tag_node->base;
484
566
 
485
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
486
- VALUE location = rb_location_from_c_struct(node->location);
567
+ static VALUE type = 0;
568
+
569
+ if (type == 0) {
570
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
571
+ rb_gc_register_mark_object(type);
572
+ }
573
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
487
574
  VALUE errors = rb_errors_array_from_c_array(node->errors);
488
575
 
489
- VALUE erb_open_tag_node_tag_opening = rb_token_from_c_struct(erb_open_tag_node->tag_opening);
490
- VALUE erb_open_tag_node_content = rb_token_from_c_struct(erb_open_tag_node->content);
491
- VALUE erb_open_tag_node_tag_closing = rb_token_from_c_struct(erb_open_tag_node->tag_closing);
492
- VALUE erb_open_tag_node_tag_name = rb_token_from_c_struct(erb_open_tag_node->tag_name);
493
- VALUE erb_open_tag_node_children = rb_nodes_array_from_c_array(erb_open_tag_node->children);
576
+ VALUE erb_open_tag_node_tag_opening = rb_token_from_c_struct(erb_open_tag_node->tag_opening, options);
577
+ VALUE erb_open_tag_node_content = rb_token_from_c_struct(erb_open_tag_node->content, options);
578
+ VALUE erb_open_tag_node_tag_closing = rb_token_from_c_struct(erb_open_tag_node->tag_closing, options);
579
+ VALUE erb_open_tag_node_tag_name = rb_token_from_c_struct(erb_open_tag_node->tag_name, options);
580
+ VALUE erb_open_tag_node_children = rb_nodes_array_from_c_array(erb_open_tag_node->children, options);
494
581
 
495
582
  VALUE args[8] = {
496
583
  type,
@@ -506,13 +593,18 @@ static VALUE rb_erb_open_tag_node_from_c_struct(AST_ERB_OPEN_TAG_NODE_T* erb_ope
506
593
  return rb_class_new_instance(8, args, cERBOpenTagNode);
507
594
  };
508
595
 
509
- static VALUE rb_html_text_node_from_c_struct(AST_HTML_TEXT_NODE_T* html_text_node) {
596
+ static VALUE rb_html_text_node_from_c_struct(AST_HTML_TEXT_NODE_T* html_text_node, const parser_options_T* options) {
510
597
  if (html_text_node == NULL) { return Qnil; }
511
598
 
512
599
  AST_NODE_T* node = &html_text_node->base;
513
600
 
514
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
515
- VALUE location = rb_location_from_c_struct(node->location);
601
+ static VALUE type = 0;
602
+
603
+ if (type == 0) {
604
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
605
+ rb_gc_register_mark_object(type);
606
+ }
607
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
516
608
  VALUE errors = rb_errors_array_from_c_array(node->errors);
517
609
 
518
610
  VALUE html_text_node_content = rb_string_from_hb_string(html_text_node->content);
@@ -527,18 +619,23 @@ static VALUE rb_html_text_node_from_c_struct(AST_HTML_TEXT_NODE_T* html_text_nod
527
619
  return rb_class_new_instance(4, args, cHTMLTextNode);
528
620
  };
529
621
 
530
- static VALUE rb_html_comment_node_from_c_struct(AST_HTML_COMMENT_NODE_T* html_comment_node) {
622
+ static VALUE rb_html_comment_node_from_c_struct(AST_HTML_COMMENT_NODE_T* html_comment_node, const parser_options_T* options) {
531
623
  if (html_comment_node == NULL) { return Qnil; }
532
624
 
533
625
  AST_NODE_T* node = &html_comment_node->base;
534
626
 
535
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
536
- VALUE location = rb_location_from_c_struct(node->location);
627
+ static VALUE type = 0;
628
+
629
+ if (type == 0) {
630
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
631
+ rb_gc_register_mark_object(type);
632
+ }
633
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
537
634
  VALUE errors = rb_errors_array_from_c_array(node->errors);
538
635
 
539
- VALUE html_comment_node_comment_start = rb_token_from_c_struct(html_comment_node->comment_start);
540
- VALUE html_comment_node_children = rb_nodes_array_from_c_array(html_comment_node->children);
541
- VALUE html_comment_node_comment_end = rb_token_from_c_struct(html_comment_node->comment_end);
636
+ VALUE html_comment_node_comment_start = rb_token_from_c_struct(html_comment_node->comment_start, options);
637
+ VALUE html_comment_node_children = rb_nodes_array_from_c_array(html_comment_node->children, options);
638
+ VALUE html_comment_node_comment_end = rb_token_from_c_struct(html_comment_node->comment_end, options);
542
639
 
543
640
  VALUE args[6] = {
544
641
  type,
@@ -552,18 +649,23 @@ static VALUE rb_html_comment_node_from_c_struct(AST_HTML_COMMENT_NODE_T* html_co
552
649
  return rb_class_new_instance(6, args, cHTMLCommentNode);
553
650
  };
554
651
 
555
- static VALUE rb_html_doctype_node_from_c_struct(AST_HTML_DOCTYPE_NODE_T* html_doctype_node) {
652
+ static VALUE rb_html_doctype_node_from_c_struct(AST_HTML_DOCTYPE_NODE_T* html_doctype_node, const parser_options_T* options) {
556
653
  if (html_doctype_node == NULL) { return Qnil; }
557
654
 
558
655
  AST_NODE_T* node = &html_doctype_node->base;
559
656
 
560
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
561
- VALUE location = rb_location_from_c_struct(node->location);
657
+ static VALUE type = 0;
658
+
659
+ if (type == 0) {
660
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
661
+ rb_gc_register_mark_object(type);
662
+ }
663
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
562
664
  VALUE errors = rb_errors_array_from_c_array(node->errors);
563
665
 
564
- VALUE html_doctype_node_tag_opening = rb_token_from_c_struct(html_doctype_node->tag_opening);
565
- VALUE html_doctype_node_children = rb_nodes_array_from_c_array(html_doctype_node->children);
566
- VALUE html_doctype_node_tag_closing = rb_token_from_c_struct(html_doctype_node->tag_closing);
666
+ VALUE html_doctype_node_tag_opening = rb_token_from_c_struct(html_doctype_node->tag_opening, options);
667
+ VALUE html_doctype_node_children = rb_nodes_array_from_c_array(html_doctype_node->children, options);
668
+ VALUE html_doctype_node_tag_closing = rb_token_from_c_struct(html_doctype_node->tag_closing, options);
567
669
 
568
670
  VALUE args[6] = {
569
671
  type,
@@ -577,18 +679,23 @@ static VALUE rb_html_doctype_node_from_c_struct(AST_HTML_DOCTYPE_NODE_T* html_do
577
679
  return rb_class_new_instance(6, args, cHTMLDoctypeNode);
578
680
  };
579
681
 
580
- static VALUE rb_xml_declaration_node_from_c_struct(AST_XML_DECLARATION_NODE_T* xml_declaration_node) {
682
+ static VALUE rb_xml_declaration_node_from_c_struct(AST_XML_DECLARATION_NODE_T* xml_declaration_node, const parser_options_T* options) {
581
683
  if (xml_declaration_node == NULL) { return Qnil; }
582
684
 
583
685
  AST_NODE_T* node = &xml_declaration_node->base;
584
686
 
585
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
586
- VALUE location = rb_location_from_c_struct(node->location);
687
+ static VALUE type = 0;
688
+
689
+ if (type == 0) {
690
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
691
+ rb_gc_register_mark_object(type);
692
+ }
693
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
587
694
  VALUE errors = rb_errors_array_from_c_array(node->errors);
588
695
 
589
- VALUE xml_declaration_node_tag_opening = rb_token_from_c_struct(xml_declaration_node->tag_opening);
590
- VALUE xml_declaration_node_children = rb_nodes_array_from_c_array(xml_declaration_node->children);
591
- VALUE xml_declaration_node_tag_closing = rb_token_from_c_struct(xml_declaration_node->tag_closing);
696
+ VALUE xml_declaration_node_tag_opening = rb_token_from_c_struct(xml_declaration_node->tag_opening, options);
697
+ VALUE xml_declaration_node_children = rb_nodes_array_from_c_array(xml_declaration_node->children, options);
698
+ VALUE xml_declaration_node_tag_closing = rb_token_from_c_struct(xml_declaration_node->tag_closing, options);
592
699
 
593
700
  VALUE args[6] = {
594
701
  type,
@@ -602,18 +709,55 @@ static VALUE rb_xml_declaration_node_from_c_struct(AST_XML_DECLARATION_NODE_T* x
602
709
  return rb_class_new_instance(6, args, cXMLDeclarationNode);
603
710
  };
604
711
 
605
- static VALUE rb_cdata_node_from_c_struct(AST_CDATA_NODE_T* cdata_node) {
712
+ static VALUE rb_xml_processing_instruction_node_from_c_struct(AST_XML_PROCESSING_INSTRUCTION_NODE_T* xml_processing_instruction_node, const parser_options_T* options) {
713
+ if (xml_processing_instruction_node == NULL) { return Qnil; }
714
+
715
+ AST_NODE_T* node = &xml_processing_instruction_node->base;
716
+
717
+ static VALUE type = 0;
718
+
719
+ if (type == 0) {
720
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
721
+ rb_gc_register_mark_object(type);
722
+ }
723
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
724
+ VALUE errors = rb_errors_array_from_c_array(node->errors);
725
+
726
+ VALUE xml_processing_instruction_node_tag_opening = rb_token_from_c_struct(xml_processing_instruction_node->tag_opening, options);
727
+ VALUE xml_processing_instruction_node_target = rb_token_from_c_struct(xml_processing_instruction_node->target, options);
728
+ VALUE xml_processing_instruction_node_children = rb_nodes_array_from_c_array(xml_processing_instruction_node->children, options);
729
+ VALUE xml_processing_instruction_node_tag_closing = rb_token_from_c_struct(xml_processing_instruction_node->tag_closing, options);
730
+
731
+ VALUE args[7] = {
732
+ type,
733
+ location,
734
+ errors,
735
+ xml_processing_instruction_node_tag_opening,
736
+ xml_processing_instruction_node_target,
737
+ xml_processing_instruction_node_children,
738
+ xml_processing_instruction_node_tag_closing
739
+ };
740
+
741
+ return rb_class_new_instance(7, args, cXMLProcessingInstructionNode);
742
+ };
743
+
744
+ static VALUE rb_cdata_node_from_c_struct(AST_CDATA_NODE_T* cdata_node, const parser_options_T* options) {
606
745
  if (cdata_node == NULL) { return Qnil; }
607
746
 
608
747
  AST_NODE_T* node = &cdata_node->base;
609
748
 
610
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
611
- VALUE location = rb_location_from_c_struct(node->location);
749
+ static VALUE type = 0;
750
+
751
+ if (type == 0) {
752
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
753
+ rb_gc_register_mark_object(type);
754
+ }
755
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
612
756
  VALUE errors = rb_errors_array_from_c_array(node->errors);
613
757
 
614
- VALUE cdata_node_tag_opening = rb_token_from_c_struct(cdata_node->tag_opening);
615
- VALUE cdata_node_children = rb_nodes_array_from_c_array(cdata_node->children);
616
- VALUE cdata_node_tag_closing = rb_token_from_c_struct(cdata_node->tag_closing);
758
+ VALUE cdata_node_tag_opening = rb_token_from_c_struct(cdata_node->tag_opening, options);
759
+ VALUE cdata_node_children = rb_nodes_array_from_c_array(cdata_node->children, options);
760
+ VALUE cdata_node_tag_closing = rb_token_from_c_struct(cdata_node->tag_closing, options);
617
761
 
618
762
  VALUE args[6] = {
619
763
  type,
@@ -627,16 +771,21 @@ static VALUE rb_cdata_node_from_c_struct(AST_CDATA_NODE_T* cdata_node) {
627
771
  return rb_class_new_instance(6, args, cCDATANode);
628
772
  };
629
773
 
630
- static VALUE rb_whitespace_node_from_c_struct(AST_WHITESPACE_NODE_T* whitespace_node) {
774
+ static VALUE rb_whitespace_node_from_c_struct(AST_WHITESPACE_NODE_T* whitespace_node, const parser_options_T* options) {
631
775
  if (whitespace_node == NULL) { return Qnil; }
632
776
 
633
777
  AST_NODE_T* node = &whitespace_node->base;
634
778
 
635
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
636
- VALUE location = rb_location_from_c_struct(node->location);
779
+ static VALUE type = 0;
780
+
781
+ if (type == 0) {
782
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
783
+ rb_gc_register_mark_object(type);
784
+ }
785
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
637
786
  VALUE errors = rb_errors_array_from_c_array(node->errors);
638
787
 
639
- VALUE whitespace_node_value = rb_token_from_c_struct(whitespace_node->value);
788
+ VALUE whitespace_node_value = rb_token_from_c_struct(whitespace_node->value, options);
640
789
 
641
790
  VALUE args[4] = {
642
791
  type,
@@ -648,18 +797,23 @@ static VALUE rb_whitespace_node_from_c_struct(AST_WHITESPACE_NODE_T* whitespace_
648
797
  return rb_class_new_instance(4, args, cWhitespaceNode);
649
798
  };
650
799
 
651
- static VALUE rb_erb_content_node_from_c_struct(AST_ERB_CONTENT_NODE_T* erb_content_node) {
800
+ static VALUE rb_erb_content_node_from_c_struct(AST_ERB_CONTENT_NODE_T* erb_content_node, const parser_options_T* options) {
652
801
  if (erb_content_node == NULL) { return Qnil; }
653
802
 
654
803
  AST_NODE_T* node = &erb_content_node->base;
655
804
 
656
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
657
- VALUE location = rb_location_from_c_struct(node->location);
805
+ static VALUE type = 0;
806
+
807
+ if (type == 0) {
808
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
809
+ rb_gc_register_mark_object(type);
810
+ }
811
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
658
812
  VALUE errors = rb_errors_array_from_c_array(node->errors);
659
813
 
660
- VALUE erb_content_node_tag_opening = rb_token_from_c_struct(erb_content_node->tag_opening);
661
- VALUE erb_content_node_content = rb_token_from_c_struct(erb_content_node->content);
662
- VALUE erb_content_node_tag_closing = rb_token_from_c_struct(erb_content_node->tag_closing);
814
+ VALUE erb_content_node_tag_opening = rb_token_from_c_struct(erb_content_node->tag_opening, options);
815
+ VALUE erb_content_node_content = rb_token_from_c_struct(erb_content_node->content, options);
816
+ VALUE erb_content_node_tag_closing = rb_token_from_c_struct(erb_content_node->tag_closing, options);
663
817
  /* analyzed_ruby is internal parser state, not exposed to Ruby */
664
818
  VALUE erb_content_node_analyzed_ruby = Qnil;
665
819
  VALUE erb_content_node_parsed = (erb_content_node->parsed) ? Qtrue : Qfalse;
@@ -697,18 +851,23 @@ static VALUE rb_erb_content_node_from_c_struct(AST_ERB_CONTENT_NODE_T* erb_conte
697
851
  return rb_class_new_instance(10, args, cERBContentNode);
698
852
  };
699
853
 
700
- static VALUE rb_erb_end_node_from_c_struct(AST_ERB_END_NODE_T* erb_end_node) {
854
+ static VALUE rb_erb_end_node_from_c_struct(AST_ERB_END_NODE_T* erb_end_node, const parser_options_T* options) {
701
855
  if (erb_end_node == NULL) { return Qnil; }
702
856
 
703
857
  AST_NODE_T* node = &erb_end_node->base;
704
858
 
705
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
706
- VALUE location = rb_location_from_c_struct(node->location);
859
+ static VALUE type = 0;
860
+
861
+ if (type == 0) {
862
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
863
+ rb_gc_register_mark_object(type);
864
+ }
865
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
707
866
  VALUE errors = rb_errors_array_from_c_array(node->errors);
708
867
 
709
- VALUE erb_end_node_tag_opening = rb_token_from_c_struct(erb_end_node->tag_opening);
710
- VALUE erb_end_node_content = rb_token_from_c_struct(erb_end_node->content);
711
- VALUE erb_end_node_tag_closing = rb_token_from_c_struct(erb_end_node->tag_closing);
868
+ VALUE erb_end_node_tag_opening = rb_token_from_c_struct(erb_end_node->tag_opening, options);
869
+ VALUE erb_end_node_content = rb_token_from_c_struct(erb_end_node->content, options);
870
+ VALUE erb_end_node_tag_closing = rb_token_from_c_struct(erb_end_node->tag_closing, options);
712
871
 
713
872
  VALUE args[6] = {
714
873
  type,
@@ -722,19 +881,24 @@ static VALUE rb_erb_end_node_from_c_struct(AST_ERB_END_NODE_T* erb_end_node) {
722
881
  return rb_class_new_instance(6, args, cERBEndNode);
723
882
  };
724
883
 
725
- static VALUE rb_erb_else_node_from_c_struct(AST_ERB_ELSE_NODE_T* erb_else_node) {
884
+ static VALUE rb_erb_else_node_from_c_struct(AST_ERB_ELSE_NODE_T* erb_else_node, const parser_options_T* options) {
726
885
  if (erb_else_node == NULL) { return Qnil; }
727
886
 
728
887
  AST_NODE_T* node = &erb_else_node->base;
729
888
 
730
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
731
- VALUE location = rb_location_from_c_struct(node->location);
889
+ static VALUE type = 0;
890
+
891
+ if (type == 0) {
892
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
893
+ rb_gc_register_mark_object(type);
894
+ }
895
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
732
896
  VALUE errors = rb_errors_array_from_c_array(node->errors);
733
897
 
734
- VALUE erb_else_node_tag_opening = rb_token_from_c_struct(erb_else_node->tag_opening);
735
- VALUE erb_else_node_content = rb_token_from_c_struct(erb_else_node->content);
736
- VALUE erb_else_node_tag_closing = rb_token_from_c_struct(erb_else_node->tag_closing);
737
- VALUE erb_else_node_statements = rb_nodes_array_from_c_array(erb_else_node->statements);
898
+ VALUE erb_else_node_tag_opening = rb_token_from_c_struct(erb_else_node->tag_opening, options);
899
+ VALUE erb_else_node_content = rb_token_from_c_struct(erb_else_node->content, options);
900
+ VALUE erb_else_node_tag_closing = rb_token_from_c_struct(erb_else_node->tag_closing, options);
901
+ VALUE erb_else_node_statements = rb_nodes_array_from_c_array(erb_else_node->statements, options);
738
902
 
739
903
  VALUE args[7] = {
740
904
  type,
@@ -749,19 +913,24 @@ static VALUE rb_erb_else_node_from_c_struct(AST_ERB_ELSE_NODE_T* erb_else_node)
749
913
  return rb_class_new_instance(7, args, cERBElseNode);
750
914
  };
751
915
 
752
- static VALUE rb_erb_if_node_from_c_struct(AST_ERB_IF_NODE_T* erb_if_node) {
916
+ static VALUE rb_erb_if_node_from_c_struct(AST_ERB_IF_NODE_T* erb_if_node, const parser_options_T* options) {
753
917
  if (erb_if_node == NULL) { return Qnil; }
754
918
 
755
919
  AST_NODE_T* node = &erb_if_node->base;
756
920
 
757
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
758
- VALUE location = rb_location_from_c_struct(node->location);
921
+ static VALUE type = 0;
922
+
923
+ if (type == 0) {
924
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
925
+ rb_gc_register_mark_object(type);
926
+ }
927
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
759
928
  VALUE errors = rb_errors_array_from_c_array(node->errors);
760
929
 
761
- VALUE erb_if_node_tag_opening = rb_token_from_c_struct(erb_if_node->tag_opening);
762
- VALUE erb_if_node_content = rb_token_from_c_struct(erb_if_node->content);
763
- VALUE erb_if_node_tag_closing = rb_token_from_c_struct(erb_if_node->tag_closing);
764
- VALUE erb_if_node_then_keyword = (erb_if_node->then_keyword != NULL) ? rb_location_from_c_struct(*erb_if_node->then_keyword) : Qnil;
930
+ VALUE erb_if_node_tag_opening = rb_token_from_c_struct(erb_if_node->tag_opening, options);
931
+ VALUE erb_if_node_content = rb_token_from_c_struct(erb_if_node->content, options);
932
+ VALUE erb_if_node_tag_closing = rb_token_from_c_struct(erb_if_node->tag_closing, options);
933
+ VALUE erb_if_node_then_keyword = (options->track_locations && erb_if_node->then_keyword != NULL) ? rb_location_from_c_struct(*erb_if_node->then_keyword) : Qnil;
765
934
  VALUE erb_if_node_prism_node;
766
935
  if (erb_if_node->prism_node.node != NULL && erb_if_node->prism_node.parser != NULL) {
767
936
  pm_buffer_t pm_buffer = { 0 };
@@ -778,9 +947,9 @@ static VALUE rb_erb_if_node_from_c_struct(AST_ERB_IF_NODE_T* erb_if_node) {
778
947
  } else {
779
948
  erb_if_node_prism_node = Qnil;
780
949
  }
781
- VALUE erb_if_node_statements = rb_nodes_array_from_c_array(erb_if_node->statements);
782
- VALUE erb_if_node_subsequent = rb_node_from_c_struct((AST_NODE_T*) erb_if_node->subsequent);
783
- VALUE erb_if_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_if_node->end_node);
950
+ VALUE erb_if_node_statements = rb_nodes_array_from_c_array(erb_if_node->statements, options);
951
+ VALUE erb_if_node_subsequent = rb_node_from_c_struct((AST_NODE_T*) erb_if_node->subsequent, options);
952
+ VALUE erb_if_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_if_node->end_node, options);
784
953
 
785
954
  VALUE args[11] = {
786
955
  type,
@@ -799,18 +968,23 @@ static VALUE rb_erb_if_node_from_c_struct(AST_ERB_IF_NODE_T* erb_if_node) {
799
968
  return rb_class_new_instance(11, args, cERBIfNode);
800
969
  };
801
970
 
802
- static VALUE rb_erb_block_node_from_c_struct(AST_ERB_BLOCK_NODE_T* erb_block_node) {
971
+ static VALUE rb_erb_block_node_from_c_struct(AST_ERB_BLOCK_NODE_T* erb_block_node, const parser_options_T* options) {
803
972
  if (erb_block_node == NULL) { return Qnil; }
804
973
 
805
974
  AST_NODE_T* node = &erb_block_node->base;
806
975
 
807
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
808
- VALUE location = rb_location_from_c_struct(node->location);
976
+ static VALUE type = 0;
977
+
978
+ if (type == 0) {
979
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
980
+ rb_gc_register_mark_object(type);
981
+ }
982
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
809
983
  VALUE errors = rb_errors_array_from_c_array(node->errors);
810
984
 
811
- VALUE erb_block_node_tag_opening = rb_token_from_c_struct(erb_block_node->tag_opening);
812
- VALUE erb_block_node_content = rb_token_from_c_struct(erb_block_node->content);
813
- VALUE erb_block_node_tag_closing = rb_token_from_c_struct(erb_block_node->tag_closing);
985
+ VALUE erb_block_node_tag_opening = rb_token_from_c_struct(erb_block_node->tag_opening, options);
986
+ VALUE erb_block_node_content = rb_token_from_c_struct(erb_block_node->content, options);
987
+ VALUE erb_block_node_tag_closing = rb_token_from_c_struct(erb_block_node->tag_closing, options);
814
988
  VALUE erb_block_node_prism_node;
815
989
  if (erb_block_node->prism_node.node != NULL && erb_block_node->prism_node.parser != NULL) {
816
990
  pm_buffer_t pm_buffer = { 0 };
@@ -827,12 +1001,12 @@ static VALUE rb_erb_block_node_from_c_struct(AST_ERB_BLOCK_NODE_T* erb_block_nod
827
1001
  } else {
828
1002
  erb_block_node_prism_node = Qnil;
829
1003
  }
830
- VALUE erb_block_node_body = rb_nodes_array_from_c_array(erb_block_node->body);
831
- VALUE erb_block_node_block_arguments = rb_nodes_array_from_c_array(erb_block_node->block_arguments);
832
- VALUE erb_block_node_rescue_clause = rb_node_from_c_struct((AST_NODE_T*) erb_block_node->rescue_clause);
833
- VALUE erb_block_node_else_clause = rb_node_from_c_struct((AST_NODE_T*) erb_block_node->else_clause);
834
- VALUE erb_block_node_ensure_clause = rb_node_from_c_struct((AST_NODE_T*) erb_block_node->ensure_clause);
835
- VALUE erb_block_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_block_node->end_node);
1004
+ VALUE erb_block_node_body = rb_nodes_array_from_c_array(erb_block_node->body, options);
1005
+ VALUE erb_block_node_block_arguments = rb_nodes_array_from_c_array(erb_block_node->block_arguments, options);
1006
+ VALUE erb_block_node_rescue_clause = rb_node_from_c_struct((AST_NODE_T*) erb_block_node->rescue_clause, options);
1007
+ VALUE erb_block_node_else_clause = rb_node_from_c_struct((AST_NODE_T*) erb_block_node->else_clause, options);
1008
+ VALUE erb_block_node_ensure_clause = rb_node_from_c_struct((AST_NODE_T*) erb_block_node->ensure_clause, options);
1009
+ VALUE erb_block_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_block_node->end_node, options);
836
1010
 
837
1011
  VALUE args[13] = {
838
1012
  type,
@@ -853,20 +1027,94 @@ static VALUE rb_erb_block_node_from_c_struct(AST_ERB_BLOCK_NODE_T* erb_block_nod
853
1027
  return rb_class_new_instance(13, args, cERBBlockNode);
854
1028
  };
855
1029
 
856
- static VALUE rb_erb_when_node_from_c_struct(AST_ERB_WHEN_NODE_T* erb_when_node) {
1030
+ static VALUE rb_erb_iteration_block_node_from_c_struct(AST_ERB_ITERATION_BLOCK_NODE_T* erb_iteration_block_node, const parser_options_T* options) {
1031
+ if (erb_iteration_block_node == NULL) { return Qnil; }
1032
+
1033
+ AST_NODE_T* node = &erb_iteration_block_node->base;
1034
+
1035
+ static VALUE type = 0;
1036
+
1037
+ if (type == 0) {
1038
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1039
+ rb_gc_register_mark_object(type);
1040
+ }
1041
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
1042
+ VALUE errors = rb_errors_array_from_c_array(node->errors);
1043
+
1044
+ VALUE erb_iteration_block_node_tag_opening = rb_token_from_c_struct(erb_iteration_block_node->tag_opening, options);
1045
+ VALUE erb_iteration_block_node_content = rb_token_from_c_struct(erb_iteration_block_node->content, options);
1046
+ VALUE erb_iteration_block_node_tag_closing = rb_token_from_c_struct(erb_iteration_block_node->tag_closing, options);
1047
+ VALUE erb_iteration_block_node_prism_node;
1048
+ if (erb_iteration_block_node->prism_node.node != NULL && erb_iteration_block_node->prism_node.parser != NULL) {
1049
+ pm_buffer_t pm_buffer = { 0 };
1050
+ pm_serialize(erb_iteration_block_node->prism_node.parser, erb_iteration_block_node->prism_node.node, &pm_buffer);
1051
+
1052
+ if (pm_buffer.length > 0) {
1053
+ erb_iteration_block_node_prism_node = rb_str_new(pm_buffer.value, pm_buffer.length);
1054
+ rb_enc_associate(erb_iteration_block_node_prism_node, rb_ascii8bit_encoding());
1055
+ OBJ_FREEZE(erb_iteration_block_node_prism_node);
1056
+ } else {
1057
+ erb_iteration_block_node_prism_node = Qnil;
1058
+ }
1059
+ pm_buffer_free(&pm_buffer);
1060
+ } else {
1061
+ erb_iteration_block_node_prism_node = Qnil;
1062
+ }
1063
+ VALUE erb_iteration_block_node_receiver = rb_token_from_c_struct(erb_iteration_block_node->receiver, options);
1064
+ VALUE erb_iteration_block_node_call_operator = rb_token_from_c_struct(erb_iteration_block_node->call_operator, options);
1065
+ VALUE erb_iteration_block_node_message = rb_token_from_c_struct(erb_iteration_block_node->message, options);
1066
+ VALUE erb_iteration_block_node_arguments = rb_nodes_array_from_c_array(erb_iteration_block_node->arguments, options);
1067
+ VALUE erb_iteration_block_node_block_opening = rb_token_from_c_struct(erb_iteration_block_node->block_opening, options);
1068
+ VALUE erb_iteration_block_node_body = rb_nodes_array_from_c_array(erb_iteration_block_node->body, options);
1069
+ VALUE erb_iteration_block_node_block_arguments = rb_nodes_array_from_c_array(erb_iteration_block_node->block_arguments, options);
1070
+ VALUE erb_iteration_block_node_rescue_clause = rb_node_from_c_struct((AST_NODE_T*) erb_iteration_block_node->rescue_clause, options);
1071
+ VALUE erb_iteration_block_node_else_clause = rb_node_from_c_struct((AST_NODE_T*) erb_iteration_block_node->else_clause, options);
1072
+ VALUE erb_iteration_block_node_ensure_clause = rb_node_from_c_struct((AST_NODE_T*) erb_iteration_block_node->ensure_clause, options);
1073
+ VALUE erb_iteration_block_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_iteration_block_node->end_node, options);
1074
+
1075
+ VALUE args[18] = {
1076
+ type,
1077
+ location,
1078
+ errors,
1079
+ erb_iteration_block_node_tag_opening,
1080
+ erb_iteration_block_node_content,
1081
+ erb_iteration_block_node_tag_closing,
1082
+ erb_iteration_block_node_prism_node,
1083
+ erb_iteration_block_node_receiver,
1084
+ erb_iteration_block_node_call_operator,
1085
+ erb_iteration_block_node_message,
1086
+ erb_iteration_block_node_arguments,
1087
+ erb_iteration_block_node_block_opening,
1088
+ erb_iteration_block_node_body,
1089
+ erb_iteration_block_node_block_arguments,
1090
+ erb_iteration_block_node_rescue_clause,
1091
+ erb_iteration_block_node_else_clause,
1092
+ erb_iteration_block_node_ensure_clause,
1093
+ erb_iteration_block_node_end_node
1094
+ };
1095
+
1096
+ return rb_class_new_instance(18, args, cERBIterationBlockNode);
1097
+ };
1098
+
1099
+ static VALUE rb_erb_when_node_from_c_struct(AST_ERB_WHEN_NODE_T* erb_when_node, const parser_options_T* options) {
857
1100
  if (erb_when_node == NULL) { return Qnil; }
858
1101
 
859
1102
  AST_NODE_T* node = &erb_when_node->base;
860
1103
 
861
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
862
- VALUE location = rb_location_from_c_struct(node->location);
1104
+ static VALUE type = 0;
1105
+
1106
+ if (type == 0) {
1107
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1108
+ rb_gc_register_mark_object(type);
1109
+ }
1110
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
863
1111
  VALUE errors = rb_errors_array_from_c_array(node->errors);
864
1112
 
865
- VALUE erb_when_node_tag_opening = rb_token_from_c_struct(erb_when_node->tag_opening);
866
- VALUE erb_when_node_content = rb_token_from_c_struct(erb_when_node->content);
867
- VALUE erb_when_node_tag_closing = rb_token_from_c_struct(erb_when_node->tag_closing);
868
- VALUE erb_when_node_then_keyword = (erb_when_node->then_keyword != NULL) ? rb_location_from_c_struct(*erb_when_node->then_keyword) : Qnil;
869
- VALUE erb_when_node_statements = rb_nodes_array_from_c_array(erb_when_node->statements);
1113
+ VALUE erb_when_node_tag_opening = rb_token_from_c_struct(erb_when_node->tag_opening, options);
1114
+ VALUE erb_when_node_content = rb_token_from_c_struct(erb_when_node->content, options);
1115
+ VALUE erb_when_node_tag_closing = rb_token_from_c_struct(erb_when_node->tag_closing, options);
1116
+ VALUE erb_when_node_then_keyword = (options->track_locations && erb_when_node->then_keyword != NULL) ? rb_location_from_c_struct(*erb_when_node->then_keyword) : Qnil;
1117
+ VALUE erb_when_node_statements = rb_nodes_array_from_c_array(erb_when_node->statements, options);
870
1118
 
871
1119
  VALUE args[8] = {
872
1120
  type,
@@ -882,19 +1130,24 @@ static VALUE rb_erb_when_node_from_c_struct(AST_ERB_WHEN_NODE_T* erb_when_node)
882
1130
  return rb_class_new_instance(8, args, cERBWhenNode);
883
1131
  };
884
1132
 
885
- static VALUE rb_erb_case_node_from_c_struct(AST_ERB_CASE_NODE_T* erb_case_node) {
1133
+ static VALUE rb_erb_case_node_from_c_struct(AST_ERB_CASE_NODE_T* erb_case_node, const parser_options_T* options) {
886
1134
  if (erb_case_node == NULL) { return Qnil; }
887
1135
 
888
1136
  AST_NODE_T* node = &erb_case_node->base;
889
1137
 
890
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
891
- VALUE location = rb_location_from_c_struct(node->location);
1138
+ static VALUE type = 0;
1139
+
1140
+ if (type == 0) {
1141
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1142
+ rb_gc_register_mark_object(type);
1143
+ }
1144
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
892
1145
  VALUE errors = rb_errors_array_from_c_array(node->errors);
893
1146
 
894
- VALUE erb_case_node_tag_opening = rb_token_from_c_struct(erb_case_node->tag_opening);
895
- VALUE erb_case_node_content = rb_token_from_c_struct(erb_case_node->content);
896
- VALUE erb_case_node_tag_closing = rb_token_from_c_struct(erb_case_node->tag_closing);
897
- VALUE erb_case_node_children = rb_nodes_array_from_c_array(erb_case_node->children);
1147
+ VALUE erb_case_node_tag_opening = rb_token_from_c_struct(erb_case_node->tag_opening, options);
1148
+ VALUE erb_case_node_content = rb_token_from_c_struct(erb_case_node->content, options);
1149
+ VALUE erb_case_node_tag_closing = rb_token_from_c_struct(erb_case_node->tag_closing, options);
1150
+ VALUE erb_case_node_children = rb_nodes_array_from_c_array(erb_case_node->children, options);
898
1151
  VALUE erb_case_node_prism_node;
899
1152
  if (erb_case_node->prism_node.node != NULL && erb_case_node->prism_node.parser != NULL) {
900
1153
  pm_buffer_t pm_buffer = { 0 };
@@ -911,9 +1164,9 @@ static VALUE rb_erb_case_node_from_c_struct(AST_ERB_CASE_NODE_T* erb_case_node)
911
1164
  } else {
912
1165
  erb_case_node_prism_node = Qnil;
913
1166
  }
914
- VALUE erb_case_node_conditions = rb_nodes_array_from_c_array(erb_case_node->conditions);
915
- VALUE erb_case_node_else_clause = rb_node_from_c_struct((AST_NODE_T*) erb_case_node->else_clause);
916
- VALUE erb_case_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_case_node->end_node);
1167
+ VALUE erb_case_node_conditions = rb_nodes_array_from_c_array(erb_case_node->conditions, options);
1168
+ VALUE erb_case_node_else_clause = rb_node_from_c_struct((AST_NODE_T*) erb_case_node->else_clause, options);
1169
+ VALUE erb_case_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_case_node->end_node, options);
917
1170
 
918
1171
  VALUE args[11] = {
919
1172
  type,
@@ -932,19 +1185,24 @@ static VALUE rb_erb_case_node_from_c_struct(AST_ERB_CASE_NODE_T* erb_case_node)
932
1185
  return rb_class_new_instance(11, args, cERBCaseNode);
933
1186
  };
934
1187
 
935
- static VALUE rb_erb_case_match_node_from_c_struct(AST_ERB_CASE_MATCH_NODE_T* erb_case_match_node) {
1188
+ static VALUE rb_erb_case_match_node_from_c_struct(AST_ERB_CASE_MATCH_NODE_T* erb_case_match_node, const parser_options_T* options) {
936
1189
  if (erb_case_match_node == NULL) { return Qnil; }
937
1190
 
938
1191
  AST_NODE_T* node = &erb_case_match_node->base;
939
1192
 
940
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
941
- VALUE location = rb_location_from_c_struct(node->location);
1193
+ static VALUE type = 0;
1194
+
1195
+ if (type == 0) {
1196
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1197
+ rb_gc_register_mark_object(type);
1198
+ }
1199
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
942
1200
  VALUE errors = rb_errors_array_from_c_array(node->errors);
943
1201
 
944
- VALUE erb_case_match_node_tag_opening = rb_token_from_c_struct(erb_case_match_node->tag_opening);
945
- VALUE erb_case_match_node_content = rb_token_from_c_struct(erb_case_match_node->content);
946
- VALUE erb_case_match_node_tag_closing = rb_token_from_c_struct(erb_case_match_node->tag_closing);
947
- VALUE erb_case_match_node_children = rb_nodes_array_from_c_array(erb_case_match_node->children);
1202
+ VALUE erb_case_match_node_tag_opening = rb_token_from_c_struct(erb_case_match_node->tag_opening, options);
1203
+ VALUE erb_case_match_node_content = rb_token_from_c_struct(erb_case_match_node->content, options);
1204
+ VALUE erb_case_match_node_tag_closing = rb_token_from_c_struct(erb_case_match_node->tag_closing, options);
1205
+ VALUE erb_case_match_node_children = rb_nodes_array_from_c_array(erb_case_match_node->children, options);
948
1206
  VALUE erb_case_match_node_prism_node;
949
1207
  if (erb_case_match_node->prism_node.node != NULL && erb_case_match_node->prism_node.parser != NULL) {
950
1208
  pm_buffer_t pm_buffer = { 0 };
@@ -961,9 +1219,9 @@ static VALUE rb_erb_case_match_node_from_c_struct(AST_ERB_CASE_MATCH_NODE_T* erb
961
1219
  } else {
962
1220
  erb_case_match_node_prism_node = Qnil;
963
1221
  }
964
- VALUE erb_case_match_node_conditions = rb_nodes_array_from_c_array(erb_case_match_node->conditions);
965
- VALUE erb_case_match_node_else_clause = rb_node_from_c_struct((AST_NODE_T*) erb_case_match_node->else_clause);
966
- VALUE erb_case_match_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_case_match_node->end_node);
1222
+ VALUE erb_case_match_node_conditions = rb_nodes_array_from_c_array(erb_case_match_node->conditions, options);
1223
+ VALUE erb_case_match_node_else_clause = rb_node_from_c_struct((AST_NODE_T*) erb_case_match_node->else_clause, options);
1224
+ VALUE erb_case_match_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_case_match_node->end_node, options);
967
1225
 
968
1226
  VALUE args[11] = {
969
1227
  type,
@@ -982,18 +1240,23 @@ static VALUE rb_erb_case_match_node_from_c_struct(AST_ERB_CASE_MATCH_NODE_T* erb
982
1240
  return rb_class_new_instance(11, args, cERBCaseMatchNode);
983
1241
  };
984
1242
 
985
- static VALUE rb_erb_while_node_from_c_struct(AST_ERB_WHILE_NODE_T* erb_while_node) {
1243
+ static VALUE rb_erb_while_node_from_c_struct(AST_ERB_WHILE_NODE_T* erb_while_node, const parser_options_T* options) {
986
1244
  if (erb_while_node == NULL) { return Qnil; }
987
1245
 
988
1246
  AST_NODE_T* node = &erb_while_node->base;
989
1247
 
990
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
991
- VALUE location = rb_location_from_c_struct(node->location);
1248
+ static VALUE type = 0;
1249
+
1250
+ if (type == 0) {
1251
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1252
+ rb_gc_register_mark_object(type);
1253
+ }
1254
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
992
1255
  VALUE errors = rb_errors_array_from_c_array(node->errors);
993
1256
 
994
- VALUE erb_while_node_tag_opening = rb_token_from_c_struct(erb_while_node->tag_opening);
995
- VALUE erb_while_node_content = rb_token_from_c_struct(erb_while_node->content);
996
- VALUE erb_while_node_tag_closing = rb_token_from_c_struct(erb_while_node->tag_closing);
1257
+ VALUE erb_while_node_tag_opening = rb_token_from_c_struct(erb_while_node->tag_opening, options);
1258
+ VALUE erb_while_node_content = rb_token_from_c_struct(erb_while_node->content, options);
1259
+ VALUE erb_while_node_tag_closing = rb_token_from_c_struct(erb_while_node->tag_closing, options);
997
1260
  VALUE erb_while_node_prism_node;
998
1261
  if (erb_while_node->prism_node.node != NULL && erb_while_node->prism_node.parser != NULL) {
999
1262
  pm_buffer_t pm_buffer = { 0 };
@@ -1010,8 +1273,8 @@ static VALUE rb_erb_while_node_from_c_struct(AST_ERB_WHILE_NODE_T* erb_while_nod
1010
1273
  } else {
1011
1274
  erb_while_node_prism_node = Qnil;
1012
1275
  }
1013
- VALUE erb_while_node_statements = rb_nodes_array_from_c_array(erb_while_node->statements);
1014
- VALUE erb_while_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_while_node->end_node);
1276
+ VALUE erb_while_node_statements = rb_nodes_array_from_c_array(erb_while_node->statements, options);
1277
+ VALUE erb_while_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_while_node->end_node, options);
1015
1278
 
1016
1279
  VALUE args[9] = {
1017
1280
  type,
@@ -1028,18 +1291,23 @@ static VALUE rb_erb_while_node_from_c_struct(AST_ERB_WHILE_NODE_T* erb_while_nod
1028
1291
  return rb_class_new_instance(9, args, cERBWhileNode);
1029
1292
  };
1030
1293
 
1031
- static VALUE rb_erb_until_node_from_c_struct(AST_ERB_UNTIL_NODE_T* erb_until_node) {
1294
+ static VALUE rb_erb_until_node_from_c_struct(AST_ERB_UNTIL_NODE_T* erb_until_node, const parser_options_T* options) {
1032
1295
  if (erb_until_node == NULL) { return Qnil; }
1033
1296
 
1034
1297
  AST_NODE_T* node = &erb_until_node->base;
1035
1298
 
1036
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
1037
- VALUE location = rb_location_from_c_struct(node->location);
1299
+ static VALUE type = 0;
1300
+
1301
+ if (type == 0) {
1302
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1303
+ rb_gc_register_mark_object(type);
1304
+ }
1305
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
1038
1306
  VALUE errors = rb_errors_array_from_c_array(node->errors);
1039
1307
 
1040
- VALUE erb_until_node_tag_opening = rb_token_from_c_struct(erb_until_node->tag_opening);
1041
- VALUE erb_until_node_content = rb_token_from_c_struct(erb_until_node->content);
1042
- VALUE erb_until_node_tag_closing = rb_token_from_c_struct(erb_until_node->tag_closing);
1308
+ VALUE erb_until_node_tag_opening = rb_token_from_c_struct(erb_until_node->tag_opening, options);
1309
+ VALUE erb_until_node_content = rb_token_from_c_struct(erb_until_node->content, options);
1310
+ VALUE erb_until_node_tag_closing = rb_token_from_c_struct(erb_until_node->tag_closing, options);
1043
1311
  VALUE erb_until_node_prism_node;
1044
1312
  if (erb_until_node->prism_node.node != NULL && erb_until_node->prism_node.parser != NULL) {
1045
1313
  pm_buffer_t pm_buffer = { 0 };
@@ -1056,8 +1324,8 @@ static VALUE rb_erb_until_node_from_c_struct(AST_ERB_UNTIL_NODE_T* erb_until_nod
1056
1324
  } else {
1057
1325
  erb_until_node_prism_node = Qnil;
1058
1326
  }
1059
- VALUE erb_until_node_statements = rb_nodes_array_from_c_array(erb_until_node->statements);
1060
- VALUE erb_until_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_until_node->end_node);
1327
+ VALUE erb_until_node_statements = rb_nodes_array_from_c_array(erb_until_node->statements, options);
1328
+ VALUE erb_until_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_until_node->end_node, options);
1061
1329
 
1062
1330
  VALUE args[9] = {
1063
1331
  type,
@@ -1074,18 +1342,23 @@ static VALUE rb_erb_until_node_from_c_struct(AST_ERB_UNTIL_NODE_T* erb_until_nod
1074
1342
  return rb_class_new_instance(9, args, cERBUntilNode);
1075
1343
  };
1076
1344
 
1077
- static VALUE rb_erb_for_node_from_c_struct(AST_ERB_FOR_NODE_T* erb_for_node) {
1345
+ static VALUE rb_erb_for_node_from_c_struct(AST_ERB_FOR_NODE_T* erb_for_node, const parser_options_T* options) {
1078
1346
  if (erb_for_node == NULL) { return Qnil; }
1079
1347
 
1080
1348
  AST_NODE_T* node = &erb_for_node->base;
1081
1349
 
1082
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
1083
- VALUE location = rb_location_from_c_struct(node->location);
1350
+ static VALUE type = 0;
1351
+
1352
+ if (type == 0) {
1353
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1354
+ rb_gc_register_mark_object(type);
1355
+ }
1356
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
1084
1357
  VALUE errors = rb_errors_array_from_c_array(node->errors);
1085
1358
 
1086
- VALUE erb_for_node_tag_opening = rb_token_from_c_struct(erb_for_node->tag_opening);
1087
- VALUE erb_for_node_content = rb_token_from_c_struct(erb_for_node->content);
1088
- VALUE erb_for_node_tag_closing = rb_token_from_c_struct(erb_for_node->tag_closing);
1359
+ VALUE erb_for_node_tag_opening = rb_token_from_c_struct(erb_for_node->tag_opening, options);
1360
+ VALUE erb_for_node_content = rb_token_from_c_struct(erb_for_node->content, options);
1361
+ VALUE erb_for_node_tag_closing = rb_token_from_c_struct(erb_for_node->tag_closing, options);
1089
1362
  VALUE erb_for_node_prism_node;
1090
1363
  if (erb_for_node->prism_node.node != NULL && erb_for_node->prism_node.parser != NULL) {
1091
1364
  pm_buffer_t pm_buffer = { 0 };
@@ -1102,8 +1375,8 @@ static VALUE rb_erb_for_node_from_c_struct(AST_ERB_FOR_NODE_T* erb_for_node) {
1102
1375
  } else {
1103
1376
  erb_for_node_prism_node = Qnil;
1104
1377
  }
1105
- VALUE erb_for_node_statements = rb_nodes_array_from_c_array(erb_for_node->statements);
1106
- VALUE erb_for_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_for_node->end_node);
1378
+ VALUE erb_for_node_statements = rb_nodes_array_from_c_array(erb_for_node->statements, options);
1379
+ VALUE erb_for_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_for_node->end_node, options);
1107
1380
 
1108
1381
  VALUE args[9] = {
1109
1382
  type,
@@ -1120,20 +1393,25 @@ static VALUE rb_erb_for_node_from_c_struct(AST_ERB_FOR_NODE_T* erb_for_node) {
1120
1393
  return rb_class_new_instance(9, args, cERBForNode);
1121
1394
  };
1122
1395
 
1123
- static VALUE rb_erb_rescue_node_from_c_struct(AST_ERB_RESCUE_NODE_T* erb_rescue_node) {
1396
+ static VALUE rb_erb_rescue_node_from_c_struct(AST_ERB_RESCUE_NODE_T* erb_rescue_node, const parser_options_T* options) {
1124
1397
  if (erb_rescue_node == NULL) { return Qnil; }
1125
1398
 
1126
1399
  AST_NODE_T* node = &erb_rescue_node->base;
1127
1400
 
1128
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
1129
- VALUE location = rb_location_from_c_struct(node->location);
1401
+ static VALUE type = 0;
1402
+
1403
+ if (type == 0) {
1404
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1405
+ rb_gc_register_mark_object(type);
1406
+ }
1407
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
1130
1408
  VALUE errors = rb_errors_array_from_c_array(node->errors);
1131
1409
 
1132
- VALUE erb_rescue_node_tag_opening = rb_token_from_c_struct(erb_rescue_node->tag_opening);
1133
- VALUE erb_rescue_node_content = rb_token_from_c_struct(erb_rescue_node->content);
1134
- VALUE erb_rescue_node_tag_closing = rb_token_from_c_struct(erb_rescue_node->tag_closing);
1135
- VALUE erb_rescue_node_statements = rb_nodes_array_from_c_array(erb_rescue_node->statements);
1136
- VALUE erb_rescue_node_subsequent = rb_node_from_c_struct((AST_NODE_T*) erb_rescue_node->subsequent);
1410
+ VALUE erb_rescue_node_tag_opening = rb_token_from_c_struct(erb_rescue_node->tag_opening, options);
1411
+ VALUE erb_rescue_node_content = rb_token_from_c_struct(erb_rescue_node->content, options);
1412
+ VALUE erb_rescue_node_tag_closing = rb_token_from_c_struct(erb_rescue_node->tag_closing, options);
1413
+ VALUE erb_rescue_node_statements = rb_nodes_array_from_c_array(erb_rescue_node->statements, options);
1414
+ VALUE erb_rescue_node_subsequent = rb_node_from_c_struct((AST_NODE_T*) erb_rescue_node->subsequent, options);
1137
1415
 
1138
1416
  VALUE args[8] = {
1139
1417
  type,
@@ -1149,19 +1427,24 @@ static VALUE rb_erb_rescue_node_from_c_struct(AST_ERB_RESCUE_NODE_T* erb_rescue_
1149
1427
  return rb_class_new_instance(8, args, cERBRescueNode);
1150
1428
  };
1151
1429
 
1152
- static VALUE rb_erb_ensure_node_from_c_struct(AST_ERB_ENSURE_NODE_T* erb_ensure_node) {
1430
+ static VALUE rb_erb_ensure_node_from_c_struct(AST_ERB_ENSURE_NODE_T* erb_ensure_node, const parser_options_T* options) {
1153
1431
  if (erb_ensure_node == NULL) { return Qnil; }
1154
1432
 
1155
1433
  AST_NODE_T* node = &erb_ensure_node->base;
1156
1434
 
1157
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
1158
- VALUE location = rb_location_from_c_struct(node->location);
1435
+ static VALUE type = 0;
1436
+
1437
+ if (type == 0) {
1438
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1439
+ rb_gc_register_mark_object(type);
1440
+ }
1441
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
1159
1442
  VALUE errors = rb_errors_array_from_c_array(node->errors);
1160
1443
 
1161
- VALUE erb_ensure_node_tag_opening = rb_token_from_c_struct(erb_ensure_node->tag_opening);
1162
- VALUE erb_ensure_node_content = rb_token_from_c_struct(erb_ensure_node->content);
1163
- VALUE erb_ensure_node_tag_closing = rb_token_from_c_struct(erb_ensure_node->tag_closing);
1164
- VALUE erb_ensure_node_statements = rb_nodes_array_from_c_array(erb_ensure_node->statements);
1444
+ VALUE erb_ensure_node_tag_opening = rb_token_from_c_struct(erb_ensure_node->tag_opening, options);
1445
+ VALUE erb_ensure_node_content = rb_token_from_c_struct(erb_ensure_node->content, options);
1446
+ VALUE erb_ensure_node_tag_closing = rb_token_from_c_struct(erb_ensure_node->tag_closing, options);
1447
+ VALUE erb_ensure_node_statements = rb_nodes_array_from_c_array(erb_ensure_node->statements, options);
1165
1448
 
1166
1449
  VALUE args[7] = {
1167
1450
  type,
@@ -1176,18 +1459,23 @@ static VALUE rb_erb_ensure_node_from_c_struct(AST_ERB_ENSURE_NODE_T* erb_ensure_
1176
1459
  return rb_class_new_instance(7, args, cERBEnsureNode);
1177
1460
  };
1178
1461
 
1179
- static VALUE rb_erb_begin_node_from_c_struct(AST_ERB_BEGIN_NODE_T* erb_begin_node) {
1462
+ static VALUE rb_erb_begin_node_from_c_struct(AST_ERB_BEGIN_NODE_T* erb_begin_node, const parser_options_T* options) {
1180
1463
  if (erb_begin_node == NULL) { return Qnil; }
1181
1464
 
1182
1465
  AST_NODE_T* node = &erb_begin_node->base;
1183
1466
 
1184
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
1185
- VALUE location = rb_location_from_c_struct(node->location);
1467
+ static VALUE type = 0;
1468
+
1469
+ if (type == 0) {
1470
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1471
+ rb_gc_register_mark_object(type);
1472
+ }
1473
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
1186
1474
  VALUE errors = rb_errors_array_from_c_array(node->errors);
1187
1475
 
1188
- VALUE erb_begin_node_tag_opening = rb_token_from_c_struct(erb_begin_node->tag_opening);
1189
- VALUE erb_begin_node_content = rb_token_from_c_struct(erb_begin_node->content);
1190
- VALUE erb_begin_node_tag_closing = rb_token_from_c_struct(erb_begin_node->tag_closing);
1476
+ VALUE erb_begin_node_tag_opening = rb_token_from_c_struct(erb_begin_node->tag_opening, options);
1477
+ VALUE erb_begin_node_content = rb_token_from_c_struct(erb_begin_node->content, options);
1478
+ VALUE erb_begin_node_tag_closing = rb_token_from_c_struct(erb_begin_node->tag_closing, options);
1191
1479
  VALUE erb_begin_node_prism_node;
1192
1480
  if (erb_begin_node->prism_node.node != NULL && erb_begin_node->prism_node.parser != NULL) {
1193
1481
  pm_buffer_t pm_buffer = { 0 };
@@ -1204,11 +1492,11 @@ static VALUE rb_erb_begin_node_from_c_struct(AST_ERB_BEGIN_NODE_T* erb_begin_nod
1204
1492
  } else {
1205
1493
  erb_begin_node_prism_node = Qnil;
1206
1494
  }
1207
- VALUE erb_begin_node_statements = rb_nodes_array_from_c_array(erb_begin_node->statements);
1208
- VALUE erb_begin_node_rescue_clause = rb_node_from_c_struct((AST_NODE_T*) erb_begin_node->rescue_clause);
1209
- VALUE erb_begin_node_else_clause = rb_node_from_c_struct((AST_NODE_T*) erb_begin_node->else_clause);
1210
- VALUE erb_begin_node_ensure_clause = rb_node_from_c_struct((AST_NODE_T*) erb_begin_node->ensure_clause);
1211
- VALUE erb_begin_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_begin_node->end_node);
1495
+ VALUE erb_begin_node_statements = rb_nodes_array_from_c_array(erb_begin_node->statements, options);
1496
+ VALUE erb_begin_node_rescue_clause = rb_node_from_c_struct((AST_NODE_T*) erb_begin_node->rescue_clause, options);
1497
+ VALUE erb_begin_node_else_clause = rb_node_from_c_struct((AST_NODE_T*) erb_begin_node->else_clause, options);
1498
+ VALUE erb_begin_node_ensure_clause = rb_node_from_c_struct((AST_NODE_T*) erb_begin_node->ensure_clause, options);
1499
+ VALUE erb_begin_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_begin_node->end_node, options);
1212
1500
 
1213
1501
  VALUE args[12] = {
1214
1502
  type,
@@ -1228,19 +1516,24 @@ static VALUE rb_erb_begin_node_from_c_struct(AST_ERB_BEGIN_NODE_T* erb_begin_nod
1228
1516
  return rb_class_new_instance(12, args, cERBBeginNode);
1229
1517
  };
1230
1518
 
1231
- static VALUE rb_erb_unless_node_from_c_struct(AST_ERB_UNLESS_NODE_T* erb_unless_node) {
1519
+ static VALUE rb_erb_unless_node_from_c_struct(AST_ERB_UNLESS_NODE_T* erb_unless_node, const parser_options_T* options) {
1232
1520
  if (erb_unless_node == NULL) { return Qnil; }
1233
1521
 
1234
1522
  AST_NODE_T* node = &erb_unless_node->base;
1235
1523
 
1236
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
1237
- VALUE location = rb_location_from_c_struct(node->location);
1524
+ static VALUE type = 0;
1525
+
1526
+ if (type == 0) {
1527
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1528
+ rb_gc_register_mark_object(type);
1529
+ }
1530
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
1238
1531
  VALUE errors = rb_errors_array_from_c_array(node->errors);
1239
1532
 
1240
- VALUE erb_unless_node_tag_opening = rb_token_from_c_struct(erb_unless_node->tag_opening);
1241
- VALUE erb_unless_node_content = rb_token_from_c_struct(erb_unless_node->content);
1242
- VALUE erb_unless_node_tag_closing = rb_token_from_c_struct(erb_unless_node->tag_closing);
1243
- VALUE erb_unless_node_then_keyword = (erb_unless_node->then_keyword != NULL) ? rb_location_from_c_struct(*erb_unless_node->then_keyword) : Qnil;
1533
+ VALUE erb_unless_node_tag_opening = rb_token_from_c_struct(erb_unless_node->tag_opening, options);
1534
+ VALUE erb_unless_node_content = rb_token_from_c_struct(erb_unless_node->content, options);
1535
+ VALUE erb_unless_node_tag_closing = rb_token_from_c_struct(erb_unless_node->tag_closing, options);
1536
+ VALUE erb_unless_node_then_keyword = (options->track_locations && erb_unless_node->then_keyword != NULL) ? rb_location_from_c_struct(*erb_unless_node->then_keyword) : Qnil;
1244
1537
  VALUE erb_unless_node_prism_node;
1245
1538
  if (erb_unless_node->prism_node.node != NULL && erb_unless_node->prism_node.parser != NULL) {
1246
1539
  pm_buffer_t pm_buffer = { 0 };
@@ -1257,9 +1550,9 @@ static VALUE rb_erb_unless_node_from_c_struct(AST_ERB_UNLESS_NODE_T* erb_unless_
1257
1550
  } else {
1258
1551
  erb_unless_node_prism_node = Qnil;
1259
1552
  }
1260
- VALUE erb_unless_node_statements = rb_nodes_array_from_c_array(erb_unless_node->statements);
1261
- VALUE erb_unless_node_else_clause = rb_node_from_c_struct((AST_NODE_T*) erb_unless_node->else_clause);
1262
- VALUE erb_unless_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_unless_node->end_node);
1553
+ VALUE erb_unless_node_statements = rb_nodes_array_from_c_array(erb_unless_node->statements, options);
1554
+ VALUE erb_unless_node_else_clause = rb_node_from_c_struct((AST_NODE_T*) erb_unless_node->else_clause, options);
1555
+ VALUE erb_unless_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_unless_node->end_node, options);
1263
1556
 
1264
1557
  VALUE args[11] = {
1265
1558
  type,
@@ -1278,17 +1571,22 @@ static VALUE rb_erb_unless_node_from_c_struct(AST_ERB_UNLESS_NODE_T* erb_unless_
1278
1571
  return rb_class_new_instance(11, args, cERBUnlessNode);
1279
1572
  };
1280
1573
 
1281
- static VALUE rb_ruby_render_local_node_from_c_struct(AST_RUBY_RENDER_LOCAL_NODE_T* ruby_render_local_node) {
1574
+ static VALUE rb_ruby_render_local_node_from_c_struct(AST_RUBY_RENDER_LOCAL_NODE_T* ruby_render_local_node, const parser_options_T* options) {
1282
1575
  if (ruby_render_local_node == NULL) { return Qnil; }
1283
1576
 
1284
1577
  AST_NODE_T* node = &ruby_render_local_node->base;
1285
1578
 
1286
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
1287
- VALUE location = rb_location_from_c_struct(node->location);
1579
+ static VALUE type = 0;
1580
+
1581
+ if (type == 0) {
1582
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1583
+ rb_gc_register_mark_object(type);
1584
+ }
1585
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
1288
1586
  VALUE errors = rb_errors_array_from_c_array(node->errors);
1289
1587
 
1290
- VALUE ruby_render_local_node_name = rb_token_from_c_struct(ruby_render_local_node->name);
1291
- VALUE ruby_render_local_node_value = rb_node_from_c_struct((AST_NODE_T*) ruby_render_local_node->value);
1588
+ VALUE ruby_render_local_node_name = rb_token_from_c_struct(ruby_render_local_node->name, options);
1589
+ VALUE ruby_render_local_node_value = rb_node_from_c_struct((AST_NODE_T*) ruby_render_local_node->value, options);
1292
1590
 
1293
1591
  VALUE args[5] = {
1294
1592
  type,
@@ -1301,35 +1599,42 @@ static VALUE rb_ruby_render_local_node_from_c_struct(AST_RUBY_RENDER_LOCAL_NODE_
1301
1599
  return rb_class_new_instance(5, args, cRubyRenderLocalNode);
1302
1600
  };
1303
1601
 
1304
- static VALUE rb_ruby_render_keywords_node_from_c_struct(AST_RUBY_RENDER_KEYWORDS_NODE_T* ruby_render_keywords_node) {
1602
+ static VALUE rb_ruby_render_keywords_node_from_c_struct(AST_RUBY_RENDER_KEYWORDS_NODE_T* ruby_render_keywords_node, const parser_options_T* options) {
1305
1603
  if (ruby_render_keywords_node == NULL) { return Qnil; }
1306
1604
 
1307
1605
  AST_NODE_T* node = &ruby_render_keywords_node->base;
1308
1606
 
1309
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
1310
- VALUE location = rb_location_from_c_struct(node->location);
1607
+ static VALUE type = 0;
1608
+
1609
+ if (type == 0) {
1610
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1611
+ rb_gc_register_mark_object(type);
1612
+ }
1613
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
1311
1614
  VALUE errors = rb_errors_array_from_c_array(node->errors);
1312
1615
 
1313
- VALUE ruby_render_keywords_node_partial = rb_token_from_c_struct(ruby_render_keywords_node->partial);
1314
- VALUE ruby_render_keywords_node_template_path = rb_token_from_c_struct(ruby_render_keywords_node->template_path);
1315
- VALUE ruby_render_keywords_node_layout = rb_token_from_c_struct(ruby_render_keywords_node->layout);
1316
- VALUE ruby_render_keywords_node_file = rb_token_from_c_struct(ruby_render_keywords_node->file);
1317
- VALUE ruby_render_keywords_node_inline_template = rb_token_from_c_struct(ruby_render_keywords_node->inline_template);
1318
- VALUE ruby_render_keywords_node_body = rb_token_from_c_struct(ruby_render_keywords_node->body);
1319
- VALUE ruby_render_keywords_node_plain = rb_token_from_c_struct(ruby_render_keywords_node->plain);
1320
- VALUE ruby_render_keywords_node_html = rb_token_from_c_struct(ruby_render_keywords_node->html);
1321
- VALUE ruby_render_keywords_node_renderable = rb_token_from_c_struct(ruby_render_keywords_node->renderable);
1322
- VALUE ruby_render_keywords_node_collection = rb_token_from_c_struct(ruby_render_keywords_node->collection);
1323
- VALUE ruby_render_keywords_node_object = rb_token_from_c_struct(ruby_render_keywords_node->object);
1324
- VALUE ruby_render_keywords_node_as_name = rb_token_from_c_struct(ruby_render_keywords_node->as_name);
1325
- VALUE ruby_render_keywords_node_spacer_template = rb_token_from_c_struct(ruby_render_keywords_node->spacer_template);
1326
- VALUE ruby_render_keywords_node_formats = rb_token_from_c_struct(ruby_render_keywords_node->formats);
1327
- VALUE ruby_render_keywords_node_variants = rb_token_from_c_struct(ruby_render_keywords_node->variants);
1328
- VALUE ruby_render_keywords_node_handlers = rb_token_from_c_struct(ruby_render_keywords_node->handlers);
1329
- VALUE ruby_render_keywords_node_content_type = rb_token_from_c_struct(ruby_render_keywords_node->content_type);
1330
- VALUE ruby_render_keywords_node_locals = rb_nodes_array_from_c_array(ruby_render_keywords_node->locals);
1331
-
1332
- VALUE args[21] = {
1616
+ VALUE ruby_render_keywords_node_partial = rb_token_from_c_struct(ruby_render_keywords_node->partial, options);
1617
+ VALUE ruby_render_keywords_node_template_path = rb_token_from_c_struct(ruby_render_keywords_node->template_path, options);
1618
+ VALUE ruby_render_keywords_node_layout = rb_token_from_c_struct(ruby_render_keywords_node->layout, options);
1619
+ VALUE ruby_render_keywords_node_file = rb_token_from_c_struct(ruby_render_keywords_node->file, options);
1620
+ VALUE ruby_render_keywords_node_inline_template = rb_token_from_c_struct(ruby_render_keywords_node->inline_template, options);
1621
+ VALUE ruby_render_keywords_node_body = rb_token_from_c_struct(ruby_render_keywords_node->body, options);
1622
+ VALUE ruby_render_keywords_node_plain = rb_token_from_c_struct(ruby_render_keywords_node->plain, options);
1623
+ VALUE ruby_render_keywords_node_html = rb_token_from_c_struct(ruby_render_keywords_node->html, options);
1624
+ VALUE ruby_render_keywords_node_renderable = rb_token_from_c_struct(ruby_render_keywords_node->renderable, options);
1625
+ VALUE ruby_render_keywords_node_collection = rb_token_from_c_struct(ruby_render_keywords_node->collection, options);
1626
+ VALUE ruby_render_keywords_node_object = rb_token_from_c_struct(ruby_render_keywords_node->object, options);
1627
+ VALUE ruby_render_keywords_node_as_name = rb_token_from_c_struct(ruby_render_keywords_node->as_name, options);
1628
+ VALUE ruby_render_keywords_node_spacer_template = rb_token_from_c_struct(ruby_render_keywords_node->spacer_template, options);
1629
+ VALUE ruby_render_keywords_node_formats = rb_token_from_c_struct(ruby_render_keywords_node->formats, options);
1630
+ VALUE ruby_render_keywords_node_variants = rb_token_from_c_struct(ruby_render_keywords_node->variants, options);
1631
+ VALUE ruby_render_keywords_node_handlers = rb_token_from_c_struct(ruby_render_keywords_node->handlers, options);
1632
+ VALUE ruby_render_keywords_node_content_type = rb_token_from_c_struct(ruby_render_keywords_node->content_type, options);
1633
+ VALUE ruby_render_keywords_node_locals = rb_nodes_array_from_c_array(ruby_render_keywords_node->locals, options);
1634
+ VALUE ruby_render_keywords_node_state = rb_nodes_array_from_c_array(ruby_render_keywords_node->state, options);
1635
+ VALUE ruby_render_keywords_node_state_location = (options->track_locations && ruby_render_keywords_node->state_location != NULL) ? rb_location_from_c_struct(*ruby_render_keywords_node->state_location) : Qnil;
1636
+
1637
+ VALUE args[23] = {
1333
1638
  type,
1334
1639
  location,
1335
1640
  errors,
@@ -1350,24 +1655,31 @@ static VALUE rb_ruby_render_keywords_node_from_c_struct(AST_RUBY_RENDER_KEYWORDS
1350
1655
  ruby_render_keywords_node_variants,
1351
1656
  ruby_render_keywords_node_handlers,
1352
1657
  ruby_render_keywords_node_content_type,
1353
- ruby_render_keywords_node_locals
1658
+ ruby_render_keywords_node_locals,
1659
+ ruby_render_keywords_node_state,
1660
+ ruby_render_keywords_node_state_location
1354
1661
  };
1355
1662
 
1356
- return rb_class_new_instance(21, args, cRubyRenderKeywordsNode);
1663
+ return rb_class_new_instance(23, args, cRubyRenderKeywordsNode);
1357
1664
  };
1358
1665
 
1359
- static VALUE rb_erb_render_node_from_c_struct(AST_ERB_RENDER_NODE_T* erb_render_node) {
1666
+ static VALUE rb_erb_render_node_from_c_struct(AST_ERB_RENDER_NODE_T* erb_render_node, const parser_options_T* options) {
1360
1667
  if (erb_render_node == NULL) { return Qnil; }
1361
1668
 
1362
1669
  AST_NODE_T* node = &erb_render_node->base;
1363
1670
 
1364
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
1365
- VALUE location = rb_location_from_c_struct(node->location);
1671
+ static VALUE type = 0;
1672
+
1673
+ if (type == 0) {
1674
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1675
+ rb_gc_register_mark_object(type);
1676
+ }
1677
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
1366
1678
  VALUE errors = rb_errors_array_from_c_array(node->errors);
1367
1679
 
1368
- VALUE erb_render_node_tag_opening = rb_token_from_c_struct(erb_render_node->tag_opening);
1369
- VALUE erb_render_node_content = rb_token_from_c_struct(erb_render_node->content);
1370
- VALUE erb_render_node_tag_closing = rb_token_from_c_struct(erb_render_node->tag_closing);
1680
+ VALUE erb_render_node_tag_opening = rb_token_from_c_struct(erb_render_node->tag_opening, options);
1681
+ VALUE erb_render_node_content = rb_token_from_c_struct(erb_render_node->content, options);
1682
+ VALUE erb_render_node_tag_closing = rb_token_from_c_struct(erb_render_node->tag_closing, options);
1371
1683
  /* analyzed_ruby is internal parser state, not exposed to Ruby */
1372
1684
  VALUE erb_render_node_analyzed_ruby = Qnil;
1373
1685
  VALUE erb_render_node_prism_node;
@@ -1386,13 +1698,13 @@ static VALUE rb_erb_render_node_from_c_struct(AST_ERB_RENDER_NODE_T* erb_render_
1386
1698
  } else {
1387
1699
  erb_render_node_prism_node = Qnil;
1388
1700
  }
1389
- VALUE erb_render_node_keywords = rb_node_from_c_struct((AST_NODE_T*) erb_render_node->keywords);
1390
- VALUE erb_render_node_body = rb_nodes_array_from_c_array(erb_render_node->body);
1391
- VALUE erb_render_node_block_arguments = rb_nodes_array_from_c_array(erb_render_node->block_arguments);
1392
- VALUE erb_render_node_rescue_clause = rb_node_from_c_struct((AST_NODE_T*) erb_render_node->rescue_clause);
1393
- VALUE erb_render_node_else_clause = rb_node_from_c_struct((AST_NODE_T*) erb_render_node->else_clause);
1394
- VALUE erb_render_node_ensure_clause = rb_node_from_c_struct((AST_NODE_T*) erb_render_node->ensure_clause);
1395
- VALUE erb_render_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_render_node->end_node);
1701
+ VALUE erb_render_node_keywords = rb_node_from_c_struct((AST_NODE_T*) erb_render_node->keywords, options);
1702
+ VALUE erb_render_node_body = rb_nodes_array_from_c_array(erb_render_node->body, options);
1703
+ VALUE erb_render_node_block_arguments = rb_nodes_array_from_c_array(erb_render_node->block_arguments, options);
1704
+ VALUE erb_render_node_rescue_clause = rb_node_from_c_struct((AST_NODE_T*) erb_render_node->rescue_clause, options);
1705
+ VALUE erb_render_node_else_clause = rb_node_from_c_struct((AST_NODE_T*) erb_render_node->else_clause, options);
1706
+ VALUE erb_render_node_ensure_clause = rb_node_from_c_struct((AST_NODE_T*) erb_render_node->ensure_clause, options);
1707
+ VALUE erb_render_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_render_node->end_node, options);
1396
1708
 
1397
1709
  VALUE args[15] = {
1398
1710
  type,
@@ -1415,17 +1727,22 @@ static VALUE rb_erb_render_node_from_c_struct(AST_ERB_RENDER_NODE_T* erb_render_
1415
1727
  return rb_class_new_instance(15, args, cERBRenderNode);
1416
1728
  };
1417
1729
 
1418
- static VALUE rb_ruby_parameter_node_from_c_struct(AST_RUBY_PARAMETER_NODE_T* ruby_parameter_node) {
1730
+ static VALUE rb_ruby_parameter_node_from_c_struct(AST_RUBY_PARAMETER_NODE_T* ruby_parameter_node, const parser_options_T* options) {
1419
1731
  if (ruby_parameter_node == NULL) { return Qnil; }
1420
1732
 
1421
1733
  AST_NODE_T* node = &ruby_parameter_node->base;
1422
1734
 
1423
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
1424
- VALUE location = rb_location_from_c_struct(node->location);
1735
+ static VALUE type = 0;
1736
+
1737
+ if (type == 0) {
1738
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1739
+ rb_gc_register_mark_object(type);
1740
+ }
1741
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
1425
1742
  VALUE errors = rb_errors_array_from_c_array(node->errors);
1426
1743
 
1427
- VALUE ruby_parameter_node_name = rb_token_from_c_struct(ruby_parameter_node->name);
1428
- VALUE ruby_parameter_node_default_value = rb_node_from_c_struct((AST_NODE_T*) ruby_parameter_node->default_value);
1744
+ VALUE ruby_parameter_node_name = rb_token_from_c_struct(ruby_parameter_node->name, options);
1745
+ VALUE ruby_parameter_node_default_value = rb_node_from_c_struct((AST_NODE_T*) ruby_parameter_node->default_value, options);
1429
1746
  VALUE ruby_parameter_node_kind = rb_string_from_hb_string(ruby_parameter_node->kind);
1430
1747
  VALUE ruby_parameter_node_required = (ruby_parameter_node->required) ? Qtrue : Qfalse;
1431
1748
 
@@ -1442,18 +1759,23 @@ static VALUE rb_ruby_parameter_node_from_c_struct(AST_RUBY_PARAMETER_NODE_T* rub
1442
1759
  return rb_class_new_instance(7, args, cRubyParameterNode);
1443
1760
  };
1444
1761
 
1445
- static VALUE rb_erb_strict_locals_node_from_c_struct(AST_ERB_STRICT_LOCALS_NODE_T* erb_strict_locals_node) {
1762
+ static VALUE rb_erb_strict_locals_node_from_c_struct(AST_ERB_STRICT_LOCALS_NODE_T* erb_strict_locals_node, const parser_options_T* options) {
1446
1763
  if (erb_strict_locals_node == NULL) { return Qnil; }
1447
1764
 
1448
1765
  AST_NODE_T* node = &erb_strict_locals_node->base;
1449
1766
 
1450
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
1451
- VALUE location = rb_location_from_c_struct(node->location);
1767
+ static VALUE type = 0;
1768
+
1769
+ if (type == 0) {
1770
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1771
+ rb_gc_register_mark_object(type);
1772
+ }
1773
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
1452
1774
  VALUE errors = rb_errors_array_from_c_array(node->errors);
1453
1775
 
1454
- VALUE erb_strict_locals_node_tag_opening = rb_token_from_c_struct(erb_strict_locals_node->tag_opening);
1455
- VALUE erb_strict_locals_node_content = rb_token_from_c_struct(erb_strict_locals_node->content);
1456
- VALUE erb_strict_locals_node_tag_closing = rb_token_from_c_struct(erb_strict_locals_node->tag_closing);
1776
+ VALUE erb_strict_locals_node_tag_opening = rb_token_from_c_struct(erb_strict_locals_node->tag_opening, options);
1777
+ VALUE erb_strict_locals_node_content = rb_token_from_c_struct(erb_strict_locals_node->content, options);
1778
+ VALUE erb_strict_locals_node_tag_closing = rb_token_from_c_struct(erb_strict_locals_node->tag_closing, options);
1457
1779
  /* analyzed_ruby is internal parser state, not exposed to Ruby */
1458
1780
  VALUE erb_strict_locals_node_analyzed_ruby = Qnil;
1459
1781
  VALUE erb_strict_locals_node_prism_node;
@@ -1472,7 +1794,7 @@ static VALUE rb_erb_strict_locals_node_from_c_struct(AST_ERB_STRICT_LOCALS_NODE_
1472
1794
  } else {
1473
1795
  erb_strict_locals_node_prism_node = Qnil;
1474
1796
  }
1475
- VALUE erb_strict_locals_node_locals = rb_nodes_array_from_c_array(erb_strict_locals_node->locals);
1797
+ VALUE erb_strict_locals_node_locals = rb_nodes_array_from_c_array(erb_strict_locals_node->locals, options);
1476
1798
 
1477
1799
  VALUE args[9] = {
1478
1800
  type,
@@ -1489,18 +1811,23 @@ static VALUE rb_erb_strict_locals_node_from_c_struct(AST_ERB_STRICT_LOCALS_NODE_
1489
1811
  return rb_class_new_instance(9, args, cERBStrictLocalsNode);
1490
1812
  };
1491
1813
 
1492
- static VALUE rb_erb_yield_node_from_c_struct(AST_ERB_YIELD_NODE_T* erb_yield_node) {
1814
+ static VALUE rb_erb_yield_node_from_c_struct(AST_ERB_YIELD_NODE_T* erb_yield_node, const parser_options_T* options) {
1493
1815
  if (erb_yield_node == NULL) { return Qnil; }
1494
1816
 
1495
1817
  AST_NODE_T* node = &erb_yield_node->base;
1496
1818
 
1497
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
1498
- VALUE location = rb_location_from_c_struct(node->location);
1819
+ static VALUE type = 0;
1820
+
1821
+ if (type == 0) {
1822
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1823
+ rb_gc_register_mark_object(type);
1824
+ }
1825
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
1499
1826
  VALUE errors = rb_errors_array_from_c_array(node->errors);
1500
1827
 
1501
- VALUE erb_yield_node_tag_opening = rb_token_from_c_struct(erb_yield_node->tag_opening);
1502
- VALUE erb_yield_node_content = rb_token_from_c_struct(erb_yield_node->content);
1503
- VALUE erb_yield_node_tag_closing = rb_token_from_c_struct(erb_yield_node->tag_closing);
1828
+ VALUE erb_yield_node_tag_opening = rb_token_from_c_struct(erb_yield_node->tag_opening, options);
1829
+ VALUE erb_yield_node_content = rb_token_from_c_struct(erb_yield_node->content, options);
1830
+ VALUE erb_yield_node_tag_closing = rb_token_from_c_struct(erb_yield_node->tag_closing, options);
1504
1831
 
1505
1832
  VALUE args[6] = {
1506
1833
  type,
@@ -1514,20 +1841,25 @@ static VALUE rb_erb_yield_node_from_c_struct(AST_ERB_YIELD_NODE_T* erb_yield_nod
1514
1841
  return rb_class_new_instance(6, args, cERBYieldNode);
1515
1842
  };
1516
1843
 
1517
- static VALUE rb_erb_in_node_from_c_struct(AST_ERB_IN_NODE_T* erb_in_node) {
1844
+ static VALUE rb_erb_in_node_from_c_struct(AST_ERB_IN_NODE_T* erb_in_node, const parser_options_T* options) {
1518
1845
  if (erb_in_node == NULL) { return Qnil; }
1519
1846
 
1520
1847
  AST_NODE_T* node = &erb_in_node->base;
1521
1848
 
1522
- VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
1523
- VALUE location = rb_location_from_c_struct(node->location);
1849
+ static VALUE type = 0;
1850
+
1851
+ if (type == 0) {
1852
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1853
+ rb_gc_register_mark_object(type);
1854
+ }
1855
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
1524
1856
  VALUE errors = rb_errors_array_from_c_array(node->errors);
1525
1857
 
1526
- VALUE erb_in_node_tag_opening = rb_token_from_c_struct(erb_in_node->tag_opening);
1527
- VALUE erb_in_node_content = rb_token_from_c_struct(erb_in_node->content);
1528
- VALUE erb_in_node_tag_closing = rb_token_from_c_struct(erb_in_node->tag_closing);
1529
- VALUE erb_in_node_then_keyword = (erb_in_node->then_keyword != NULL) ? rb_location_from_c_struct(*erb_in_node->then_keyword) : Qnil;
1530
- VALUE erb_in_node_statements = rb_nodes_array_from_c_array(erb_in_node->statements);
1858
+ VALUE erb_in_node_tag_opening = rb_token_from_c_struct(erb_in_node->tag_opening, options);
1859
+ VALUE erb_in_node_content = rb_token_from_c_struct(erb_in_node->content, options);
1860
+ VALUE erb_in_node_tag_closing = rb_token_from_c_struct(erb_in_node->tag_closing, options);
1861
+ VALUE erb_in_node_then_keyword = (options->track_locations && erb_in_node->then_keyword != NULL) ? rb_location_from_c_struct(*erb_in_node->then_keyword) : Qnil;
1862
+ VALUE erb_in_node_statements = rb_nodes_array_from_c_array(erb_in_node->statements, options);
1531
1863
 
1532
1864
  VALUE args[8] = {
1533
1865
  type,
@@ -1543,60 +1875,196 @@ static VALUE rb_erb_in_node_from_c_struct(AST_ERB_IN_NODE_T* erb_in_node) {
1543
1875
  return rb_class_new_instance(8, args, cERBInNode);
1544
1876
  };
1545
1877
 
1878
+ static VALUE rb_herb_directive_node_from_c_struct(AST_HERB_DIRECTIVE_NODE_T* herb_directive_node, const parser_options_T* options) {
1879
+ if (herb_directive_node == NULL) { return Qnil; }
1880
+
1881
+ AST_NODE_T* node = &herb_directive_node->base;
1882
+
1883
+ static VALUE type = 0;
1884
+
1885
+ if (type == 0) {
1886
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1887
+ rb_gc_register_mark_object(type);
1888
+ }
1889
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
1890
+ VALUE errors = rb_errors_array_from_c_array(node->errors);
1891
+
1892
+ VALUE herb_directive_node_tag_opening = rb_token_from_c_struct(herb_directive_node->tag_opening, options);
1893
+ VALUE herb_directive_node_content = rb_token_from_c_struct(herb_directive_node->content, options);
1894
+ VALUE herb_directive_node_tag_closing = rb_token_from_c_struct(herb_directive_node->tag_closing, options);
1895
+ VALUE herb_directive_node_key = rb_token_from_c_struct(herb_directive_node->key, options);
1896
+ VALUE herb_directive_node_arguments = rb_token_from_c_struct(herb_directive_node->arguments, options);
1897
+
1898
+ VALUE args[8] = {
1899
+ type,
1900
+ location,
1901
+ errors,
1902
+ herb_directive_node_tag_opening,
1903
+ herb_directive_node_content,
1904
+ herb_directive_node_tag_closing,
1905
+ herb_directive_node_key,
1906
+ herb_directive_node_arguments
1907
+ };
1908
+
1909
+ return rb_class_new_instance(8, args, cHerbDirectiveNode);
1910
+ };
1911
+
1912
+ static VALUE rb_herb_state_declaration_node_from_c_struct(AST_HERB_STATE_DECLARATION_NODE_T* herb_state_declaration_node, const parser_options_T* options) {
1913
+ if (herb_state_declaration_node == NULL) { return Qnil; }
1914
+
1915
+ AST_NODE_T* node = &herb_state_declaration_node->base;
1916
+
1917
+ static VALUE type = 0;
1918
+
1919
+ if (type == 0) {
1920
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1921
+ rb_gc_register_mark_object(type);
1922
+ }
1923
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
1924
+ VALUE errors = rb_errors_array_from_c_array(node->errors);
1925
+
1926
+ VALUE herb_state_declaration_node_name = rb_token_from_c_struct(herb_state_declaration_node->name, options);
1927
+ VALUE herb_state_declaration_node_default_value = rb_node_from_c_struct((AST_NODE_T*) herb_state_declaration_node->default_value, options);
1928
+ VALUE herb_state_declaration_node_kind = rb_string_from_hb_string(herb_state_declaration_node->kind);
1929
+
1930
+ VALUE args[6] = {
1931
+ type,
1932
+ location,
1933
+ errors,
1934
+ herb_state_declaration_node_name,
1935
+ herb_state_declaration_node_default_value,
1936
+ herb_state_declaration_node_kind
1937
+ };
1938
+
1939
+ return rb_class_new_instance(6, args, cHerbStateDeclarationNode);
1940
+ };
1941
+
1942
+ static VALUE rb_herb_state_directive_node_from_c_struct(AST_HERB_STATE_DIRECTIVE_NODE_T* herb_state_directive_node, const parser_options_T* options) {
1943
+ if (herb_state_directive_node == NULL) { return Qnil; }
1944
+
1945
+ AST_NODE_T* node = &herb_state_directive_node->base;
1946
+
1947
+ static VALUE type = 0;
1948
+
1949
+ if (type == 0) {
1950
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1951
+ rb_gc_register_mark_object(type);
1952
+ }
1953
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
1954
+ VALUE errors = rb_errors_array_from_c_array(node->errors);
1955
+
1956
+ VALUE herb_state_directive_node_tag_opening = rb_token_from_c_struct(herb_state_directive_node->tag_opening, options);
1957
+ VALUE herb_state_directive_node_content = rb_token_from_c_struct(herb_state_directive_node->content, options);
1958
+ VALUE herb_state_directive_node_tag_closing = rb_token_from_c_struct(herb_state_directive_node->tag_closing, options);
1959
+ VALUE herb_state_directive_node_key = rb_token_from_c_struct(herb_state_directive_node->key, options);
1960
+ VALUE herb_state_directive_node_signature = rb_token_from_c_struct(herb_state_directive_node->signature, options);
1961
+ VALUE herb_state_directive_node_states = rb_nodes_array_from_c_array(herb_state_directive_node->states, options);
1962
+
1963
+ VALUE args[9] = {
1964
+ type,
1965
+ location,
1966
+ errors,
1967
+ herb_state_directive_node_tag_opening,
1968
+ herb_state_directive_node_content,
1969
+ herb_state_directive_node_tag_closing,
1970
+ herb_state_directive_node_key,
1971
+ herb_state_directive_node_signature,
1972
+ herb_state_directive_node_states
1973
+ };
1974
+
1975
+ return rb_class_new_instance(9, args, cHerbStateDirectiveNode);
1976
+ };
1977
+
1978
+ static VALUE rb_erb_comment_node_from_c_struct(AST_ERB_COMMENT_NODE_T* erb_comment_node, const parser_options_T* options) {
1979
+ if (erb_comment_node == NULL) { return Qnil; }
1980
+
1981
+ AST_NODE_T* node = &erb_comment_node->base;
1982
+
1983
+ static VALUE type = 0;
1984
+
1985
+ if (type == 0) {
1986
+ type = rb_interned_string_from_hb_string(ast_node_type_to_string(node));
1987
+ rb_gc_register_mark_object(type);
1988
+ }
1989
+ VALUE location = options->track_locations ? rb_location_from_c_struct(node->location) : Qnil;
1990
+ VALUE errors = rb_errors_array_from_c_array(node->errors);
1991
+
1992
+ VALUE erb_comment_node_tag_opening = rb_token_from_c_struct(erb_comment_node->tag_opening, options);
1993
+ VALUE erb_comment_node_content = rb_token_from_c_struct(erb_comment_node->content, options);
1994
+ VALUE erb_comment_node_tag_closing = rb_token_from_c_struct(erb_comment_node->tag_closing, options);
1995
+
1996
+ VALUE args[6] = {
1997
+ type,
1998
+ location,
1999
+ errors,
2000
+ erb_comment_node_tag_opening,
2001
+ erb_comment_node_content,
2002
+ erb_comment_node_tag_closing
2003
+ };
2004
+
2005
+ return rb_class_new_instance(6, args, cERBCommentNode);
2006
+ };
2007
+
1546
2008
 
1547
- VALUE rb_node_from_c_struct(AST_NODE_T* node) {
2009
+ VALUE rb_node_from_c_struct(AST_NODE_T* node, const parser_options_T* options) {
1548
2010
  if (!node) { return Qnil; }
1549
2011
 
1550
2012
  switch (node->type) {
1551
- case AST_DOCUMENT_NODE: return rb_document_node_from_c_struct((AST_DOCUMENT_NODE_T*) node); break;
1552
- case AST_LITERAL_NODE: return rb_literal_node_from_c_struct((AST_LITERAL_NODE_T*) node); break;
1553
- case AST_HTML_OPEN_TAG_NODE: return rb_html_open_tag_node_from_c_struct((AST_HTML_OPEN_TAG_NODE_T*) node); break;
1554
- case AST_HTML_CONDITIONAL_OPEN_TAG_NODE: return rb_html_conditional_open_tag_node_from_c_struct((AST_HTML_CONDITIONAL_OPEN_TAG_NODE_T*) node); break;
1555
- case AST_HTML_CLOSE_TAG_NODE: return rb_html_close_tag_node_from_c_struct((AST_HTML_CLOSE_TAG_NODE_T*) node); break;
1556
- case AST_HTML_OMITTED_CLOSE_TAG_NODE: return rb_html_omitted_close_tag_node_from_c_struct((AST_HTML_OMITTED_CLOSE_TAG_NODE_T*) node); break;
1557
- case AST_HTML_VIRTUAL_CLOSE_TAG_NODE: return rb_html_virtual_close_tag_node_from_c_struct((AST_HTML_VIRTUAL_CLOSE_TAG_NODE_T*) node); break;
1558
- case AST_HTML_ELEMENT_NODE: return rb_html_element_node_from_c_struct((AST_HTML_ELEMENT_NODE_T*) node); break;
1559
- case AST_HTML_CONDITIONAL_ELEMENT_NODE: return rb_html_conditional_element_node_from_c_struct((AST_HTML_CONDITIONAL_ELEMENT_NODE_T*) node); break;
1560
- case AST_HTML_ATTRIBUTE_VALUE_NODE: return rb_html_attribute_value_node_from_c_struct((AST_HTML_ATTRIBUTE_VALUE_NODE_T*) node); break;
1561
- case AST_HTML_ATTRIBUTE_NAME_NODE: return rb_html_attribute_name_node_from_c_struct((AST_HTML_ATTRIBUTE_NAME_NODE_T*) node); break;
1562
- case AST_HTML_ATTRIBUTE_NODE: return rb_html_attribute_node_from_c_struct((AST_HTML_ATTRIBUTE_NODE_T*) node); break;
1563
- case AST_RUBY_LITERAL_NODE: return rb_ruby_literal_node_from_c_struct((AST_RUBY_LITERAL_NODE_T*) node); break;
1564
- case AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE: return rb_ruby_html_attributes_splat_node_from_c_struct((AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE_T*) node); break;
1565
- case AST_ERB_OPEN_TAG_NODE: return rb_erb_open_tag_node_from_c_struct((AST_ERB_OPEN_TAG_NODE_T*) node); break;
1566
- case AST_HTML_TEXT_NODE: return rb_html_text_node_from_c_struct((AST_HTML_TEXT_NODE_T*) node); break;
1567
- case AST_HTML_COMMENT_NODE: return rb_html_comment_node_from_c_struct((AST_HTML_COMMENT_NODE_T*) node); break;
1568
- case AST_HTML_DOCTYPE_NODE: return rb_html_doctype_node_from_c_struct((AST_HTML_DOCTYPE_NODE_T*) node); break;
1569
- case AST_XML_DECLARATION_NODE: return rb_xml_declaration_node_from_c_struct((AST_XML_DECLARATION_NODE_T*) node); break;
1570
- case AST_CDATA_NODE: return rb_cdata_node_from_c_struct((AST_CDATA_NODE_T*) node); break;
1571
- case AST_WHITESPACE_NODE: return rb_whitespace_node_from_c_struct((AST_WHITESPACE_NODE_T*) node); break;
1572
- case AST_ERB_CONTENT_NODE: return rb_erb_content_node_from_c_struct((AST_ERB_CONTENT_NODE_T*) node); break;
1573
- case AST_ERB_END_NODE: return rb_erb_end_node_from_c_struct((AST_ERB_END_NODE_T*) node); break;
1574
- case AST_ERB_ELSE_NODE: return rb_erb_else_node_from_c_struct((AST_ERB_ELSE_NODE_T*) node); break;
1575
- case AST_ERB_IF_NODE: return rb_erb_if_node_from_c_struct((AST_ERB_IF_NODE_T*) node); break;
1576
- case AST_ERB_BLOCK_NODE: return rb_erb_block_node_from_c_struct((AST_ERB_BLOCK_NODE_T*) node); break;
1577
- case AST_ERB_WHEN_NODE: return rb_erb_when_node_from_c_struct((AST_ERB_WHEN_NODE_T*) node); break;
1578
- case AST_ERB_CASE_NODE: return rb_erb_case_node_from_c_struct((AST_ERB_CASE_NODE_T*) node); break;
1579
- case AST_ERB_CASE_MATCH_NODE: return rb_erb_case_match_node_from_c_struct((AST_ERB_CASE_MATCH_NODE_T*) node); break;
1580
- case AST_ERB_WHILE_NODE: return rb_erb_while_node_from_c_struct((AST_ERB_WHILE_NODE_T*) node); break;
1581
- case AST_ERB_UNTIL_NODE: return rb_erb_until_node_from_c_struct((AST_ERB_UNTIL_NODE_T*) node); break;
1582
- case AST_ERB_FOR_NODE: return rb_erb_for_node_from_c_struct((AST_ERB_FOR_NODE_T*) node); break;
1583
- case AST_ERB_RESCUE_NODE: return rb_erb_rescue_node_from_c_struct((AST_ERB_RESCUE_NODE_T*) node); break;
1584
- case AST_ERB_ENSURE_NODE: return rb_erb_ensure_node_from_c_struct((AST_ERB_ENSURE_NODE_T*) node); break;
1585
- case AST_ERB_BEGIN_NODE: return rb_erb_begin_node_from_c_struct((AST_ERB_BEGIN_NODE_T*) node); break;
1586
- case AST_ERB_UNLESS_NODE: return rb_erb_unless_node_from_c_struct((AST_ERB_UNLESS_NODE_T*) node); break;
1587
- case AST_RUBY_RENDER_LOCAL_NODE: return rb_ruby_render_local_node_from_c_struct((AST_RUBY_RENDER_LOCAL_NODE_T*) node); break;
1588
- case AST_RUBY_RENDER_KEYWORDS_NODE: return rb_ruby_render_keywords_node_from_c_struct((AST_RUBY_RENDER_KEYWORDS_NODE_T*) node); break;
1589
- case AST_ERB_RENDER_NODE: return rb_erb_render_node_from_c_struct((AST_ERB_RENDER_NODE_T*) node); break;
1590
- case AST_RUBY_PARAMETER_NODE: return rb_ruby_parameter_node_from_c_struct((AST_RUBY_PARAMETER_NODE_T*) node); break;
1591
- case AST_ERB_STRICT_LOCALS_NODE: return rb_erb_strict_locals_node_from_c_struct((AST_ERB_STRICT_LOCALS_NODE_T*) node); break;
1592
- case AST_ERB_YIELD_NODE: return rb_erb_yield_node_from_c_struct((AST_ERB_YIELD_NODE_T*) node); break;
1593
- case AST_ERB_IN_NODE: return rb_erb_in_node_from_c_struct((AST_ERB_IN_NODE_T*) node); break;
2013
+ case AST_DOCUMENT_NODE: return rb_document_node_from_c_struct((AST_DOCUMENT_NODE_T*) node, options); break;
2014
+ case AST_LITERAL_NODE: return rb_literal_node_from_c_struct((AST_LITERAL_NODE_T*) node, options); break;
2015
+ case AST_HTML_OPEN_TAG_NODE: return rb_html_open_tag_node_from_c_struct((AST_HTML_OPEN_TAG_NODE_T*) node, options); break;
2016
+ case AST_HTML_CONDITIONAL_OPEN_TAG_NODE: return rb_html_conditional_open_tag_node_from_c_struct((AST_HTML_CONDITIONAL_OPEN_TAG_NODE_T*) node, options); break;
2017
+ case AST_HTML_CLOSE_TAG_NODE: return rb_html_close_tag_node_from_c_struct((AST_HTML_CLOSE_TAG_NODE_T*) node, options); break;
2018
+ case AST_HTML_OMITTED_CLOSE_TAG_NODE: return rb_html_omitted_close_tag_node_from_c_struct((AST_HTML_OMITTED_CLOSE_TAG_NODE_T*) node, options); break;
2019
+ case AST_HTML_VIRTUAL_CLOSE_TAG_NODE: return rb_html_virtual_close_tag_node_from_c_struct((AST_HTML_VIRTUAL_CLOSE_TAG_NODE_T*) node, options); break;
2020
+ case AST_HTML_ELEMENT_NODE: return rb_html_element_node_from_c_struct((AST_HTML_ELEMENT_NODE_T*) node, options); break;
2021
+ case AST_HTML_CONDITIONAL_ELEMENT_NODE: return rb_html_conditional_element_node_from_c_struct((AST_HTML_CONDITIONAL_ELEMENT_NODE_T*) node, options); break;
2022
+ case AST_HTML_ATTRIBUTE_VALUE_NODE: return rb_html_attribute_value_node_from_c_struct((AST_HTML_ATTRIBUTE_VALUE_NODE_T*) node, options); break;
2023
+ case AST_HTML_ATTRIBUTE_NAME_NODE: return rb_html_attribute_name_node_from_c_struct((AST_HTML_ATTRIBUTE_NAME_NODE_T*) node, options); break;
2024
+ case AST_HTML_ATTRIBUTE_NODE: return rb_html_attribute_node_from_c_struct((AST_HTML_ATTRIBUTE_NODE_T*) node, options); break;
2025
+ case AST_RUBY_LITERAL_NODE: return rb_ruby_literal_node_from_c_struct((AST_RUBY_LITERAL_NODE_T*) node, options); break;
2026
+ case AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE: return rb_ruby_html_attributes_splat_node_from_c_struct((AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE_T*) node, options); break;
2027
+ case AST_ERB_OPEN_TAG_NODE: return rb_erb_open_tag_node_from_c_struct((AST_ERB_OPEN_TAG_NODE_T*) node, options); break;
2028
+ case AST_HTML_TEXT_NODE: return rb_html_text_node_from_c_struct((AST_HTML_TEXT_NODE_T*) node, options); break;
2029
+ case AST_HTML_COMMENT_NODE: return rb_html_comment_node_from_c_struct((AST_HTML_COMMENT_NODE_T*) node, options); break;
2030
+ case AST_HTML_DOCTYPE_NODE: return rb_html_doctype_node_from_c_struct((AST_HTML_DOCTYPE_NODE_T*) node, options); break;
2031
+ case AST_XML_DECLARATION_NODE: return rb_xml_declaration_node_from_c_struct((AST_XML_DECLARATION_NODE_T*) node, options); break;
2032
+ case AST_XML_PROCESSING_INSTRUCTION_NODE: return rb_xml_processing_instruction_node_from_c_struct((AST_XML_PROCESSING_INSTRUCTION_NODE_T*) node, options); break;
2033
+ case AST_CDATA_NODE: return rb_cdata_node_from_c_struct((AST_CDATA_NODE_T*) node, options); break;
2034
+ case AST_WHITESPACE_NODE: return rb_whitespace_node_from_c_struct((AST_WHITESPACE_NODE_T*) node, options); break;
2035
+ case AST_ERB_CONTENT_NODE: return rb_erb_content_node_from_c_struct((AST_ERB_CONTENT_NODE_T*) node, options); break;
2036
+ case AST_ERB_END_NODE: return rb_erb_end_node_from_c_struct((AST_ERB_END_NODE_T*) node, options); break;
2037
+ case AST_ERB_ELSE_NODE: return rb_erb_else_node_from_c_struct((AST_ERB_ELSE_NODE_T*) node, options); break;
2038
+ case AST_ERB_IF_NODE: return rb_erb_if_node_from_c_struct((AST_ERB_IF_NODE_T*) node, options); break;
2039
+ case AST_ERB_BLOCK_NODE: return rb_erb_block_node_from_c_struct((AST_ERB_BLOCK_NODE_T*) node, options); break;
2040
+ case AST_ERB_ITERATION_BLOCK_NODE: return rb_erb_iteration_block_node_from_c_struct((AST_ERB_ITERATION_BLOCK_NODE_T*) node, options); break;
2041
+ case AST_ERB_WHEN_NODE: return rb_erb_when_node_from_c_struct((AST_ERB_WHEN_NODE_T*) node, options); break;
2042
+ case AST_ERB_CASE_NODE: return rb_erb_case_node_from_c_struct((AST_ERB_CASE_NODE_T*) node, options); break;
2043
+ case AST_ERB_CASE_MATCH_NODE: return rb_erb_case_match_node_from_c_struct((AST_ERB_CASE_MATCH_NODE_T*) node, options); break;
2044
+ case AST_ERB_WHILE_NODE: return rb_erb_while_node_from_c_struct((AST_ERB_WHILE_NODE_T*) node, options); break;
2045
+ case AST_ERB_UNTIL_NODE: return rb_erb_until_node_from_c_struct((AST_ERB_UNTIL_NODE_T*) node, options); break;
2046
+ case AST_ERB_FOR_NODE: return rb_erb_for_node_from_c_struct((AST_ERB_FOR_NODE_T*) node, options); break;
2047
+ case AST_ERB_RESCUE_NODE: return rb_erb_rescue_node_from_c_struct((AST_ERB_RESCUE_NODE_T*) node, options); break;
2048
+ case AST_ERB_ENSURE_NODE: return rb_erb_ensure_node_from_c_struct((AST_ERB_ENSURE_NODE_T*) node, options); break;
2049
+ case AST_ERB_BEGIN_NODE: return rb_erb_begin_node_from_c_struct((AST_ERB_BEGIN_NODE_T*) node, options); break;
2050
+ case AST_ERB_UNLESS_NODE: return rb_erb_unless_node_from_c_struct((AST_ERB_UNLESS_NODE_T*) node, options); break;
2051
+ case AST_RUBY_RENDER_LOCAL_NODE: return rb_ruby_render_local_node_from_c_struct((AST_RUBY_RENDER_LOCAL_NODE_T*) node, options); break;
2052
+ case AST_RUBY_RENDER_KEYWORDS_NODE: return rb_ruby_render_keywords_node_from_c_struct((AST_RUBY_RENDER_KEYWORDS_NODE_T*) node, options); break;
2053
+ case AST_ERB_RENDER_NODE: return rb_erb_render_node_from_c_struct((AST_ERB_RENDER_NODE_T*) node, options); break;
2054
+ case AST_RUBY_PARAMETER_NODE: return rb_ruby_parameter_node_from_c_struct((AST_RUBY_PARAMETER_NODE_T*) node, options); break;
2055
+ case AST_ERB_STRICT_LOCALS_NODE: return rb_erb_strict_locals_node_from_c_struct((AST_ERB_STRICT_LOCALS_NODE_T*) node, options); break;
2056
+ case AST_ERB_YIELD_NODE: return rb_erb_yield_node_from_c_struct((AST_ERB_YIELD_NODE_T*) node, options); break;
2057
+ case AST_ERB_IN_NODE: return rb_erb_in_node_from_c_struct((AST_ERB_IN_NODE_T*) node, options); break;
2058
+ case AST_HERB_DIRECTIVE_NODE: return rb_herb_directive_node_from_c_struct((AST_HERB_DIRECTIVE_NODE_T*) node, options); break;
2059
+ case AST_HERB_STATE_DECLARATION_NODE: return rb_herb_state_declaration_node_from_c_struct((AST_HERB_STATE_DECLARATION_NODE_T*) node, options); break;
2060
+ case AST_HERB_STATE_DIRECTIVE_NODE: return rb_herb_state_directive_node_from_c_struct((AST_HERB_STATE_DIRECTIVE_NODE_T*) node, options); break;
2061
+ case AST_ERB_COMMENT_NODE: return rb_erb_comment_node_from_c_struct((AST_ERB_COMMENT_NODE_T*) node, options); break;
1594
2062
  }
1595
2063
 
1596
2064
  return Qnil;
1597
2065
  }
1598
2066
 
1599
- static VALUE rb_nodes_array_from_c_array(hb_array_T* array) {
2067
+ static VALUE rb_nodes_array_from_c_array(hb_array_T* array, const parser_options_T* options) {
1600
2068
  VALUE rb_array = rb_ary_new();
1601
2069
 
1602
2070
  if (array) {
@@ -1604,7 +2072,7 @@ static VALUE rb_nodes_array_from_c_array(hb_array_T* array) {
1604
2072
  AST_NODE_T* child_node = (AST_NODE_T*) hb_array_get(array, i);
1605
2073
 
1606
2074
  if (child_node) {
1607
- VALUE rb_child = rb_node_from_c_struct(child_node);
2075
+ VALUE rb_child = rb_node_from_c_struct(child_node, options);
1608
2076
  rb_ary_push(rb_array, rb_child);
1609
2077
  }
1610
2078
  }