herb 0.11.0-x86_64-linux-gnu → 0.11.2-x86_64-linux-gnu

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +4 -2
  3. data/config.yml +9 -0
  4. data/ext/herb/extconf.rb +8 -31
  5. data/ext/herb/nodes.c +90 -73
  6. data/ext/herb/parser_options_helpers.c +26 -0
  7. data/lib/herb/3.2/herb.so +0 -0
  8. data/lib/herb/3.3/herb.so +0 -0
  9. data/lib/herb/3.4/herb.so +0 -0
  10. data/lib/herb/4.0/herb.so +0 -0
  11. data/lib/herb/analysis/partial_index.rb +1 -1
  12. data/lib/herb/analysis/partial_resolution.rb +27 -0
  13. data/lib/herb/ast/helpers.rb +1 -1
  14. data/lib/herb/ast/nodes.rb +32 -6
  15. data/lib/herb/bootstrap.rb +6 -2
  16. data/lib/herb/configuration.rb +11 -1
  17. data/lib/herb/dev/classifier.rb +1 -1
  18. data/lib/herb/dev/runner.rb +6 -1
  19. data/lib/herb/engine/compiler.rb +52 -19
  20. data/lib/herb/engine/slots/dynamics_compiler.rb +63 -14
  21. data/lib/herb/engine/slots/markers.rb +24 -0
  22. data/lib/herb/engine/slots/state_compiler.rb +1 -2
  23. data/lib/herb/engine/slots/subtree_compiler.rb +1 -1
  24. data/lib/herb/engine/slots/visitor.rb +71 -32
  25. data/lib/herb/engine/visitors/instrumentation_visitor.rb +18 -6
  26. data/lib/herb/engine.rb +0 -2
  27. data/lib/herb/parser_options.rb +6 -3
  28. data/lib/herb/project.rb +19 -8
  29. data/lib/herb/version.rb +1 -1
  30. data/lib/herb.rb +1 -1
  31. data/sig/herb/analysis/partial_resolution.rbs +8 -0
  32. data/sig/herb/ast/nodes.rbs +10 -4
  33. data/sig/herb/bootstrap.rbs +2 -0
  34. data/sig/herb/configuration.rbs +3 -0
  35. data/sig/herb/dev/runner.rbs +3 -0
  36. data/sig/herb/engine/compiler.rbs +14 -3
  37. data/sig/herb/engine/slots/dynamics_compiler.rbs +27 -7
  38. data/sig/herb/engine/slots/markers.rbs +14 -0
  39. data/sig/herb/engine/slots/visitor.rbs +31 -13
  40. data/sig/herb/engine/visitors/instrumentation_visitor.rbs +5 -1
  41. data/sig/herb/parser_options.rbs +6 -4
  42. data/sig/herb.rbs +2 -2
  43. data/sig/serialized_ast_nodes.rbs +1 -0
  44. data/src/analyze/action_view/attribute_extraction_helpers.c +40 -21
  45. data/src/analyze/action_view/generated_handlers.c +36 -36
  46. data/src/analyze/action_view/image_tag.c +7 -3
  47. data/src/analyze/action_view/javascript_include_tag.c +6 -3
  48. data/src/analyze/action_view/link_to.c +23 -23
  49. data/src/analyze/action_view/registry.c +7 -3
  50. data/src/analyze/action_view/tag_helper_node_builders.c +12 -16
  51. data/src/analyze/action_view/tag_helpers.c +215 -110
  52. data/src/analyze/action_view/turbo_frame_tag.c +5 -4
  53. data/src/analyze/analyze.c +41 -45
  54. data/src/analyze/analyze_helpers.c +240 -405
  55. data/src/analyze/analyzed_ruby.c +10 -7
  56. data/src/analyze/builders.c +1 -0
  57. data/src/analyze/control_type.c +46 -29
  58. data/src/analyze/herb_directives.c +16 -20
  59. data/src/analyze/iteration_nodes.c +69 -24
  60. data/src/analyze/parse_errors.c +32 -22
  61. data/src/analyze/postfix_conditionals.c +23 -13
  62. data/src/analyze/prism_annotate.c +56 -32
  63. data/src/analyze/render_nodes.c +51 -41
  64. data/src/analyze/strict_locals.c +14 -15
  65. data/src/analyze/ternary_conditionals.c +14 -10
  66. data/src/ast/ast_nodes.c +3 -1
  67. data/src/ast/ast_pretty_print.c +5 -1
  68. data/src/extract.c +204 -143
  69. data/src/herb.c +10 -8
  70. data/src/include/analyze/action_view/tag_helper_handler.h +1 -1
  71. data/src/include/analyze/action_view/tag_helper_node_builders.h +1 -0
  72. data/src/include/analyze/action_view/tag_helpers.h +1 -1
  73. data/src/include/analyze/analyze.h +3 -24
  74. data/src/include/analyze/analyzed_ruby.h +29 -2
  75. data/src/include/analyze/helpers.h +7 -27
  76. data/src/include/ast/ast_nodes.h +2 -1
  77. data/src/include/herb.h +3 -2
  78. data/src/include/lexer/lexer.h +1 -0
  79. data/src/include/parser/parser_options.h +5 -0
  80. data/src/include/prism/herb_prism_node.h +6 -1
  81. data/src/include/prism/prism_context.h +12 -12
  82. data/src/include/prism/prism_helpers.h +30 -0
  83. data/src/include/prism_version.h +11 -0
  84. data/src/include/version.h +1 -1
  85. data/src/lexer.c +32 -0
  86. data/src/parser/parser_helpers.c +1 -2
  87. data/src/parser.c +6 -7
  88. data/src/parser_options_defaults.c +1 -0
  89. data/src/prism/prism_helpers.c +167 -42
  90. data/src/prism/ruby_parser.c +20 -20
  91. data/templates/ext/herb/nodes.c.erb +5 -5
  92. data/templates/ext/herb/parser_options_helpers.c.erb +33 -0
  93. data/templates/java/nodes.c.erb +6 -6
  94. data/templates/java/parser_options_helpers.c.erb +41 -2
  95. data/templates/java/parser_options_helpers.h.erb +2 -1
  96. data/templates/javascript/packages/core/src/nodes.ts.erb +21 -1
  97. data/templates/javascript/packages/node/extension/nodes.cpp.erb +5 -5
  98. data/templates/javascript/packages/node/extension/parser_options_helpers.cpp.erb +34 -2
  99. data/templates/javascript/packages/node/extension/parser_options_helpers.h.erb +1 -1
  100. data/templates/lib/herb/parser_options.rb.erb +1 -1
  101. data/templates/rust/src/ast/nodes.rs.erb +1 -4
  102. data/templates/rust/src/prism/generated_deserialize.rs.erb +90 -44
  103. data/templates/rust/src/prism/generated_prettyprint.rs.erb +18 -27
  104. data/templates/src/analyze/action_view/generated_handlers.c.erb +23 -22
  105. data/templates/src/include/parser/parser_options.h.erb +10 -0
  106. data/templates/src/include/prism_version.h.erb +17 -0
  107. data/templates/src/parser_options_defaults.c.erb +1 -1
  108. data/templates/template.rb +17 -2
  109. data/templates/wasm/nodes.cpp.erb +8 -18
  110. data/templates/wasm/parser_options_helpers.cpp.erb +24 -0
  111. data/vendor/prism/Rakefile +76 -7
  112. data/vendor/prism/config.yml +174 -161
  113. data/vendor/prism/include/prism/arena.h +45 -0
  114. data/vendor/prism/include/prism/arena.hpp +42 -0
  115. data/vendor/prism/include/prism/ast.h +2738 -611
  116. data/vendor/prism/include/prism/ast.hpp +641 -0
  117. data/vendor/prism/include/prism/buffer.h +60 -0
  118. data/vendor/prism/include/prism/buffer.hpp +55 -0
  119. data/vendor/prism/include/prism/comments.h +72 -0
  120. data/vendor/prism/include/prism/compiler/accel.h +26 -0
  121. data/vendor/prism/include/prism/compiler/align.h +36 -0
  122. data/vendor/prism/include/prism/compiler/assume.h +25 -0
  123. data/vendor/prism/include/prism/compiler/branch.h +26 -0
  124. data/vendor/prism/include/prism/compiler/bswap.h +46 -0
  125. data/vendor/prism/include/prism/compiler/cplusplus.hpp +16 -0
  126. data/vendor/prism/include/prism/compiler/endianness.h +34 -0
  127. data/vendor/prism/include/prism/compiler/exceptions.hpp +17 -0
  128. data/vendor/prism/include/prism/compiler/exported.h +24 -0
  129. data/vendor/prism/include/prism/compiler/fallthrough.h +22 -0
  130. data/vendor/prism/include/prism/compiler/filesystem.h +32 -0
  131. data/vendor/prism/include/prism/compiler/flex_array.h +19 -0
  132. data/vendor/prism/include/prism/compiler/force_inline.h +21 -0
  133. data/vendor/prism/include/prism/compiler/format.h +27 -0
  134. data/vendor/prism/include/prism/compiler/inline.h +17 -0
  135. data/vendor/prism/include/prism/compiler/lifetimebound.hpp +25 -0
  136. data/vendor/prism/include/prism/compiler/nodiscard.h +22 -0
  137. data/vendor/prism/include/prism/compiler/nonnull.h +18 -0
  138. data/vendor/prism/include/prism/compiler/unused.h +18 -0
  139. data/vendor/prism/include/prism/constant_pool.h +106 -0
  140. data/vendor/prism/include/prism/diagnostic.h +55 -402
  141. data/vendor/prism/include/prism/errors_format.h +61 -0
  142. data/vendor/prism/include/prism/excludes.h +29 -0
  143. data/vendor/prism/include/prism/integer.h +41 -0
  144. data/vendor/prism/include/prism/internal/allocator.h +68 -0
  145. data/vendor/prism/include/prism/internal/allocator_debug.h +88 -0
  146. data/vendor/prism/include/prism/internal/arena.h +108 -0
  147. data/vendor/prism/include/prism/internal/bit.h +42 -0
  148. data/vendor/prism/include/prism/internal/buffer.h +94 -0
  149. data/vendor/prism/include/prism/internal/char.h +145 -0
  150. data/vendor/prism/include/prism/internal/comments.h +54 -0
  151. data/vendor/prism/include/prism/internal/constant_pool.h +152 -0
  152. data/vendor/prism/include/prism/internal/diagnostic.h +389 -0
  153. data/vendor/prism/include/prism/{encoding.h → internal/encoding.h} +27 -68
  154. data/vendor/prism/include/prism/internal/integer.h +68 -0
  155. data/vendor/prism/include/prism/internal/isinf.h +16 -0
  156. data/vendor/prism/include/prism/internal/line_offset_list.h +34 -0
  157. data/vendor/prism/include/prism/{util/pm_list.h → internal/list.h} +11 -52
  158. data/vendor/prism/include/prism/internal/magic_comments.h +23 -0
  159. data/vendor/prism/include/prism/internal/memchr.h +15 -0
  160. data/vendor/prism/include/prism/internal/node.h +42 -0
  161. data/vendor/prism/include/prism/internal/options.h +232 -0
  162. data/vendor/prism/include/prism/internal/parser.h +1015 -0
  163. data/vendor/prism/include/prism/internal/regexp.h +26 -0
  164. data/vendor/prism/include/prism/internal/serialize.h +39 -0
  165. data/vendor/prism/include/prism/internal/source.h +72 -0
  166. data/vendor/prism/include/prism/internal/static_literals.h +60 -0
  167. data/vendor/prism/include/prism/internal/stringy.h +30 -0
  168. data/vendor/prism/include/prism/{util/pm_strncasecmp.h → internal/strncasecmp.h} +3 -17
  169. data/vendor/prism/include/prism/{util/pm_strpbrk.h → internal/strpbrk.h} +7 -20
  170. data/vendor/prism/include/prism/internal/tokens.h +11 -0
  171. data/vendor/prism/include/prism/internal/xxh3.h +16 -0
  172. data/vendor/prism/include/prism/json.h +40 -0
  173. data/vendor/prism/include/prism/line_offset_list.h +69 -0
  174. data/vendor/prism/include/prism/magic_comments.h +53 -0
  175. data/vendor/prism/include/prism/node.h +59 -49
  176. data/vendor/prism/include/prism/node.hpp +272 -0
  177. data/vendor/prism/include/prism/node_type.hpp +38 -0
  178. data/vendor/prism/include/prism/options.h +154 -279
  179. data/vendor/prism/include/prism/options.hpp +43 -0
  180. data/vendor/prism/include/prism/parser.h +367 -870
  181. data/vendor/prism/include/prism/parser.hpp +274 -0
  182. data/vendor/prism/include/prism/prettyprint.h +14 -9
  183. data/vendor/prism/include/prism/serialize.h +123 -0
  184. data/vendor/prism/include/prism/source.h +163 -0
  185. data/vendor/prism/include/prism/stream.h +36 -0
  186. data/vendor/prism/include/prism/string_query.h +82 -0
  187. data/vendor/prism/include/prism/stringy.h +61 -0
  188. data/vendor/prism/include/prism/stringy.hpp +31 -0
  189. data/vendor/prism/include/prism/version.h +20 -3
  190. data/vendor/prism/include/prism.h +35 -320
  191. data/vendor/prism/include/prism.hpp +24 -0
  192. data/vendor/prism/src/arena.c +122 -0
  193. data/vendor/prism/src/{util/pm_buffer.c → buffer.c} +53 -21
  194. data/vendor/prism/src/{util/pm_char.c → char.c} +28 -57
  195. data/vendor/prism/src/comments.c +455 -0
  196. data/vendor/prism/src/constant_pool.c +406 -0
  197. data/vendor/prism/src/diagnostic.c +120 -68
  198. data/vendor/prism/src/encoding.c +8 -3
  199. data/vendor/prism/src/errors_format.c +519 -0
  200. data/vendor/prism/src/{util/pm_integer.c → integer.c} +38 -22
  201. data/vendor/prism/src/json.c +5733 -0
  202. data/vendor/prism/src/line_offset_list.c +100 -0
  203. data/vendor/prism/src/list.c +24 -0
  204. data/vendor/prism/src/{util/pm_memchr.c → memchr.c} +8 -6
  205. data/vendor/prism/src/node.c +3465 -7787
  206. data/vendor/prism/src/options.c +161 -54
  207. data/vendor/prism/src/parser.c +371 -0
  208. data/vendor/prism/src/prettyprint.c +421 -354
  209. data/vendor/prism/src/prism.c +8522 -7280
  210. data/vendor/prism/src/regexp.c +960 -45
  211. data/vendor/prism/src/serialize.c +2434 -2048
  212. data/vendor/prism/src/source.c +524 -0
  213. data/vendor/prism/src/static_literals.c +303 -360
  214. data/vendor/prism/src/string_query.c +180 -0
  215. data/vendor/prism/src/stringy.c +61 -0
  216. data/vendor/prism/src/{util/pm_strncasecmp.c → strncasecmp.c} +5 -4
  217. data/vendor/prism/src/strpbrk.c +447 -0
  218. data/vendor/prism/src/{token_type.c → tokens.c} +39 -18
  219. data/vendor/prism/src/xxh3.c +292 -0
  220. data/vendor/prism/templates/ext/prism/api_node.c.erb +58 -44
  221. data/vendor/prism/templates/include/prism/ast.h.erb +67 -17
  222. data/vendor/prism/templates/include/prism/ast.hpp.erb +31 -0
  223. data/vendor/prism/templates/include/prism/internal/diagnostic.h.erb +60 -0
  224. data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/AbstractNodeVisitor.java.erb +1 -1
  225. data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/Loader.java.erb +232 -133
  226. data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/Nodes.java.erb +62 -23
  227. data/vendor/prism/templates/javascript/src/deserialize.js.erb +153 -146
  228. data/vendor/prism/templates/javascript/src/nodes.js.erb +4 -9
  229. data/vendor/prism/templates/lib/prism/compiler.rb.erb +14 -5
  230. data/vendor/prism/templates/lib/prism/dispatcher.rb.erb +20 -12
  231. data/vendor/prism/templates/lib/prism/dot_visitor.rb.erb +37 -11
  232. data/vendor/prism/templates/lib/prism/dsl.rb.erb +43 -4
  233. data/vendor/prism/templates/lib/prism/inspect_visitor.rb.erb +26 -10
  234. data/vendor/prism/templates/lib/prism/mutation_compiler.rb.erb +5 -2
  235. data/vendor/prism/templates/lib/prism/node.rb.erb +283 -105
  236. data/vendor/prism/templates/lib/prism/reflection.rb.erb +11 -2
  237. data/vendor/prism/templates/lib/prism/serialize.rb.erb +291 -134
  238. data/vendor/prism/templates/lib/prism/visitor.rb.erb +18 -0
  239. data/vendor/prism/templates/src/diagnostic.c.erb +114 -63
  240. data/vendor/prism/templates/src/json.c.erb +130 -0
  241. data/vendor/prism/templates/src/node.c.erb +79 -236
  242. data/vendor/prism/templates/src/prettyprint.c.erb +24 -13
  243. data/vendor/prism/templates/src/serialize.c.erb +369 -183
  244. data/vendor/prism/templates/src/{token_type.c.erb → tokens.c.erb} +22 -11
  245. data/vendor/prism/templates/template.rb +193 -91
  246. metadata +100 -42
  247. data/vendor/prism/include/prism/defines.h +0 -260
  248. data/vendor/prism/include/prism/pack.h +0 -163
  249. data/vendor/prism/include/prism/regexp.h +0 -43
  250. data/vendor/prism/include/prism/static_literals.h +0 -121
  251. data/vendor/prism/include/prism/util/pm_buffer.h +0 -236
  252. data/vendor/prism/include/prism/util/pm_char.h +0 -204
  253. data/vendor/prism/include/prism/util/pm_constant_pool.h +0 -218
  254. data/vendor/prism/include/prism/util/pm_integer.h +0 -130
  255. data/vendor/prism/include/prism/util/pm_memchr.h +0 -29
  256. data/vendor/prism/include/prism/util/pm_newline_list.h +0 -113
  257. data/vendor/prism/include/prism/util/pm_string.h +0 -200
  258. data/vendor/prism/src/pack.c +0 -509
  259. data/vendor/prism/src/util/pm_constant_pool.c +0 -342
  260. data/vendor/prism/src/util/pm_list.c +0 -49
  261. data/vendor/prism/src/util/pm_newline_list.c +0 -125
  262. data/vendor/prism/src/util/pm_string.c +0 -381
  263. data/vendor/prism/src/util/pm_strpbrk.c +0 -206
  264. data/vendor/prism/templates/include/prism/diagnostic.h.erb +0 -130
  265. data/vendor/prism/templates/rbi/prism/dsl.rbi.erb +0 -68
  266. data/vendor/prism/templates/rbi/prism/node.rbi.erb +0 -167
  267. data/vendor/prism/templates/rbi/prism/visitor.rbi.erb +0 -18
  268. data/vendor/prism/templates/sig/prism/_private/dot_visitor.rbs.erb +0 -45
  269. data/vendor/prism/templates/sig/prism/dsl.rbs.erb +0 -31
  270. data/vendor/prism/templates/sig/prism/mutation_compiler.rbs.erb +0 -7
  271. data/vendor/prism/templates/sig/prism/node.rbs.erb +0 -136
  272. data/vendor/prism/templates/sig/prism/visitor.rbs.erb +0 -17
  273. data/vendor/prism/templates/sig/prism.rbs.erb +0 -92
@@ -66,6 +66,7 @@ module Herb
66
66
  COVERED = "@_herb_covered" #: String
67
67
  OCCURRENCES = "@_herb_region_occurrences" #: String
68
68
  OCCURRENCE = "_herb_occurrence" #: String
69
+ POSITION = "__herb_position" #: String
69
70
  NAME_ATTRIBUTE = "data-herb-name" #: String
70
71
  KEY_ATTRIBUTE = "herb-key" #: String
71
72
 
@@ -109,6 +110,15 @@ module Herb
109
110
 
110
111
  #: () -> bool
111
112
  def interpolated? = Types.interpolated?(type)
113
+
114
+ #: () -> bool
115
+ def positional? = type == :collection && key_expression.nil?
116
+
117
+ #: () -> String
118
+ def position_variable = "#{POSITION}#{index}"
119
+
120
+ #: () -> String?
121
+ def item_key = positional? ? "#{position_variable} += 1" : key_expression
112
122
  end
113
123
 
114
124
  #: (String) -> bool
@@ -1202,6 +1212,11 @@ module Herb
1202
1212
  )
1203
1213
  end
1204
1214
 
1215
+ #: (Array[untyped], Integer) -> String
1216
+ def attribute_spacing(children, position)
1217
+ position.positive? && children[position - 1].is_a?(Herb::AST::WhitespaceNode) ? "" : " "
1218
+ end
1219
+
1205
1220
  private
1206
1221
 
1207
1222
  def visit_children_with_paths(children)
@@ -1212,6 +1227,7 @@ module Herb
1212
1227
  @states.check_state_assignment(child)
1213
1228
 
1214
1229
  @path.push(index)
1230
+ record_slot(child, :child) if child.is_a?(Herb::AST::RubyLiteralNode)
1215
1231
  visit(child)
1216
1232
  @path.pop
1217
1233
  end
@@ -1521,7 +1537,7 @@ module Herb
1521
1537
  def convert_helper_boolean_attribute(node)
1522
1538
  open_tag = @current_open_tag
1523
1539
 
1524
- return nil unless @in_open_tag && open_tag.is_a?(Herb::AST::ERBOpenTagNode)
1540
+ return nil unless @in_open_tag && (open_tag.is_a?(Herb::AST::ERBOpenTagNode) || open_tag.is_a?(Herb::AST::HTMLOpenTagNode))
1525
1541
  return nil if continuation?(node)
1526
1542
  return nil unless node.respond_to?(:subsequent) && node.subsequent.nil?
1527
1543
 
@@ -1540,7 +1556,7 @@ module Herb
1540
1556
  return nil unless name && Herb::HTML::Util.boolean_attribute?(name)
1541
1557
 
1542
1558
  condition = @states.condition_expression(node)
1543
- replacement = erb_output_node(%[(" #{name}" if #{condition})])
1559
+ replacement = erb_output_node(%[("#{attribute_spacing(children, position)}#{name}" if #{condition})])
1544
1560
 
1545
1561
  children[position] = replacement
1546
1562
  record_slot(replacement, :attribute)
@@ -1864,23 +1880,27 @@ module Herb
1864
1880
  outputs.fetch(0).content&.value&.strip
1865
1881
  end
1866
1882
 
1867
- def insert_markers(node)
1883
+ #: (untyped, ?Symbol) -> untyped
1884
+ def insert_markers(node, namespace = :html)
1868
1885
  anchored = content_anchor_index(node)
1886
+ namespace = Markers.namespace_within(namespace, node.tag_name&.value&.downcase.to_s) if node.is_a?(Herb::AST::HTMLElementNode)
1869
1887
 
1870
- each_child_array(node) do |array|
1888
+ each_child_array(node, namespace) do |array|
1871
1889
  index = 0
1872
1890
 
1873
1891
  while index < array.size
1874
1892
  child = array[index]
1875
1893
  slot_index = @standing[child]&.survivor&.index
1876
1894
 
1877
- insert_markers(child)
1878
- wrap_items(child, slot_index)
1879
- mark_branches(child, slot_index)
1895
+ insert_markers(child, namespace)
1896
+ wrap_items(child, slot_index, namespace)
1897
+ mark_branches(child, slot_index, namespace)
1898
+
1899
+ index += insert_position_counter(array, index, slot_index)
1880
1900
 
1881
1901
  if slot_index && slot_index != anchored
1882
1902
  if @slots[slot_index].type == :keyed
1883
- park_keyed(slot_index, child)
1903
+ park_keyed(slot_index, child, namespace)
1884
1904
 
1885
1905
  array.insert(
1886
1906
  index,
@@ -1921,27 +1941,29 @@ module Herb
1921
1941
  annotation.index
1922
1942
  end
1923
1943
 
1924
- #: (untyped, Integer?) -> void
1925
- def mark_branches(node, slot_index)
1944
+ #: (untyped, Integer?, ?Symbol) -> void
1945
+ def mark_branches(node, slot_index, namespace = :html)
1926
1946
  return unless slot_index
1927
1947
  return unless @slots[slot_index].type == :conditional
1928
1948
 
1929
1949
  branch_bodies(node).each_with_index do |body, branch_index|
1930
- body.unshift(text_node(@markers.branch(slot_index, branch_index)))
1950
+ marker = @markers.branch(slot_index, branch_index)
1951
+
1952
+ park_branch(@markers.statics_key(slot_index, branch_index), marker, body, namespace)
1931
1953
 
1932
- park_branch(@markers.statics_key(slot_index, branch_index), body)
1954
+ body.unshift(text_node(marker))
1933
1955
  end
1934
1956
  end
1935
1957
 
1936
- #: (String, Array[untyped]) -> void
1937
- def park_branch(key, body)
1958
+ #: (String, String, Array[untyped], Symbol) -> void
1959
+ def park_branch(key, marker, body, namespace)
1938
1960
  statics = @statics
1939
1961
  return unless statics
1940
1962
 
1941
1963
  markup = Statics.new(@standing).markup(body)
1942
1964
  return unless markup
1943
1965
 
1944
- statics[key] = markup
1966
+ statics[key] = "#{marker}#{@markers.foreign(markup, namespace)}"
1945
1967
  end
1946
1968
 
1947
1969
  #: (Herb::AST::DocumentNode) -> void
@@ -2062,12 +2084,23 @@ module Herb
2062
2084
  bodies
2063
2085
  end
2064
2086
 
2065
- #: (Herb::AST::Node, Integer?) -> void
2066
- def wrap_items(node, slot_index)
2087
+ #: (Array[untyped], Integer, Integer?) -> Integer
2088
+ def insert_position_counter(array, index, slot_index)
2089
+ slot = slot_index ? @slots[slot_index] : nil
2090
+
2091
+ return 0 unless slot&.positional?
2092
+
2093
+ array.insert(index, erb_code_node("#{slot.position_variable} = -1"))
2094
+
2095
+ 1
2096
+ end
2097
+
2098
+ #: (Herb::AST::Node, Integer?, ?Symbol) -> void
2099
+ def wrap_items(node, slot_index, namespace = :html)
2067
2100
  return unless slot_index
2068
2101
 
2069
2102
  slot = @slots[slot_index]
2070
- return unless slot.type == :collection && slot.key_expression
2103
+ return unless slot.type == :collection
2071
2104
 
2072
2105
  BRANCH_BODY_PROPERTIES.each do |property|
2073
2106
  next unless node.respond_to?(property)
@@ -2076,17 +2109,22 @@ module Herb
2076
2109
  next unless body.is_a?(Array) && !body.empty?
2077
2110
 
2078
2111
  key = @markers.item_statics_key(slot_index)
2079
- parked = park_item(key, body)
2112
+ parked = park_item(key, body, namespace)
2080
2113
 
2081
2114
  body.unshift(
2082
2115
  text_node(@markers.item_open_prefix(slot_index)),
2083
- erb_code_node("#{@bufvar} << ::Herb::Engine.raw((#{slot.key_expression}).to_s)"),
2084
- text_node(@markers.item_open_suffix)
2116
+ erb_code_node("#{@bufvar} << ::Herb::Engine.raw((#{slot.item_key}).to_s)"),
2117
+ text_node(@markers.item_open_suffix),
2118
+ erb_code_node("begin")
2085
2119
  )
2086
2120
 
2087
2121
  body.insert(3, erb_code_node(%(#{COVERED}[#{covered_key(key).inspect}] = true))) if parked && client?
2088
2122
 
2089
- body.push(text_node(@markers.item_close(slot_index)))
2123
+ body.push(
2124
+ erb_code_node("ensure"),
2125
+ text_node(@markers.item_close(slot_index)),
2126
+ erb_code_node("end")
2127
+ )
2090
2128
  end
2091
2129
  end
2092
2130
 
@@ -2112,19 +2150,19 @@ module Herb
2112
2150
  segments.size > 1 ? segments : nil
2113
2151
  end
2114
2152
 
2115
- #: (Integer, untyped) -> void
2116
- def park_keyed(slot_index, element)
2153
+ #: (Integer, untyped, Symbol) -> void
2154
+ def park_keyed(slot_index, element, namespace)
2117
2155
  statics = @statics
2118
2156
  return unless statics
2119
2157
 
2120
2158
  markup = Statics.new(@standing).markup([element.open_tag, *element.body, element.close_tag].compact)
2121
2159
  return unless markup
2122
2160
 
2123
- statics[@markers.item_statics_key(slot_index)] = "#{@markers.branch(slot_index, Markers::ITEM_STATICS)}#{markup}"
2161
+ statics[@markers.item_statics_key(slot_index)] = "#{@markers.branch(slot_index, Markers::ITEM_STATICS)}#{@markers.foreign(markup, namespace)}"
2124
2162
  end
2125
2163
 
2126
- #: (untyped, untyped) -> Array[untyped]?
2127
- def park_item(key, body)
2164
+ #: (untyped, untyped, Symbol) -> Array[untyped]?
2165
+ def park_item(key, body, namespace)
2128
2166
  statics = @statics
2129
2167
  return unless statics
2130
2168
 
@@ -2132,13 +2170,14 @@ module Herb
2132
2170
  markup = Statics.new(@standing).markup(body)
2133
2171
  return unless markup
2134
2172
 
2135
- statics[key] = [
2136
- @markers.branch(slot_index, Markers::ITEM_STATICS),
2173
+ item = [
2137
2174
  @markers.item_open_prefix(slot_index),
2138
2175
  @markers.item_open_suffix,
2139
2176
  markup,
2140
2177
  @markers.item_close(slot_index)
2141
2178
  ].join
2179
+
2180
+ statics[key] = "#{@markers.branch(slot_index, Markers::ITEM_STATICS)}#{@markers.foreign(item, namespace)}"
2142
2181
  end
2143
2182
 
2144
2183
  def anchor_attributes(node, content_index = nil)
@@ -2173,8 +2212,8 @@ module Herb
2173
2212
  name
2174
2213
  end
2175
2214
 
2176
- #: (Herb::AST::Node) { (Array[untyped]) -> void } -> void
2177
- def each_child_array(node)
2215
+ #: (Herb::AST::Node, ?Symbol) { (Array[untyped]) -> void } -> void
2216
+ def each_child_array(node, namespace = :html)
2178
2217
  BRANCH_BODY_PROPERTIES.each do |property|
2179
2218
  next unless node.respond_to?(property)
2180
2219
 
@@ -2186,7 +2225,7 @@ module Herb
2186
2225
  next unless node.respond_to?(property)
2187
2226
 
2188
2227
  child = node.send(property)
2189
- insert_markers(child) if child
2228
+ insert_markers(child, namespace) if child
2190
2229
  end
2191
2230
  end
2192
2231
 
@@ -140,6 +140,8 @@ module Herb
140
140
 
141
141
  instrument(node)
142
142
 
143
+ return [node] if literal?(node)
144
+
143
145
  if framed?(node)
144
146
  [enter_node(node), node, leave_node(node)]
145
147
  elsif erb_outputs?(node)
@@ -158,6 +160,12 @@ module Herb
158
160
  replacement
159
161
  end
160
162
 
163
+ def literal?(node)
164
+ return false unless node.respond_to?(:tag_opening) && node.tag_opening
165
+
166
+ erb_escaped?(node.tag_opening.value)
167
+ end
168
+
161
169
  def framed?(node)
162
170
  return true if node.is_a?(Herb::AST::ERBRenderNode)
163
171
 
@@ -197,9 +205,9 @@ module Herb
197
205
  body = code(node)
198
206
  call = captured?(node) ? "output" : "at"
199
207
 
200
- return erb_node(node, "<%=", "#{SESSION}.#{call}(#{position(node)}) {\n#{body}\n}") if spans_lines?(body)
208
+ return rewrapped(node, "#{SESSION}.#{call}(#{position(node)}) {\n#{body}\n}") if spans_lines?(body)
201
209
 
202
- erb_node(node, "<%=", "#{SESSION}.#{call}(#{position(node)}) { #{body} }")
210
+ rewrapped(node, "#{SESSION}.#{call}(#{position(node)}) { #{body} }")
203
211
  end
204
212
 
205
213
  def captured?(node)
@@ -221,10 +229,10 @@ module Herb
221
229
  body = code(node)
222
230
 
223
231
  if spans_lines?(body)
224
- return erb_node(node, "<%", "#{SESSION}.enter(#{position(node)}); begin\n#{body}\nensure; #{SESSION}.leave; end")
232
+ return rewrapped(node, "#{SESSION}.enter(#{position(node)}); begin\n#{body}\nensure; #{SESSION}.leave; end")
225
233
  end
226
234
 
227
- erb_node(node, "<%", "#{SESSION}.enter(#{position(node)}); begin; #{body}; ensure; #{SESSION}.leave; end")
235
+ rewrapped(node, "#{SESSION}.enter(#{position(node)}); begin; #{body}; ensure; #{SESSION}.leave; end")
228
236
  end
229
237
 
230
238
  #: (String) -> bool
@@ -276,11 +284,15 @@ module Herb
276
284
  node.content&.value.to_s.strip
277
285
  end
278
286
 
279
- def erb_node(node, opening, code)
287
+ def rewrapped(node, code)
288
+ erb_node(node, node.tag_opening.value, code, closing: node.tag_closing&.value || "%>")
289
+ end
290
+
291
+ def erb_node(node, opening, code, closing: "%>")
280
292
  Herb::AST::ERBContentNode.build(
281
293
  tag_opening: Herb::Token.from("TOKEN_ERB_START", opening),
282
294
  content: Herb::Token.from("TOKEN_ERB_CONTENT", " #{code} "),
283
- tag_closing: Herb::Token.from("TOKEN_ERB_END", "%>"),
295
+ tag_closing: Herb::Token.from("TOKEN_ERB_END", closing),
284
296
  valid: true,
285
297
  location: node.location
286
298
  )
data/lib/herb/engine.rb CHANGED
@@ -220,8 +220,6 @@ module Herb
220
220
  @src << "\n" << code
221
221
  @src << "\n" unless code.end_with?("\n")
222
222
  else
223
- @src.chomp! if @src.end_with?("\n") && code.start_with?(" ") && !code.end_with?("\n")
224
-
225
223
  @src << " " unless code.match?(/\A\n+\z/)
226
224
  @src << code
227
225
 
@@ -19,6 +19,7 @@ module Herb
19
19
  attr_reader :prism_nodes_deep #: bool
20
20
  attr_reader :prism_program #: bool
21
21
  attr_reader :render_nodes #: bool
22
+ attr_reader :ruby_version #: String?
22
23
  attr_reader :strict #: bool
23
24
  attr_reader :strict_locals #: bool
24
25
  attr_reader :timeout #: Numeric
@@ -45,8 +46,8 @@ module Herb
45
46
  DEFAULT_TRACK_WHITESPACE = false #: bool
46
47
  DEFAULT_TRANSFORM_CONDITIONALS = false #: bool
47
48
 
48
- #: (?action_view_helpers: bool, ?analyze: bool, ?arena_stats: bool, ?dot_notation_tags: bool, ?erb_openers: Array[String], ?herb_directives: bool, ?html: bool, ?iteration_nodes: bool, ?max_errors: Integer?, ?prism_nodes: bool, ?prism_nodes_deep: bool, ?prism_program: bool, ?render_nodes: bool, ?strict: bool, ?strict_locals: bool, ?timeout: Numeric, ?track_locations: bool, ?track_whitespace: bool, ?transform_conditionals: bool) -> void
49
- def initialize(action_view_helpers: DEFAULT_ACTION_VIEW_HELPERS, analyze: DEFAULT_ANALYZE, arena_stats: DEFAULT_CAPTURE_ARENA_STATS, dot_notation_tags: DEFAULT_DOT_NOTATION_TAGS, erb_openers: [], herb_directives: DEFAULT_HERB_DIRECTIVES, html: DEFAULT_HTML, iteration_nodes: DEFAULT_ITERATION_NODES, max_errors: DEFAULT_MAX_ERRORS, prism_nodes: DEFAULT_PRISM_NODES, prism_nodes_deep: DEFAULT_PRISM_NODES_DEEP, prism_program: DEFAULT_PRISM_PROGRAM, render_nodes: DEFAULT_RENDER_NODES, strict: DEFAULT_STRICT, strict_locals: DEFAULT_STRICT_LOCALS, timeout: DEFAULT_TIMEOUT, track_locations: DEFAULT_TRACK_LOCATIONS, track_whitespace: DEFAULT_TRACK_WHITESPACE, transform_conditionals: DEFAULT_TRANSFORM_CONDITIONALS)
49
+ #: (?action_view_helpers: bool, ?analyze: bool, ?arena_stats: bool, ?dot_notation_tags: bool, ?erb_openers: Array[String], ?herb_directives: bool, ?html: bool, ?iteration_nodes: bool, ?max_errors: Integer?, ?prism_nodes: bool, ?prism_nodes_deep: bool, ?prism_program: bool, ?render_nodes: bool, ?ruby_version: String?, ?strict: bool, ?strict_locals: bool, ?timeout: Numeric, ?track_locations: bool, ?track_whitespace: bool, ?transform_conditionals: bool) -> void
50
+ def initialize(action_view_helpers: DEFAULT_ACTION_VIEW_HELPERS, analyze: DEFAULT_ANALYZE, arena_stats: DEFAULT_CAPTURE_ARENA_STATS, dot_notation_tags: DEFAULT_DOT_NOTATION_TAGS, erb_openers: [], herb_directives: DEFAULT_HERB_DIRECTIVES, html: DEFAULT_HTML, iteration_nodes: DEFAULT_ITERATION_NODES, max_errors: DEFAULT_MAX_ERRORS, prism_nodes: DEFAULT_PRISM_NODES, prism_nodes_deep: DEFAULT_PRISM_NODES_DEEP, prism_program: DEFAULT_PRISM_PROGRAM, render_nodes: DEFAULT_RENDER_NODES, ruby_version: "4.0", strict: DEFAULT_STRICT, strict_locals: DEFAULT_STRICT_LOCALS, timeout: DEFAULT_TIMEOUT, track_locations: DEFAULT_TRACK_LOCATIONS, track_whitespace: DEFAULT_TRACK_WHITESPACE, transform_conditionals: DEFAULT_TRANSFORM_CONDITIONALS)
50
51
  @action_view_helpers = action_view_helpers
51
52
  @analyze = analyze
52
53
  @arena_stats = arena_stats
@@ -60,6 +61,7 @@ module Herb
60
61
  @prism_nodes_deep = prism_nodes_deep
61
62
  @prism_program = prism_program
62
63
  @render_nodes = render_nodes
64
+ @ruby_version = ruby_version
63
65
  @strict = strict
64
66
  @strict_locals = strict_locals
65
67
  @timeout = timeout
@@ -68,7 +70,7 @@ module Herb
68
70
  @transform_conditionals = transform_conditionals
69
71
  end
70
72
 
71
- #: () -> Hash[Symbol, (bool | Numeric | Array[String] | nil)]
73
+ #: () -> Hash[Symbol, (bool | Numeric | String | Array[String] | nil)]
72
74
  def to_h
73
75
  {
74
76
  action_view_helpers: @action_view_helpers,
@@ -84,6 +86,7 @@ module Herb
84
86
  prism_nodes_deep: @prism_nodes_deep,
85
87
  prism_program: @prism_program,
86
88
  render_nodes: @render_nodes,
89
+ ruby_version: @ruby_version,
87
90
  strict: @strict,
88
91
  strict_locals: @strict_locals,
89
92
  timeout: @timeout,
data/lib/herb/project.rb CHANGED
@@ -332,7 +332,7 @@ module Herb
332
332
  return unless issue_type[:key] == :invalid_ruby && file_content
333
333
 
334
334
  begin
335
- engine = Herb::Engine.new(file_content, filename: file_path, escape: true, visitors: [])
335
+ engine = Herb::Engine.new(file_content, filename: file_path, escape: true, parser_options: engine_parser_options, visitors: [])
336
336
  puts ""
337
337
  puts "**Compiled Ruby:**"
338
338
  puts "```ruby"
@@ -345,6 +345,16 @@ module Herb
345
345
 
346
346
  private
347
347
 
348
+ #: () -> Hash[Symbol, untyped]
349
+ def parser_options
350
+ @parser_options ||= configuration.parser_options
351
+ end
352
+
353
+ #: () -> Hash[Symbol, untyped]
354
+ def engine_parser_options
355
+ @engine_parser_options ||= configuration.engine_option("parser_options", {}).transform_keys(&:to_sym).merge(parser_options)
356
+ end
357
+
348
358
  def process_file(file_path)
349
359
  isolate ? process_file_isolated(file_path) : process_file_direct(file_path)
350
360
  end
@@ -362,7 +372,7 @@ module Herb
362
372
  end
363
373
 
364
374
  Timeout.timeout(file_timeout) do
365
- parse_result = Herb.parse(file_content)
375
+ parse_result = Herb.parse(file_content, **parser_options)
366
376
 
367
377
  if parse_result.failed?
368
378
  result[:file_content] = file_content
@@ -401,7 +411,7 @@ module Herb
401
411
  $stderr.reopen(stderr_file.path, "w")
402
412
 
403
413
  begin
404
- parse_result = Herb.parse(file_content)
414
+ parse_result = Herb.parse(file_content, **parser_options)
405
415
  exit!(parse_result.failed? ? 2 : 0)
406
416
  rescue StandardError => e
407
417
  warn "Ruby exception: #{e.class}: #{e.message}"
@@ -457,7 +467,7 @@ module Herb
457
467
  end
458
468
 
459
469
  def classify_parse_errors(file_path, file_content)
460
- default_result = Herb.parse(file_content)
470
+ default_result = Herb.parse(file_content, **parser_options)
461
471
 
462
472
  diagnostics = if default_result.respond_to?(:errors) && default_result.errors.any?
463
473
  default_result.errors.map do |error|
@@ -470,8 +480,8 @@ module Herb
470
480
  end
471
481
  end
472
482
 
473
- no_strict_result = Herb.parse(file_content, strict: false)
474
- no_analyze_result = Herb.parse(file_content, analyze: false)
483
+ no_strict_result = Herb.parse(file_content, **parser_options, strict: false)
484
+ no_analyze_result = Herb.parse(file_content, **parser_options, analyze: false)
475
485
 
476
486
  if no_strict_result.success?
477
487
  { status: :strict_parse_error, diagnostics: diagnostics,
@@ -496,6 +506,7 @@ module Herb
496
506
  file_content,
497
507
  filename: file_path,
498
508
  escape: true,
509
+ parser_options: engine_parser_options,
499
510
  validate_ruby: validate_ruby,
500
511
  visitors: Herb::Engine::Validators.all
501
512
  )
@@ -514,7 +525,7 @@ module Herb
514
525
 
515
526
  # Retry without validators
516
527
  begin
517
- Herb::Engine.new(file_content, filename: file_path, escape: true, visitors: [], validate_ruby: validate_ruby)
528
+ Herb::Engine.new(file_content, filename: file_path, escape: true, parser_options: engine_parser_options, visitors: [], validate_ruby: validate_ruby)
518
529
  error_name = e.is_a?(Herb::Engine::SecurityError) ? "SecurityError" : "ValidationError"
519
530
  return { status: :validation_error, file_content: file_content,
520
531
  compilation_error: compilation_error,
@@ -526,7 +537,7 @@ module Herb
526
537
 
527
538
  # Retry without strict mode
528
539
  begin
529
- Herb::Engine.new(file_content, filename: file_path, escape: true, strict: false, validate_ruby: validate_ruby)
540
+ Herb::Engine.new(file_content, filename: file_path, escape: true, parser_options: engine_parser_options, strict: false, validate_ruby: validate_ruby)
530
541
  return { status: :strict_compilation_failed, file_content: file_content,
531
542
  compilation_error: compilation_error,
532
543
  diagnostics: [{ name: "CompilationError", message: "#{e.message} (strict mode)" }],
data/lib/herb/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # typed: true
3
3
 
4
4
  module Herb
5
- VERSION = "0.11.0"
5
+ VERSION = "0.11.2"
6
6
  end
data/lib/herb.rb CHANGED
@@ -67,7 +67,7 @@ rescue LoadError => e
67
67
  end
68
68
 
69
69
  module Herb
70
- #: (String input, ?track_whitespace: bool, ?track_locations: bool, ?analyze: bool, ?strict: bool, ?action_view_helpers: bool, ?transform_conditionals: bool, ?dot_notation_tags: bool, ?render_nodes: bool, ?strict_locals: bool, ?herb_directives: bool, ?iteration_nodes: bool, ?prism_nodes: bool, ?prism_nodes_deep: bool, ?prism_program: bool, ?html: bool, ?erb_openers: Array[String], ?arena_stats: bool) -> ParseResult
70
+ #: (String input, ?track_whitespace: bool, ?track_locations: bool, ?analyze: bool, ?strict: bool, ?action_view_helpers: bool, ?transform_conditionals: bool, ?dot_notation_tags: bool, ?render_nodes: bool, ?strict_locals: bool, ?herb_directives: bool, ?iteration_nodes: bool, ?prism_nodes: bool, ?prism_nodes_deep: bool, ?prism_program: bool, ?html: bool, ?erb_openers: Array[String], ?ruby_version: String?, ?arena_stats: bool) -> ParseResult
71
71
  def self.parse(...)
72
72
  Backend.parse(...)
73
73
  end
@@ -5,6 +5,8 @@ module Herb
5
5
  module PartialResolution
6
6
  PARTIAL_PREFIX: String
7
7
 
8
+ VARIANT_SEPARATOR: String
9
+
8
10
  EXTENSIONS: Array[String]
9
11
 
10
12
  EXTENSION_ALTERNATIVES: String
@@ -41,6 +43,12 @@ module Herb
41
43
  # : (Array[String]) -> Array[String]
42
44
  def self.by_precedence: (Array[String]) -> Array[String]
43
45
 
46
+ # : (String?) -> String?
47
+ def self.template_variant: (String?) -> String?
48
+
49
+ # : (Array[String], String?) -> String?
50
+ def self.preferred_for: (Array[String], String?) -> String?
51
+
44
52
  # : (String, String | Pathname) -> String?
45
53
  def self.template_name_for: (String, String | Pathname) -> String?
46
54
 
@@ -2133,6 +2133,7 @@ module Herb
2133
2133
  # | tag_opening: Herb::Token?,
2134
2134
  # | content: Herb::Token?,
2135
2135
  # | tag_closing: Herb::Token?,
2136
+ # | prism_node: String?,
2136
2137
  # | }
2137
2138
  class ERBYieldNode < Node
2138
2139
  include Colors
@@ -2143,14 +2144,19 @@ module Herb
2143
2144
 
2144
2145
  attr_reader tag_closing: Herb::Token?
2145
2146
 
2146
- # : (String, Location, Array[Herb::Errors::Error], Herb::Token?, Herb::Token?, Herb::Token?) -> void
2147
- def initialize: (String, Location, Array[Herb::Errors::Error], Herb::Token?, Herb::Token?, Herb::Token?) -> void
2147
+ attr_reader prism_node: String?
2148
+
2149
+ # : (String, Location, Array[Herb::Errors::Error], Herb::Token?, Herb::Token?, Herb::Token?, String?) -> void
2150
+ def initialize: (String, Location, Array[Herb::Errors::Error], Herb::Token?, Herb::Token?, Herb::Token?, String?) -> void
2148
2151
 
2149
2152
  # : () -> String
2150
2153
  def self.type: () -> String
2151
2154
 
2152
- # : (?tag_opening: Herb::Token?, ?content: Herb::Token?, ?tag_closing: Herb::Token?, ?location: Location, ?errors: Array[Herb::Errors::Error]) -> ERBYieldNode
2153
- def self.build: (?tag_opening: Herb::Token?, ?content: Herb::Token?, ?tag_closing: Herb::Token?, ?location: Location, ?errors: Array[Herb::Errors::Error]) -> ERBYieldNode
2155
+ # : (?tag_opening: Herb::Token?, ?content: Herb::Token?, ?tag_closing: Herb::Token?, ?prism_node: String?, ?location: Location, ?errors: Array[Herb::Errors::Error]) -> ERBYieldNode
2156
+ def self.build: (?tag_opening: Herb::Token?, ?content: Herb::Token?, ?tag_closing: Herb::Token?, ?prism_node: String?, ?location: Location, ?errors: Array[Herb::Errors::Error]) -> ERBYieldNode
2157
+
2158
+ # : () -> Prism::node?
2159
+ def deserialized_prism_node: () -> Prism::node?
2154
2160
 
2155
2161
  # : () -> serialized_erb_yield_node
2156
2162
  def to_hash: () -> serialized_erb_yield_node
@@ -26,6 +26,8 @@ module Herb
26
26
 
27
27
  def self.find_prism_as_bundler_sibling: () -> untyped
28
28
 
29
+ def self.prism_source?: (untyped path) -> untyped
30
+
29
31
  def self.find_prism_from_gem_spec: () -> untyped
30
32
  end
31
33
  end
@@ -57,6 +57,9 @@ module Herb
57
57
  # : () -> Array[String]
58
58
  def erb_openers: () -> Array[String]
59
59
 
60
+ # : () -> String?
61
+ def ruby_version: () -> String?
62
+
60
63
  # : () -> Hash[Symbol, untyped]
61
64
  def parser_options: () -> Hash[Symbol, untyped]
62
65
 
@@ -36,6 +36,9 @@ module Herb
36
36
  # : () -> bool
37
37
  def interactive?: () -> bool
38
38
 
39
+ # : () -> bool
40
+ def process_manager?: () -> bool
41
+
39
42
  # : (String) -> void
40
43
  def terminal: (String) -> void
41
44
 
@@ -65,6 +65,8 @@ module Herb
65
65
 
66
66
  def visit_erb_comment_node: (untyped node) -> untyped
67
67
 
68
+ def visit_erb_strict_locals_node: (untyped node) -> untyped
69
+
68
70
  def visit_erb_control_node: (untyped node) ?{ (?) -> untyped } -> untyped
69
71
 
70
72
  def visit_erb_if_node: (untyped node) -> untyped
@@ -105,9 +107,9 @@ module Herb
105
107
 
106
108
  def visit_erb_block_end_node: (untyped node, ?escaped: untyped) -> untyped
107
109
 
108
- def case_parts: (untyped node) -> untyped
110
+ def visit_erb_case_parts: (untyped node) -> untyped
109
111
 
110
- def visit_erb_control_with_parts: (untyped node, *untyped parts) -> untyped
112
+ def visit_erb_control_with_parts: (untyped node, *untyped parts) ?{ (?) -> untyped } -> untyped
111
113
 
112
114
  private
113
115
 
@@ -188,7 +190,7 @@ module Herb
188
190
 
189
191
  def leading_space_follows_newline?: () -> untyped
190
192
 
191
- def preceding_text_ends_with_newline?: () -> untyped
193
+ def preceding_token_value_ends_with_newline?: () -> untyped
192
194
 
193
195
  def extract_and_remove_leading_space!: () -> untyped
194
196
 
@@ -205,6 +207,15 @@ module Herb
205
207
  # : (bool) -> void
206
208
  def settle_pending_trim_newline!: (bool) -> void
207
209
 
210
+ # : (Array[untyped]) -> void
211
+ def skip_case_children: (Array[untyped]) -> void
212
+
213
+ # : (untyped) -> bool
214
+ def follows_trimmed_statement_tag?: (untyped) -> bool
215
+
216
+ # : () -> void
217
+ def drop_pending_trim_newline!: () -> void
218
+
208
219
  def save_pending_leading_whitespace!: (untyped whitespace) -> untyped
209
220
 
210
221
  def restore_pending_leading_whitespace!: () -> untyped