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.
- checksums.yaml +4 -4
- data/config.yml +156 -0
- data/ext/herb/error_helpers.c +168 -0
- data/ext/herb/extension.c +4 -0
- data/ext/herb/extension_helpers.c +1 -0
- data/ext/herb/nodes.c +110 -0
- data/lib/herb/3.0/herb.so +0 -0
- data/lib/herb/3.1/herb.so +0 -0
- data/lib/herb/3.2/herb.so +0 -0
- data/lib/herb/3.3/herb.so +0 -0
- data/lib/herb/3.4/herb.so +0 -0
- data/lib/herb/4.0/herb.so +0 -0
- data/lib/herb/ast/nodes.rb +393 -17
- data/lib/herb/engine/compiler.rb +17 -41
- data/lib/herb/engine.rb +76 -26
- data/lib/herb/errors.rb +245 -0
- data/lib/herb/parser_options.rb +6 -1
- data/lib/herb/prism_inspect.rb +5 -1
- data/lib/herb/version.rb +1 -1
- data/lib/herb/visitor.rb +10 -0
- data/sig/herb/ast/nodes.rbs +132 -0
- data/sig/herb/engine/compiler.rbs +4 -2
- data/sig/herb/engine.rbs +8 -0
- data/sig/herb/errors.rbs +114 -0
- data/sig/herb/parser_options.rbs +4 -0
- data/sig/herb/visitor.rbs +6 -0
- data/sig/rubyvm.rbs +5 -0
- data/sig/serialized_ast_errors.rbs +28 -0
- data/sig/serialized_ast_nodes.rbs +31 -0
- data/src/analyze/action_view/attribute_extraction_helpers.c +23 -1
- data/src/analyze/action_view/content_tag.c +19 -11
- data/src/analyze/action_view/javascript_include_tag.c +92 -0
- data/src/analyze/action_view/javascript_tag.c +55 -0
- data/src/analyze/action_view/link_to.c +25 -1
- data/src/analyze/action_view/registry.c +29 -2
- data/src/analyze/action_view/tag.c +14 -8
- data/src/analyze/action_view/tag_helper_node_builders.c +16 -3
- data/src/analyze/action_view/tag_helpers.c +332 -12
- data/src/analyze/analyze.c +3 -0
- data/src/analyze/prism_annotate.c +4 -2
- data/src/analyze/render_nodes.c +761 -0
- data/src/analyze/transform.c +7 -0
- data/src/ast_nodes.c +97 -0
- data/src/ast_pretty_print.c +74 -0
- data/src/errors.c +379 -0
- data/src/html_util.c +50 -0
- data/src/include/analyze/action_view/tag_helper_handler.h +2 -0
- data/src/include/analyze/render_nodes.h +11 -0
- data/src/include/ast_nodes.h +37 -0
- data/src/include/errors.h +58 -0
- data/src/include/html_util.h +1 -0
- data/src/include/parser.h +1 -0
- data/src/include/version.h +1 -1
- data/src/parser.c +1 -0
- data/src/parser_match_tags.c +20 -0
- data/src/util/hb_arena.c +3 -7
- data/src/visitor.c +20 -0
- data/templates/lib/herb/ast/nodes.rb.erb +8 -2
- data/templates/rust/src/ast/nodes.rs.erb +1 -1
- data/templates/rust/src/nodes.rs.erb +1 -1
- 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
|
-
|
|
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
|
-
|
|
243
|
-
|
|
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
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
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
|
-
|
|
306
|
+
if @_expression_block_open_paren
|
|
307
|
+
terminate_expression
|
|
283
308
|
|
|
284
|
-
|
|
285
|
-
|
|
309
|
+
trailing_newline = code.end_with?("\n")
|
|
310
|
+
code_stripped = code.chomp
|
|
286
311
|
|
|
287
|
-
|
|
312
|
+
@src.chomp! if @src.end_with?("\n") && code_stripped.start_with?(" ")
|
|
288
313
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
314
|
+
@src << " " << code_stripped
|
|
315
|
+
@src << "\n" if self.class.comment?(code_stripped)
|
|
316
|
+
@src << (escaped ? "))" : ")")
|
|
317
|
+
@src << (trailing_newline ? "\n" : ";")
|
|
293
318
|
|
|
294
|
-
|
|
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
|
data/lib/herb/parser_options.rb
CHANGED
|
@@ -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}>"
|
data/lib/herb/prism_inspect.rb
CHANGED
|
@@ -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
|
-
|
|
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
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)
|
data/sig/herb/ast/nodes.rbs
CHANGED
|
@@ -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
|