herb 0.9.0-arm-linux-gnu → 0.9.2-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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/config.yml +156 -0
  3. data/ext/herb/error_helpers.c +168 -0
  4. data/ext/herb/extension.c +4 -0
  5. data/ext/herb/extension_helpers.c +1 -0
  6. data/ext/herb/nodes.c +110 -0
  7. data/lib/herb/3.0/herb.so +0 -0
  8. data/lib/herb/3.1/herb.so +0 -0
  9. data/lib/herb/3.2/herb.so +0 -0
  10. data/lib/herb/3.3/herb.so +0 -0
  11. data/lib/herb/3.4/herb.so +0 -0
  12. data/lib/herb/4.0/herb.so +0 -0
  13. data/lib/herb/ast/nodes.rb +393 -17
  14. data/lib/herb/engine/compiler.rb +17 -41
  15. data/lib/herb/engine.rb +76 -26
  16. data/lib/herb/errors.rb +245 -0
  17. data/lib/herb/parser_options.rb +6 -1
  18. data/lib/herb/prism_inspect.rb +5 -1
  19. data/lib/herb/version.rb +1 -1
  20. data/lib/herb/visitor.rb +10 -0
  21. data/sig/herb/ast/nodes.rbs +132 -0
  22. data/sig/herb/engine/compiler.rbs +4 -2
  23. data/sig/herb/engine.rbs +8 -0
  24. data/sig/herb/errors.rbs +114 -0
  25. data/sig/herb/parser_options.rbs +4 -0
  26. data/sig/herb/visitor.rbs +6 -0
  27. data/sig/rubyvm.rbs +5 -0
  28. data/sig/serialized_ast_errors.rbs +28 -0
  29. data/sig/serialized_ast_nodes.rbs +31 -0
  30. data/src/analyze/action_view/attribute_extraction_helpers.c +23 -1
  31. data/src/analyze/action_view/content_tag.c +19 -11
  32. data/src/analyze/action_view/javascript_include_tag.c +92 -0
  33. data/src/analyze/action_view/javascript_tag.c +55 -0
  34. data/src/analyze/action_view/link_to.c +25 -1
  35. data/src/analyze/action_view/registry.c +29 -2
  36. data/src/analyze/action_view/tag.c +14 -8
  37. data/src/analyze/action_view/tag_helper_node_builders.c +16 -3
  38. data/src/analyze/action_view/tag_helpers.c +332 -12
  39. data/src/analyze/analyze.c +3 -0
  40. data/src/analyze/prism_annotate.c +4 -2
  41. data/src/analyze/render_nodes.c +761 -0
  42. data/src/analyze/transform.c +7 -0
  43. data/src/ast_nodes.c +97 -0
  44. data/src/ast_pretty_print.c +74 -0
  45. data/src/errors.c +379 -0
  46. data/src/html_util.c +50 -0
  47. data/src/include/analyze/action_view/tag_helper_handler.h +2 -0
  48. data/src/include/analyze/render_nodes.h +11 -0
  49. data/src/include/ast_nodes.h +37 -0
  50. data/src/include/errors.h +58 -0
  51. data/src/include/html_util.h +1 -0
  52. data/src/include/parser.h +1 -0
  53. data/src/include/version.h +1 -1
  54. data/src/parser.c +1 -0
  55. data/src/parser_match_tags.c +20 -0
  56. data/src/util/hb_arena.c +3 -7
  57. data/src/visitor.c +20 -0
  58. data/templates/lib/herb/ast/nodes.rb.erb +8 -2
  59. data/templates/rust/src/ast/nodes.rs.erb +1 -1
  60. data/templates/rust/src/nodes.rs.erb +1 -1
  61. metadata +6 -1
data/lib/herb/engine.rb CHANGED
@@ -55,6 +55,9 @@ module Herb
55
55
  @bufvar = properties[:bufvar] || properties[:outvar] || "_buf"
56
56
  @escape = properties.fetch(:escape) { properties.fetch(:escape_html, false) }
57
57
  @escapefunc = properties.fetch(:escapefunc, @escape ? "__herb.h" : "::Herb::Engine.h")
58
+ @attrfunc = properties.fetch(:attrfunc, @escape ? "__herb.attr" : "::Herb::Engine.attr")
59
+ @jsfunc = properties.fetch(:jsfunc, @escape ? "__herb.js" : "::Herb::Engine.js")
60
+ @cssfunc = properties.fetch(:cssfunc, @escape ? "__herb.css" : "::Herb::Engine.css")
58
61
  @src = properties[:src] || String.new
59
62
  @chain_appends = properties[:chain_appends]
60
63
  @buffer_on_stack = false
@@ -148,15 +151,7 @@ module Herb
148
151
  @src << "; ensure\n #{@bufvar} = __original_outvar\nend\n" if properties[:ensure]
149
152
 
150
153
  if properties.fetch(:validate_ruby, false)
151
- require "prism"
152
-
153
- prism_result = Prism.parse(@src)
154
- syntax_errors = prism_result.errors.reject { |e| e.type == :invalid_yield }
155
-
156
- if syntax_errors.any?
157
- details = syntax_errors.map { |e| " - #{e.message} (line #{e.location.start_line})" }.join("\n")
158
- raise InvalidRubyError.new("Compiled template produced invalid Ruby:\n#{details}", compiled_source: @src)
159
- end
154
+ ensure_valid_ruby!(@src)
160
155
  end
161
156
 
162
157
  @src.freeze
@@ -238,11 +233,35 @@ module Herb
238
233
  @buffer_on_stack = false
239
234
  end
240
235
 
236
+ def expression_block?
237
+ @_in_expression_block || false
238
+ end
239
+
241
240
  def add_expression(indicator, code)
242
- if (indicator == "=") ^ @escape
243
- add_expression_result(code)
241
+ unescaped = (indicator == "=") ^ @escape
242
+
243
+ if expression_block?
244
+ unescaped ? add_expression_block_result(code) : add_expression_block_result_escaped(code)
244
245
  else
245
- add_expression_result_escaped(code)
246
+ unescaped ? add_expression_result(code) : add_expression_result_escaped(code)
247
+ end
248
+ end
249
+
250
+ def add_context_aware_expression(indicator, code, context)
251
+ escapefunc = context_escape_function(context)
252
+
253
+ if escapefunc.nil?
254
+ add_expression(indicator, code)
255
+ else
256
+ with_buffer { @src << " << #{escapefunc}((" << code << trailing_newline(code) << "))" }
257
+ end
258
+ end
259
+
260
+ def context_escape_function(context)
261
+ case context
262
+ when :attribute_value then @attrfunc
263
+ when :script_content then @jsfunc
264
+ when :style_content then @cssfunc
246
265
  end
247
266
  end
248
267
 
@@ -259,39 +278,48 @@ module Herb
259
278
  end
260
279
 
261
280
  def add_expression_block(indicator, code)
262
- if (indicator == "=") ^ @escape
263
- add_expression_block_result(code)
264
- else
265
- add_expression_block_result_escaped(code)
266
- end
281
+ @_in_expression_block = true
282
+ @_expression_block_open_paren = false
283
+
284
+ add_expression(indicator, code)
285
+ ensure
286
+ @_in_expression_block = false
267
287
  end
268
288
 
269
289
  def add_expression_block_result(code)
290
+ @_expression_block_open_paren = true
291
+
270
292
  with_buffer {
271
293
  @src << " << (" << code << trailing_newline(code)
272
294
  }
273
295
  end
274
296
 
275
297
  def add_expression_block_result_escaped(code)
298
+ @_expression_block_open_paren = true
299
+
276
300
  with_buffer {
277
301
  @src << " << " << @escapefunc << "((" << code << trailing_newline(code)
278
302
  }
279
303
  end
280
304
 
281
305
  def add_expression_block_end(code, escaped: false)
282
- terminate_expression
306
+ if @_expression_block_open_paren
307
+ terminate_expression
283
308
 
284
- trailing_newline = code.end_with?("\n")
285
- code_stripped = code.chomp
309
+ trailing_newline = code.end_with?("\n")
310
+ code_stripped = code.chomp
286
311
 
287
- @src.chomp! if @src.end_with?("\n") && code_stripped.start_with?(" ")
312
+ @src.chomp! if @src.end_with?("\n") && code_stripped.start_with?(" ")
288
313
 
289
- @src << " " << code_stripped
290
- @src << "\n" if self.class.comment?(code_stripped)
291
- @src << (escaped ? "))" : ")")
292
- @src << (trailing_newline ? "\n" : ";")
314
+ @src << " " << code_stripped
315
+ @src << "\n" if self.class.comment?(code_stripped)
316
+ @src << (escaped ? "))" : ")")
317
+ @src << (trailing_newline ? "\n" : ";")
293
318
 
294
- @buffer_on_stack = false
319
+ @buffer_on_stack = false
320
+ else
321
+ add_code(code)
322
+ end
295
323
  end
296
324
 
297
325
  def trailing_newline(code)
@@ -440,5 +468,27 @@ module Herb
440
468
  def default_visitors
441
469
  []
442
470
  end
471
+
472
+ def ensure_valid_ruby!(source)
473
+ RubyVM::InstructionSequence.compile(source)
474
+ rescue SyntaxError => e
475
+ return if e.message.include?("Invalid yield")
476
+
477
+ begin
478
+ require "prism"
479
+ rescue LoadError
480
+ # Prism not available, fall through
481
+ end
482
+
483
+ raise InvalidRubyError.new("Compiled template produced invalid Ruby:\n - #{e.message}", compiled_source: @src) unless defined?(Prism)
484
+
485
+ prism_result = Prism.parse(@src)
486
+ syntax_errors = prism_result.errors.reject { |error| error.type == :invalid_yield }
487
+
488
+ if syntax_errors.any?
489
+ details = syntax_errors.map { |err| " - #{err.message} (line #{err.location.start_line})" }.join("\n")
490
+ raise InvalidRubyError.new("Compiled template produced invalid Ruby:\n#{details}", compiled_source: @src)
491
+ end
492
+ end
443
493
  end
444
494
  end
data/lib/herb/errors.rb CHANGED
@@ -1013,5 +1013,250 @@ module Herb
1013
1013
  end
1014
1014
  end
1015
1015
 
1016
+ class RenderAmbiguousLocalsError < Error
1017
+ include Colors
1018
+
1019
+ #| partial: String?,
1020
+ #| }
1021
+
1022
+ attr_reader :partial #: String?
1023
+
1024
+ #: (String, Location?, String, String) -> void
1025
+ def initialize(type, location, message, partial)
1026
+ super(type, location, message)
1027
+ @partial = partial
1028
+ end
1029
+
1030
+ #: () -> String
1031
+ def inspect
1032
+ tree_inspect.rstrip.gsub(/\s+$/, "")
1033
+ end
1034
+
1035
+ #: () -> serialized_render_ambiguous_locals_error
1036
+ def to_hash
1037
+ super.merge(
1038
+ partial: partial
1039
+ ) #: Herb::serialized_render_ambiguous_locals_error
1040
+ end
1041
+
1042
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1043
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1044
+ output = +""
1045
+
1046
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1047
+ output += white("├── message: #{green(message.inspect)}\n")
1048
+ output += white("└── partial: #{green(partial.inspect)}\n")
1049
+ output += %(\n)
1050
+
1051
+ output.gsub(/^/, " " * indent)
1052
+ end
1053
+ end
1054
+
1055
+ class RenderMissingLocalsError < Error
1056
+ include Colors
1057
+
1058
+ #| partial: String?,
1059
+ #| keywords: String?,
1060
+ #| }
1061
+
1062
+ attr_reader :partial #: String?
1063
+ attr_reader :keywords #: String?
1064
+
1065
+ #: (String, Location?, String, String, String) -> void
1066
+ def initialize(type, location, message, partial, keywords)
1067
+ super(type, location, message)
1068
+ @partial = partial
1069
+ @keywords = keywords
1070
+ end
1071
+
1072
+ #: () -> String
1073
+ def inspect
1074
+ tree_inspect.rstrip.gsub(/\s+$/, "")
1075
+ end
1076
+
1077
+ #: () -> serialized_render_missing_locals_error
1078
+ def to_hash
1079
+ super.merge(
1080
+ partial: partial,
1081
+ keywords: keywords
1082
+ ) #: Herb::serialized_render_missing_locals_error
1083
+ end
1084
+
1085
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1086
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1087
+ output = +""
1088
+
1089
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1090
+ output += white("├── message: #{green(message.inspect)}\n")
1091
+ output += white("├── partial: #{green(partial.inspect)}\n")
1092
+ output += white("└── keywords: #{green(keywords.inspect)}\n")
1093
+ output += %(\n)
1094
+
1095
+ output.gsub(/^/, " " * indent)
1096
+ end
1097
+ end
1098
+
1099
+ class RenderNoArgumentsError < Error
1100
+ include Colors
1101
+
1102
+ #: () -> String
1103
+ def inspect
1104
+ tree_inspect.rstrip.gsub(/\s+$/, "")
1105
+ end
1106
+
1107
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1108
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1109
+ output = +""
1110
+
1111
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1112
+ output += white("└── message: #{green(message.inspect)}\n")
1113
+ output += %(\n)
1114
+
1115
+ output.gsub(/^/, " " * indent)
1116
+ end
1117
+ end
1118
+
1119
+ class RenderConflictingPartialError < Error
1120
+ include Colors
1121
+
1122
+ #| positional_partial: String?,
1123
+ #| keyword_partial: String?,
1124
+ #| }
1125
+
1126
+ attr_reader :positional_partial #: String?
1127
+ attr_reader :keyword_partial #: String?
1128
+
1129
+ #: (String, Location?, String, String, String) -> void
1130
+ def initialize(type, location, message, positional_partial, keyword_partial)
1131
+ super(type, location, message)
1132
+ @positional_partial = positional_partial
1133
+ @keyword_partial = keyword_partial
1134
+ end
1135
+
1136
+ #: () -> String
1137
+ def inspect
1138
+ tree_inspect.rstrip.gsub(/\s+$/, "")
1139
+ end
1140
+
1141
+ #: () -> serialized_render_conflicting_partial_error
1142
+ def to_hash
1143
+ super.merge(
1144
+ positional_partial: positional_partial,
1145
+ keyword_partial: keyword_partial
1146
+ ) #: Herb::serialized_render_conflicting_partial_error
1147
+ end
1148
+
1149
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1150
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1151
+ output = +""
1152
+
1153
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1154
+ output += white("├── message: #{green(message.inspect)}\n")
1155
+ output += white("├── positional_partial: #{green(positional_partial.inspect)}\n")
1156
+ output += white("└── keyword_partial: #{green(keyword_partial.inspect)}\n")
1157
+ output += %(\n)
1158
+
1159
+ output.gsub(/^/, " " * indent)
1160
+ end
1161
+ end
1162
+
1163
+ class RenderInvalidAsOptionError < Error
1164
+ include Colors
1165
+
1166
+ #| as_value: String?,
1167
+ #| }
1168
+
1169
+ attr_reader :as_value #: String?
1170
+
1171
+ #: (String, Location?, String, String) -> void
1172
+ def initialize(type, location, message, as_value)
1173
+ super(type, location, message)
1174
+ @as_value = as_value
1175
+ end
1176
+
1177
+ #: () -> String
1178
+ def inspect
1179
+ tree_inspect.rstrip.gsub(/\s+$/, "")
1180
+ end
1181
+
1182
+ #: () -> serialized_render_invalid_as_option_error
1183
+ def to_hash
1184
+ super.merge(
1185
+ as_value: as_value
1186
+ ) #: Herb::serialized_render_invalid_as_option_error
1187
+ end
1188
+
1189
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1190
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1191
+ output = +""
1192
+
1193
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1194
+ output += white("├── message: #{green(message.inspect)}\n")
1195
+ output += white("└── as_value: #{green(as_value.inspect)}\n")
1196
+ output += %(\n)
1197
+
1198
+ output.gsub(/^/, " " * indent)
1199
+ end
1200
+ end
1201
+
1202
+ class RenderObjectAndCollectionError < Error
1203
+ include Colors
1204
+
1205
+ #: () -> String
1206
+ def inspect
1207
+ tree_inspect.rstrip.gsub(/\s+$/, "")
1208
+ end
1209
+
1210
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1211
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1212
+ output = +""
1213
+
1214
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1215
+ output += white("└── message: #{green(message.inspect)}\n")
1216
+ output += %(\n)
1217
+
1218
+ output.gsub(/^/, " " * indent)
1219
+ end
1220
+ end
1221
+
1222
+ class RenderLayoutWithoutBlockError < Error
1223
+ include Colors
1224
+
1225
+ #| layout: String?,
1226
+ #| }
1227
+
1228
+ attr_reader :layout #: String?
1229
+
1230
+ #: (String, Location?, String, String) -> void
1231
+ def initialize(type, location, message, layout)
1232
+ super(type, location, message)
1233
+ @layout = layout
1234
+ end
1235
+
1236
+ #: () -> String
1237
+ def inspect
1238
+ tree_inspect.rstrip.gsub(/\s+$/, "")
1239
+ end
1240
+
1241
+ #: () -> serialized_render_layout_without_block_error
1242
+ def to_hash
1243
+ super.merge(
1244
+ layout: layout
1245
+ ) #: Herb::serialized_render_layout_without_block_error
1246
+ end
1247
+
1248
+ #: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1249
+ def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
1250
+ output = +""
1251
+
1252
+ output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
1253
+ output += white("├── message: #{green(message.inspect)}\n")
1254
+ output += white("└── layout: #{green(layout.inspect)}\n")
1255
+ output += %(\n)
1256
+
1257
+ output.gsub(/^/, " " * indent)
1258
+ end
1259
+ end
1260
+
1016
1261
  end
1017
1262
  end
@@ -6,6 +6,7 @@ module Herb
6
6
  attr_reader :track_whitespace #: bool
7
7
  attr_reader :analyze #: bool
8
8
  attr_reader :action_view_helpers #: bool
9
+ attr_reader :render_nodes #: bool
9
10
  attr_reader :prism_program #: bool
10
11
  attr_reader :prism_nodes #: bool
11
12
  attr_reader :prism_nodes_deep #: bool
@@ -14,16 +15,18 @@ module Herb
14
15
  DEFAULT_TRACK_WHITESPACE = false #: bool
15
16
  DEFAULT_ANALYZE = true #: bool
16
17
  DEFAULT_ACTION_VIEW_HELPERS = false #: bool
18
+ DEFAULT_RENDER_NODES = false #: bool
17
19
  DEFAULT_PRISM_PROGRAM = false #: bool
18
20
  DEFAULT_PRISM_NODES = false #: bool
19
21
  DEFAULT_PRISM_NODES_DEEP = false #: bool
20
22
 
21
23
  #: (?strict: bool, ?track_whitespace: bool, ?analyze: bool, ?action_view_helpers: bool, ?prism_nodes: bool, ?prism_nodes_deep: bool, ?prism_program: bool) -> void
22
- def initialize(strict: DEFAULT_STRICT, track_whitespace: DEFAULT_TRACK_WHITESPACE, analyze: DEFAULT_ANALYZE, action_view_helpers: DEFAULT_ACTION_VIEW_HELPERS, prism_nodes: DEFAULT_PRISM_NODES, prism_nodes_deep: DEFAULT_PRISM_NODES_DEEP, prism_program: DEFAULT_PRISM_PROGRAM)
24
+ def initialize(strict: DEFAULT_STRICT, track_whitespace: DEFAULT_TRACK_WHITESPACE, analyze: DEFAULT_ANALYZE, action_view_helpers: DEFAULT_ACTION_VIEW_HELPERS, render_nodes: DEFAULT_RENDER_NODES, prism_nodes: DEFAULT_PRISM_NODES, prism_nodes_deep: DEFAULT_PRISM_NODES_DEEP, prism_program: DEFAULT_PRISM_PROGRAM)
23
25
  @strict = strict
24
26
  @track_whitespace = track_whitespace
25
27
  @analyze = analyze
26
28
  @action_view_helpers = action_view_helpers
29
+ @render_nodes = render_nodes
27
30
  @prism_nodes = prism_nodes
28
31
  @prism_nodes_deep = prism_nodes_deep
29
32
  @prism_program = prism_program
@@ -36,6 +39,7 @@ module Herb
36
39
  track_whitespace: @track_whitespace,
37
40
  analyze: @analyze,
38
41
  action_view_helpers: @action_view_helpers,
42
+ render_nodes: @render_nodes,
39
43
  prism_nodes: @prism_nodes,
40
44
  prism_nodes_deep: @prism_nodes_deep,
41
45
  prism_program: @prism_program,
@@ -49,6 +53,7 @@ module Herb
49
53
  "track_whitespace=#{@track_whitespace}\n " \
50
54
  "analyze=#{@analyze}\n " \
51
55
  "action_view_helpers=#{@action_view_helpers}\n " \
56
+ "render_nodes=#{@render_nodes}\n " \
52
57
  "prism_nodes=#{@prism_nodes}\n " \
53
58
  "prism_nodes_deep=#{@prism_nodes_deep}\n " \
54
59
  "prism_program=#{@prism_program}>"
@@ -9,7 +9,11 @@ module Herb
9
9
  def inspect_prism_serialized(serialized_bytes, source, prefix)
10
10
  return "∅" unless serialized_bytes
11
11
 
12
- require "prism"
12
+ begin
13
+ require "prism"
14
+ rescue LoadError
15
+ return "(#{serialized_bytes.bytesize} bytes, prism gem not available)"
16
+ end
13
17
 
14
18
  node = Prism.load(source, serialized_bytes).value
15
19
  return "∅" unless node
data/lib/herb/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # typed: true
3
3
 
4
4
  module Herb
5
- VERSION = "0.9.0"
5
+ VERSION = "0.9.2"
6
6
  end
data/lib/herb/visitor.rb CHANGED
@@ -203,6 +203,16 @@ module Herb
203
203
  visit_child_nodes(node)
204
204
  end
205
205
 
206
+ #: (Herb::AST::RubyRenderLocalNode) -> void
207
+ def visit_ruby_render_local_node(node)
208
+ visit_child_nodes(node)
209
+ end
210
+
211
+ #: (Herb::AST::ERBRenderNode) -> void
212
+ def visit_erb_render_node(node)
213
+ visit_child_nodes(node)
214
+ end
215
+
206
216
  #: (Herb::AST::ERBYieldNode) -> void
207
217
  def visit_erb_yield_node(node)
208
218
  visit_child_nodes(node)
@@ -1472,6 +1472,138 @@ module Herb
1472
1472
  def tree_inspect: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1473
1473
  end
1474
1474
 
1475
+ # : type serialized_ruby_render_local_node = {
1476
+ # | name: Herb::Token?,
1477
+ # | value: Herb::AST::RubyLiteralNode?,
1478
+ # | }
1479
+ class RubyRenderLocalNode < Node
1480
+ include Colors
1481
+
1482
+ attr_reader name: Herb::Token?
1483
+
1484
+ attr_reader value: Herb::AST::RubyLiteralNode?
1485
+
1486
+ # : (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::AST::RubyLiteralNode) -> void
1487
+ def initialize: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::AST::RubyLiteralNode) -> void
1488
+
1489
+ # : () -> serialized_ruby_render_local_node
1490
+ def to_hash: () -> serialized_ruby_render_local_node
1491
+
1492
+ # : (Visitor) -> void
1493
+ def accept: (Visitor) -> void
1494
+
1495
+ # : () -> Array[Herb::AST::Node?]
1496
+ def child_nodes: () -> Array[Herb::AST::Node?]
1497
+
1498
+ # : () -> Array[Herb::AST::Node]
1499
+ def compact_child_nodes: () -> Array[Herb::AST::Node]
1500
+
1501
+ # : () -> String
1502
+ def inspect: () -> String
1503
+
1504
+ # : (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1505
+ def tree_inspect: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1506
+ end
1507
+
1508
+ # : type serialized_erb_render_node = {
1509
+ # | tag_opening: Herb::Token?,
1510
+ # | content: Herb::Token?,
1511
+ # | tag_closing: Herb::Token?,
1512
+ # | analyzed_ruby: nil,
1513
+ # | prism_node: String?,
1514
+ # | partial: Herb::Token?,
1515
+ # | template_path: Herb::Token?,
1516
+ # | layout: Herb::Token?,
1517
+ # | file: Herb::Token?,
1518
+ # | inline_template: Herb::Token?,
1519
+ # | body: Herb::Token?,
1520
+ # | plain: Herb::Token?,
1521
+ # | html: Herb::Token?,
1522
+ # | renderable: Herb::Token?,
1523
+ # | collection: Herb::Token?,
1524
+ # | object: Herb::Token?,
1525
+ # | as_name: Herb::Token?,
1526
+ # | spacer_template: Herb::Token?,
1527
+ # | formats: Herb::Token?,
1528
+ # | variants: Herb::Token?,
1529
+ # | handlers: Herb::Token?,
1530
+ # | content_type: Herb::Token?,
1531
+ # | locals: Array[Herb::AST::RubyRenderLocalNode]?,
1532
+ # | }
1533
+ class ERBRenderNode < Node
1534
+ include Colors
1535
+
1536
+ attr_reader tag_opening: Herb::Token?
1537
+
1538
+ attr_reader content: Herb::Token?
1539
+
1540
+ attr_reader tag_closing: Herb::Token?
1541
+
1542
+ attr_reader analyzed_ruby: nil
1543
+
1544
+ attr_reader prism_node: String?
1545
+
1546
+ attr_reader partial: Herb::Token?
1547
+
1548
+ attr_reader template_path: Herb::Token?
1549
+
1550
+ attr_reader layout: Herb::Token?
1551
+
1552
+ attr_reader file: Herb::Token?
1553
+
1554
+ attr_reader inline_template: Herb::Token?
1555
+
1556
+ attr_reader body: Herb::Token?
1557
+
1558
+ attr_reader plain: Herb::Token?
1559
+
1560
+ attr_reader html: Herb::Token?
1561
+
1562
+ attr_reader renderable: Herb::Token?
1563
+
1564
+ attr_reader collection: Herb::Token?
1565
+
1566
+ attr_reader object: Herb::Token?
1567
+
1568
+ attr_reader as_name: Herb::Token?
1569
+
1570
+ attr_reader spacer_template: Herb::Token?
1571
+
1572
+ attr_reader formats: Herb::Token?
1573
+
1574
+ attr_reader variants: Herb::Token?
1575
+
1576
+ attr_reader handlers: Herb::Token?
1577
+
1578
+ attr_reader content_type: Herb::Token?
1579
+
1580
+ attr_reader locals: Array[Herb::AST::RubyRenderLocalNode]?
1581
+
1582
+ # : (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, nil, String, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Array[Herb::AST::RubyRenderLocalNode]) -> void
1583
+ def initialize: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, nil, String, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Array[Herb::AST::RubyRenderLocalNode]) -> void
1584
+
1585
+ # : () -> Prism::node?
1586
+ def deserialized_prism_node: () -> Prism::node?
1587
+
1588
+ # : () -> serialized_erb_render_node
1589
+ def to_hash: () -> serialized_erb_render_node
1590
+
1591
+ # : (Visitor) -> void
1592
+ def accept: (Visitor) -> void
1593
+
1594
+ # : () -> Array[Herb::AST::Node?]
1595
+ def child_nodes: () -> Array[Herb::AST::Node?]
1596
+
1597
+ # : () -> Array[Herb::AST::Node]
1598
+ def compact_child_nodes: () -> Array[Herb::AST::Node]
1599
+
1600
+ # : () -> String
1601
+ def inspect: () -> String
1602
+
1603
+ # : (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1604
+ def tree_inspect: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
1605
+ end
1606
+
1475
1607
  # : type serialized_erb_yield_node = {
1476
1608
  # | tag_opening: Herb::Token?,
1477
1609
  # | content: Herb::Token?,
@@ -89,8 +89,6 @@ module Herb
89
89
 
90
90
  def pop_context: () -> untyped
91
91
 
92
- def add_context_aware_expression: (untyped code, untyped context) -> untyped
93
-
94
92
  def process_erb_tag: (untyped node, ?skip_comment_check: untyped) -> untyped
95
93
 
96
94
  def add_text: (untyped text) -> untyped
@@ -119,6 +117,10 @@ module Herb
119
117
 
120
118
  def process_erb_output: (untyped node, untyped opening, untyped code) -> untyped
121
119
 
120
+ def indicator_for: (untyped type) -> untyped
121
+
122
+ def context_aware_context?: (untyped context) -> untyped
123
+
122
124
  def should_escape_output?: (untyped opening) -> untyped
123
125
 
124
126
  def add_expression_with_escaping: (untyped code, untyped should_escape) -> untyped
data/sig/herb/engine.rbs CHANGED
@@ -51,8 +51,14 @@ module Herb
51
51
 
52
52
  def add_code: (untyped code) -> untyped
53
53
 
54
+ def expression_block?: () -> untyped
55
+
54
56
  def add_expression: (untyped indicator, untyped code) -> untyped
55
57
 
58
+ def add_context_aware_expression: (untyped indicator, untyped code, untyped context) -> untyped
59
+
60
+ def context_escape_function: (untyped context) -> untyped
61
+
56
62
  def add_expression_result: (untyped code) -> untyped
57
63
 
58
64
  def add_expression_result_escaped: (untyped code) -> untyped
@@ -89,5 +95,7 @@ module Herb
89
95
 
90
96
  # : () -> Array[Herb::Visitor]
91
97
  def default_visitors: () -> Array[Herb::Visitor]
98
+
99
+ def ensure_valid_ruby!: (untyped source) -> untyped
92
100
  end
93
101
  end