herb 0.11.0-aarch64-linux-gnu → 0.11.1-aarch64-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 +3 -0
- data/ext/herb/nodes.c +34 -17
- 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 +32 -6
- data/lib/herb/bootstrap.rb +6 -2
- data/lib/herb/dev/runner.rb +6 -1
- data/lib/herb/engine/compiler.rb +47 -11
- data/lib/herb/engine/slots/dynamics_compiler.rb +10 -0
- data/lib/herb/engine/slots/markers.rb +24 -0
- data/lib/herb/engine/slots/state_compiler.rb +1 -2
- data/lib/herb/engine/slots/visitor.rb +39 -28
- data/lib/herb/engine.rb +0 -2
- data/lib/herb/version.rb +1 -1
- data/sig/herb/ast/nodes.rbs +10 -4
- data/sig/herb/bootstrap.rbs +2 -0
- data/sig/herb/dev/runner.rbs +3 -0
- data/sig/herb/engine/compiler.rbs +14 -3
- data/sig/herb/engine/slots/dynamics_compiler.rbs +3 -0
- data/sig/herb/engine/slots/markers.rbs +14 -0
- data/sig/herb/engine/slots/visitor.rbs +17 -13
- data/sig/serialized_ast_nodes.rbs +1 -0
- data/src/analyze/action_view/tag_helper_node_builders.c +6 -3
- data/src/analyze/action_view/tag_helpers.c +76 -20
- data/src/analyze/analyze.c +5 -25
- data/src/analyze/analyze_helpers.c +94 -232
- data/src/analyze/analyzed_ruby.c +2 -0
- data/src/analyze/builders.c +1 -0
- data/src/analyze/control_type.c +17 -7
- data/src/analyze/prism_annotate.c +32 -9
- data/src/ast/ast_nodes.c +3 -1
- data/src/ast/ast_pretty_print.c +5 -1
- data/src/extract.c +204 -143
- data/src/include/analyze/analyze.h +0 -22
- data/src/include/analyze/analyzed_ruby.h +25 -0
- data/src/include/analyze/helpers.h +2 -22
- data/src/include/ast/ast_nodes.h +2 -1
- data/src/include/lexer/lexer.h +1 -0
- data/src/include/prism/herb_prism_node.h +6 -1
- data/src/include/version.h +1 -1
- data/src/lexer.c +32 -0
- data/src/prism/prism_helpers.c +91 -0
- data/templates/ext/herb/nodes.c.erb +1 -1
- data/templates/java/nodes.c.erb +1 -1
- data/templates/javascript/packages/core/src/nodes.ts.erb +21 -1
- data/templates/javascript/packages/node/extension/nodes.cpp.erb +1 -1
- data/templates/rust/src/ast/nodes.rs.erb +1 -4
- data/templates/wasm/nodes.cpp.erb +5 -15
- metadata +1 -1
|
@@ -1202,6 +1202,11 @@ module Herb
|
|
|
1202
1202
|
)
|
|
1203
1203
|
end
|
|
1204
1204
|
|
|
1205
|
+
#: (Array[untyped], Integer) -> String
|
|
1206
|
+
def attribute_spacing(children, position)
|
|
1207
|
+
position.positive? && children[position - 1].is_a?(Herb::AST::WhitespaceNode) ? "" : " "
|
|
1208
|
+
end
|
|
1209
|
+
|
|
1205
1210
|
private
|
|
1206
1211
|
|
|
1207
1212
|
def visit_children_with_paths(children)
|
|
@@ -1212,6 +1217,7 @@ module Herb
|
|
|
1212
1217
|
@states.check_state_assignment(child)
|
|
1213
1218
|
|
|
1214
1219
|
@path.push(index)
|
|
1220
|
+
record_slot(child, :child) if child.is_a?(Herb::AST::RubyLiteralNode)
|
|
1215
1221
|
visit(child)
|
|
1216
1222
|
@path.pop
|
|
1217
1223
|
end
|
|
@@ -1521,7 +1527,7 @@ module Herb
|
|
|
1521
1527
|
def convert_helper_boolean_attribute(node)
|
|
1522
1528
|
open_tag = @current_open_tag
|
|
1523
1529
|
|
|
1524
|
-
return nil unless @in_open_tag && open_tag.is_a?(Herb::AST::ERBOpenTagNode)
|
|
1530
|
+
return nil unless @in_open_tag && (open_tag.is_a?(Herb::AST::ERBOpenTagNode) || open_tag.is_a?(Herb::AST::HTMLOpenTagNode))
|
|
1525
1531
|
return nil if continuation?(node)
|
|
1526
1532
|
return nil unless node.respond_to?(:subsequent) && node.subsequent.nil?
|
|
1527
1533
|
|
|
@@ -1540,7 +1546,7 @@ module Herb
|
|
|
1540
1546
|
return nil unless name && Herb::HTML::Util.boolean_attribute?(name)
|
|
1541
1547
|
|
|
1542
1548
|
condition = @states.condition_expression(node)
|
|
1543
|
-
replacement = erb_output_node(%[(" #{name}" if #{condition})])
|
|
1549
|
+
replacement = erb_output_node(%[("#{attribute_spacing(children, position)}#{name}" if #{condition})])
|
|
1544
1550
|
|
|
1545
1551
|
children[position] = replacement
|
|
1546
1552
|
record_slot(replacement, :attribute)
|
|
@@ -1864,23 +1870,25 @@ module Herb
|
|
|
1864
1870
|
outputs.fetch(0).content&.value&.strip
|
|
1865
1871
|
end
|
|
1866
1872
|
|
|
1867
|
-
|
|
1873
|
+
#: (untyped, ?Symbol) -> untyped
|
|
1874
|
+
def insert_markers(node, namespace = :html)
|
|
1868
1875
|
anchored = content_anchor_index(node)
|
|
1876
|
+
namespace = Markers.namespace_within(namespace, node.tag_name&.value&.downcase.to_s) if node.is_a?(Herb::AST::HTMLElementNode)
|
|
1869
1877
|
|
|
1870
|
-
each_child_array(node) do |array|
|
|
1878
|
+
each_child_array(node, namespace) do |array|
|
|
1871
1879
|
index = 0
|
|
1872
1880
|
|
|
1873
1881
|
while index < array.size
|
|
1874
1882
|
child = array[index]
|
|
1875
1883
|
slot_index = @standing[child]&.survivor&.index
|
|
1876
1884
|
|
|
1877
|
-
insert_markers(child)
|
|
1878
|
-
wrap_items(child, slot_index)
|
|
1879
|
-
mark_branches(child, slot_index)
|
|
1885
|
+
insert_markers(child, namespace)
|
|
1886
|
+
wrap_items(child, slot_index, namespace)
|
|
1887
|
+
mark_branches(child, slot_index, namespace)
|
|
1880
1888
|
|
|
1881
1889
|
if slot_index && slot_index != anchored
|
|
1882
1890
|
if @slots[slot_index].type == :keyed
|
|
1883
|
-
park_keyed(slot_index, child)
|
|
1891
|
+
park_keyed(slot_index, child, namespace)
|
|
1884
1892
|
|
|
1885
1893
|
array.insert(
|
|
1886
1894
|
index,
|
|
@@ -1921,27 +1929,29 @@ module Herb
|
|
|
1921
1929
|
annotation.index
|
|
1922
1930
|
end
|
|
1923
1931
|
|
|
1924
|
-
#: (untyped, Integer?) -> void
|
|
1925
|
-
def mark_branches(node, slot_index)
|
|
1932
|
+
#: (untyped, Integer?, ?Symbol) -> void
|
|
1933
|
+
def mark_branches(node, slot_index, namespace = :html)
|
|
1926
1934
|
return unless slot_index
|
|
1927
1935
|
return unless @slots[slot_index].type == :conditional
|
|
1928
1936
|
|
|
1929
1937
|
branch_bodies(node).each_with_index do |body, branch_index|
|
|
1930
|
-
|
|
1938
|
+
marker = @markers.branch(slot_index, branch_index)
|
|
1931
1939
|
|
|
1932
|
-
park_branch(@markers.statics_key(slot_index, branch_index), body)
|
|
1940
|
+
park_branch(@markers.statics_key(slot_index, branch_index), marker, body, namespace)
|
|
1941
|
+
|
|
1942
|
+
body.unshift(text_node(marker))
|
|
1933
1943
|
end
|
|
1934
1944
|
end
|
|
1935
1945
|
|
|
1936
|
-
#: (String, Array[untyped]) -> void
|
|
1937
|
-
def park_branch(key, body)
|
|
1946
|
+
#: (String, String, Array[untyped], Symbol) -> void
|
|
1947
|
+
def park_branch(key, marker, body, namespace)
|
|
1938
1948
|
statics = @statics
|
|
1939
1949
|
return unless statics
|
|
1940
1950
|
|
|
1941
1951
|
markup = Statics.new(@standing).markup(body)
|
|
1942
1952
|
return unless markup
|
|
1943
1953
|
|
|
1944
|
-
statics[key] = markup
|
|
1954
|
+
statics[key] = "#{marker}#{@markers.foreign(markup, namespace)}"
|
|
1945
1955
|
end
|
|
1946
1956
|
|
|
1947
1957
|
#: (Herb::AST::DocumentNode) -> void
|
|
@@ -2062,8 +2072,8 @@ module Herb
|
|
|
2062
2072
|
bodies
|
|
2063
2073
|
end
|
|
2064
2074
|
|
|
2065
|
-
#: (Herb::AST::Node, Integer?) -> void
|
|
2066
|
-
def wrap_items(node, slot_index)
|
|
2075
|
+
#: (Herb::AST::Node, Integer?, ?Symbol) -> void
|
|
2076
|
+
def wrap_items(node, slot_index, namespace = :html)
|
|
2067
2077
|
return unless slot_index
|
|
2068
2078
|
|
|
2069
2079
|
slot = @slots[slot_index]
|
|
@@ -2076,7 +2086,7 @@ module Herb
|
|
|
2076
2086
|
next unless body.is_a?(Array) && !body.empty?
|
|
2077
2087
|
|
|
2078
2088
|
key = @markers.item_statics_key(slot_index)
|
|
2079
|
-
parked = park_item(key, body)
|
|
2089
|
+
parked = park_item(key, body, namespace)
|
|
2080
2090
|
|
|
2081
2091
|
body.unshift(
|
|
2082
2092
|
text_node(@markers.item_open_prefix(slot_index)),
|
|
@@ -2112,19 +2122,19 @@ module Herb
|
|
|
2112
2122
|
segments.size > 1 ? segments : nil
|
|
2113
2123
|
end
|
|
2114
2124
|
|
|
2115
|
-
#: (Integer, untyped) -> void
|
|
2116
|
-
def park_keyed(slot_index, element)
|
|
2125
|
+
#: (Integer, untyped, Symbol) -> void
|
|
2126
|
+
def park_keyed(slot_index, element, namespace)
|
|
2117
2127
|
statics = @statics
|
|
2118
2128
|
return unless statics
|
|
2119
2129
|
|
|
2120
2130
|
markup = Statics.new(@standing).markup([element.open_tag, *element.body, element.close_tag].compact)
|
|
2121
2131
|
return unless markup
|
|
2122
2132
|
|
|
2123
|
-
statics[@markers.item_statics_key(slot_index)] = "#{@markers.branch(slot_index, Markers::ITEM_STATICS)}#{markup}"
|
|
2133
|
+
statics[@markers.item_statics_key(slot_index)] = "#{@markers.branch(slot_index, Markers::ITEM_STATICS)}#{@markers.foreign(markup, namespace)}"
|
|
2124
2134
|
end
|
|
2125
2135
|
|
|
2126
|
-
#: (untyped, untyped) -> Array[untyped]?
|
|
2127
|
-
def park_item(key, body)
|
|
2136
|
+
#: (untyped, untyped, Symbol) -> Array[untyped]?
|
|
2137
|
+
def park_item(key, body, namespace)
|
|
2128
2138
|
statics = @statics
|
|
2129
2139
|
return unless statics
|
|
2130
2140
|
|
|
@@ -2132,13 +2142,14 @@ module Herb
|
|
|
2132
2142
|
markup = Statics.new(@standing).markup(body)
|
|
2133
2143
|
return unless markup
|
|
2134
2144
|
|
|
2135
|
-
|
|
2136
|
-
@markers.branch(slot_index, Markers::ITEM_STATICS),
|
|
2145
|
+
item = [
|
|
2137
2146
|
@markers.item_open_prefix(slot_index),
|
|
2138
2147
|
@markers.item_open_suffix,
|
|
2139
2148
|
markup,
|
|
2140
2149
|
@markers.item_close(slot_index)
|
|
2141
2150
|
].join
|
|
2151
|
+
|
|
2152
|
+
statics[key] = "#{@markers.branch(slot_index, Markers::ITEM_STATICS)}#{@markers.foreign(item, namespace)}"
|
|
2142
2153
|
end
|
|
2143
2154
|
|
|
2144
2155
|
def anchor_attributes(node, content_index = nil)
|
|
@@ -2173,8 +2184,8 @@ module Herb
|
|
|
2173
2184
|
name
|
|
2174
2185
|
end
|
|
2175
2186
|
|
|
2176
|
-
#: (Herb::AST::Node) { (Array[untyped]) -> void } -> void
|
|
2177
|
-
def each_child_array(node)
|
|
2187
|
+
#: (Herb::AST::Node, ?Symbol) { (Array[untyped]) -> void } -> void
|
|
2188
|
+
def each_child_array(node, namespace = :html)
|
|
2178
2189
|
BRANCH_BODY_PROPERTIES.each do |property|
|
|
2179
2190
|
next unless node.respond_to?(property)
|
|
2180
2191
|
|
|
@@ -2186,7 +2197,7 @@ module Herb
|
|
|
2186
2197
|
next unless node.respond_to?(property)
|
|
2187
2198
|
|
|
2188
2199
|
child = node.send(property)
|
|
2189
|
-
insert_markers(child) if child
|
|
2200
|
+
insert_markers(child, namespace) if child
|
|
2190
2201
|
end
|
|
2191
2202
|
end
|
|
2192
2203
|
|
data/lib/herb/engine.rb
CHANGED
data/lib/herb/version.rb
CHANGED
data/sig/herb/ast/nodes.rbs
CHANGED
|
@@ -2133,6 +2133,7 @@ module Herb
|
|
|
2133
2133
|
# | tag_opening: Herb::Token?,
|
|
2134
2134
|
# | content: Herb::Token?,
|
|
2135
2135
|
# | tag_closing: Herb::Token?,
|
|
2136
|
+
# | prism_node: String?,
|
|
2136
2137
|
# | }
|
|
2137
2138
|
class ERBYieldNode < Node
|
|
2138
2139
|
include Colors
|
|
@@ -2143,14 +2144,19 @@ module Herb
|
|
|
2143
2144
|
|
|
2144
2145
|
attr_reader tag_closing: Herb::Token?
|
|
2145
2146
|
|
|
2146
|
-
|
|
2147
|
-
|
|
2147
|
+
attr_reader prism_node: String?
|
|
2148
|
+
|
|
2149
|
+
# : (String, Location, Array[Herb::Errors::Error], Herb::Token?, Herb::Token?, Herb::Token?, String?) -> void
|
|
2150
|
+
def initialize: (String, Location, Array[Herb::Errors::Error], Herb::Token?, Herb::Token?, Herb::Token?, String?) -> void
|
|
2148
2151
|
|
|
2149
2152
|
# : () -> String
|
|
2150
2153
|
def self.type: () -> String
|
|
2151
2154
|
|
|
2152
|
-
# : (?tag_opening: Herb::Token?, ?content: Herb::Token?, ?tag_closing: Herb::Token?, ?location: Location, ?errors: Array[Herb::Errors::Error]) -> ERBYieldNode
|
|
2153
|
-
def self.build: (?tag_opening: Herb::Token?, ?content: Herb::Token?, ?tag_closing: Herb::Token?, ?location: Location, ?errors: Array[Herb::Errors::Error]) -> ERBYieldNode
|
|
2155
|
+
# : (?tag_opening: Herb::Token?, ?content: Herb::Token?, ?tag_closing: Herb::Token?, ?prism_node: String?, ?location: Location, ?errors: Array[Herb::Errors::Error]) -> ERBYieldNode
|
|
2156
|
+
def self.build: (?tag_opening: Herb::Token?, ?content: Herb::Token?, ?tag_closing: Herb::Token?, ?prism_node: String?, ?location: Location, ?errors: Array[Herb::Errors::Error]) -> ERBYieldNode
|
|
2157
|
+
|
|
2158
|
+
# : () -> Prism::node?
|
|
2159
|
+
def deserialized_prism_node: () -> Prism::node?
|
|
2154
2160
|
|
|
2155
2161
|
# : () -> serialized_erb_yield_node
|
|
2156
2162
|
def to_hash: () -> serialized_erb_yield_node
|
data/sig/herb/bootstrap.rbs
CHANGED
data/sig/herb/dev/runner.rbs
CHANGED
|
@@ -65,6 +65,8 @@ module Herb
|
|
|
65
65
|
|
|
66
66
|
def visit_erb_comment_node: (untyped node) -> untyped
|
|
67
67
|
|
|
68
|
+
def visit_erb_strict_locals_node: (untyped node) -> untyped
|
|
69
|
+
|
|
68
70
|
def visit_erb_control_node: (untyped node) ?{ (?) -> untyped } -> untyped
|
|
69
71
|
|
|
70
72
|
def visit_erb_if_node: (untyped node) -> untyped
|
|
@@ -105,9 +107,9 @@ module Herb
|
|
|
105
107
|
|
|
106
108
|
def visit_erb_block_end_node: (untyped node, ?escaped: untyped) -> untyped
|
|
107
109
|
|
|
108
|
-
def
|
|
110
|
+
def visit_erb_case_parts: (untyped node) -> untyped
|
|
109
111
|
|
|
110
|
-
def visit_erb_control_with_parts: (untyped node, *untyped parts) -> untyped
|
|
112
|
+
def visit_erb_control_with_parts: (untyped node, *untyped parts) ?{ (?) -> untyped } -> untyped
|
|
111
113
|
|
|
112
114
|
private
|
|
113
115
|
|
|
@@ -188,7 +190,7 @@ module Herb
|
|
|
188
190
|
|
|
189
191
|
def leading_space_follows_newline?: () -> untyped
|
|
190
192
|
|
|
191
|
-
def
|
|
193
|
+
def preceding_token_value_ends_with_newline?: () -> untyped
|
|
192
194
|
|
|
193
195
|
def extract_and_remove_leading_space!: () -> untyped
|
|
194
196
|
|
|
@@ -205,6 +207,15 @@ module Herb
|
|
|
205
207
|
# : (bool) -> void
|
|
206
208
|
def settle_pending_trim_newline!: (bool) -> void
|
|
207
209
|
|
|
210
|
+
# : (Array[untyped]) -> void
|
|
211
|
+
def skip_case_children: (Array[untyped]) -> void
|
|
212
|
+
|
|
213
|
+
# : (untyped) -> bool
|
|
214
|
+
def follows_trimmed_statement_tag?: (untyped) -> bool
|
|
215
|
+
|
|
216
|
+
# : () -> void
|
|
217
|
+
def drop_pending_trim_newline!: () -> void
|
|
218
|
+
|
|
208
219
|
def save_pending_leading_whitespace!: (untyped whitespace) -> untyped
|
|
209
220
|
|
|
210
221
|
def restore_pending_leading_whitespace!: () -> untyped
|
|
@@ -132,6 +132,9 @@ module Herb
|
|
|
132
132
|
# : (untyped) -> void
|
|
133
133
|
def visit_erb_content_node: (untyped) -> void
|
|
134
134
|
|
|
135
|
+
# : (untyped) -> void
|
|
136
|
+
def visit_ruby_literal_node: (untyped) -> void
|
|
137
|
+
|
|
135
138
|
# : (untyped) -> void
|
|
136
139
|
def visit_erb_yield_node: (untyped) -> void
|
|
137
140
|
|
|
@@ -14,15 +14,29 @@ module Herb
|
|
|
14
14
|
|
|
15
15
|
COMMENT: Regexp
|
|
16
16
|
|
|
17
|
+
FOREIGN_ATTRIBUTE: String
|
|
18
|
+
|
|
19
|
+
FOREIGN_ROOTS: Hash[Symbol, String]
|
|
20
|
+
|
|
21
|
+
SVG_INTEGRATION_POINTS: Array[String]
|
|
22
|
+
|
|
23
|
+
MATH_INTEGRATION_POINTS: Array[String]
|
|
24
|
+
|
|
17
25
|
# : (String) -> bool
|
|
18
26
|
def self.marker?: (String) -> bool
|
|
19
27
|
|
|
20
28
|
# : (String) -> String
|
|
21
29
|
def self.seeds_expression: (String) -> String
|
|
22
30
|
|
|
31
|
+
# : (Symbol, String) -> Symbol
|
|
32
|
+
def self.namespace_within: (Symbol, String) -> Symbol
|
|
33
|
+
|
|
23
34
|
# : (Integer, Symbol) -> String
|
|
24
35
|
def slot_open: (Integer, Symbol) -> String
|
|
25
36
|
|
|
37
|
+
# : (String, Symbol) -> String
|
|
38
|
+
def foreign: (String, Symbol) -> String
|
|
39
|
+
|
|
26
40
|
# : (Array[[Integer, Symbol, String?]]) -> String
|
|
27
41
|
def element_anchors: (Array[[ Integer, Symbol, String? ]]) -> String
|
|
28
42
|
|
|
@@ -404,6 +404,9 @@ module Herb
|
|
|
404
404
|
|
|
405
405
|
def erb_output_node: (untyped code) -> untyped
|
|
406
406
|
|
|
407
|
+
# : (Array[untyped], Integer) -> String
|
|
408
|
+
def attribute_spacing: (Array[untyped], Integer) -> String
|
|
409
|
+
|
|
407
410
|
private
|
|
408
411
|
|
|
409
412
|
def visit_children_with_paths: (untyped children) -> untyped
|
|
@@ -526,16 +529,17 @@ module Herb
|
|
|
526
529
|
# : (untyped) -> String?
|
|
527
530
|
def attribute_expression_for: (untyped) -> String?
|
|
528
531
|
|
|
529
|
-
|
|
532
|
+
# : (untyped, ?Symbol) -> untyped
|
|
533
|
+
def insert_markers: (untyped, ?Symbol) -> untyped
|
|
530
534
|
|
|
531
535
|
# : (untyped) -> Integer?
|
|
532
536
|
def content_anchor_index: (untyped) -> Integer?
|
|
533
537
|
|
|
534
|
-
# : (untyped, Integer?) -> void
|
|
535
|
-
def mark_branches: (untyped, Integer?) -> void
|
|
538
|
+
# : (untyped, Integer?, ?Symbol) -> void
|
|
539
|
+
def mark_branches: (untyped, Integer?, ?Symbol) -> void
|
|
536
540
|
|
|
537
|
-
# : (String, Array[untyped]) -> void
|
|
538
|
-
def park_branch: (String, Array[untyped]) -> void
|
|
541
|
+
# : (String, String, Array[untyped], Symbol) -> void
|
|
542
|
+
def park_branch: (String, String, Array[untyped], Symbol) -> void
|
|
539
543
|
|
|
540
544
|
# : (Herb::AST::DocumentNode) -> void
|
|
541
545
|
def append_statics: (Herb::AST::DocumentNode) -> void
|
|
@@ -558,25 +562,25 @@ module Herb
|
|
|
558
562
|
# : (untyped) -> Array[Array[Herb::AST::Node]]
|
|
559
563
|
def branch_bodies: (untyped) -> Array[Array[Herb::AST::Node]]
|
|
560
564
|
|
|
561
|
-
# : (Herb::AST::Node, Integer?) -> void
|
|
562
|
-
def wrap_items: (Herb::AST::Node, Integer?) -> void
|
|
565
|
+
# : (Herb::AST::Node, Integer?, ?Symbol) -> void
|
|
566
|
+
def wrap_items: (Herb::AST::Node, Integer?, ?Symbol) -> void
|
|
563
567
|
|
|
564
568
|
# : (untyped) -> Array[String]?
|
|
565
569
|
def attribute_segments: (untyped) -> Array[String]?
|
|
566
570
|
|
|
567
|
-
# : (Integer, untyped) -> void
|
|
568
|
-
def park_keyed: (Integer, untyped) -> void
|
|
571
|
+
# : (Integer, untyped, Symbol) -> void
|
|
572
|
+
def park_keyed: (Integer, untyped, Symbol) -> void
|
|
569
573
|
|
|
570
|
-
# : (untyped, untyped) -> Array[untyped]?
|
|
571
|
-
def park_item: (untyped, untyped) -> Array[untyped]?
|
|
574
|
+
# : (untyped, untyped, Symbol) -> Array[untyped]?
|
|
575
|
+
def park_item: (untyped, untyped, Symbol) -> Array[untyped]?
|
|
572
576
|
|
|
573
577
|
def anchor_attributes: (untyped node, ?untyped content_index) -> untyped
|
|
574
578
|
|
|
575
579
|
# : (Slot) -> String?
|
|
576
580
|
def anchor_name_for: (Slot) -> String?
|
|
577
581
|
|
|
578
|
-
# : (Herb::AST::Node) { (Array[untyped]) -> void } -> void
|
|
579
|
-
def each_child_array: (Herb::AST::Node) { (Array[untyped]) -> void } -> void
|
|
582
|
+
# : (Herb::AST::Node, ?Symbol) { (Array[untyped]) -> void } -> void
|
|
583
|
+
def each_child_array: (Herb::AST::Node, ?Symbol) { (Array[untyped]) -> void } -> void
|
|
580
584
|
|
|
581
585
|
# : (Herb::AST::DocumentNode) -> void
|
|
582
586
|
def wrap_region: (Herb::AST::DocumentNode) -> void
|
|
@@ -368,11 +368,14 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* create_interpolated_attribute_value(
|
|
|
368
368
|
}
|
|
369
369
|
}
|
|
370
370
|
|
|
371
|
+
token_T* open_quote = create_synthetic_token(allocator, "\"", TOKEN_QUOTE, start_position, start_position);
|
|
372
|
+
token_T* close_quote = create_synthetic_token(allocator, "\"", TOKEN_QUOTE, end_position, end_position);
|
|
373
|
+
|
|
371
374
|
return ast_html_attribute_value_node_init(
|
|
372
|
-
|
|
375
|
+
open_quote,
|
|
373
376
|
value_children,
|
|
374
|
-
|
|
375
|
-
|
|
377
|
+
close_quote,
|
|
378
|
+
true,
|
|
376
379
|
start_position,
|
|
377
380
|
end_position,
|
|
378
381
|
hb_array_init(0, allocator),
|
|
@@ -132,6 +132,50 @@ static bool build_scope_options_from_context(
|
|
|
132
132
|
return built;
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
static bool symbol_node_equals(pm_node_t* node, const char* name) {
|
|
136
|
+
if (!node || node->type != PM_SYMBOL_NODE) { return false; }
|
|
137
|
+
|
|
138
|
+
pm_symbol_node_t* symbol = (pm_symbol_node_t*) node;
|
|
139
|
+
size_t length = pm_string_length(&symbol->unescaped);
|
|
140
|
+
|
|
141
|
+
return length == strlen(name) && strncmp((const char*) pm_string_source(&symbol->unescaped), name, length) == 0;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
static bool asset_tag_resolves_at_render_time(pm_call_node_t* call_node, const char* helper_name) {
|
|
145
|
+
bool is_stylesheet_link_tag = string_equals(helper_name, "stylesheet_link_tag");
|
|
146
|
+
|
|
147
|
+
if (!is_stylesheet_link_tag && !string_equals(helper_name, "javascript_include_tag")) { return false; }
|
|
148
|
+
if (!call_node || !call_node->arguments) { return false; }
|
|
149
|
+
|
|
150
|
+
pm_node_list_t* arguments = &call_node->arguments->arguments;
|
|
151
|
+
|
|
152
|
+
for (size_t i = 0; i < arguments->size; i++) {
|
|
153
|
+
pm_node_t* argument = arguments->nodes[i];
|
|
154
|
+
|
|
155
|
+
if (argument->type == PM_SPLAT_NODE || argument->type == PM_ARRAY_NODE) { return true; }
|
|
156
|
+
|
|
157
|
+
if (is_stylesheet_link_tag && i == 0
|
|
158
|
+
&& (symbol_node_equals(argument, "all") || symbol_node_equals(argument, "app"))) {
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (argument->type != PM_KEYWORD_HASH_NODE) { continue; }
|
|
163
|
+
|
|
164
|
+
pm_keyword_hash_node_t* hash = (pm_keyword_hash_node_t*) argument;
|
|
165
|
+
|
|
166
|
+
for (size_t j = 0; j < hash->elements.size; j++) {
|
|
167
|
+
pm_node_t* element = hash->elements.nodes[j];
|
|
168
|
+
if (element->type != PM_ASSOC_NODE) { continue; }
|
|
169
|
+
|
|
170
|
+
pm_assoc_node_t* assoc = (pm_assoc_node_t*) element;
|
|
171
|
+
|
|
172
|
+
if (symbol_node_equals(assoc->key, "integrity") && assoc->value->type != PM_STRING_NODE) { return true; }
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
|
|
135
179
|
static tag_helper_parse_context_T* parse_tag_helper_content(
|
|
136
180
|
const char* content_string,
|
|
137
181
|
const char* original_source,
|
|
@@ -181,7 +225,8 @@ static tag_helper_parse_context_T* parse_tag_helper_content(
|
|
|
181
225
|
.found = false };
|
|
182
226
|
pm_visit_node(parse_context->root, search_tag_helper_node, &search);
|
|
183
227
|
|
|
184
|
-
if (!search.found
|
|
228
|
+
if (!search.found
|
|
229
|
+
|| asset_tag_resolves_at_render_time(parse_context->info->call_node, search.matched_handler->name)) {
|
|
185
230
|
tag_helper_info_free(&parse_context->info);
|
|
186
231
|
pm_node_destroy(&parse_context->parser, parse_context->root);
|
|
187
232
|
pm_parser_free(&parse_context->parser);
|
|
@@ -252,13 +297,17 @@ position_T byte_offset_to_position(const char* source, size_t offset) {
|
|
|
252
297
|
|
|
253
298
|
if (!source) { return position; }
|
|
254
299
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
300
|
+
const char* cursor = source;
|
|
301
|
+
const char* end = source + strnlen(source, offset);
|
|
302
|
+
const char* newline = NULL;
|
|
303
|
+
|
|
304
|
+
while ((newline = memchr(cursor, '\n', (size_t) (end - cursor))) != NULL) {
|
|
305
|
+
position.line++;
|
|
306
|
+
cursor = newline + 1;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
for (; cursor < end; cursor++) {
|
|
310
|
+
if (!utf8_is_valid_continuation_byte((unsigned char) *cursor)) { position.column++; }
|
|
262
311
|
}
|
|
263
312
|
|
|
264
313
|
return position;
|
|
@@ -277,33 +326,40 @@ position_T prism_location_to_position_with_offset(
|
|
|
277
326
|
size_t offset_in_erb = (size_t) (pm_location->start - erb_content_source);
|
|
278
327
|
size_t total_offset = erb_content_offset + offset_in_erb;
|
|
279
328
|
|
|
280
|
-
|
|
281
|
-
|
|
329
|
+
if (strnlen(original_source, total_offset) < total_offset) {
|
|
330
|
+
return byte_offset_to_position(original_source, erb_content_offset);
|
|
331
|
+
}
|
|
282
332
|
|
|
283
333
|
return byte_offset_to_position(original_source, total_offset);
|
|
284
334
|
}
|
|
285
335
|
|
|
286
336
|
size_t calculate_byte_offset_from_position(const char* source, position_T position) {
|
|
287
337
|
if (!source) { return 0; }
|
|
338
|
+
if (position.line == 0) { return strlen(source); }
|
|
339
|
+
|
|
340
|
+
const char* line_start = source;
|
|
341
|
+
|
|
342
|
+
for (uint32_t line = 1; line < position.line; line++) {
|
|
343
|
+
const char* newline = strchr(line_start, '\n');
|
|
288
344
|
|
|
289
|
-
|
|
290
|
-
|
|
345
|
+
if (!newline) { return (size_t) (line_start - source) + strlen(line_start); }
|
|
346
|
+
|
|
347
|
+
line_start = newline + 1;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
size_t offset = (size_t) (line_start - source);
|
|
291
351
|
uint32_t column = 1;
|
|
292
352
|
|
|
293
353
|
while (source[offset] != '\0') {
|
|
294
|
-
if (
|
|
354
|
+
if (column == position.column) { return offset; }
|
|
355
|
+
if (source[offset] == '\n') { break; }
|
|
295
356
|
|
|
296
|
-
if (source[offset]
|
|
297
|
-
line++;
|
|
298
|
-
column = 1;
|
|
299
|
-
} else if (!utf8_is_valid_continuation_byte((unsigned char) source[offset])) {
|
|
300
|
-
column++;
|
|
301
|
-
}
|
|
357
|
+
if (!utf8_is_valid_continuation_byte((unsigned char) source[offset])) { column++; }
|
|
302
358
|
|
|
303
359
|
offset++;
|
|
304
360
|
}
|
|
305
361
|
|
|
306
|
-
return offset;
|
|
362
|
+
return offset + strlen(source + offset);
|
|
307
363
|
}
|
|
308
364
|
|
|
309
365
|
static void prism_node_location_to_positions(
|
data/src/analyze/analyze.c
CHANGED
|
@@ -37,31 +37,11 @@
|
|
|
37
37
|
static analyzed_ruby_T* herb_analyze_ruby(hb_string_T source) {
|
|
38
38
|
analyzed_ruby_T* analyzed = init_analyzed_ruby(source);
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
pm_visit_node(analyzed->root,
|
|
43
|
-
|
|
44
|
-
pm_visit_node(analyzed->root,
|
|
45
|
-
pm_visit_node(analyzed->root, search_for_nodes, analyzed);
|
|
46
|
-
pm_visit_node(analyzed->root, search_until_nodes, analyzed);
|
|
47
|
-
pm_visit_node(analyzed->root, search_begin_nodes, analyzed);
|
|
48
|
-
pm_visit_node(analyzed->root, search_unless_nodes, analyzed);
|
|
49
|
-
pm_visit_node(analyzed->root, search_when_nodes, analyzed);
|
|
50
|
-
pm_visit_node(analyzed->root, search_in_nodes, analyzed);
|
|
51
|
-
|
|
52
|
-
search_unexpected_elsif_nodes(analyzed);
|
|
53
|
-
search_unexpected_else_nodes(analyzed);
|
|
54
|
-
search_unexpected_end_nodes(analyzed);
|
|
55
|
-
search_unexpected_when_nodes(analyzed);
|
|
56
|
-
search_unexpected_in_nodes(analyzed);
|
|
57
|
-
|
|
58
|
-
search_unexpected_rescue_nodes(analyzed);
|
|
59
|
-
search_unexpected_ensure_nodes(analyzed);
|
|
60
|
-
search_yield_nodes(analyzed->root, analyzed);
|
|
61
|
-
search_then_keywords(analyzed->root, analyzed);
|
|
62
|
-
search_unexpected_block_closing_nodes(analyzed);
|
|
63
|
-
|
|
64
|
-
if (!analyzed->valid) { pm_visit_node(analyzed->root, search_unclosed_control_flows, analyzed); }
|
|
40
|
+
if (analyzed->valid) { return analyzed; }
|
|
41
|
+
|
|
42
|
+
pm_visit_node(analyzed->root, search_control_flow_nodes, analyzed);
|
|
43
|
+
search_unexpected_keyword_errors(analyzed);
|
|
44
|
+
pm_visit_node(analyzed->root, search_unclosed_control_flows, analyzed);
|
|
65
45
|
|
|
66
46
|
return analyzed;
|
|
67
47
|
}
|