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/lib/herb/errors.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  # typed: true
3
3
 
4
4
  # NOTE: This file is generated by the templates/template.rb script and should not be
5
- # modified manually. See /home/runner/work/herb/herb/templates/lib/herb/errors.rb.erb
5
+ # modified manually. See templates/lib/herb/errors.rb.erb
6
6
 
7
7
  module Herb
8
8
  #: type serialized_error = {
@@ -23,6 +23,26 @@ module Herb
23
23
  @message = message
24
24
  end
25
25
 
26
+ #: () -> String?
27
+ def suggestion
28
+ nil
29
+ end
30
+
31
+ #: (template: String, ?origin: String) -> Herb::Diagnostic
32
+ def to_diagnostic(template:, origin: "Herb Parser")
33
+ Herb::Diagnostic.new(
34
+ template: template,
35
+ message: message,
36
+ severity: :error,
37
+ origin: origin,
38
+ code: error_name,
39
+ location: location,
40
+ suggestion: suggestion,
41
+ phase: :compile,
42
+ data: { type: type }
43
+ )
44
+ end
45
+
26
46
  #: () -> serialized_error
27
47
  def to_hash
28
48
  {
@@ -56,11 +76,6 @@ module Herb
56
76
  class UnexpectedError < Error
57
77
  include Colors
58
78
 
59
- #| description: String?,
60
- #| expected: String?,
61
- #| found: String?,
62
- #| }
63
-
64
79
  attr_reader :description #: String?
65
80
  attr_reader :expected #: String?
66
81
  attr_reader :found #: String?
@@ -91,7 +106,7 @@ module Herb
91
106
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
92
107
  output = +""
93
108
 
94
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
109
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
95
110
  output += white("├── message: #{green(message.inspect)}\n")
96
111
  output += white("├── description: #{green(description.inspect)}\n")
97
112
  output += white("├── expected: #{green(expected.inspect)}\n")
@@ -105,10 +120,6 @@ module Herb
105
120
  class UnexpectedTokenError < Error
106
121
  include Colors
107
122
 
108
- #| expected_type: String?,
109
- #| found: Herb::Token?,
110
- #| }
111
-
112
123
  attr_reader :expected_type #: String?
113
124
  attr_reader :found #: Herb::Token?
114
125
 
@@ -136,7 +147,7 @@ module Herb
136
147
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
137
148
  output = +""
138
149
 
139
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
150
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
140
151
  output += white("├── message: #{green(message.inspect)}\n")
141
152
  output += white("├── expected_type: #{green(expected_type.inspect)}\n")
142
153
  output += white("└── found: ")
@@ -151,9 +162,6 @@ module Herb
151
162
  class MissingOpeningTagError < Error
152
163
  include Colors
153
164
 
154
- #| closing_tag: Herb::Token?,
155
- #| }
156
-
157
165
  attr_reader :closing_tag #: Herb::Token?
158
166
 
159
167
  #: (String, Location?, String, Herb::Token) -> void
@@ -162,6 +170,11 @@ module Herb
162
170
  @closing_tag = closing_tag
163
171
  end
164
172
 
173
+ #: () -> String?
174
+ def suggestion
175
+ "Add the matching opening tag, or remove this closing tag."
176
+ end
177
+
165
178
  #: () -> String
166
179
  def inspect
167
180
  tree_inspect.rstrip.gsub(/\s+$/, "")
@@ -178,7 +191,7 @@ module Herb
178
191
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
179
192
  output = +""
180
193
 
181
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
194
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
182
195
  output += white("├── message: #{green(message.inspect)}\n")
183
196
  output += white("└── closing_tag: ")
184
197
  output += closing_tag ? closing_tag.tree_inspect : magenta("∅")
@@ -192,9 +205,6 @@ module Herb
192
205
  class MissingClosingTagError < Error
193
206
  include Colors
194
207
 
195
- #| opening_tag: Herb::Token?,
196
- #| }
197
-
198
208
  attr_reader :opening_tag #: Herb::Token?
199
209
 
200
210
  #: (String, Location?, String, Herb::Token) -> void
@@ -203,6 +213,11 @@ module Herb
203
213
  @opening_tag = opening_tag
204
214
  end
205
215
 
216
+ #: () -> String?
217
+ def suggestion
218
+ "Add the closing tag, or make it self-closing."
219
+ end
220
+
206
221
  #: () -> String
207
222
  def inspect
208
223
  tree_inspect.rstrip.gsub(/\s+$/, "")
@@ -219,7 +234,7 @@ module Herb
219
234
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
220
235
  output = +""
221
236
 
222
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
237
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
223
238
  output += white("├── message: #{green(message.inspect)}\n")
224
239
  output += white("└── opening_tag: ")
225
240
  output += opening_tag ? opening_tag.tree_inspect : magenta("∅")
@@ -233,10 +248,6 @@ module Herb
233
248
  class TagNamesMismatchError < Error
234
249
  include Colors
235
250
 
236
- #| opening_tag: Herb::Token?,
237
- #| closing_tag: Herb::Token?,
238
- #| }
239
-
240
251
  attr_reader :opening_tag #: Herb::Token?
241
252
  attr_reader :closing_tag #: Herb::Token?
242
253
 
@@ -247,6 +258,13 @@ module Herb
247
258
  @closing_tag = closing_tag
248
259
  end
249
260
 
261
+ #: () -> String?
262
+ def suggestion
263
+ return nil unless opening_tag
264
+
265
+ format("Change the closing tag to `</%s>`.", opening_tag.value)
266
+ end
267
+
250
268
  #: () -> String
251
269
  def inspect
252
270
  tree_inspect.rstrip.gsub(/\s+$/, "")
@@ -264,7 +282,7 @@ module Herb
264
282
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
265
283
  output = +""
266
284
 
267
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
285
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
268
286
  output += white("├── message: #{green(message.inspect)}\n")
269
287
  output += white("├── opening_tag: ")
270
288
  output += opening_tag ? opening_tag.tree_inspect : magenta("∅")
@@ -281,11 +299,6 @@ module Herb
281
299
  class VoidElementClosingTagError < Error
282
300
  include Colors
283
301
 
284
- #| tag_name: Herb::Token?,
285
- #| expected: String?,
286
- #| found: String?,
287
- #| }
288
-
289
302
  attr_reader :tag_name #: Herb::Token?
290
303
  attr_reader :expected #: String?
291
304
  attr_reader :found #: String?
@@ -298,6 +311,13 @@ module Herb
298
311
  @found = found
299
312
  end
300
313
 
314
+ #: () -> String?
315
+ def suggestion
316
+ return nil unless tag_name
317
+
318
+ format("A void element cannot have a closing tag. Remove it, or write `<%s />`.", tag_name.value)
319
+ end
320
+
301
321
  #: () -> String
302
322
  def inspect
303
323
  tree_inspect.rstrip.gsub(/\s+$/, "")
@@ -316,7 +336,7 @@ module Herb
316
336
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
317
337
  output = +""
318
338
 
319
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
339
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
320
340
  output += white("├── message: #{green(message.inspect)}\n")
321
341
  output += white("├── tag_name: ")
322
342
  output += tag_name ? tag_name.tree_inspect : magenta("∅")
@@ -332,9 +352,6 @@ module Herb
332
352
  class UnclosedElementError < Error
333
353
  include Colors
334
354
 
335
- #| opening_tag: Herb::Token?,
336
- #| }
337
-
338
355
  attr_reader :opening_tag #: Herb::Token?
339
356
 
340
357
  #: (String, Location?, String, Herb::Token) -> void
@@ -343,6 +360,11 @@ module Herb
343
360
  @opening_tag = opening_tag
344
361
  end
345
362
 
363
+ #: () -> String?
364
+ def suggestion
365
+ "Close this element before the end of the template."
366
+ end
367
+
346
368
  #: () -> String
347
369
  def inspect
348
370
  tree_inspect.rstrip.gsub(/\s+$/, "")
@@ -359,7 +381,7 @@ module Herb
359
381
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
360
382
  output = +""
361
383
 
362
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
384
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
363
385
  output += white("├── message: #{green(message.inspect)}\n")
364
386
  output += white("└── opening_tag: ")
365
387
  output += opening_tag ? opening_tag.tree_inspect : magenta("∅")
@@ -373,11 +395,6 @@ module Herb
373
395
  class RubyParseError < Error
374
396
  include Colors
375
397
 
376
- #| error_message: String?,
377
- #| diagnostic_id: String?,
378
- #| level: String?,
379
- #| }
380
-
381
398
  attr_reader :error_message #: String?
382
399
  attr_reader :diagnostic_id #: String?
383
400
  attr_reader :level #: String?
@@ -390,6 +407,11 @@ module Herb
390
407
  @level = level
391
408
  end
392
409
 
410
+ #: () -> String?
411
+ def suggestion
412
+ "Check the Ruby syntax inside the ERB tag."
413
+ end
414
+
393
415
  #: () -> String
394
416
  def inspect
395
417
  tree_inspect.rstrip.gsub(/\s+$/, "")
@@ -408,7 +430,7 @@ module Herb
408
430
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
409
431
  output = +""
410
432
 
411
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
433
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
412
434
  output += white("├── message: #{green(message.inspect)}\n")
413
435
  output += white("├── error_message: #{green(error_message.inspect)}\n")
414
436
  output += white("├── diagnostic_id: #{green(diagnostic_id.inspect)}\n")
@@ -422,9 +444,6 @@ module Herb
422
444
  class ERBControlFlowScopeError < Error
423
445
  include Colors
424
446
 
425
- #| keyword: String?,
426
- #| }
427
-
428
447
  attr_reader :keyword #: String?
429
448
 
430
449
  #: (String, Location?, String, String) -> void
@@ -449,7 +468,7 @@ module Herb
449
468
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
450
469
  output = +""
451
470
 
452
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
471
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
453
472
  output += white("├── message: #{green(message.inspect)}\n")
454
473
  output += white("└── keyword: #{green(keyword.inspect)}\n")
455
474
  output += %(\n)
@@ -461,9 +480,6 @@ module Herb
461
480
  class MissingERBEndTagError < Error
462
481
  include Colors
463
482
 
464
- #| keyword: String?,
465
- #| }
466
-
467
483
  attr_reader :keyword #: String?
468
484
 
469
485
  #: (String, Location?, String, String) -> void
@@ -488,7 +504,7 @@ module Herb
488
504
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
489
505
  output = +""
490
506
 
491
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
507
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
492
508
  output += white("├── message: #{green(message.inspect)}\n")
493
509
  output += white("└── keyword: #{green(keyword.inspect)}\n")
494
510
  output += %(\n)
@@ -509,7 +525,7 @@ module Herb
509
525
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
510
526
  output = +""
511
527
 
512
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
528
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
513
529
  output += white("└── message: #{green(message.inspect)}\n")
514
530
  output += %(\n)
515
531
 
@@ -529,7 +545,7 @@ module Herb
529
545
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
530
546
  output = +""
531
547
 
532
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
548
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
533
549
  output += white("└── message: #{green(message.inspect)}\n")
534
550
  output += %(\n)
535
551
 
@@ -537,12 +553,28 @@ module Herb
537
553
  end
538
554
  end
539
555
 
540
- class ConditionalElementMultipleTagsError < Error
556
+ class ERBCaseInlinePatternMatchError < Error
541
557
  include Colors
542
558
 
543
- #| line: Integer?,
544
- #| column: Integer?,
545
- #| }
559
+ #: () -> String
560
+ def inspect
561
+ tree_inspect.rstrip.gsub(/\s+$/, "")
562
+ end
563
+
564
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
565
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
566
+ output = +""
567
+
568
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
569
+ output += white("└── message: #{green(message.inspect)}\n")
570
+ output += %(\n)
571
+
572
+ output.gsub(/^/, " " * indent)
573
+ end
574
+ end
575
+
576
+ class ConditionalElementMultipleTagsError < Error
577
+ include Colors
546
578
 
547
579
  attr_reader :line #: Integer?
548
580
  attr_reader :column #: Integer?
@@ -571,7 +603,7 @@ module Herb
571
603
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
572
604
  output = +""
573
605
 
574
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
606
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
575
607
  output += white("├── message: #{green(message.inspect)}\n")
576
608
  output += white("├── line: #{green(line.inspect)}\n")
577
609
  output += white("└── column: #{green(column.inspect)}\n")
@@ -584,15 +616,6 @@ module Herb
584
616
  class ConditionalElementConditionMismatchError < Error
585
617
  include Colors
586
618
 
587
- #| tag_name: String?,
588
- #| open_condition: String?,
589
- #| open_line: Integer?,
590
- #| open_column: Integer?,
591
- #| close_condition: String?,
592
- #| close_line: Integer?,
593
- #| close_column: Integer?,
594
- #| }
595
-
596
619
  attr_reader :tag_name #: String?
597
620
  attr_reader :open_condition #: String?
598
621
  attr_reader :open_line #: Integer?
@@ -635,7 +658,7 @@ module Herb
635
658
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
636
659
  output = +""
637
660
 
638
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
661
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
639
662
  output += white("├── message: #{green(message.inspect)}\n")
640
663
  output += white("├── tag_name: #{green(tag_name.inspect)}\n")
641
664
  output += white("├── open_condition: #{green(open_condition.inspect)}\n")
@@ -650,11 +673,100 @@ module Herb
650
673
  end
651
674
  end
652
675
 
653
- class InvalidCommentClosingTagError < Error
676
+ class UnclosedCommentError < Error
677
+ include Colors
678
+
679
+ attr_reader :comment_start #: Herb::Token?
680
+
681
+ #: (String, Location?, String, Herb::Token) -> void
682
+ def initialize(type, location, message, comment_start)
683
+ super(type, location, message)
684
+ @comment_start = comment_start
685
+ end
686
+
687
+ #: () -> String?
688
+ def suggestion
689
+ "Add `-->` where the comment should end."
690
+ end
691
+
692
+ #: () -> String
693
+ def inspect
694
+ tree_inspect.rstrip.gsub(/\s+$/, "")
695
+ end
696
+
697
+ #: () -> serialized_unclosed_comment_error
698
+ def to_hash
699
+ super.merge(
700
+ comment_start: comment_start
701
+ ) #: Herb::serialized_unclosed_comment_error
702
+ end
703
+
704
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
705
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
706
+ output = +""
707
+
708
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
709
+ output += white("├── message: #{green(message.inspect)}\n")
710
+ output += white("└── comment_start: ")
711
+ output += comment_start ? comment_start.tree_inspect : magenta("∅")
712
+ output += "\n"
713
+ output += %(\n)
714
+
715
+ output.gsub(/^/, " " * indent)
716
+ end
717
+ end
718
+
719
+ class NestedCommentError < Error
654
720
  include Colors
655
721
 
656
- #| closing_tag: Herb::Token?,
657
- #| }
722
+ attr_reader :comment_start #: Herb::Token?
723
+ attr_reader :nested_start #: Herb::Token?
724
+
725
+ #: (String, Location?, String, Herb::Token, Herb::Token) -> void
726
+ def initialize(type, location, message, comment_start, nested_start)
727
+ super(type, location, message)
728
+ @comment_start = comment_start
729
+ @nested_start = nested_start
730
+ end
731
+
732
+ #: () -> String?
733
+ def suggestion
734
+ "Comments cannot nest. The outer comment ends at the first `-->`, so remove the inner `<!--` or close the outer comment before it."
735
+ end
736
+
737
+ #: () -> String
738
+ def inspect
739
+ tree_inspect.rstrip.gsub(/\s+$/, "")
740
+ end
741
+
742
+ #: () -> serialized_nested_comment_error
743
+ def to_hash
744
+ super.merge(
745
+ comment_start: comment_start,
746
+ nested_start: nested_start
747
+ ) #: Herb::serialized_nested_comment_error
748
+ end
749
+
750
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
751
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
752
+ output = +""
753
+
754
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
755
+ output += white("├── message: #{green(message.inspect)}\n")
756
+ output += white("├── comment_start: ")
757
+ output += comment_start ? comment_start.tree_inspect : magenta("∅")
758
+ output += "\n"
759
+ output += white("└── nested_start: ")
760
+ output += nested_start ? nested_start.tree_inspect : magenta("∅")
761
+ output += "\n"
762
+ output += %(\n)
763
+
764
+ output.gsub(/^/, " " * indent)
765
+ end
766
+ end
767
+
768
+ class InvalidCommentClosingTagError < Error
769
+ include Colors
658
770
 
659
771
  attr_reader :closing_tag #: Herb::Token?
660
772
 
@@ -680,7 +792,7 @@ module Herb
680
792
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
681
793
  output = +""
682
794
 
683
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
795
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
684
796
  output += white("├── message: #{green(message.inspect)}\n")
685
797
  output += white("└── closing_tag: ")
686
798
  output += closing_tag ? closing_tag.tree_inspect : magenta("∅")
@@ -694,10 +806,6 @@ module Herb
694
806
  class OmittedClosingTagError < Error
695
807
  include Colors
696
808
 
697
- #| opening_tag: Herb::Token?,
698
- #| insertion_point: Herb::Position?,
699
- #| }
700
-
701
809
  attr_reader :opening_tag #: Herb::Token?
702
810
  attr_reader :insertion_point #: Herb::Position?
703
811
 
@@ -725,7 +833,7 @@ module Herb
725
833
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
726
834
  output = +""
727
835
 
728
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
836
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
729
837
  output += white("├── message: #{green(message.inspect)}\n")
730
838
  output += white("├── opening_tag: ")
731
839
  output += opening_tag ? opening_tag.tree_inspect : magenta("∅")
@@ -742,9 +850,6 @@ module Herb
742
850
  class UnclosedOpenTagError < Error
743
851
  include Colors
744
852
 
745
- #| tag_name: Herb::Token?,
746
- #| }
747
-
748
853
  attr_reader :tag_name #: Herb::Token?
749
854
 
750
855
  #: (String, Location?, String, Herb::Token) -> void
@@ -769,7 +874,7 @@ module Herb
769
874
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
770
875
  output = +""
771
876
 
772
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
877
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
773
878
  output += white("├── message: #{green(message.inspect)}\n")
774
879
  output += white("└── tag_name: ")
775
880
  output += tag_name ? tag_name.tree_inspect : magenta("∅")
@@ -783,9 +888,6 @@ module Herb
783
888
  class UnclosedCloseTagError < Error
784
889
  include Colors
785
890
 
786
- #| tag_name: Herb::Token?,
787
- #| }
788
-
789
891
  attr_reader :tag_name #: Herb::Token?
790
892
 
791
893
  #: (String, Location?, String, Herb::Token) -> void
@@ -810,7 +912,7 @@ module Herb
810
912
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
811
913
  output = +""
812
914
 
813
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
915
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
814
916
  output += white("├── message: #{green(message.inspect)}\n")
815
917
  output += white("└── tag_name: ")
816
918
  output += tag_name ? tag_name.tree_inspect : magenta("∅")
@@ -821,11 +923,51 @@ module Herb
821
923
  end
822
924
  end
823
925
 
824
- class UnclosedQuoteError < Error
926
+ class EndTagWithTrailingSolidusError < Error
825
927
  include Colors
826
928
 
827
- #| opening_quote: Herb::Token?,
828
- #| }
929
+ attr_reader :tag_name #: Herb::Token?
930
+
931
+ #: (String, Location?, String, Herb::Token) -> void
932
+ def initialize(type, location, message, tag_name)
933
+ super(type, location, message)
934
+ @tag_name = tag_name
935
+ end
936
+
937
+ #: () -> String?
938
+ def suggestion
939
+ "Close it with `>`. A closing tag cannot self-close."
940
+ end
941
+
942
+ #: () -> String
943
+ def inspect
944
+ tree_inspect.rstrip.gsub(/\s+$/, "")
945
+ end
946
+
947
+ #: () -> serialized_end_tag_with_trailing_solidus_error
948
+ def to_hash
949
+ super.merge(
950
+ tag_name: tag_name
951
+ ) #: Herb::serialized_end_tag_with_trailing_solidus_error
952
+ end
953
+
954
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
955
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
956
+ output = +""
957
+
958
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
959
+ output += white("├── message: #{green(message.inspect)}\n")
960
+ output += white("└── tag_name: ")
961
+ output += tag_name ? tag_name.tree_inspect : magenta("∅")
962
+ output += "\n"
963
+ output += %(\n)
964
+
965
+ output.gsub(/^/, " " * indent)
966
+ end
967
+ end
968
+
969
+ class UnclosedQuoteError < Error
970
+ include Colors
829
971
 
830
972
  attr_reader :opening_quote #: Herb::Token?
831
973
 
@@ -851,7 +993,7 @@ module Herb
851
993
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
852
994
  output = +""
853
995
 
854
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
996
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
855
997
  output += white("├── message: #{green(message.inspect)}\n")
856
998
  output += white("└── opening_quote: ")
857
999
  output += opening_quote ? opening_quote.tree_inspect : magenta("∅")
@@ -865,9 +1007,6 @@ module Herb
865
1007
  class MissingAttributeValueError < Error
866
1008
  include Colors
867
1009
 
868
- #| attribute_name: String?,
869
- #| }
870
-
871
1010
  attr_reader :attribute_name #: String?
872
1011
 
873
1012
  #: (String, Location?, String, String) -> void
@@ -876,6 +1015,13 @@ module Herb
876
1015
  @attribute_name = attribute_name
877
1016
  end
878
1017
 
1018
+ #: () -> String?
1019
+ def suggestion
1020
+ return nil unless attribute_name
1021
+
1022
+ format("Give `%s` a value, or drop the equals sign.", attribute_name)
1023
+ end
1024
+
879
1025
  #: () -> String
880
1026
  def inspect
881
1027
  tree_inspect.rstrip.gsub(/\s+$/, "")
@@ -892,7 +1038,7 @@ module Herb
892
1038
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
893
1039
  output = +""
894
1040
 
895
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1041
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
896
1042
  output += white("├── message: #{green(message.inspect)}\n")
897
1043
  output += white("└── attribute_name: #{green(attribute_name.inspect)}\n")
898
1044
  output += %(\n)
@@ -901,11 +1047,223 @@ module Herb
901
1047
  end
902
1048
  end
903
1049
 
904
- class UnclosedERBTagError < Error
1050
+ class MissingWhitespaceBetweenAttributesError < Error
1051
+ include Colors
1052
+
1053
+ attr_reader :found #: Herb::Token?
1054
+
1055
+ #: (String, Location?, String, Herb::Token) -> void
1056
+ def initialize(type, location, message, found)
1057
+ super(type, location, message)
1058
+ @found = found
1059
+ end
1060
+
1061
+ #: () -> String?
1062
+ def suggestion
1063
+ "Add a space before it."
1064
+ end
1065
+
1066
+ #: () -> String
1067
+ def inspect
1068
+ tree_inspect.rstrip.gsub(/\s+$/, "")
1069
+ end
1070
+
1071
+ #: () -> serialized_missing_whitespace_between_attributes_error
1072
+ def to_hash
1073
+ super.merge(
1074
+ found: found
1075
+ ) #: Herb::serialized_missing_whitespace_between_attributes_error
1076
+ end
1077
+
1078
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1079
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1080
+ output = +""
1081
+
1082
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1083
+ output += white("├── message: #{green(message.inspect)}\n")
1084
+ output += white("└── found: ")
1085
+ output += found ? found.tree_inspect : magenta("∅")
1086
+ output += "\n"
1087
+ output += %(\n)
1088
+
1089
+ output.gsub(/^/, " " * indent)
1090
+ end
1091
+ end
1092
+
1093
+ class UnexpectedCharacterInAttributeNameError < Error
1094
+ include Colors
1095
+
1096
+ attr_reader :character #: Herb::Token?
1097
+
1098
+ #: (String, Location?, String, Herb::Token) -> void
1099
+ def initialize(type, location, message, character)
1100
+ super(type, location, message)
1101
+ @character = character
1102
+ end
1103
+
1104
+ #: () -> String?
1105
+ def suggestion
1106
+ "Quotes cannot appear in an attribute name. Check the quoting of the previous attribute value."
1107
+ end
1108
+
1109
+ #: () -> String
1110
+ def inspect
1111
+ tree_inspect.rstrip.gsub(/\s+$/, "")
1112
+ end
1113
+
1114
+ #: () -> serialized_unexpected_character_in_attribute_name_error
1115
+ def to_hash
1116
+ super.merge(
1117
+ character: character
1118
+ ) #: Herb::serialized_unexpected_character_in_attribute_name_error
1119
+ end
1120
+
1121
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1122
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1123
+ output = +""
1124
+
1125
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1126
+ output += white("├── message: #{green(message.inspect)}\n")
1127
+ output += white("└── character: ")
1128
+ output += character ? character.tree_inspect : magenta("∅")
1129
+ output += "\n"
1130
+ output += %(\n)
1131
+
1132
+ output.gsub(/^/, " " * indent)
1133
+ end
1134
+ end
1135
+
1136
+ class UnexpectedCharacterInUnquotedAttributeValueError < Error
1137
+ include Colors
1138
+
1139
+ attr_reader :character #: Herb::Token?
1140
+
1141
+ #: (String, Location?, String, Herb::Token) -> void
1142
+ def initialize(type, location, message, character)
1143
+ super(type, location, message)
1144
+ @character = character
1145
+ end
1146
+
1147
+ #: () -> String?
1148
+ def suggestion
1149
+ "Wrap the value in quotes."
1150
+ end
1151
+
1152
+ #: () -> String
1153
+ def inspect
1154
+ tree_inspect.rstrip.gsub(/\s+$/, "")
1155
+ end
1156
+
1157
+ #: () -> serialized_unexpected_character_in_unquoted_attribute_value_error
1158
+ def to_hash
1159
+ super.merge(
1160
+ character: character
1161
+ ) #: Herb::serialized_unexpected_character_in_unquoted_attribute_value_error
1162
+ end
1163
+
1164
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1165
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1166
+ output = +""
1167
+
1168
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1169
+ output += white("├── message: #{green(message.inspect)}\n")
1170
+ output += white("└── character: ")
1171
+ output += character ? character.tree_inspect : magenta("∅")
1172
+ output += "\n"
1173
+ output += %(\n)
1174
+
1175
+ output.gsub(/^/, " " * indent)
1176
+ end
1177
+ end
1178
+
1179
+ class UnexpectedEqualsSignBeforeAttributeNameError < Error
905
1180
  include Colors
906
1181
 
907
- #| opening_tag: Herb::Token?,
908
- #| }
1182
+ attr_reader :equals #: Herb::Token?
1183
+
1184
+ #: (String, Location?, String, Herb::Token) -> void
1185
+ def initialize(type, location, message, equals)
1186
+ super(type, location, message)
1187
+ @equals = equals
1188
+ end
1189
+
1190
+ #: () -> String?
1191
+ def suggestion
1192
+ "Remove the `=`, or put an attribute name in front of it."
1193
+ end
1194
+
1195
+ #: () -> String
1196
+ def inspect
1197
+ tree_inspect.rstrip.gsub(/\s+$/, "")
1198
+ end
1199
+
1200
+ #: () -> serialized_unexpected_equals_sign_before_attribute_name_error
1201
+ def to_hash
1202
+ super.merge(
1203
+ equals: equals
1204
+ ) #: Herb::serialized_unexpected_equals_sign_before_attribute_name_error
1205
+ end
1206
+
1207
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1208
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1209
+ output = +""
1210
+
1211
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1212
+ output += white("├── message: #{green(message.inspect)}\n")
1213
+ output += white("└── equals: ")
1214
+ output += equals ? equals.tree_inspect : magenta("∅")
1215
+ output += "\n"
1216
+ output += %(\n)
1217
+
1218
+ output.gsub(/^/, " " * indent)
1219
+ end
1220
+ end
1221
+
1222
+ class UnexpectedSolidusInTagError < Error
1223
+ include Colors
1224
+
1225
+ attr_reader :solidus #: Herb::Token?
1226
+
1227
+ #: (String, Location?, String, Herb::Token) -> void
1228
+ def initialize(type, location, message, solidus)
1229
+ super(type, location, message)
1230
+ @solidus = solidus
1231
+ end
1232
+
1233
+ #: () -> String?
1234
+ def suggestion
1235
+ "Remove it, or use `/>` to self-close the tag."
1236
+ end
1237
+
1238
+ #: () -> String
1239
+ def inspect
1240
+ tree_inspect.rstrip.gsub(/\s+$/, "")
1241
+ end
1242
+
1243
+ #: () -> serialized_unexpected_solidus_in_tag_error
1244
+ def to_hash
1245
+ super.merge(
1246
+ solidus: solidus
1247
+ ) #: Herb::serialized_unexpected_solidus_in_tag_error
1248
+ end
1249
+
1250
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1251
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1252
+ output = +""
1253
+
1254
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1255
+ output += white("├── message: #{green(message.inspect)}\n")
1256
+ output += white("└── solidus: ")
1257
+ output += solidus ? solidus.tree_inspect : magenta("∅")
1258
+ output += "\n"
1259
+ output += %(\n)
1260
+
1261
+ output.gsub(/^/, " " * indent)
1262
+ end
1263
+ end
1264
+
1265
+ class UnclosedERBTagError < Error
1266
+ include Colors
909
1267
 
910
1268
  attr_reader :opening_tag #: Herb::Token?
911
1269
 
@@ -931,7 +1289,7 @@ module Herb
931
1289
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
932
1290
  output = +""
933
1291
 
934
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1292
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
935
1293
  output += white("├── message: #{green(message.inspect)}\n")
936
1294
  output += white("└── opening_tag: ")
937
1295
  output += opening_tag ? opening_tag.tree_inspect : magenta("∅")
@@ -942,6 +1300,50 @@ module Herb
942
1300
  end
943
1301
  end
944
1302
 
1303
+ class MalformedERBClosingTagError < Error
1304
+ include Colors
1305
+
1306
+ attr_reader :opening_tag #: Herb::Token?
1307
+ attr_reader :closing_tag #: Herb::Token?
1308
+
1309
+ #: (String, Location?, String, Herb::Token, Herb::Token) -> void
1310
+ def initialize(type, location, message, opening_tag, closing_tag)
1311
+ super(type, location, message)
1312
+ @opening_tag = opening_tag
1313
+ @closing_tag = closing_tag
1314
+ end
1315
+
1316
+ #: () -> String
1317
+ def inspect
1318
+ tree_inspect.rstrip.gsub(/\s+$/, "")
1319
+ end
1320
+
1321
+ #: () -> serialized_malformed_erb_closing_tag_error
1322
+ def to_hash
1323
+ super.merge(
1324
+ opening_tag: opening_tag,
1325
+ closing_tag: closing_tag
1326
+ ) #: Herb::serialized_malformed_erb_closing_tag_error
1327
+ end
1328
+
1329
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1330
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1331
+ output = +""
1332
+
1333
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1334
+ output += white("├── message: #{green(message.inspect)}\n")
1335
+ output += white("├── opening_tag: ")
1336
+ output += opening_tag ? opening_tag.tree_inspect : magenta("∅")
1337
+ output += "\n"
1338
+ output += white("└── closing_tag: ")
1339
+ output += closing_tag ? closing_tag.tree_inspect : magenta("∅")
1340
+ output += "\n"
1341
+ output += %(\n)
1342
+
1343
+ output.gsub(/^/, " " * indent)
1344
+ end
1345
+ end
1346
+
945
1347
  class StrayERBClosingTagError < Error
946
1348
  include Colors
947
1349
 
@@ -954,7 +1356,7 @@ module Herb
954
1356
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
955
1357
  output = +""
956
1358
 
957
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1359
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
958
1360
  output += white("└── message: #{green(message.inspect)}\n")
959
1361
  output += %(\n)
960
1362
 
@@ -965,11 +1367,6 @@ module Herb
965
1367
  class NestedERBTagError < Error
966
1368
  include Colors
967
1369
 
968
- #| opening_tag: Herb::Token?,
969
- #| nested_tag_line: Integer?,
970
- #| nested_tag_column: Integer?,
971
- #| }
972
-
973
1370
  attr_reader :opening_tag #: Herb::Token?
974
1371
  attr_reader :nested_tag_line #: Integer?
975
1372
  attr_reader :nested_tag_column #: Integer?
@@ -1000,7 +1397,7 @@ module Herb
1000
1397
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1001
1398
  output = +""
1002
1399
 
1003
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1400
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1004
1401
  output += white("├── message: #{green(message.inspect)}\n")
1005
1402
  output += white("├── opening_tag: ")
1006
1403
  output += opening_tag ? opening_tag.tree_inspect : magenta("∅")
@@ -1016,9 +1413,6 @@ module Herb
1016
1413
  class RenderAmbiguousLocalsError < Error
1017
1414
  include Colors
1018
1415
 
1019
- #| partial: String?,
1020
- #| }
1021
-
1022
1416
  attr_reader :partial #: String?
1023
1417
 
1024
1418
  #: (String, Location?, String, String) -> void
@@ -1043,7 +1437,7 @@ module Herb
1043
1437
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1044
1438
  output = +""
1045
1439
 
1046
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1440
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1047
1441
  output += white("├── message: #{green(message.inspect)}\n")
1048
1442
  output += white("└── partial: #{green(partial.inspect)}\n")
1049
1443
  output += %(\n)
@@ -1055,10 +1449,6 @@ module Herb
1055
1449
  class RenderMissingLocalsError < Error
1056
1450
  include Colors
1057
1451
 
1058
- #| partial: String?,
1059
- #| keywords: String?,
1060
- #| }
1061
-
1062
1452
  attr_reader :partial #: String?
1063
1453
  attr_reader :keywords #: String?
1064
1454
 
@@ -1086,7 +1476,7 @@ module Herb
1086
1476
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1087
1477
  output = +""
1088
1478
 
1089
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1479
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1090
1480
  output += white("├── message: #{green(message.inspect)}\n")
1091
1481
  output += white("├── partial: #{green(partial.inspect)}\n")
1092
1482
  output += white("└── keywords: #{green(keywords.inspect)}\n")
@@ -1108,7 +1498,7 @@ module Herb
1108
1498
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1109
1499
  output = +""
1110
1500
 
1111
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1501
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1112
1502
  output += white("└── message: #{green(message.inspect)}\n")
1113
1503
  output += %(\n)
1114
1504
 
@@ -1119,10 +1509,6 @@ module Herb
1119
1509
  class RenderConflictingPartialError < Error
1120
1510
  include Colors
1121
1511
 
1122
- #| positional_partial: String?,
1123
- #| keyword_partial: String?,
1124
- #| }
1125
-
1126
1512
  attr_reader :positional_partial #: String?
1127
1513
  attr_reader :keyword_partial #: String?
1128
1514
 
@@ -1150,7 +1536,7 @@ module Herb
1150
1536
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1151
1537
  output = +""
1152
1538
 
1153
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1539
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1154
1540
  output += white("├── message: #{green(message.inspect)}\n")
1155
1541
  output += white("├── positional_partial: #{green(positional_partial.inspect)}\n")
1156
1542
  output += white("└── keyword_partial: #{green(keyword_partial.inspect)}\n")
@@ -1163,9 +1549,6 @@ module Herb
1163
1549
  class RenderInvalidAsOptionError < Error
1164
1550
  include Colors
1165
1551
 
1166
- #| as_value: String?,
1167
- #| }
1168
-
1169
1552
  attr_reader :as_value #: String?
1170
1553
 
1171
1554
  #: (String, Location?, String, String) -> void
@@ -1190,7 +1573,7 @@ module Herb
1190
1573
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1191
1574
  output = +""
1192
1575
 
1193
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1576
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1194
1577
  output += white("├── message: #{green(message.inspect)}\n")
1195
1578
  output += white("└── as_value: #{green(as_value.inspect)}\n")
1196
1579
  output += %(\n)
@@ -1211,7 +1594,7 @@ module Herb
1211
1594
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1212
1595
  output = +""
1213
1596
 
1214
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1597
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1215
1598
  output += white("└── message: #{green(message.inspect)}\n")
1216
1599
  output += %(\n)
1217
1600
 
@@ -1222,9 +1605,6 @@ module Herb
1222
1605
  class RenderLayoutWithoutBlockError < Error
1223
1606
  include Colors
1224
1607
 
1225
- #| layout: String?,
1226
- #| }
1227
-
1228
1608
  attr_reader :layout #: String?
1229
1609
 
1230
1610
  #: (String, Location?, String, String) -> void
@@ -1249,7 +1629,7 @@ module Herb
1249
1629
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1250
1630
  output = +""
1251
1631
 
1252
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1632
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1253
1633
  output += white("├── message: #{green(message.inspect)}\n")
1254
1634
  output += white("└── layout: #{green(layout.inspect)}\n")
1255
1635
  output += %(\n)
@@ -1261,9 +1641,6 @@ module Herb
1261
1641
  class StrictLocalsPositionalArgumentError < Error
1262
1642
  include Colors
1263
1643
 
1264
- #| name: String?,
1265
- #| }
1266
-
1267
1644
  attr_reader :name #: String?
1268
1645
 
1269
1646
  #: (String, Location?, String, String) -> void
@@ -1288,7 +1665,7 @@ module Herb
1288
1665
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1289
1666
  output = +""
1290
1667
 
1291
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1668
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1292
1669
  output += white("├── message: #{green(message.inspect)}\n")
1293
1670
  output += white("└── name: #{green(name.inspect)}\n")
1294
1671
  output += %(\n)
@@ -1300,9 +1677,6 @@ module Herb
1300
1677
  class StrictLocalsBlockArgumentError < Error
1301
1678
  include Colors
1302
1679
 
1303
- #| name: String?,
1304
- #| }
1305
-
1306
1680
  attr_reader :name #: String?
1307
1681
 
1308
1682
  #: (String, Location?, String, String) -> void
@@ -1327,7 +1701,7 @@ module Herb
1327
1701
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1328
1702
  output = +""
1329
1703
 
1330
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1704
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1331
1705
  output += white("├── message: #{green(message.inspect)}\n")
1332
1706
  output += white("└── name: #{green(name.inspect)}\n")
1333
1707
  output += %(\n)
@@ -1339,9 +1713,6 @@ module Herb
1339
1713
  class StrictLocalsSplatArgumentError < Error
1340
1714
  include Colors
1341
1715
 
1342
- #| name: String?,
1343
- #| }
1344
-
1345
1716
  attr_reader :name #: String?
1346
1717
 
1347
1718
  #: (String, Location?, String, String) -> void
@@ -1366,7 +1737,7 @@ module Herb
1366
1737
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1367
1738
  output = +""
1368
1739
 
1369
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1740
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1370
1741
  output += white("├── message: #{green(message.inspect)}\n")
1371
1742
  output += white("└── name: #{green(name.inspect)}\n")
1372
1743
  output += %(\n)
@@ -1378,9 +1749,6 @@ module Herb
1378
1749
  class StrictLocalsMissingParenthesisError < Error
1379
1750
  include Colors
1380
1751
 
1381
- #| rest: String?,
1382
- #| }
1383
-
1384
1752
  attr_reader :rest #: String?
1385
1753
 
1386
1754
  #: (String, Location?, String, String) -> void
@@ -1405,7 +1773,7 @@ module Herb
1405
1773
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1406
1774
  output = +""
1407
1775
 
1408
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1776
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1409
1777
  output += white("├── message: #{green(message.inspect)}\n")
1410
1778
  output += white("└── rest: #{green(rest.inspect)}\n")
1411
1779
  output += %(\n)
@@ -1426,7 +1794,7 @@ module Herb
1426
1794
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1427
1795
  output = +""
1428
1796
 
1429
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1797
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1430
1798
  output += white("└── message: #{green(message.inspect)}\n")
1431
1799
  output += %(\n)
1432
1800
 
@@ -1434,13 +1802,140 @@ module Herb
1434
1802
  end
1435
1803
  end
1436
1804
 
1437
- class VoidElementContentError < Error
1805
+ class HerbStateMissingParenthesisError < Error
1806
+ include Colors
1807
+
1808
+ attr_reader :rest #: String?
1809
+
1810
+ #: (String, Location?, String, String) -> void
1811
+ def initialize(type, location, message, rest)
1812
+ super(type, location, message)
1813
+ @rest = rest
1814
+ end
1815
+
1816
+ #: () -> String
1817
+ def inspect
1818
+ tree_inspect.rstrip.gsub(/\s+$/, "")
1819
+ end
1820
+
1821
+ #: () -> serialized_herb_state_missing_parenthesis_error
1822
+ def to_hash
1823
+ super.merge(
1824
+ rest: rest
1825
+ ) #: Herb::serialized_herb_state_missing_parenthesis_error
1826
+ end
1827
+
1828
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1829
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1830
+ output = +""
1831
+
1832
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1833
+ output += white("├── message: #{green(message.inspect)}\n")
1834
+ output += white("└── rest: #{green(rest.inspect)}\n")
1835
+ output += %(\n)
1836
+
1837
+ output.gsub(/^/, " " * indent)
1838
+ end
1839
+ end
1840
+
1841
+ class HerbStateNonCanonicalDirectiveError < Error
1842
+ include Colors
1843
+
1844
+ attr_reader :found #: String?
1845
+ attr_reader :expected #: String?
1846
+
1847
+ #: (String, Location?, String, String, String) -> void
1848
+ def initialize(type, location, message, found, expected)
1849
+ super(type, location, message)
1850
+ @found = found
1851
+ @expected = expected
1852
+ end
1853
+
1854
+ #: () -> String
1855
+ def inspect
1856
+ tree_inspect.rstrip.gsub(/\s+$/, "")
1857
+ end
1858
+
1859
+ #: () -> serialized_herb_state_non_canonical_directive_error
1860
+ def to_hash
1861
+ super.merge(
1862
+ found: found,
1863
+ expected: expected
1864
+ ) #: Herb::serialized_herb_state_non_canonical_directive_error
1865
+ end
1866
+
1867
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1868
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1869
+ output = +""
1870
+
1871
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1872
+ output += white("├── message: #{green(message.inspect)}\n")
1873
+ output += white("├── found: #{green(found.inspect)}\n")
1874
+ output += white("└── expected: #{green(expected.inspect)}\n")
1875
+ output += %(\n)
1876
+
1877
+ output.gsub(/^/, " " * indent)
1878
+ end
1879
+ end
1880
+
1881
+ class HerbStateInvalidParameterError < Error
1438
1882
  include Colors
1439
1883
 
1440
- #| tag_name: Herb::Token?,
1441
- #| helper_name: String?,
1442
- #| content_type: String?,
1443
- #| }
1884
+ attr_reader :parameter #: String?
1885
+
1886
+ #: (String, Location?, String, String) -> void
1887
+ def initialize(type, location, message, parameter)
1888
+ super(type, location, message)
1889
+ @parameter = parameter
1890
+ end
1891
+
1892
+ #: () -> String
1893
+ def inspect
1894
+ tree_inspect.rstrip.gsub(/\s+$/, "")
1895
+ end
1896
+
1897
+ #: () -> serialized_herb_state_invalid_parameter_error
1898
+ def to_hash
1899
+ super.merge(
1900
+ parameter: parameter
1901
+ ) #: Herb::serialized_herb_state_invalid_parameter_error
1902
+ end
1903
+
1904
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1905
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1906
+ output = +""
1907
+
1908
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1909
+ output += white("├── message: #{green(message.inspect)}\n")
1910
+ output += white("└── parameter: #{green(parameter.inspect)}\n")
1911
+ output += %(\n)
1912
+
1913
+ output.gsub(/^/, " " * indent)
1914
+ end
1915
+ end
1916
+
1917
+ class HerbStateDuplicateDeclarationError < Error
1918
+ include Colors
1919
+
1920
+ #: () -> String
1921
+ def inspect
1922
+ tree_inspect.rstrip.gsub(/\s+$/, "")
1923
+ end
1924
+
1925
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1926
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1927
+ output = +""
1928
+
1929
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1930
+ output += white("└── message: #{green(message.inspect)}\n")
1931
+ output += %(\n)
1932
+
1933
+ output.gsub(/^/, " " * indent)
1934
+ end
1935
+ end
1936
+
1937
+ class VoidElementContentError < Error
1938
+ include Colors
1444
1939
 
1445
1940
  attr_reader :tag_name #: Herb::Token?
1446
1941
  attr_reader :helper_name #: String?
@@ -1472,7 +1967,7 @@ module Herb
1472
1967
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1473
1968
  output = +""
1474
1969
 
1475
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1970
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1476
1971
  output += white("├── message: #{green(message.inspect)}\n")
1477
1972
  output += white("├── tag_name: ")
1478
1973
  output += tag_name ? tag_name.tree_inspect : magenta("∅")
@@ -1488,9 +1983,6 @@ module Herb
1488
1983
  class DotNotationCasingError < Error
1489
1984
  include Colors
1490
1985
 
1491
- #| segment: Herb::Token?,
1492
- #| }
1493
-
1494
1986
  attr_reader :segment #: Herb::Token?
1495
1987
 
1496
1988
  #: (String, Location?, String, Herb::Token) -> void
@@ -1515,7 +2007,7 @@ module Herb
1515
2007
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1516
2008
  output = +""
1517
2009
 
1518
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
2010
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1519
2011
  output += white("├── message: #{green(message.inspect)}\n")
1520
2012
  output += white("└── segment: ")
1521
2013
  output += segment ? segment.tree_inspect : magenta("∅")
@@ -1529,9 +2021,6 @@ module Herb
1529
2021
  class TimeoutError < Error
1530
2022
  include Colors
1531
2023
 
1532
- #| timeout_ms: Integer?,
1533
- #| }
1534
-
1535
2024
  attr_reader :timeout_ms #: Integer?
1536
2025
 
1537
2026
  #: (String, Location?, String, Integer) -> void
@@ -1556,7 +2045,7 @@ module Herb
1556
2045
  def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1557
2046
  output = +""
1558
2047
 
1559
- output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
2048
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect || "∅"})\n")}")
1560
2049
  output += white("├── message: #{green(message.inspect)}\n")
1561
2050
  output += white("└── timeout_ms: #{green(timeout_ms.inspect)}\n")
1562
2051
  output += %(\n)