herb 0.8.10-arm-linux-gnu → 0.9.0-arm-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 (209) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +11 -3
  3. data/README.md +64 -34
  4. data/Rakefile +48 -40
  5. data/config.yml +317 -34
  6. data/ext/herb/error_helpers.c +367 -140
  7. data/ext/herb/error_helpers.h +1 -0
  8. data/ext/herb/extconf.rb +67 -28
  9. data/ext/herb/extension.c +317 -51
  10. data/ext/herb/extension.h +1 -0
  11. data/ext/herb/extension_helpers.c +23 -14
  12. data/ext/herb/extension_helpers.h +2 -2
  13. data/ext/herb/nodes.c +537 -270
  14. data/ext/herb/nodes.h +1 -0
  15. data/herb.gemspec +3 -2
  16. data/lib/herb/3.0/herb.so +0 -0
  17. data/lib/herb/3.1/herb.so +0 -0
  18. data/lib/herb/3.2/herb.so +0 -0
  19. data/lib/herb/3.3/herb.so +0 -0
  20. data/lib/herb/3.4/herb.so +0 -0
  21. data/lib/herb/4.0/herb.so +0 -0
  22. data/lib/herb/ast/helpers.rb +3 -3
  23. data/lib/herb/ast/node.rb +15 -2
  24. data/lib/herb/ast/nodes.rb +1132 -157
  25. data/lib/herb/bootstrap.rb +87 -0
  26. data/lib/herb/cli.rb +341 -31
  27. data/lib/herb/configuration.rb +248 -0
  28. data/lib/herb/defaults.yml +32 -0
  29. data/lib/herb/engine/compiler.rb +78 -11
  30. data/lib/herb/engine/debug_visitor.rb +13 -3
  31. data/lib/herb/engine/error_formatter.rb +13 -9
  32. data/lib/herb/engine/parser_error_overlay.rb +10 -6
  33. data/lib/herb/engine/validator.rb +8 -3
  34. data/lib/herb/engine/validators/nesting_validator.rb +2 -2
  35. data/lib/herb/engine.rb +82 -35
  36. data/lib/herb/errors.rb +563 -88
  37. data/lib/herb/lex_result.rb +1 -0
  38. data/lib/herb/location.rb +7 -3
  39. data/lib/herb/parse_result.rb +12 -2
  40. data/lib/herb/parser_options.rb +57 -0
  41. data/lib/herb/position.rb +1 -0
  42. data/lib/herb/prism_inspect.rb +116 -0
  43. data/lib/herb/project.rb +923 -331
  44. data/lib/herb/range.rb +1 -0
  45. data/lib/herb/token.rb +7 -1
  46. data/lib/herb/version.rb +1 -1
  47. data/lib/herb/visitor.rb +37 -2
  48. data/lib/herb/warnings.rb +6 -1
  49. data/lib/herb.rb +35 -3
  50. data/sig/herb/ast/helpers.rbs +2 -2
  51. data/sig/herb/ast/node.rbs +12 -2
  52. data/sig/herb/ast/nodes.rbs +641 -128
  53. data/sig/herb/bootstrap.rbs +31 -0
  54. data/sig/herb/configuration.rbs +89 -0
  55. data/sig/herb/engine/compiler.rbs +9 -1
  56. data/sig/herb/engine/debug_visitor.rbs +2 -0
  57. data/sig/herb/engine/validator.rbs +5 -1
  58. data/sig/herb/engine.rbs +17 -3
  59. data/sig/herb/errors.rbs +258 -63
  60. data/sig/herb/location.rbs +4 -0
  61. data/sig/herb/parse_result.rbs +4 -2
  62. data/sig/herb/parser_options.rbs +42 -0
  63. data/sig/herb/position.rbs +1 -0
  64. data/sig/herb/prism_inspect.rbs +28 -0
  65. data/sig/herb/range.rbs +1 -0
  66. data/sig/herb/token.rbs +6 -0
  67. data/sig/herb/visitor.rbs +25 -4
  68. data/sig/herb/warnings.rbs +6 -1
  69. data/sig/herb.rbs +14 -0
  70. data/sig/herb_c_extension.rbs +5 -2
  71. data/sig/serialized_ast_errors.rbs +54 -6
  72. data/sig/serialized_ast_nodes.rbs +60 -6
  73. data/src/analyze/action_view/attribute_extraction_helpers.c +290 -0
  74. data/src/analyze/action_view/content_tag.c +70 -0
  75. data/src/analyze/action_view/link_to.c +143 -0
  76. data/src/analyze/action_view/registry.c +60 -0
  77. data/src/analyze/action_view/tag.c +64 -0
  78. data/src/analyze/action_view/tag_helper_node_builders.c +305 -0
  79. data/src/analyze/action_view/tag_helpers.c +748 -0
  80. data/src/analyze/action_view/turbo_frame_tag.c +88 -0
  81. data/src/analyze/analyze.c +882 -0
  82. data/src/{analyzed_ruby.c → analyze/analyzed_ruby.c} +13 -11
  83. data/src/analyze/builders.c +343 -0
  84. data/src/analyze/conditional_elements.c +594 -0
  85. data/src/analyze/conditional_open_tags.c +640 -0
  86. data/src/analyze/control_type.c +250 -0
  87. data/src/{analyze_helpers.c → analyze/helpers.c} +48 -23
  88. data/src/analyze/invalid_structures.c +193 -0
  89. data/src/{analyze_missing_end.c → analyze/missing_end.c} +33 -22
  90. data/src/analyze/parse_errors.c +84 -0
  91. data/src/analyze/prism_annotate.c +397 -0
  92. data/src/{analyze_transform.c → analyze/transform.c} +17 -3
  93. data/src/ast_node.c +17 -7
  94. data/src/ast_nodes.c +662 -387
  95. data/src/ast_pretty_print.c +190 -6
  96. data/src/errors.c +1076 -520
  97. data/src/extract.c +145 -49
  98. data/src/herb.c +52 -34
  99. data/src/html_util.c +241 -12
  100. data/src/include/analyze/action_view/attribute_extraction_helpers.h +36 -0
  101. data/src/include/analyze/action_view/tag_helper_handler.h +41 -0
  102. data/src/include/analyze/action_view/tag_helper_node_builders.h +70 -0
  103. data/src/include/analyze/action_view/tag_helpers.h +38 -0
  104. data/src/include/{analyze.h → analyze/analyze.h} +14 -4
  105. data/src/include/{analyzed_ruby.h → analyze/analyzed_ruby.h} +3 -3
  106. data/src/include/analyze/builders.h +27 -0
  107. data/src/include/analyze/conditional_elements.h +9 -0
  108. data/src/include/analyze/conditional_open_tags.h +9 -0
  109. data/src/include/analyze/control_type.h +14 -0
  110. data/src/include/{analyze_helpers.h → analyze/helpers.h} +4 -2
  111. data/src/include/analyze/invalid_structures.h +11 -0
  112. data/src/include/analyze/prism_annotate.h +16 -0
  113. data/src/include/ast_node.h +11 -5
  114. data/src/include/ast_nodes.h +117 -38
  115. data/src/include/ast_pretty_print.h +5 -0
  116. data/src/include/element_source.h +3 -8
  117. data/src/include/errors.h +148 -55
  118. data/src/include/extract.h +21 -5
  119. data/src/include/herb.h +18 -6
  120. data/src/include/herb_prism_node.h +13 -0
  121. data/src/include/html_util.h +7 -2
  122. data/src/include/io.h +3 -1
  123. data/src/include/lex_helpers.h +29 -0
  124. data/src/include/lexer.h +1 -1
  125. data/src/include/lexer_peek_helpers.h +87 -13
  126. data/src/include/lexer_struct.h +2 -0
  127. data/src/include/location.h +2 -1
  128. data/src/include/parser.h +27 -2
  129. data/src/include/parser_helpers.h +19 -3
  130. data/src/include/pretty_print.h +10 -5
  131. data/src/include/prism_context.h +45 -0
  132. data/src/include/prism_helpers.h +10 -7
  133. data/src/include/prism_serialized.h +12 -0
  134. data/src/include/token.h +16 -4
  135. data/src/include/token_struct.h +10 -3
  136. data/src/include/utf8.h +2 -1
  137. data/src/include/util/hb_allocator.h +78 -0
  138. data/src/include/util/hb_arena.h +6 -1
  139. data/src/include/util/hb_arena_debug.h +12 -1
  140. data/src/include/util/hb_array.h +7 -3
  141. data/src/include/util/hb_buffer.h +6 -4
  142. data/src/include/util/hb_foreach.h +79 -0
  143. data/src/include/util/hb_narray.h +8 -4
  144. data/src/include/util/hb_string.h +56 -9
  145. data/src/include/util.h +6 -3
  146. data/src/include/version.h +1 -1
  147. data/src/io.c +3 -2
  148. data/src/lexer.c +42 -30
  149. data/src/lexer_peek_helpers.c +12 -74
  150. data/src/location.c +2 -2
  151. data/src/main.c +53 -28
  152. data/src/parser.c +783 -247
  153. data/src/parser_helpers.c +110 -23
  154. data/src/parser_match_tags.c +109 -48
  155. data/src/pretty_print.c +29 -24
  156. data/src/prism_helpers.c +30 -27
  157. data/src/ruby_parser.c +2 -0
  158. data/src/token.c +151 -66
  159. data/src/token_matchers.c +0 -1
  160. data/src/utf8.c +7 -6
  161. data/src/util/hb_allocator.c +341 -0
  162. data/src/util/hb_arena.c +81 -56
  163. data/src/util/hb_arena_debug.c +32 -17
  164. data/src/util/hb_array.c +30 -15
  165. data/src/util/hb_buffer.c +17 -21
  166. data/src/util/hb_narray.c +22 -7
  167. data/src/util/hb_string.c +49 -35
  168. data/src/util.c +21 -11
  169. data/src/visitor.c +47 -0
  170. data/templates/ext/herb/error_helpers.c.erb +24 -11
  171. data/templates/ext/herb/error_helpers.h.erb +1 -0
  172. data/templates/ext/herb/nodes.c.erb +50 -16
  173. data/templates/ext/herb/nodes.h.erb +1 -0
  174. data/templates/java/error_helpers.c.erb +1 -1
  175. data/templates/java/nodes.c.erb +30 -8
  176. data/templates/java/org/herb/ast/Errors.java.erb +24 -1
  177. data/templates/java/org/herb/ast/Nodes.java.erb +80 -21
  178. data/templates/javascript/packages/core/src/errors.ts.erb +16 -3
  179. data/templates/javascript/packages/core/src/node-type-guards.ts.erb +3 -1
  180. data/templates/javascript/packages/core/src/nodes.ts.erb +109 -32
  181. data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +13 -4
  182. data/templates/javascript/packages/node/extension/nodes.cpp.erb +43 -4
  183. data/templates/lib/herb/ast/nodes.rb.erb +88 -31
  184. data/templates/lib/herb/errors.rb.erb +15 -3
  185. data/templates/lib/herb/visitor.rb.erb +2 -2
  186. data/templates/rust/src/ast/nodes.rs.erb +97 -44
  187. data/templates/rust/src/errors.rs.erb +2 -1
  188. data/templates/rust/src/nodes.rs.erb +167 -15
  189. data/templates/rust/src/union_types.rs.erb +60 -0
  190. data/templates/rust/src/visitor.rs.erb +81 -0
  191. data/templates/src/{analyze_missing_end.c.erb → analyze/missing_end.c.erb} +9 -6
  192. data/templates/src/{analyze_transform.c.erb → analyze/transform.c.erb} +2 -2
  193. data/templates/src/ast_nodes.c.erb +34 -26
  194. data/templates/src/ast_pretty_print.c.erb +24 -5
  195. data/templates/src/errors.c.erb +60 -54
  196. data/templates/src/include/ast_nodes.h.erb +6 -2
  197. data/templates/src/include/ast_pretty_print.h.erb +5 -0
  198. data/templates/src/include/errors.h.erb +15 -11
  199. data/templates/src/include/util/hb_foreach.h.erb +20 -0
  200. data/templates/src/parser_match_tags.c.erb +10 -4
  201. data/templates/src/visitor.c.erb +2 -2
  202. data/templates/template.rb +204 -29
  203. data/templates/wasm/error_helpers.cpp.erb +9 -5
  204. data/templates/wasm/nodes.cpp.erb +41 -4
  205. metadata +57 -16
  206. data/src/analyze.c +0 -1608
  207. data/src/element_source.c +0 -12
  208. data/src/include/util/hb_system.h +0 -9
  209. data/src/util/hb_system.c +0 -30
@@ -4,23 +4,46 @@
4
4
  # NOTE: This file is generated by the templates/template.rb script and should not be
5
5
  # modified manually. See /home/runner/work/herb/herb/templates/lib/herb/ast/nodes.rb.erb
6
6
 
7
+ require_relative "../prism_inspect"
8
+
7
9
  module Herb
8
10
  module AST
11
+ #: type serialized_document_node = {
12
+ #| children: Array[Herb::AST::Node],
13
+ #| prism_context: nil,
14
+ #| prism_node: String?,
15
+ #| }
9
16
  class DocumentNode < Node
10
17
  include Colors
11
18
 
12
19
  attr_reader :children #: Array[Herb::AST::Node]
20
+ attr_reader :prism_context #: nil
21
+ attr_reader :prism_node #: String?
13
22
 
14
- #: (String, Location, Array[Herb::Errors::Error], Array[Herb::AST::Node]) -> void
15
- def initialize(type, location, errors, children)
23
+ #: (String, Location, Array[Herb::Errors::Error], Array[Herb::AST::Node], nil, String) -> void
24
+ def initialize(type, location, errors, children, prism_context, prism_node)
16
25
  super(type, location, errors)
17
26
  @children = children
27
+ @prism_context = prism_context
28
+ @prism_node = prism_node
29
+ end
30
+
31
+ #: () -> Prism::node?
32
+ def deserialized_prism_node
33
+ prism_node = @prism_node
34
+ return nil unless prism_node
35
+ return nil unless source
36
+
37
+ require "prism"
38
+ Prism.load(source, prism_node).value
18
39
  end
19
40
 
20
41
  #: () -> serialized_document_node
21
42
  def to_hash
22
43
  super.merge({
23
44
  children: children,
45
+ prism_context: prism_context,
46
+ prism_node: prism_node,
24
47
  }) #: Herb::serialized_document_node
25
48
  end
26
49
 
@@ -31,7 +54,7 @@ module Herb
31
54
 
32
55
  #: () -> Array[Herb::AST::Node?]
33
56
  def child_nodes
34
- [*children]
57
+ [*(children || [])]
35
58
  end
36
59
 
37
60
  #: () -> Array[Herb::AST::Node]
@@ -59,18 +82,28 @@ module Herb
59
82
 
60
83
  output += inspect_errors(prefix: "│ ")
61
84
 
62
- output += white("└── children: ")
63
- output += inspect_array(children, prefix: " ", indent: indent, depth: depth + 1, depth_limit: depth_limit)
85
+ dynamic_symbol = prism_node ? "├──" : "└──"
86
+ dynamic_prefix = prism_node ? "" : " "
87
+ output += white("#{dynamic_symbol} children: ")
88
+ output += inspect_array(children, prefix: dynamic_prefix, indent: indent, depth: depth + 1, depth_limit: depth_limit)
89
+ if prism_node && source
90
+ output += white("└── prism_node: ")
91
+ output += Herb::PrismInspect.inspect_prism_serialized(prism_node, source, " ")
92
+ output += "\n"
93
+ end
64
94
  output += "\n"
65
95
 
66
96
  output.gsub(/^/, " " * indent)
67
97
  end
68
98
  end
69
99
 
100
+ #: type serialized_literal_node = {
101
+ #| content: String?,
102
+ #| }
70
103
  class LiteralNode < Node
71
104
  include Colors
72
105
 
73
- attr_reader :content #: String
106
+ attr_reader :content #: String?
74
107
 
75
108
  #: (String, Location, Array[Herb::Errors::Error], String) -> void
76
109
  def initialize(type, location, errors, content)
@@ -127,12 +160,19 @@ module Herb
127
160
  end
128
161
  end
129
162
 
163
+ #: type serialized_html_open_tag_node = {
164
+ #| tag_opening: Herb::Token?,
165
+ #| tag_name: Herb::Token?,
166
+ #| tag_closing: Herb::Token?,
167
+ #| children: Array[Herb::AST::Node],
168
+ #| is_void: bool,
169
+ #| }
130
170
  class HTMLOpenTagNode < Node
131
171
  include Colors
132
172
 
133
- attr_reader :tag_opening #: Herb::Token
134
- attr_reader :tag_name #: Herb::Token
135
- attr_reader :tag_closing #: Herb::Token
173
+ attr_reader :tag_opening #: Herb::Token?
174
+ attr_reader :tag_name #: Herb::Token?
175
+ attr_reader :tag_closing #: Herb::Token?
136
176
  attr_reader :children #: Array[Herb::AST::Node]
137
177
  attr_reader :is_void #: bool
138
178
 
@@ -164,7 +204,7 @@ module Herb
164
204
 
165
205
  #: () -> Array[Herb::AST::Node?]
166
206
  def child_nodes
167
- [*children]
207
+ [*(children || [])]
168
208
  end
169
209
 
170
210
  #: () -> Array[Herb::AST::Node]
@@ -212,15 +252,105 @@ module Herb
212
252
  end
213
253
  end
214
254
 
255
+ #: type serialized_html_conditional_open_tag_node = {
256
+ #| conditional: (Herb::AST::ERBIfNode | Herb::AST::ERBUnlessNode)?,
257
+ #| tag_name: Herb::Token?,
258
+ #| is_void: bool,
259
+ #| }
260
+ class HTMLConditionalOpenTagNode < Node
261
+ include Colors
262
+
263
+ attr_reader :conditional #: (Herb::AST::ERBIfNode | Herb::AST::ERBUnlessNode)?
264
+ attr_reader :tag_name #: Herb::Token?
265
+ attr_reader :is_void #: bool
266
+
267
+ #: (String, Location, Array[Herb::Errors::Error], (Herb::AST::ERBIfNode | Herb::AST::ERBUnlessNode), Herb::Token, bool) -> void
268
+ def initialize(type, location, errors, conditional, tag_name, is_void)
269
+ super(type, location, errors)
270
+ @conditional = conditional
271
+ @tag_name = tag_name
272
+ @is_void = is_void
273
+ end
274
+
275
+ #: () -> serialized_html_conditional_open_tag_node
276
+ def to_hash
277
+ super.merge({
278
+ conditional: conditional,
279
+ tag_name: tag_name,
280
+ is_void: is_void,
281
+ }) #: Herb::serialized_html_conditional_open_tag_node
282
+ end
283
+
284
+ #: (Visitor) -> void
285
+ def accept(visitor)
286
+ visitor.visit_html_conditional_open_tag_node(self)
287
+ end
288
+
289
+ #: () -> Array[Herb::AST::Node?]
290
+ def child_nodes
291
+ [conditional]
292
+ end
293
+
294
+ #: () -> Array[Herb::AST::Node]
295
+ def compact_child_nodes
296
+ child_nodes.compact
297
+ end
298
+
299
+ #: () -> String
300
+ def inspect
301
+ tree_inspect.rstrip.gsub(/\s+$/, "")
302
+ end
303
+
304
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
305
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 10)
306
+ output = +""
307
+
308
+ output += white("@ #{bold(yellow(node_name.to_s))} #{dimmed("(location: #{location.tree_inspect})")}")
309
+ output += "\n"
310
+
311
+ if depth >= depth_limit
312
+ output += dimmed("└── [depth limit reached ...]\n\n")
313
+
314
+ return output.gsub(/^/, " " * indent)
315
+ end
316
+
317
+ output += inspect_errors(prefix: "│ ")
318
+
319
+ output += white("├── conditional: ")
320
+ if conditional
321
+ output += "\n"
322
+ output += "│ └── "
323
+ output += conditional.tree_inspect(indent: indent, depth: depth + 1, depth_limit: depth_limit).gsub(/^/, " " * (indent + 1)).lstrip.gsub(/^/, "│ ").delete_prefix("│ ")
324
+ else
325
+ output += magenta("∅\n")
326
+ end
327
+ output += white("├── tag_name: ")
328
+ output += tag_name ? tag_name.tree_inspect : magenta("∅")
329
+ output += "\n"
330
+ output += white("└── is_void: ")
331
+ output += [true, false].include?(is_void) ? bold(magenta(is_void.to_s)) : magenta("∅")
332
+ output += "\n"
333
+ output += "\n"
334
+
335
+ output.gsub(/^/, " " * indent)
336
+ end
337
+ end
338
+
339
+ #: type serialized_html_close_tag_node = {
340
+ #| tag_opening: Herb::Token?,
341
+ #| tag_name: Herb::Token?,
342
+ #| children: Array[Herb::AST::WhitespaceNode]?,
343
+ #| tag_closing: Herb::Token?,
344
+ #| }
215
345
  class HTMLCloseTagNode < Node
216
346
  include Colors
217
347
 
218
- attr_reader :tag_opening #: Herb::Token
219
- attr_reader :tag_name #: Herb::Token
220
- attr_reader :children #: Array[Herb::AST::Node]
221
- attr_reader :tag_closing #: Herb::Token
348
+ attr_reader :tag_opening #: Herb::Token?
349
+ attr_reader :tag_name #: Herb::Token?
350
+ attr_reader :children #: Array[Herb::AST::WhitespaceNode]?
351
+ attr_reader :tag_closing #: Herb::Token?
222
352
 
223
- #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Array[Herb::AST::Node], Herb::Token) -> void
353
+ #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Array[Herb::AST::WhitespaceNode], Herb::Token) -> void
224
354
  def initialize(type, location, errors, tag_opening, tag_name, children, tag_closing)
225
355
  super(type, location, errors)
226
356
  @tag_opening = tag_opening
@@ -246,7 +376,7 @@ module Herb
246
376
 
247
377
  #: () -> Array[Herb::AST::Node?]
248
378
  def child_nodes
249
- [*children]
379
+ [*(children || [])]
250
380
  end
251
381
 
252
382
  #: () -> Array[Herb::AST::Node]
@@ -291,25 +421,163 @@ module Herb
291
421
  end
292
422
  end
293
423
 
424
+ #: type serialized_html_omitted_close_tag_node = {
425
+ #| tag_name: Herb::Token?,
426
+ #| }
427
+ class HTMLOmittedCloseTagNode < Node
428
+ include Colors
429
+
430
+ attr_reader :tag_name #: Herb::Token?
431
+
432
+ #: (String, Location, Array[Herb::Errors::Error], Herb::Token) -> void
433
+ def initialize(type, location, errors, tag_name)
434
+ super(type, location, errors)
435
+ @tag_name = tag_name
436
+ end
437
+
438
+ #: () -> serialized_html_omitted_close_tag_node
439
+ def to_hash
440
+ super.merge({
441
+ tag_name: tag_name,
442
+ }) #: Herb::serialized_html_omitted_close_tag_node
443
+ end
444
+
445
+ #: (Visitor) -> void
446
+ def accept(visitor)
447
+ visitor.visit_html_omitted_close_tag_node(self)
448
+ end
449
+
450
+ #: () -> Array[Herb::AST::Node?]
451
+ def child_nodes
452
+ []
453
+ end
454
+
455
+ #: () -> Array[Herb::AST::Node]
456
+ def compact_child_nodes
457
+ child_nodes.compact
458
+ end
459
+
460
+ #: () -> String
461
+ def inspect
462
+ tree_inspect.rstrip.gsub(/\s+$/, "")
463
+ end
464
+
465
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
466
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 10)
467
+ output = +""
468
+
469
+ output += white("@ #{bold(yellow(node_name.to_s))} #{dimmed("(location: #{location.tree_inspect})")}")
470
+ output += "\n"
471
+
472
+ if depth >= depth_limit
473
+ output += dimmed("└── [depth limit reached ...]\n\n")
474
+
475
+ return output.gsub(/^/, " " * indent)
476
+ end
477
+
478
+ output += inspect_errors(prefix: "│ ")
479
+
480
+ output += white("└── tag_name: ")
481
+ output += tag_name ? tag_name.tree_inspect : magenta("∅")
482
+ output += "\n"
483
+ output += "\n"
484
+
485
+ output.gsub(/^/, " " * indent)
486
+ end
487
+ end
488
+
489
+ #: type serialized_html_virtual_close_tag_node = {
490
+ #| tag_name: Herb::Token?,
491
+ #| }
492
+ class HTMLVirtualCloseTagNode < Node
493
+ include Colors
494
+
495
+ attr_reader :tag_name #: Herb::Token?
496
+
497
+ #: (String, Location, Array[Herb::Errors::Error], Herb::Token) -> void
498
+ def initialize(type, location, errors, tag_name)
499
+ super(type, location, errors)
500
+ @tag_name = tag_name
501
+ end
502
+
503
+ #: () -> serialized_html_virtual_close_tag_node
504
+ def to_hash
505
+ super.merge({
506
+ tag_name: tag_name,
507
+ }) #: Herb::serialized_html_virtual_close_tag_node
508
+ end
509
+
510
+ #: (Visitor) -> void
511
+ def accept(visitor)
512
+ visitor.visit_html_virtual_close_tag_node(self)
513
+ end
514
+
515
+ #: () -> Array[Herb::AST::Node?]
516
+ def child_nodes
517
+ []
518
+ end
519
+
520
+ #: () -> Array[Herb::AST::Node]
521
+ def compact_child_nodes
522
+ child_nodes.compact
523
+ end
524
+
525
+ #: () -> String
526
+ def inspect
527
+ tree_inspect.rstrip.gsub(/\s+$/, "")
528
+ end
529
+
530
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
531
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 10)
532
+ output = +""
533
+
534
+ output += white("@ #{bold(yellow(node_name.to_s))} #{dimmed("(location: #{location.tree_inspect})")}")
535
+ output += "\n"
536
+
537
+ if depth >= depth_limit
538
+ output += dimmed("└── [depth limit reached ...]\n\n")
539
+
540
+ return output.gsub(/^/, " " * indent)
541
+ end
542
+
543
+ output += inspect_errors(prefix: "│ ")
544
+
545
+ output += white("└── tag_name: ")
546
+ output += tag_name ? tag_name.tree_inspect : magenta("∅")
547
+ output += "\n"
548
+ output += "\n"
549
+
550
+ output.gsub(/^/, " " * indent)
551
+ end
552
+ end
553
+
554
+ #: type serialized_html_element_node = {
555
+ #| open_tag: (Herb::AST::HTMLOpenTagNode | Herb::AST::HTMLConditionalOpenTagNode | Herb::AST::ERBOpenTagNode)?,
556
+ #| tag_name: Herb::Token?,
557
+ #| body: Array[Herb::AST::Node],
558
+ #| close_tag: (Herb::AST::HTMLCloseTagNode | Herb::AST::HTMLOmittedCloseTagNode | Herb::AST::HTMLVirtualCloseTagNode | Herb::AST::ERBEndNode)?,
559
+ #| is_void: bool,
560
+ #| element_source: String?,
561
+ #| }
294
562
  class HTMLElementNode < Node
295
563
  include Colors
296
564
 
297
- attr_reader :open_tag #: Herb::AST::HTMLOpenTagNode
298
- attr_reader :tag_name #: Herb::Token
565
+ attr_reader :open_tag #: (Herb::AST::HTMLOpenTagNode | Herb::AST::HTMLConditionalOpenTagNode | Herb::AST::ERBOpenTagNode)?
566
+ attr_reader :tag_name #: Herb::Token?
299
567
  attr_reader :body #: Array[Herb::AST::Node]
300
- attr_reader :close_tag #: Herb::AST::HTMLCloseTagNode
568
+ attr_reader :close_tag #: (Herb::AST::HTMLCloseTagNode | Herb::AST::HTMLOmittedCloseTagNode | Herb::AST::HTMLVirtualCloseTagNode | Herb::AST::ERBEndNode)?
301
569
  attr_reader :is_void #: bool
302
- attr_reader :source #: String
570
+ attr_reader :element_source #: String?
303
571
 
304
- #: (String, Location, Array[Herb::Errors::Error], Herb::AST::HTMLOpenTagNode, Herb::Token, Array[Herb::AST::Node], Herb::AST::HTMLCloseTagNode, bool, String) -> void
305
- def initialize(type, location, errors, open_tag, tag_name, body, close_tag, is_void, source)
572
+ #: (String, Location, Array[Herb::Errors::Error], (Herb::AST::HTMLOpenTagNode | Herb::AST::HTMLConditionalOpenTagNode | Herb::AST::ERBOpenTagNode), Herb::Token, Array[Herb::AST::Node], (Herb::AST::HTMLCloseTagNode | Herb::AST::HTMLOmittedCloseTagNode | Herb::AST::HTMLVirtualCloseTagNode | Herb::AST::ERBEndNode), bool, String) -> void
573
+ def initialize(type, location, errors, open_tag, tag_name, body, close_tag, is_void, element_source)
306
574
  super(type, location, errors)
307
575
  @open_tag = open_tag
308
576
  @tag_name = tag_name
309
577
  @body = body
310
578
  @close_tag = close_tag
311
579
  @is_void = is_void
312
- @source = source
580
+ @element_source = element_source
313
581
  end
314
582
 
315
583
  #: () -> serialized_html_element_node
@@ -320,7 +588,7 @@ module Herb
320
588
  body: body,
321
589
  close_tag: close_tag,
322
590
  is_void: is_void,
323
- source: source,
591
+ element_source: element_source,
324
592
  }) #: Herb::serialized_html_element_node
325
593
  end
326
594
 
@@ -331,7 +599,7 @@ module Herb
331
599
 
332
600
  #: () -> Array[Herb::AST::Node?]
333
601
  def child_nodes
334
- [open_tag, *body, close_tag]
602
+ [open_tag, *(body || []), close_tag]
335
603
  end
336
604
 
337
605
  #: () -> Array[Herb::AST::Node]
@@ -383,19 +651,154 @@ module Herb
383
651
  output += white("├── is_void: ")
384
652
  output += [true, false].include?(is_void) ? bold(magenta(is_void.to_s)) : magenta("∅")
385
653
  output += "\n"
386
- output += white("└── source: #{green(source.inspect)}\n")
654
+ output += white("└── element_source: #{green(element_source.inspect)}\n")
655
+ output += "\n"
656
+
657
+ output.gsub(/^/, " " * indent)
658
+ end
659
+ end
660
+
661
+ #: type serialized_html_conditional_element_node = {
662
+ #| condition: String?,
663
+ #| open_conditional: (Herb::AST::ERBIfNode | Herb::AST::ERBUnlessNode)?,
664
+ #| open_tag: Herb::AST::HTMLOpenTagNode?,
665
+ #| body: Array[Herb::AST::Node],
666
+ #| close_tag: (Herb::AST::HTMLCloseTagNode | Herb::AST::HTMLOmittedCloseTagNode)?,
667
+ #| close_conditional: (Herb::AST::ERBIfNode | Herb::AST::ERBUnlessNode)?,
668
+ #| tag_name: Herb::Token?,
669
+ #| element_source: String?,
670
+ #| }
671
+ class HTMLConditionalElementNode < Node
672
+ include Colors
673
+
674
+ attr_reader :condition #: String?
675
+ attr_reader :open_conditional #: (Herb::AST::ERBIfNode | Herb::AST::ERBUnlessNode)?
676
+ attr_reader :open_tag #: Herb::AST::HTMLOpenTagNode?
677
+ attr_reader :body #: Array[Herb::AST::Node]
678
+ attr_reader :close_tag #: (Herb::AST::HTMLCloseTagNode | Herb::AST::HTMLOmittedCloseTagNode)?
679
+ attr_reader :close_conditional #: (Herb::AST::ERBIfNode | Herb::AST::ERBUnlessNode)?
680
+ attr_reader :tag_name #: Herb::Token?
681
+ attr_reader :element_source #: String?
682
+
683
+ #: (String, Location, Array[Herb::Errors::Error], String, (Herb::AST::ERBIfNode | Herb::AST::ERBUnlessNode), Herb::AST::HTMLOpenTagNode, Array[Herb::AST::Node], (Herb::AST::HTMLCloseTagNode | Herb::AST::HTMLOmittedCloseTagNode), (Herb::AST::ERBIfNode | Herb::AST::ERBUnlessNode), Herb::Token, String) -> void
684
+ def initialize(type, location, errors, condition, open_conditional, open_tag, body, close_tag, close_conditional, tag_name, element_source)
685
+ super(type, location, errors)
686
+ @condition = condition.force_encoding("utf-8")
687
+ @open_conditional = open_conditional
688
+ @open_tag = open_tag
689
+ @body = body
690
+ @close_tag = close_tag
691
+ @close_conditional = close_conditional
692
+ @tag_name = tag_name
693
+ @element_source = element_source
694
+ end
695
+
696
+ #: () -> serialized_html_conditional_element_node
697
+ def to_hash
698
+ super.merge({
699
+ condition: condition,
700
+ open_conditional: open_conditional,
701
+ open_tag: open_tag,
702
+ body: body,
703
+ close_tag: close_tag,
704
+ close_conditional: close_conditional,
705
+ tag_name: tag_name,
706
+ element_source: element_source,
707
+ }) #: Herb::serialized_html_conditional_element_node
708
+ end
709
+
710
+ #: (Visitor) -> void
711
+ def accept(visitor)
712
+ visitor.visit_html_conditional_element_node(self)
713
+ end
714
+
715
+ #: () -> Array[Herb::AST::Node?]
716
+ def child_nodes
717
+ [open_conditional, open_tag, *(body || []), close_tag, close_conditional]
718
+ end
719
+
720
+ #: () -> Array[Herb::AST::Node]
721
+ def compact_child_nodes
722
+ child_nodes.compact
723
+ end
724
+
725
+ #: () -> String
726
+ def inspect
727
+ tree_inspect.rstrip.gsub(/\s+$/, "")
728
+ end
729
+
730
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
731
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 10)
732
+ output = +""
733
+
734
+ output += white("@ #{bold(yellow(node_name.to_s))} #{dimmed("(location: #{location.tree_inspect})")}")
735
+ output += "\n"
736
+
737
+ if depth >= depth_limit
738
+ output += dimmed("└── [depth limit reached ...]\n\n")
739
+
740
+ return output.gsub(/^/, " " * indent)
741
+ end
742
+
743
+ output += inspect_errors(prefix: "│ ")
744
+
745
+ output += white("├── condition: ") + green("#{condition.inspect}\n")
746
+ output += white("├── open_conditional: ")
747
+ if open_conditional
748
+ output += "\n"
749
+ output += "│ └── "
750
+ output += open_conditional.tree_inspect(indent: indent, depth: depth + 1, depth_limit: depth_limit).gsub(/^/, " " * (indent + 1)).lstrip.gsub(/^/, "│ ").delete_prefix("│ ")
751
+ else
752
+ output += magenta("∅\n")
753
+ end
754
+ output += white("├── open_tag: ")
755
+ if open_tag
756
+ output += "\n"
757
+ output += "│ └── "
758
+ output += open_tag.tree_inspect(indent: indent, depth: depth + 1, depth_limit: depth_limit).gsub(/^/, " " * (indent + 1)).lstrip.gsub(/^/, "│ ").delete_prefix("│ ")
759
+ else
760
+ output += magenta("∅\n")
761
+ end
762
+ output += white("├── body: ")
763
+ output += inspect_array(body, prefix: "│ ", indent: indent, depth: depth + 1, depth_limit: depth_limit)
764
+ output += white("├── close_tag: ")
765
+ if close_tag
766
+ output += "\n"
767
+ output += "│ └── "
768
+ output += close_tag.tree_inspect(indent: indent, depth: depth + 1, depth_limit: depth_limit).gsub(/^/, " " * (indent + 1)).lstrip.gsub(/^/, "│ ").delete_prefix("│ ")
769
+ else
770
+ output += magenta("∅\n")
771
+ end
772
+ output += white("├── close_conditional: ")
773
+ if close_conditional
774
+ output += "\n"
775
+ output += "│ └── "
776
+ output += close_conditional.tree_inspect(indent: indent, depth: depth + 1, depth_limit: depth_limit).gsub(/^/, " " * (indent + 1)).lstrip.gsub(/^/, "│ ").delete_prefix("│ ")
777
+ else
778
+ output += magenta("∅\n")
779
+ end
780
+ output += white("├── tag_name: ")
781
+ output += tag_name ? tag_name.tree_inspect : magenta("∅")
782
+ output += "\n"
783
+ output += white("└── element_source: #{green(element_source.inspect)}\n")
387
784
  output += "\n"
388
785
 
389
786
  output.gsub(/^/, " " * indent)
390
787
  end
391
788
  end
392
789
 
790
+ #: type serialized_html_attribute_value_node = {
791
+ #| open_quote: Herb::Token?,
792
+ #| children: Array[Herb::AST::Node],
793
+ #| close_quote: Herb::Token?,
794
+ #| quoted: bool,
795
+ #| }
393
796
  class HTMLAttributeValueNode < Node
394
797
  include Colors
395
798
 
396
- attr_reader :open_quote #: Herb::Token
799
+ attr_reader :open_quote #: Herb::Token?
397
800
  attr_reader :children #: Array[Herb::AST::Node]
398
- attr_reader :close_quote #: Herb::Token
801
+ attr_reader :close_quote #: Herb::Token?
399
802
  attr_reader :quoted #: bool
400
803
 
401
804
  #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Array[Herb::AST::Node], Herb::Token, bool) -> void
@@ -424,7 +827,7 @@ module Herb
424
827
 
425
828
  #: () -> Array[Herb::AST::Node?]
426
829
  def child_nodes
427
- [*children]
830
+ [*(children || [])]
428
831
  end
429
832
 
430
833
  #: () -> Array[Herb::AST::Node]
@@ -469,12 +872,15 @@ module Herb
469
872
  end
470
873
  end
471
874
 
875
+ #: type serialized_html_attribute_name_node = {
876
+ #| children: Array[(Herb::AST::LiteralNode | Herb::AST::ERBContentNode)]?,
877
+ #| }
472
878
  class HTMLAttributeNameNode < Node
473
879
  include Colors
474
880
 
475
- attr_reader :children #: Array[Herb::AST::Node]
881
+ attr_reader :children #: Array[(Herb::AST::LiteralNode | Herb::AST::ERBContentNode)]?
476
882
 
477
- #: (String, Location, Array[Herb::Errors::Error], Array[Herb::AST::Node]) -> void
883
+ #: (String, Location, Array[Herb::Errors::Error], Array[(Herb::AST::LiteralNode | Herb::AST::ERBContentNode)]) -> void
478
884
  def initialize(type, location, errors, children)
479
885
  super(type, location, errors)
480
886
  @children = children
@@ -494,7 +900,7 @@ module Herb
494
900
 
495
901
  #: () -> Array[Herb::AST::Node?]
496
902
  def child_nodes
497
- [*children]
903
+ [*(children || [])]
498
904
  end
499
905
 
500
906
  #: () -> Array[Herb::AST::Node]
@@ -530,12 +936,17 @@ module Herb
530
936
  end
531
937
  end
532
938
 
939
+ #: type serialized_html_attribute_node = {
940
+ #| name: Herb::AST::HTMLAttributeNameNode?,
941
+ #| equals: Herb::Token?,
942
+ #| value: Herb::AST::HTMLAttributeValueNode?,
943
+ #| }
533
944
  class HTMLAttributeNode < Node
534
945
  include Colors
535
946
 
536
- attr_reader :name #: Herb::AST::HTMLAttributeNameNode
537
- attr_reader :equals #: Herb::Token
538
- attr_reader :value #: Herb::AST::HTMLAttributeValueNode
947
+ attr_reader :name #: Herb::AST::HTMLAttributeNameNode?
948
+ attr_reader :equals #: Herb::Token?
949
+ attr_reader :value #: Herb::AST::HTMLAttributeValueNode?
539
950
 
540
951
  #: (String, Location, Array[Herb::Errors::Error], Herb::AST::HTMLAttributeNameNode, Herb::Token, Herb::AST::HTMLAttributeValueNode) -> void
541
952
  def initialize(type, location, errors, name, equals, value)
@@ -614,10 +1025,236 @@ module Herb
614
1025
  end
615
1026
  end
616
1027
 
1028
+ #: type serialized_ruby_literal_node = {
1029
+ #| content: String?,
1030
+ #| }
1031
+ class RubyLiteralNode < Node
1032
+ include Colors
1033
+
1034
+ attr_reader :content #: String?
1035
+
1036
+ #: (String, Location, Array[Herb::Errors::Error], String) -> void
1037
+ def initialize(type, location, errors, content)
1038
+ super(type, location, errors)
1039
+ @content = content.force_encoding("utf-8")
1040
+ end
1041
+
1042
+ #: () -> serialized_ruby_literal_node
1043
+ def to_hash
1044
+ super.merge({
1045
+ content: content,
1046
+ }) #: Herb::serialized_ruby_literal_node
1047
+ end
1048
+
1049
+ #: (Visitor) -> void
1050
+ def accept(visitor)
1051
+ visitor.visit_ruby_literal_node(self)
1052
+ end
1053
+
1054
+ #: () -> Array[Herb::AST::Node?]
1055
+ def child_nodes
1056
+ []
1057
+ end
1058
+
1059
+ #: () -> Array[Herb::AST::Node]
1060
+ def compact_child_nodes
1061
+ child_nodes.compact
1062
+ end
1063
+
1064
+ #: () -> String
1065
+ def inspect
1066
+ tree_inspect.rstrip.gsub(/\s+$/, "")
1067
+ end
1068
+
1069
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1070
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 10)
1071
+ output = +""
1072
+
1073
+ output += white("@ #{bold(yellow(node_name.to_s))} #{dimmed("(location: #{location.tree_inspect})")}")
1074
+ output += "\n"
1075
+
1076
+ if depth >= depth_limit
1077
+ output += dimmed("└── [depth limit reached ...]\n\n")
1078
+
1079
+ return output.gsub(/^/, " " * indent)
1080
+ end
1081
+
1082
+ output += inspect_errors(prefix: "│ ")
1083
+
1084
+ output += white("└── content: ") + green("#{content.inspect}\n")
1085
+ output += "\n"
1086
+
1087
+ output.gsub(/^/, " " * indent)
1088
+ end
1089
+ end
1090
+
1091
+ #: type serialized_ruby_html_attributes_splat_node = {
1092
+ #| content: String?,
1093
+ #| prefix: String?,
1094
+ #| }
1095
+ class RubyHTMLAttributesSplatNode < Node
1096
+ include Colors
1097
+
1098
+ attr_reader :content #: String?
1099
+ attr_reader :prefix #: String?
1100
+
1101
+ #: (String, Location, Array[Herb::Errors::Error], String, String) -> void
1102
+ def initialize(type, location, errors, content, prefix)
1103
+ super(type, location, errors)
1104
+ @content = content.force_encoding("utf-8")
1105
+ @prefix = prefix.force_encoding("utf-8")
1106
+ end
1107
+
1108
+ #: () -> serialized_ruby_html_attributes_splat_node
1109
+ def to_hash
1110
+ super.merge({
1111
+ content: content,
1112
+ prefix: prefix,
1113
+ }) #: Herb::serialized_ruby_html_attributes_splat_node
1114
+ end
1115
+
1116
+ #: (Visitor) -> void
1117
+ def accept(visitor)
1118
+ visitor.visit_ruby_html_attributes_splat_node(self)
1119
+ end
1120
+
1121
+ #: () -> Array[Herb::AST::Node?]
1122
+ def child_nodes
1123
+ []
1124
+ end
1125
+
1126
+ #: () -> Array[Herb::AST::Node]
1127
+ def compact_child_nodes
1128
+ child_nodes.compact
1129
+ end
1130
+
1131
+ #: () -> String
1132
+ def inspect
1133
+ tree_inspect.rstrip.gsub(/\s+$/, "")
1134
+ end
1135
+
1136
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1137
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 10)
1138
+ output = +""
1139
+
1140
+ output += white("@ #{bold(yellow(node_name.to_s))} #{dimmed("(location: #{location.tree_inspect})")}")
1141
+ output += "\n"
1142
+
1143
+ if depth >= depth_limit
1144
+ output += dimmed("└── [depth limit reached ...]\n\n")
1145
+
1146
+ return output.gsub(/^/, " " * indent)
1147
+ end
1148
+
1149
+ output += inspect_errors(prefix: "│ ")
1150
+
1151
+ output += white("├── content: ") + green("#{content.inspect}\n")
1152
+ output += white("└── prefix: ") + green("#{prefix.inspect}\n")
1153
+ output += "\n"
1154
+
1155
+ output.gsub(/^/, " " * indent)
1156
+ end
1157
+ end
1158
+
1159
+ #: type serialized_erb_open_tag_node = {
1160
+ #| tag_opening: Herb::Token?,
1161
+ #| content: Herb::Token?,
1162
+ #| tag_closing: Herb::Token?,
1163
+ #| tag_name: Herb::Token?,
1164
+ #| children: Array[Herb::AST::Node],
1165
+ #| }
1166
+ class ERBOpenTagNode < Node
1167
+ include Colors
1168
+
1169
+ attr_reader :tag_opening #: Herb::Token?
1170
+ attr_reader :content #: Herb::Token?
1171
+ attr_reader :tag_closing #: Herb::Token?
1172
+ attr_reader :tag_name #: Herb::Token?
1173
+ attr_reader :children #: Array[Herb::AST::Node]
1174
+
1175
+ #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, Herb::Token, Array[Herb::AST::Node]) -> void
1176
+ def initialize(type, location, errors, tag_opening, content, tag_closing, tag_name, children)
1177
+ super(type, location, errors)
1178
+ @tag_opening = tag_opening
1179
+ @content = content
1180
+ @tag_closing = tag_closing
1181
+ @tag_name = tag_name
1182
+ @children = children
1183
+ end
1184
+
1185
+ #: () -> serialized_erb_open_tag_node
1186
+ def to_hash
1187
+ super.merge({
1188
+ tag_opening: tag_opening,
1189
+ content: content,
1190
+ tag_closing: tag_closing,
1191
+ tag_name: tag_name,
1192
+ children: children,
1193
+ }) #: Herb::serialized_erb_open_tag_node
1194
+ end
1195
+
1196
+ #: (Visitor) -> void
1197
+ def accept(visitor)
1198
+ visitor.visit_erb_open_tag_node(self)
1199
+ end
1200
+
1201
+ #: () -> Array[Herb::AST::Node?]
1202
+ def child_nodes
1203
+ [*(children || [])]
1204
+ end
1205
+
1206
+ #: () -> Array[Herb::AST::Node]
1207
+ def compact_child_nodes
1208
+ child_nodes.compact
1209
+ end
1210
+
1211
+ #: () -> String
1212
+ def inspect
1213
+ tree_inspect.rstrip.gsub(/\s+$/, "")
1214
+ end
1215
+
1216
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1217
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 10)
1218
+ output = +""
1219
+
1220
+ output += white("@ #{bold(yellow(node_name.to_s))} #{dimmed("(location: #{location.tree_inspect})")}")
1221
+ output += "\n"
1222
+
1223
+ if depth >= depth_limit
1224
+ output += dimmed("└── [depth limit reached ...]\n\n")
1225
+
1226
+ return output.gsub(/^/, " " * indent)
1227
+ end
1228
+
1229
+ output += inspect_errors(prefix: "│ ")
1230
+
1231
+ output += white("├── tag_opening: ")
1232
+ output += tag_opening ? tag_opening.tree_inspect : magenta("∅")
1233
+ output += "\n"
1234
+ output += white("├── content: ")
1235
+ output += content ? content.tree_inspect : magenta("∅")
1236
+ output += "\n"
1237
+ output += white("├── tag_closing: ")
1238
+ output += tag_closing ? tag_closing.tree_inspect : magenta("∅")
1239
+ output += "\n"
1240
+ output += white("├── tag_name: ")
1241
+ output += tag_name ? tag_name.tree_inspect : magenta("∅")
1242
+ output += "\n"
1243
+ output += white("└── children: ")
1244
+ output += inspect_array(children, prefix: " ", indent: indent, depth: depth + 1, depth_limit: depth_limit)
1245
+ output += "\n"
1246
+
1247
+ output.gsub(/^/, " " * indent)
1248
+ end
1249
+ end
1250
+
1251
+ #: type serialized_html_text_node = {
1252
+ #| content: String?,
1253
+ #| }
617
1254
  class HTMLTextNode < Node
618
1255
  include Colors
619
1256
 
620
- attr_reader :content #: String
1257
+ attr_reader :content #: String?
621
1258
 
622
1259
  #: (String, Location, Array[Herb::Errors::Error], String) -> void
623
1260
  def initialize(type, location, errors, content)
@@ -674,12 +1311,17 @@ module Herb
674
1311
  end
675
1312
  end
676
1313
 
1314
+ #: type serialized_html_comment_node = {
1315
+ #| comment_start: Herb::Token?,
1316
+ #| children: Array[Herb::AST::Node],
1317
+ #| comment_end: Herb::Token?,
1318
+ #| }
677
1319
  class HTMLCommentNode < Node
678
1320
  include Colors
679
1321
 
680
- attr_reader :comment_start #: Herb::Token
1322
+ attr_reader :comment_start #: Herb::Token?
681
1323
  attr_reader :children #: Array[Herb::AST::Node]
682
- attr_reader :comment_end #: Herb::Token
1324
+ attr_reader :comment_end #: Herb::Token?
683
1325
 
684
1326
  #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Array[Herb::AST::Node], Herb::Token) -> void
685
1327
  def initialize(type, location, errors, comment_start, children, comment_end)
@@ -705,7 +1347,7 @@ module Herb
705
1347
 
706
1348
  #: () -> Array[Herb::AST::Node?]
707
1349
  def child_nodes
708
- [*children]
1350
+ [*(children || [])]
709
1351
  end
710
1352
 
711
1353
  #: () -> Array[Herb::AST::Node]
@@ -747,12 +1389,17 @@ module Herb
747
1389
  end
748
1390
  end
749
1391
 
1392
+ #: type serialized_html_doctype_node = {
1393
+ #| tag_opening: Herb::Token?,
1394
+ #| children: Array[Herb::AST::Node],
1395
+ #| tag_closing: Herb::Token?,
1396
+ #| }
750
1397
  class HTMLDoctypeNode < Node
751
1398
  include Colors
752
1399
 
753
- attr_reader :tag_opening #: Herb::Token
1400
+ attr_reader :tag_opening #: Herb::Token?
754
1401
  attr_reader :children #: Array[Herb::AST::Node]
755
- attr_reader :tag_closing #: Herb::Token
1402
+ attr_reader :tag_closing #: Herb::Token?
756
1403
 
757
1404
  #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Array[Herb::AST::Node], Herb::Token) -> void
758
1405
  def initialize(type, location, errors, tag_opening, children, tag_closing)
@@ -778,7 +1425,7 @@ module Herb
778
1425
 
779
1426
  #: () -> Array[Herb::AST::Node?]
780
1427
  def child_nodes
781
- [*children]
1428
+ [*(children || [])]
782
1429
  end
783
1430
 
784
1431
  #: () -> Array[Herb::AST::Node]
@@ -820,12 +1467,17 @@ module Herb
820
1467
  end
821
1468
  end
822
1469
 
1470
+ #: type serialized_xml_declaration_node = {
1471
+ #| tag_opening: Herb::Token?,
1472
+ #| children: Array[Herb::AST::Node],
1473
+ #| tag_closing: Herb::Token?,
1474
+ #| }
823
1475
  class XMLDeclarationNode < Node
824
1476
  include Colors
825
1477
 
826
- attr_reader :tag_opening #: Herb::Token
1478
+ attr_reader :tag_opening #: Herb::Token?
827
1479
  attr_reader :children #: Array[Herb::AST::Node]
828
- attr_reader :tag_closing #: Herb::Token
1480
+ attr_reader :tag_closing #: Herb::Token?
829
1481
 
830
1482
  #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Array[Herb::AST::Node], Herb::Token) -> void
831
1483
  def initialize(type, location, errors, tag_opening, children, tag_closing)
@@ -851,7 +1503,7 @@ module Herb
851
1503
 
852
1504
  #: () -> Array[Herb::AST::Node?]
853
1505
  def child_nodes
854
- [*children]
1506
+ [*(children || [])]
855
1507
  end
856
1508
 
857
1509
  #: () -> Array[Herb::AST::Node]
@@ -893,12 +1545,17 @@ module Herb
893
1545
  end
894
1546
  end
895
1547
 
1548
+ #: type serialized_cdata_node = {
1549
+ #| tag_opening: Herb::Token?,
1550
+ #| children: Array[Herb::AST::Node],
1551
+ #| tag_closing: Herb::Token?,
1552
+ #| }
896
1553
  class CDATANode < Node
897
1554
  include Colors
898
1555
 
899
- attr_reader :tag_opening #: Herb::Token
1556
+ attr_reader :tag_opening #: Herb::Token?
900
1557
  attr_reader :children #: Array[Herb::AST::Node]
901
- attr_reader :tag_closing #: Herb::Token
1558
+ attr_reader :tag_closing #: Herb::Token?
902
1559
 
903
1560
  #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Array[Herb::AST::Node], Herb::Token) -> void
904
1561
  def initialize(type, location, errors, tag_opening, children, tag_closing)
@@ -924,7 +1581,7 @@ module Herb
924
1581
 
925
1582
  #: () -> Array[Herb::AST::Node?]
926
1583
  def child_nodes
927
- [*children]
1584
+ [*(children || [])]
928
1585
  end
929
1586
 
930
1587
  #: () -> Array[Herb::AST::Node]
@@ -966,10 +1623,13 @@ module Herb
966
1623
  end
967
1624
  end
968
1625
 
1626
+ #: type serialized_whitespace_node = {
1627
+ #| value: Herb::Token?,
1628
+ #| }
969
1629
  class WhitespaceNode < Node
970
1630
  include Colors
971
1631
 
972
- attr_reader :value #: Herb::Token
1632
+ attr_reader :value #: Herb::Token?
973
1633
 
974
1634
  #: (String, Location, Array[Herb::Errors::Error], Herb::Token) -> void
975
1635
  def initialize(type, location, errors, value)
@@ -1028,18 +1688,28 @@ module Herb
1028
1688
  end
1029
1689
  end
1030
1690
 
1691
+ #: type serialized_erb_content_node = {
1692
+ #| tag_opening: Herb::Token?,
1693
+ #| content: Herb::Token?,
1694
+ #| tag_closing: Herb::Token?,
1695
+ #| analyzed_ruby: nil,
1696
+ #| parsed: bool,
1697
+ #| valid: bool,
1698
+ #| prism_node: String?,
1699
+ #| }
1031
1700
  class ERBContentNode < Node
1032
1701
  include Colors
1033
1702
 
1034
- attr_reader :tag_opening #: Herb::Token
1035
- attr_reader :content #: Herb::Token
1036
- attr_reader :tag_closing #: Herb::Token
1703
+ attr_reader :tag_opening #: Herb::Token?
1704
+ attr_reader :content #: Herb::Token?
1705
+ attr_reader :tag_closing #: Herb::Token?
1037
1706
  attr_reader :analyzed_ruby #: nil
1038
1707
  attr_reader :parsed #: bool
1039
1708
  attr_reader :valid #: bool
1709
+ attr_reader :prism_node #: String?
1040
1710
 
1041
- #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, nil, bool, bool) -> void
1042
- def initialize(type, location, errors, tag_opening, content, tag_closing, analyzed_ruby, parsed, valid)
1711
+ #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, nil, bool, bool, String) -> void
1712
+ def initialize(type, location, errors, tag_opening, content, tag_closing, analyzed_ruby, parsed, valid, prism_node)
1043
1713
  super(type, location, errors)
1044
1714
  @tag_opening = tag_opening
1045
1715
  @content = content
@@ -1047,6 +1717,17 @@ module Herb
1047
1717
  @analyzed_ruby = analyzed_ruby
1048
1718
  @parsed = parsed
1049
1719
  @valid = valid
1720
+ @prism_node = prism_node
1721
+ end
1722
+
1723
+ #: () -> Prism::node?
1724
+ def deserialized_prism_node
1725
+ prism_node = @prism_node
1726
+ return nil unless prism_node
1727
+ return nil unless source
1728
+
1729
+ require "prism"
1730
+ Prism.load(source, prism_node).value
1050
1731
  end
1051
1732
 
1052
1733
  #: () -> serialized_erb_content_node
@@ -1058,6 +1739,7 @@ module Herb
1058
1739
  analyzed_ruby: analyzed_ruby,
1059
1740
  parsed: parsed,
1060
1741
  valid: valid,
1742
+ prism_node: prism_node,
1061
1743
  }) #: Herb::serialized_erb_content_node
1062
1744
  end
1063
1745
 
@@ -1105,25 +1787,35 @@ module Herb
1105
1787
  output += white("├── tag_closing: ")
1106
1788
  output += tag_closing ? tag_closing.tree_inspect : magenta("∅")
1107
1789
  output += "\n"
1108
- # no-op for analyzed_ruby
1109
1790
  output += white("├── parsed: ")
1110
1791
  output += [true, false].include?(parsed) ? bold(magenta(parsed.to_s)) : magenta("∅")
1111
1792
  output += "\n"
1112
- output += white("└── valid: ")
1793
+ dynamic_symbol = prism_node ? "├──" : "└──"
1794
+ output += white("#{dynamic_symbol} valid: ")
1113
1795
  output += [true, false].include?(valid) ? bold(magenta(valid.to_s)) : magenta("∅")
1114
1796
  output += "\n"
1797
+ if prism_node && source
1798
+ output += white("└── prism_node: ")
1799
+ output += Herb::PrismInspect.inspect_prism_serialized(prism_node, source, " ")
1800
+ output += "\n"
1801
+ end
1115
1802
  output += "\n"
1116
1803
 
1117
1804
  output.gsub(/^/, " " * indent)
1118
1805
  end
1119
1806
  end
1120
1807
 
1808
+ #: type serialized_erb_end_node = {
1809
+ #| tag_opening: Herb::Token?,
1810
+ #| content: Herb::Token?,
1811
+ #| tag_closing: Herb::Token?,
1812
+ #| }
1121
1813
  class ERBEndNode < Node
1122
1814
  include Colors
1123
1815
 
1124
- attr_reader :tag_opening #: Herb::Token
1125
- attr_reader :content #: Herb::Token
1126
- attr_reader :tag_closing #: Herb::Token
1816
+ attr_reader :tag_opening #: Herb::Token?
1817
+ attr_reader :content #: Herb::Token?
1818
+ attr_reader :tag_closing #: Herb::Token?
1127
1819
 
1128
1820
  #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token) -> void
1129
1821
  def initialize(type, location, errors, tag_opening, content, tag_closing)
@@ -1192,12 +1884,18 @@ module Herb
1192
1884
  end
1193
1885
  end
1194
1886
 
1887
+ #: type serialized_erb_else_node = {
1888
+ #| tag_opening: Herb::Token?,
1889
+ #| content: Herb::Token?,
1890
+ #| tag_closing: Herb::Token?,
1891
+ #| statements: Array[Herb::AST::Node],
1892
+ #| }
1195
1893
  class ERBElseNode < Node
1196
1894
  include Colors
1197
1895
 
1198
- attr_reader :tag_opening #: Herb::Token
1199
- attr_reader :content #: Herb::Token
1200
- attr_reader :tag_closing #: Herb::Token
1896
+ attr_reader :tag_opening #: Herb::Token?
1897
+ attr_reader :content #: Herb::Token?
1898
+ attr_reader :tag_closing #: Herb::Token?
1201
1899
  attr_reader :statements #: Array[Herb::AST::Node]
1202
1900
 
1203
1901
  #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, Array[Herb::AST::Node]) -> void
@@ -1226,7 +1924,7 @@ module Herb
1226
1924
 
1227
1925
  #: () -> Array[Herb::AST::Node?]
1228
1926
  def child_nodes
1229
- [*statements]
1927
+ [*(statements || [])]
1230
1928
  end
1231
1929
 
1232
1930
  #: () -> Array[Herb::AST::Node]
@@ -1271,29 +1969,51 @@ module Herb
1271
1969
  end
1272
1970
  end
1273
1971
 
1972
+ #: type serialized_erb_if_node = {
1973
+ #| tag_opening: Herb::Token?,
1974
+ #| content: Herb::Token?,
1975
+ #| tag_closing: Herb::Token?,
1976
+ #| then_keyword: Herb::Location?,
1977
+ #| prism_node: String?,
1978
+ #| statements: Array[Herb::AST::Node],
1979
+ #| subsequent: (Herb::AST::ERBIfNode | Herb::AST::ERBElseNode)?,
1980
+ #| end_node: Herb::AST::ERBEndNode?,
1981
+ #| }
1274
1982
  class ERBIfNode < Node
1275
1983
  include Colors
1276
1984
 
1277
- attr_reader :tag_opening #: Herb::Token
1278
- attr_reader :content #: Herb::Token
1279
- attr_reader :tag_closing #: Herb::Token
1280
- attr_reader :then_keyword #: Herb::Location
1985
+ attr_reader :tag_opening #: Herb::Token?
1986
+ attr_reader :content #: Herb::Token?
1987
+ attr_reader :tag_closing #: Herb::Token?
1988
+ attr_reader :then_keyword #: Herb::Location?
1989
+ attr_reader :prism_node #: String?
1281
1990
  attr_reader :statements #: Array[Herb::AST::Node]
1282
- attr_reader :subsequent #: Herb::AST::Node
1283
- attr_reader :end_node #: Herb::AST::ERBEndNode
1991
+ attr_reader :subsequent #: (Herb::AST::ERBIfNode | Herb::AST::ERBElseNode)?
1992
+ attr_reader :end_node #: Herb::AST::ERBEndNode?
1284
1993
 
1285
- #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, Herb::Location, Array[Herb::AST::Node], Herb::AST::Node, Herb::AST::ERBEndNode) -> void
1286
- def initialize(type, location, errors, tag_opening, content, tag_closing, then_keyword, statements, subsequent, end_node)
1994
+ #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, Herb::Location, String, Array[Herb::AST::Node], (Herb::AST::ERBIfNode | Herb::AST::ERBElseNode), Herb::AST::ERBEndNode) -> void
1995
+ def initialize(type, location, errors, tag_opening, content, tag_closing, then_keyword, prism_node, statements, subsequent, end_node)
1287
1996
  super(type, location, errors)
1288
1997
  @tag_opening = tag_opening
1289
1998
  @content = content
1290
1999
  @tag_closing = tag_closing
1291
2000
  @then_keyword = then_keyword
2001
+ @prism_node = prism_node
1292
2002
  @statements = statements
1293
2003
  @subsequent = subsequent
1294
2004
  @end_node = end_node
1295
2005
  end
1296
2006
 
2007
+ #: () -> Prism::node?
2008
+ def deserialized_prism_node
2009
+ prism_node = @prism_node
2010
+ return nil unless prism_node
2011
+ return nil unless source
2012
+
2013
+ require "prism"
2014
+ Prism.load(source, prism_node).value
2015
+ end
2016
+
1297
2017
  #: () -> serialized_erb_if_node
1298
2018
  def to_hash
1299
2019
  super.merge({
@@ -1301,6 +2021,7 @@ module Herb
1301
2021
  content: content,
1302
2022
  tag_closing: tag_closing,
1303
2023
  then_keyword: then_keyword,
2024
+ prism_node: prism_node,
1304
2025
  statements: statements,
1305
2026
  subsequent: subsequent,
1306
2027
  end_node: end_node,
@@ -1314,7 +2035,7 @@ module Herb
1314
2035
 
1315
2036
  #: () -> Array[Herb::AST::Node?]
1316
2037
  def child_nodes
1317
- [*statements, subsequent, end_node]
2038
+ [*(statements || []), subsequent, end_node]
1318
2039
  end
1319
2040
 
1320
2041
  #: () -> Array[Herb::AST::Node]
@@ -1354,6 +2075,11 @@ module Herb
1354
2075
  output += white("├── then_keyword: ")
1355
2076
  output += then_keyword ? dimmed("(location: #{then_keyword.tree_inspect})") : magenta("∅")
1356
2077
  output += "\n"
2078
+ if prism_node && source
2079
+ output += white("├── prism_node: ")
2080
+ output += Herb::PrismInspect.inspect_prism_serialized(prism_node, source, "│ ")
2081
+ output += "\n"
2082
+ end
1357
2083
  output += white("├── statements: ")
1358
2084
  output += inspect_array(statements, prefix: "│ ", indent: indent, depth: depth + 1, depth_limit: depth_limit)
1359
2085
  output += white("├── subsequent: ")
@@ -1378,31 +2104,52 @@ module Herb
1378
2104
  end
1379
2105
  end
1380
2106
 
2107
+ #: type serialized_erb_block_node = {
2108
+ #| tag_opening: Herb::Token?,
2109
+ #| content: Herb::Token?,
2110
+ #| tag_closing: Herb::Token?,
2111
+ #| prism_node: String?,
2112
+ #| body: Array[Herb::AST::Node],
2113
+ #| end_node: Herb::AST::ERBEndNode?,
2114
+ #| }
1381
2115
  class ERBBlockNode < Node
1382
2116
  include Colors
1383
2117
 
1384
- attr_reader :tag_opening #: Herb::Token
1385
- attr_reader :content #: Herb::Token
1386
- attr_reader :tag_closing #: Herb::Token
2118
+ attr_reader :tag_opening #: Herb::Token?
2119
+ attr_reader :content #: Herb::Token?
2120
+ attr_reader :tag_closing #: Herb::Token?
2121
+ attr_reader :prism_node #: String?
1387
2122
  attr_reader :body #: Array[Herb::AST::Node]
1388
- attr_reader :end_node #: Herb::AST::ERBEndNode
2123
+ attr_reader :end_node #: Herb::AST::ERBEndNode?
1389
2124
 
1390
- #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, Array[Herb::AST::Node], Herb::AST::ERBEndNode) -> void
1391
- def initialize(type, location, errors, tag_opening, content, tag_closing, body, end_node)
2125
+ #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, String, Array[Herb::AST::Node], Herb::AST::ERBEndNode) -> void
2126
+ def initialize(type, location, errors, tag_opening, content, tag_closing, prism_node, body, end_node)
1392
2127
  super(type, location, errors)
1393
2128
  @tag_opening = tag_opening
1394
2129
  @content = content
1395
2130
  @tag_closing = tag_closing
2131
+ @prism_node = prism_node
1396
2132
  @body = body
1397
2133
  @end_node = end_node
1398
2134
  end
1399
2135
 
2136
+ #: () -> Prism::node?
2137
+ def deserialized_prism_node
2138
+ prism_node = @prism_node
2139
+ return nil unless prism_node
2140
+ return nil unless source
2141
+
2142
+ require "prism"
2143
+ Prism.load(source, prism_node).value
2144
+ end
2145
+
1400
2146
  #: () -> serialized_erb_block_node
1401
2147
  def to_hash
1402
2148
  super.merge({
1403
2149
  tag_opening: tag_opening,
1404
2150
  content: content,
1405
2151
  tag_closing: tag_closing,
2152
+ prism_node: prism_node,
1406
2153
  body: body,
1407
2154
  end_node: end_node,
1408
2155
  }) #: Herb::serialized_erb_block_node
@@ -1415,7 +2162,7 @@ module Herb
1415
2162
 
1416
2163
  #: () -> Array[Herb::AST::Node?]
1417
2164
  def child_nodes
1418
- [*body, end_node]
2165
+ [*(body || []), end_node]
1419
2166
  end
1420
2167
 
1421
2168
  #: () -> Array[Herb::AST::Node]
@@ -1452,6 +2199,11 @@ module Herb
1452
2199
  output += white("├── tag_closing: ")
1453
2200
  output += tag_closing ? tag_closing.tree_inspect : magenta("∅")
1454
2201
  output += "\n"
2202
+ if prism_node && source
2203
+ output += white("├── prism_node: ")
2204
+ output += Herb::PrismInspect.inspect_prism_serialized(prism_node, source, "│ ")
2205
+ output += "\n"
2206
+ end
1455
2207
  output += white("├── body: ")
1456
2208
  output += inspect_array(body, prefix: "│ ", indent: indent, depth: depth + 1, depth_limit: depth_limit)
1457
2209
  output += white("└── end_node: ")
@@ -1468,13 +2220,20 @@ module Herb
1468
2220
  end
1469
2221
  end
1470
2222
 
2223
+ #: type serialized_erb_when_node = {
2224
+ #| tag_opening: Herb::Token?,
2225
+ #| content: Herb::Token?,
2226
+ #| tag_closing: Herb::Token?,
2227
+ #| then_keyword: Herb::Location?,
2228
+ #| statements: Array[Herb::AST::Node],
2229
+ #| }
1471
2230
  class ERBWhenNode < Node
1472
2231
  include Colors
1473
2232
 
1474
- attr_reader :tag_opening #: Herb::Token
1475
- attr_reader :content #: Herb::Token
1476
- attr_reader :tag_closing #: Herb::Token
1477
- attr_reader :then_keyword #: Herb::Location
2233
+ attr_reader :tag_opening #: Herb::Token?
2234
+ attr_reader :content #: Herb::Token?
2235
+ attr_reader :tag_closing #: Herb::Token?
2236
+ attr_reader :then_keyword #: Herb::Location?
1478
2237
  attr_reader :statements #: Array[Herb::AST::Node]
1479
2238
 
1480
2239
  #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, Herb::Location, Array[Herb::AST::Node]) -> void
@@ -1505,7 +2264,7 @@ module Herb
1505
2264
 
1506
2265
  #: () -> Array[Herb::AST::Node?]
1507
2266
  def child_nodes
1508
- [*statements]
2267
+ [*(statements || [])]
1509
2268
  end
1510
2269
 
1511
2270
  #: () -> Array[Herb::AST::Node]
@@ -1553,29 +2312,51 @@ module Herb
1553
2312
  end
1554
2313
  end
1555
2314
 
2315
+ #: type serialized_erb_case_node = {
2316
+ #| tag_opening: Herb::Token?,
2317
+ #| content: Herb::Token?,
2318
+ #| tag_closing: Herb::Token?,
2319
+ #| children: Array[Herb::AST::Node],
2320
+ #| prism_node: String?,
2321
+ #| conditions: Array[Herb::AST::ERBWhenNode],
2322
+ #| else_clause: Herb::AST::ERBElseNode?,
2323
+ #| end_node: Herb::AST::ERBEndNode?,
2324
+ #| }
1556
2325
  class ERBCaseNode < Node
1557
2326
  include Colors
1558
2327
 
1559
- attr_reader :tag_opening #: Herb::Token
1560
- attr_reader :content #: Herb::Token
1561
- attr_reader :tag_closing #: Herb::Token
2328
+ attr_reader :tag_opening #: Herb::Token?
2329
+ attr_reader :content #: Herb::Token?
2330
+ attr_reader :tag_closing #: Herb::Token?
1562
2331
  attr_reader :children #: Array[Herb::AST::Node]
2332
+ attr_reader :prism_node #: String?
1563
2333
  attr_reader :conditions #: Array[Herb::AST::ERBWhenNode]
1564
- attr_reader :else_clause #: Herb::AST::ERBElseNode
1565
- attr_reader :end_node #: Herb::AST::ERBEndNode
2334
+ attr_reader :else_clause #: Herb::AST::ERBElseNode?
2335
+ attr_reader :end_node #: Herb::AST::ERBEndNode?
1566
2336
 
1567
- #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, Array[Herb::AST::Node], Array[Herb::AST::ERBWhenNode], Herb::AST::ERBElseNode, Herb::AST::ERBEndNode) -> void
1568
- def initialize(type, location, errors, tag_opening, content, tag_closing, children, conditions, else_clause, end_node)
2337
+ #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, Array[Herb::AST::Node], String, Array[Herb::AST::ERBWhenNode], Herb::AST::ERBElseNode, Herb::AST::ERBEndNode) -> void
2338
+ def initialize(type, location, errors, tag_opening, content, tag_closing, children, prism_node, conditions, else_clause, end_node)
1569
2339
  super(type, location, errors)
1570
2340
  @tag_opening = tag_opening
1571
2341
  @content = content
1572
2342
  @tag_closing = tag_closing
1573
2343
  @children = children
2344
+ @prism_node = prism_node
1574
2345
  @conditions = conditions
1575
2346
  @else_clause = else_clause
1576
2347
  @end_node = end_node
1577
2348
  end
1578
2349
 
2350
+ #: () -> Prism::node?
2351
+ def deserialized_prism_node
2352
+ prism_node = @prism_node
2353
+ return nil unless prism_node
2354
+ return nil unless source
2355
+
2356
+ require "prism"
2357
+ Prism.load(source, prism_node).value
2358
+ end
2359
+
1579
2360
  #: () -> serialized_erb_case_node
1580
2361
  def to_hash
1581
2362
  super.merge({
@@ -1583,6 +2364,7 @@ module Herb
1583
2364
  content: content,
1584
2365
  tag_closing: tag_closing,
1585
2366
  children: children,
2367
+ prism_node: prism_node,
1586
2368
  conditions: conditions,
1587
2369
  else_clause: else_clause,
1588
2370
  end_node: end_node,
@@ -1596,7 +2378,7 @@ module Herb
1596
2378
 
1597
2379
  #: () -> Array[Herb::AST::Node?]
1598
2380
  def child_nodes
1599
- [*children, *conditions, else_clause, end_node]
2381
+ [*(children || []), *(conditions || []), else_clause, end_node]
1600
2382
  end
1601
2383
 
1602
2384
  #: () -> Array[Herb::AST::Node]
@@ -1635,6 +2417,11 @@ module Herb
1635
2417
  output += "\n"
1636
2418
  output += white("├── children: ")
1637
2419
  output += inspect_array(children, prefix: "│ ", indent: indent, depth: depth + 1, depth_limit: depth_limit)
2420
+ if prism_node && source
2421
+ output += white("├── prism_node: ")
2422
+ output += Herb::PrismInspect.inspect_prism_serialized(prism_node, source, "│ ")
2423
+ output += "\n"
2424
+ end
1638
2425
  output += white("├── conditions: ")
1639
2426
  output += inspect_array(conditions, prefix: "│ ", indent: indent, depth: depth + 1, depth_limit: depth_limit)
1640
2427
  output += white("├── else_clause: ")
@@ -1659,29 +2446,51 @@ module Herb
1659
2446
  end
1660
2447
  end
1661
2448
 
2449
+ #: type serialized_erb_case_match_node = {
2450
+ #| tag_opening: Herb::Token?,
2451
+ #| content: Herb::Token?,
2452
+ #| tag_closing: Herb::Token?,
2453
+ #| children: Array[Herb::AST::Node],
2454
+ #| prism_node: String?,
2455
+ #| conditions: Array[Herb::AST::ERBInNode],
2456
+ #| else_clause: Herb::AST::ERBElseNode?,
2457
+ #| end_node: Herb::AST::ERBEndNode?,
2458
+ #| }
1662
2459
  class ERBCaseMatchNode < Node
1663
2460
  include Colors
1664
2461
 
1665
- attr_reader :tag_opening #: Herb::Token
1666
- attr_reader :content #: Herb::Token
1667
- attr_reader :tag_closing #: Herb::Token
2462
+ attr_reader :tag_opening #: Herb::Token?
2463
+ attr_reader :content #: Herb::Token?
2464
+ attr_reader :tag_closing #: Herb::Token?
1668
2465
  attr_reader :children #: Array[Herb::AST::Node]
2466
+ attr_reader :prism_node #: String?
1669
2467
  attr_reader :conditions #: Array[Herb::AST::ERBInNode]
1670
- attr_reader :else_clause #: Herb::AST::ERBElseNode
1671
- attr_reader :end_node #: Herb::AST::ERBEndNode
2468
+ attr_reader :else_clause #: Herb::AST::ERBElseNode?
2469
+ attr_reader :end_node #: Herb::AST::ERBEndNode?
1672
2470
 
1673
- #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, Array[Herb::AST::Node], Array[Herb::AST::ERBInNode], Herb::AST::ERBElseNode, Herb::AST::ERBEndNode) -> void
1674
- def initialize(type, location, errors, tag_opening, content, tag_closing, children, conditions, else_clause, end_node)
2471
+ #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, Array[Herb::AST::Node], String, Array[Herb::AST::ERBInNode], Herb::AST::ERBElseNode, Herb::AST::ERBEndNode) -> void
2472
+ def initialize(type, location, errors, tag_opening, content, tag_closing, children, prism_node, conditions, else_clause, end_node)
1675
2473
  super(type, location, errors)
1676
2474
  @tag_opening = tag_opening
1677
2475
  @content = content
1678
2476
  @tag_closing = tag_closing
1679
2477
  @children = children
2478
+ @prism_node = prism_node
1680
2479
  @conditions = conditions
1681
2480
  @else_clause = else_clause
1682
2481
  @end_node = end_node
1683
2482
  end
1684
2483
 
2484
+ #: () -> Prism::node?
2485
+ def deserialized_prism_node
2486
+ prism_node = @prism_node
2487
+ return nil unless prism_node
2488
+ return nil unless source
2489
+
2490
+ require "prism"
2491
+ Prism.load(source, prism_node).value
2492
+ end
2493
+
1685
2494
  #: () -> serialized_erb_case_match_node
1686
2495
  def to_hash
1687
2496
  super.merge({
@@ -1689,6 +2498,7 @@ module Herb
1689
2498
  content: content,
1690
2499
  tag_closing: tag_closing,
1691
2500
  children: children,
2501
+ prism_node: prism_node,
1692
2502
  conditions: conditions,
1693
2503
  else_clause: else_clause,
1694
2504
  end_node: end_node,
@@ -1702,7 +2512,7 @@ module Herb
1702
2512
 
1703
2513
  #: () -> Array[Herb::AST::Node?]
1704
2514
  def child_nodes
1705
- [*children, *conditions, else_clause, end_node]
2515
+ [*(children || []), *(conditions || []), else_clause, end_node]
1706
2516
  end
1707
2517
 
1708
2518
  #: () -> Array[Herb::AST::Node]
@@ -1741,6 +2551,11 @@ module Herb
1741
2551
  output += "\n"
1742
2552
  output += white("├── children: ")
1743
2553
  output += inspect_array(children, prefix: "│ ", indent: indent, depth: depth + 1, depth_limit: depth_limit)
2554
+ if prism_node && source
2555
+ output += white("├── prism_node: ")
2556
+ output += Herb::PrismInspect.inspect_prism_serialized(prism_node, source, "│ ")
2557
+ output += "\n"
2558
+ end
1744
2559
  output += white("├── conditions: ")
1745
2560
  output += inspect_array(conditions, prefix: "│ ", indent: indent, depth: depth + 1, depth_limit: depth_limit)
1746
2561
  output += white("├── else_clause: ")
@@ -1765,31 +2580,52 @@ module Herb
1765
2580
  end
1766
2581
  end
1767
2582
 
2583
+ #: type serialized_erb_while_node = {
2584
+ #| tag_opening: Herb::Token?,
2585
+ #| content: Herb::Token?,
2586
+ #| tag_closing: Herb::Token?,
2587
+ #| prism_node: String?,
2588
+ #| statements: Array[Herb::AST::Node],
2589
+ #| end_node: Herb::AST::ERBEndNode?,
2590
+ #| }
1768
2591
  class ERBWhileNode < Node
1769
2592
  include Colors
1770
2593
 
1771
- attr_reader :tag_opening #: Herb::Token
1772
- attr_reader :content #: Herb::Token
1773
- attr_reader :tag_closing #: Herb::Token
2594
+ attr_reader :tag_opening #: Herb::Token?
2595
+ attr_reader :content #: Herb::Token?
2596
+ attr_reader :tag_closing #: Herb::Token?
2597
+ attr_reader :prism_node #: String?
1774
2598
  attr_reader :statements #: Array[Herb::AST::Node]
1775
- attr_reader :end_node #: Herb::AST::ERBEndNode
2599
+ attr_reader :end_node #: Herb::AST::ERBEndNode?
1776
2600
 
1777
- #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, Array[Herb::AST::Node], Herb::AST::ERBEndNode) -> void
1778
- def initialize(type, location, errors, tag_opening, content, tag_closing, statements, end_node)
2601
+ #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, String, Array[Herb::AST::Node], Herb::AST::ERBEndNode) -> void
2602
+ def initialize(type, location, errors, tag_opening, content, tag_closing, prism_node, statements, end_node)
1779
2603
  super(type, location, errors)
1780
2604
  @tag_opening = tag_opening
1781
2605
  @content = content
1782
2606
  @tag_closing = tag_closing
2607
+ @prism_node = prism_node
1783
2608
  @statements = statements
1784
2609
  @end_node = end_node
1785
2610
  end
1786
2611
 
2612
+ #: () -> Prism::node?
2613
+ def deserialized_prism_node
2614
+ prism_node = @prism_node
2615
+ return nil unless prism_node
2616
+ return nil unless source
2617
+
2618
+ require "prism"
2619
+ Prism.load(source, prism_node).value
2620
+ end
2621
+
1787
2622
  #: () -> serialized_erb_while_node
1788
2623
  def to_hash
1789
2624
  super.merge({
1790
2625
  tag_opening: tag_opening,
1791
2626
  content: content,
1792
2627
  tag_closing: tag_closing,
2628
+ prism_node: prism_node,
1793
2629
  statements: statements,
1794
2630
  end_node: end_node,
1795
2631
  }) #: Herb::serialized_erb_while_node
@@ -1802,7 +2638,7 @@ module Herb
1802
2638
 
1803
2639
  #: () -> Array[Herb::AST::Node?]
1804
2640
  def child_nodes
1805
- [*statements, end_node]
2641
+ [*(statements || []), end_node]
1806
2642
  end
1807
2643
 
1808
2644
  #: () -> Array[Herb::AST::Node]
@@ -1839,6 +2675,11 @@ module Herb
1839
2675
  output += white("├── tag_closing: ")
1840
2676
  output += tag_closing ? tag_closing.tree_inspect : magenta("∅")
1841
2677
  output += "\n"
2678
+ if prism_node && source
2679
+ output += white("├── prism_node: ")
2680
+ output += Herb::PrismInspect.inspect_prism_serialized(prism_node, source, "│ ")
2681
+ output += "\n"
2682
+ end
1842
2683
  output += white("├── statements: ")
1843
2684
  output += inspect_array(statements, prefix: "│ ", indent: indent, depth: depth + 1, depth_limit: depth_limit)
1844
2685
  output += white("└── end_node: ")
@@ -1855,31 +2696,52 @@ module Herb
1855
2696
  end
1856
2697
  end
1857
2698
 
2699
+ #: type serialized_erb_until_node = {
2700
+ #| tag_opening: Herb::Token?,
2701
+ #| content: Herb::Token?,
2702
+ #| tag_closing: Herb::Token?,
2703
+ #| prism_node: String?,
2704
+ #| statements: Array[Herb::AST::Node],
2705
+ #| end_node: Herb::AST::ERBEndNode?,
2706
+ #| }
1858
2707
  class ERBUntilNode < Node
1859
2708
  include Colors
1860
2709
 
1861
- attr_reader :tag_opening #: Herb::Token
1862
- attr_reader :content #: Herb::Token
1863
- attr_reader :tag_closing #: Herb::Token
2710
+ attr_reader :tag_opening #: Herb::Token?
2711
+ attr_reader :content #: Herb::Token?
2712
+ attr_reader :tag_closing #: Herb::Token?
2713
+ attr_reader :prism_node #: String?
1864
2714
  attr_reader :statements #: Array[Herb::AST::Node]
1865
- attr_reader :end_node #: Herb::AST::ERBEndNode
2715
+ attr_reader :end_node #: Herb::AST::ERBEndNode?
1866
2716
 
1867
- #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, Array[Herb::AST::Node], Herb::AST::ERBEndNode) -> void
1868
- def initialize(type, location, errors, tag_opening, content, tag_closing, statements, end_node)
2717
+ #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, String, Array[Herb::AST::Node], Herb::AST::ERBEndNode) -> void
2718
+ def initialize(type, location, errors, tag_opening, content, tag_closing, prism_node, statements, end_node)
1869
2719
  super(type, location, errors)
1870
2720
  @tag_opening = tag_opening
1871
2721
  @content = content
1872
2722
  @tag_closing = tag_closing
2723
+ @prism_node = prism_node
1873
2724
  @statements = statements
1874
2725
  @end_node = end_node
1875
2726
  end
1876
2727
 
2728
+ #: () -> Prism::node?
2729
+ def deserialized_prism_node
2730
+ prism_node = @prism_node
2731
+ return nil unless prism_node
2732
+ return nil unless source
2733
+
2734
+ require "prism"
2735
+ Prism.load(source, prism_node).value
2736
+ end
2737
+
1877
2738
  #: () -> serialized_erb_until_node
1878
2739
  def to_hash
1879
2740
  super.merge({
1880
2741
  tag_opening: tag_opening,
1881
2742
  content: content,
1882
2743
  tag_closing: tag_closing,
2744
+ prism_node: prism_node,
1883
2745
  statements: statements,
1884
2746
  end_node: end_node,
1885
2747
  }) #: Herb::serialized_erb_until_node
@@ -1892,7 +2754,7 @@ module Herb
1892
2754
 
1893
2755
  #: () -> Array[Herb::AST::Node?]
1894
2756
  def child_nodes
1895
- [*statements, end_node]
2757
+ [*(statements || []), end_node]
1896
2758
  end
1897
2759
 
1898
2760
  #: () -> Array[Herb::AST::Node]
@@ -1929,6 +2791,11 @@ module Herb
1929
2791
  output += white("├── tag_closing: ")
1930
2792
  output += tag_closing ? tag_closing.tree_inspect : magenta("∅")
1931
2793
  output += "\n"
2794
+ if prism_node && source
2795
+ output += white("├── prism_node: ")
2796
+ output += Herb::PrismInspect.inspect_prism_serialized(prism_node, source, "│ ")
2797
+ output += "\n"
2798
+ end
1932
2799
  output += white("├── statements: ")
1933
2800
  output += inspect_array(statements, prefix: "│ ", indent: indent, depth: depth + 1, depth_limit: depth_limit)
1934
2801
  output += white("└── end_node: ")
@@ -1945,31 +2812,52 @@ module Herb
1945
2812
  end
1946
2813
  end
1947
2814
 
2815
+ #: type serialized_erb_for_node = {
2816
+ #| tag_opening: Herb::Token?,
2817
+ #| content: Herb::Token?,
2818
+ #| tag_closing: Herb::Token?,
2819
+ #| prism_node: String?,
2820
+ #| statements: Array[Herb::AST::Node],
2821
+ #| end_node: Herb::AST::ERBEndNode?,
2822
+ #| }
1948
2823
  class ERBForNode < Node
1949
2824
  include Colors
1950
2825
 
1951
- attr_reader :tag_opening #: Herb::Token
1952
- attr_reader :content #: Herb::Token
1953
- attr_reader :tag_closing #: Herb::Token
2826
+ attr_reader :tag_opening #: Herb::Token?
2827
+ attr_reader :content #: Herb::Token?
2828
+ attr_reader :tag_closing #: Herb::Token?
2829
+ attr_reader :prism_node #: String?
1954
2830
  attr_reader :statements #: Array[Herb::AST::Node]
1955
- attr_reader :end_node #: Herb::AST::ERBEndNode
2831
+ attr_reader :end_node #: Herb::AST::ERBEndNode?
1956
2832
 
1957
- #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, Array[Herb::AST::Node], Herb::AST::ERBEndNode) -> void
1958
- def initialize(type, location, errors, tag_opening, content, tag_closing, statements, end_node)
2833
+ #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, String, Array[Herb::AST::Node], Herb::AST::ERBEndNode) -> void
2834
+ def initialize(type, location, errors, tag_opening, content, tag_closing, prism_node, statements, end_node)
1959
2835
  super(type, location, errors)
1960
2836
  @tag_opening = tag_opening
1961
2837
  @content = content
1962
2838
  @tag_closing = tag_closing
2839
+ @prism_node = prism_node
1963
2840
  @statements = statements
1964
2841
  @end_node = end_node
1965
2842
  end
1966
2843
 
2844
+ #: () -> Prism::node?
2845
+ def deserialized_prism_node
2846
+ prism_node = @prism_node
2847
+ return nil unless prism_node
2848
+ return nil unless source
2849
+
2850
+ require "prism"
2851
+ Prism.load(source, prism_node).value
2852
+ end
2853
+
1967
2854
  #: () -> serialized_erb_for_node
1968
2855
  def to_hash
1969
2856
  super.merge({
1970
2857
  tag_opening: tag_opening,
1971
2858
  content: content,
1972
2859
  tag_closing: tag_closing,
2860
+ prism_node: prism_node,
1973
2861
  statements: statements,
1974
2862
  end_node: end_node,
1975
2863
  }) #: Herb::serialized_erb_for_node
@@ -1982,7 +2870,7 @@ module Herb
1982
2870
 
1983
2871
  #: () -> Array[Herb::AST::Node?]
1984
2872
  def child_nodes
1985
- [*statements, end_node]
2873
+ [*(statements || []), end_node]
1986
2874
  end
1987
2875
 
1988
2876
  #: () -> Array[Herb::AST::Node]
@@ -2019,6 +2907,11 @@ module Herb
2019
2907
  output += white("├── tag_closing: ")
2020
2908
  output += tag_closing ? tag_closing.tree_inspect : magenta("∅")
2021
2909
  output += "\n"
2910
+ if prism_node && source
2911
+ output += white("├── prism_node: ")
2912
+ output += Herb::PrismInspect.inspect_prism_serialized(prism_node, source, "│ ")
2913
+ output += "\n"
2914
+ end
2022
2915
  output += white("├── statements: ")
2023
2916
  output += inspect_array(statements, prefix: "│ ", indent: indent, depth: depth + 1, depth_limit: depth_limit)
2024
2917
  output += white("└── end_node: ")
@@ -2035,14 +2928,21 @@ module Herb
2035
2928
  end
2036
2929
  end
2037
2930
 
2931
+ #: type serialized_erb_rescue_node = {
2932
+ #| tag_opening: Herb::Token?,
2933
+ #| content: Herb::Token?,
2934
+ #| tag_closing: Herb::Token?,
2935
+ #| statements: Array[Herb::AST::Node],
2936
+ #| subsequent: Herb::AST::ERBRescueNode?,
2937
+ #| }
2038
2938
  class ERBRescueNode < Node
2039
2939
  include Colors
2040
2940
 
2041
- attr_reader :tag_opening #: Herb::Token
2042
- attr_reader :content #: Herb::Token
2043
- attr_reader :tag_closing #: Herb::Token
2941
+ attr_reader :tag_opening #: Herb::Token?
2942
+ attr_reader :content #: Herb::Token?
2943
+ attr_reader :tag_closing #: Herb::Token?
2044
2944
  attr_reader :statements #: Array[Herb::AST::Node]
2045
- attr_reader :subsequent #: Herb::AST::ERBRescueNode
2945
+ attr_reader :subsequent #: Herb::AST::ERBRescueNode?
2046
2946
 
2047
2947
  #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, Array[Herb::AST::Node], Herb::AST::ERBRescueNode) -> void
2048
2948
  def initialize(type, location, errors, tag_opening, content, tag_closing, statements, subsequent)
@@ -2072,7 +2972,7 @@ module Herb
2072
2972
 
2073
2973
  #: () -> Array[Herb::AST::Node?]
2074
2974
  def child_nodes
2075
- [*statements, subsequent]
2975
+ [*(statements || []), subsequent]
2076
2976
  end
2077
2977
 
2078
2978
  #: () -> Array[Herb::AST::Node]
@@ -2125,12 +3025,18 @@ module Herb
2125
3025
  end
2126
3026
  end
2127
3027
 
3028
+ #: type serialized_erb_ensure_node = {
3029
+ #| tag_opening: Herb::Token?,
3030
+ #| content: Herb::Token?,
3031
+ #| tag_closing: Herb::Token?,
3032
+ #| statements: Array[Herb::AST::Node],
3033
+ #| }
2128
3034
  class ERBEnsureNode < Node
2129
3035
  include Colors
2130
3036
 
2131
- attr_reader :tag_opening #: Herb::Token
2132
- attr_reader :content #: Herb::Token
2133
- attr_reader :tag_closing #: Herb::Token
3037
+ attr_reader :tag_opening #: Herb::Token?
3038
+ attr_reader :content #: Herb::Token?
3039
+ attr_reader :tag_closing #: Herb::Token?
2134
3040
  attr_reader :statements #: Array[Herb::AST::Node]
2135
3041
 
2136
3042
  #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, Array[Herb::AST::Node]) -> void
@@ -2159,7 +3065,7 @@ module Herb
2159
3065
 
2160
3066
  #: () -> Array[Herb::AST::Node?]
2161
3067
  def child_nodes
2162
- [*statements]
3068
+ [*(statements || [])]
2163
3069
  end
2164
3070
 
2165
3071
  #: () -> Array[Herb::AST::Node]
@@ -2204,24 +3110,37 @@ module Herb
2204
3110
  end
2205
3111
  end
2206
3112
 
3113
+ #: type serialized_erb_begin_node = {
3114
+ #| tag_opening: Herb::Token?,
3115
+ #| content: Herb::Token?,
3116
+ #| tag_closing: Herb::Token?,
3117
+ #| prism_node: String?,
3118
+ #| statements: Array[Herb::AST::Node],
3119
+ #| rescue_clause: Herb::AST::ERBRescueNode?,
3120
+ #| else_clause: Herb::AST::ERBElseNode?,
3121
+ #| ensure_clause: Herb::AST::ERBEnsureNode?,
3122
+ #| end_node: Herb::AST::ERBEndNode?,
3123
+ #| }
2207
3124
  class ERBBeginNode < Node
2208
3125
  include Colors
2209
3126
 
2210
- attr_reader :tag_opening #: Herb::Token
2211
- attr_reader :content #: Herb::Token
2212
- attr_reader :tag_closing #: Herb::Token
3127
+ attr_reader :tag_opening #: Herb::Token?
3128
+ attr_reader :content #: Herb::Token?
3129
+ attr_reader :tag_closing #: Herb::Token?
3130
+ attr_reader :prism_node #: String?
2213
3131
  attr_reader :statements #: Array[Herb::AST::Node]
2214
- attr_reader :rescue_clause #: Herb::AST::ERBRescueNode
2215
- attr_reader :else_clause #: Herb::AST::ERBElseNode
2216
- attr_reader :ensure_clause #: Herb::AST::ERBEnsureNode
2217
- attr_reader :end_node #: Herb::AST::ERBEndNode
3132
+ attr_reader :rescue_clause #: Herb::AST::ERBRescueNode?
3133
+ attr_reader :else_clause #: Herb::AST::ERBElseNode?
3134
+ attr_reader :ensure_clause #: Herb::AST::ERBEnsureNode?
3135
+ attr_reader :end_node #: Herb::AST::ERBEndNode?
2218
3136
 
2219
- #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, Array[Herb::AST::Node], Herb::AST::ERBRescueNode, Herb::AST::ERBElseNode, Herb::AST::ERBEnsureNode, Herb::AST::ERBEndNode) -> void
2220
- def initialize(type, location, errors, tag_opening, content, tag_closing, statements, rescue_clause, else_clause, ensure_clause, end_node)
3137
+ #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, String, Array[Herb::AST::Node], Herb::AST::ERBRescueNode, Herb::AST::ERBElseNode, Herb::AST::ERBEnsureNode, Herb::AST::ERBEndNode) -> void
3138
+ def initialize(type, location, errors, tag_opening, content, tag_closing, prism_node, statements, rescue_clause, else_clause, ensure_clause, end_node)
2221
3139
  super(type, location, errors)
2222
3140
  @tag_opening = tag_opening
2223
3141
  @content = content
2224
3142
  @tag_closing = tag_closing
3143
+ @prism_node = prism_node
2225
3144
  @statements = statements
2226
3145
  @rescue_clause = rescue_clause
2227
3146
  @else_clause = else_clause
@@ -2229,12 +3148,23 @@ module Herb
2229
3148
  @end_node = end_node
2230
3149
  end
2231
3150
 
3151
+ #: () -> Prism::node?
3152
+ def deserialized_prism_node
3153
+ prism_node = @prism_node
3154
+ return nil unless prism_node
3155
+ return nil unless source
3156
+
3157
+ require "prism"
3158
+ Prism.load(source, prism_node).value
3159
+ end
3160
+
2232
3161
  #: () -> serialized_erb_begin_node
2233
3162
  def to_hash
2234
3163
  super.merge({
2235
3164
  tag_opening: tag_opening,
2236
3165
  content: content,
2237
3166
  tag_closing: tag_closing,
3167
+ prism_node: prism_node,
2238
3168
  statements: statements,
2239
3169
  rescue_clause: rescue_clause,
2240
3170
  else_clause: else_clause,
@@ -2250,7 +3180,7 @@ module Herb
2250
3180
 
2251
3181
  #: () -> Array[Herb::AST::Node?]
2252
3182
  def child_nodes
2253
- [*statements, rescue_clause, else_clause, ensure_clause, end_node]
3183
+ [*(statements || []), rescue_clause, else_clause, ensure_clause, end_node]
2254
3184
  end
2255
3185
 
2256
3186
  #: () -> Array[Herb::AST::Node]
@@ -2287,6 +3217,11 @@ module Herb
2287
3217
  output += white("├── tag_closing: ")
2288
3218
  output += tag_closing ? tag_closing.tree_inspect : magenta("∅")
2289
3219
  output += "\n"
3220
+ if prism_node && source
3221
+ output += white("├── prism_node: ")
3222
+ output += Herb::PrismInspect.inspect_prism_serialized(prism_node, source, "│ ")
3223
+ output += "\n"
3224
+ end
2290
3225
  output += white("├── statements: ")
2291
3226
  output += inspect_array(statements, prefix: "│ ", indent: indent, depth: depth + 1, depth_limit: depth_limit)
2292
3227
  output += white("├── rescue_clause: ")
@@ -2327,29 +3262,51 @@ module Herb
2327
3262
  end
2328
3263
  end
2329
3264
 
3265
+ #: type serialized_erb_unless_node = {
3266
+ #| tag_opening: Herb::Token?,
3267
+ #| content: Herb::Token?,
3268
+ #| tag_closing: Herb::Token?,
3269
+ #| then_keyword: Herb::Location?,
3270
+ #| prism_node: String?,
3271
+ #| statements: Array[Herb::AST::Node],
3272
+ #| else_clause: Herb::AST::ERBElseNode?,
3273
+ #| end_node: Herb::AST::ERBEndNode?,
3274
+ #| }
2330
3275
  class ERBUnlessNode < Node
2331
3276
  include Colors
2332
3277
 
2333
- attr_reader :tag_opening #: Herb::Token
2334
- attr_reader :content #: Herb::Token
2335
- attr_reader :tag_closing #: Herb::Token
2336
- attr_reader :then_keyword #: Herb::Location
3278
+ attr_reader :tag_opening #: Herb::Token?
3279
+ attr_reader :content #: Herb::Token?
3280
+ attr_reader :tag_closing #: Herb::Token?
3281
+ attr_reader :then_keyword #: Herb::Location?
3282
+ attr_reader :prism_node #: String?
2337
3283
  attr_reader :statements #: Array[Herb::AST::Node]
2338
- attr_reader :else_clause #: Herb::AST::ERBElseNode
2339
- attr_reader :end_node #: Herb::AST::ERBEndNode
3284
+ attr_reader :else_clause #: Herb::AST::ERBElseNode?
3285
+ attr_reader :end_node #: Herb::AST::ERBEndNode?
2340
3286
 
2341
- #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, Herb::Location, Array[Herb::AST::Node], Herb::AST::ERBElseNode, Herb::AST::ERBEndNode) -> void
2342
- def initialize(type, location, errors, tag_opening, content, tag_closing, then_keyword, statements, else_clause, end_node)
3287
+ #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, Herb::Location, String, Array[Herb::AST::Node], Herb::AST::ERBElseNode, Herb::AST::ERBEndNode) -> void
3288
+ def initialize(type, location, errors, tag_opening, content, tag_closing, then_keyword, prism_node, statements, else_clause, end_node)
2343
3289
  super(type, location, errors)
2344
3290
  @tag_opening = tag_opening
2345
3291
  @content = content
2346
3292
  @tag_closing = tag_closing
2347
3293
  @then_keyword = then_keyword
3294
+ @prism_node = prism_node
2348
3295
  @statements = statements
2349
3296
  @else_clause = else_clause
2350
3297
  @end_node = end_node
2351
3298
  end
2352
3299
 
3300
+ #: () -> Prism::node?
3301
+ def deserialized_prism_node
3302
+ prism_node = @prism_node
3303
+ return nil unless prism_node
3304
+ return nil unless source
3305
+
3306
+ require "prism"
3307
+ Prism.load(source, prism_node).value
3308
+ end
3309
+
2353
3310
  #: () -> serialized_erb_unless_node
2354
3311
  def to_hash
2355
3312
  super.merge({
@@ -2357,6 +3314,7 @@ module Herb
2357
3314
  content: content,
2358
3315
  tag_closing: tag_closing,
2359
3316
  then_keyword: then_keyword,
3317
+ prism_node: prism_node,
2360
3318
  statements: statements,
2361
3319
  else_clause: else_clause,
2362
3320
  end_node: end_node,
@@ -2370,7 +3328,7 @@ module Herb
2370
3328
 
2371
3329
  #: () -> Array[Herb::AST::Node?]
2372
3330
  def child_nodes
2373
- [*statements, else_clause, end_node]
3331
+ [*(statements || []), else_clause, end_node]
2374
3332
  end
2375
3333
 
2376
3334
  #: () -> Array[Herb::AST::Node]
@@ -2410,6 +3368,11 @@ module Herb
2410
3368
  output += white("├── then_keyword: ")
2411
3369
  output += then_keyword ? dimmed("(location: #{then_keyword.tree_inspect})") : magenta("∅")
2412
3370
  output += "\n"
3371
+ if prism_node && source
3372
+ output += white("├── prism_node: ")
3373
+ output += Herb::PrismInspect.inspect_prism_serialized(prism_node, source, "│ ")
3374
+ output += "\n"
3375
+ end
2413
3376
  output += white("├── statements: ")
2414
3377
  output += inspect_array(statements, prefix: "│ ", indent: indent, depth: depth + 1, depth_limit: depth_limit)
2415
3378
  output += white("├── else_clause: ")
@@ -2434,12 +3397,17 @@ module Herb
2434
3397
  end
2435
3398
  end
2436
3399
 
3400
+ #: type serialized_erb_yield_node = {
3401
+ #| tag_opening: Herb::Token?,
3402
+ #| content: Herb::Token?,
3403
+ #| tag_closing: Herb::Token?,
3404
+ #| }
2437
3405
  class ERBYieldNode < Node
2438
3406
  include Colors
2439
3407
 
2440
- attr_reader :tag_opening #: Herb::Token
2441
- attr_reader :content #: Herb::Token
2442
- attr_reader :tag_closing #: Herb::Token
3408
+ attr_reader :tag_opening #: Herb::Token?
3409
+ attr_reader :content #: Herb::Token?
3410
+ attr_reader :tag_closing #: Herb::Token?
2443
3411
 
2444
3412
  #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token) -> void
2445
3413
  def initialize(type, location, errors, tag_opening, content, tag_closing)
@@ -2508,13 +3476,20 @@ module Herb
2508
3476
  end
2509
3477
  end
2510
3478
 
3479
+ #: type serialized_erb_in_node = {
3480
+ #| tag_opening: Herb::Token?,
3481
+ #| content: Herb::Token?,
3482
+ #| tag_closing: Herb::Token?,
3483
+ #| then_keyword: Herb::Location?,
3484
+ #| statements: Array[Herb::AST::Node],
3485
+ #| }
2511
3486
  class ERBInNode < Node
2512
3487
  include Colors
2513
3488
 
2514
- attr_reader :tag_opening #: Herb::Token
2515
- attr_reader :content #: Herb::Token
2516
- attr_reader :tag_closing #: Herb::Token
2517
- attr_reader :then_keyword #: Herb::Location
3489
+ attr_reader :tag_opening #: Herb::Token?
3490
+ attr_reader :content #: Herb::Token?
3491
+ attr_reader :tag_closing #: Herb::Token?
3492
+ attr_reader :then_keyword #: Herb::Location?
2518
3493
  attr_reader :statements #: Array[Herb::AST::Node]
2519
3494
 
2520
3495
  #: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, Herb::Location, Array[Herb::AST::Node]) -> void
@@ -2545,7 +3520,7 @@ module Herb
2545
3520
 
2546
3521
  #: () -> Array[Herb::AST::Node?]
2547
3522
  def child_nodes
2548
- [*statements]
3523
+ [*(statements || [])]
2549
3524
  end
2550
3525
 
2551
3526
  #: () -> Array[Herb::AST::Node]