herb 0.9.7 → 0.10.0
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/README.md +1 -0
- data/ext/herb/extconf.rb +1 -0
- data/ext/herb/extension.c +108 -0
- data/herb.gemspec +1 -1
- data/lib/herb/action_view/render_analyzer.rb +1057 -0
- data/lib/herb/ast/erb_render_node.rb +155 -0
- data/lib/herb/bootstrap.rb +0 -1
- data/lib/herb/cli.rb +253 -19
- data/lib/herb/colors.rb +18 -0
- data/lib/herb/configuration.rb +49 -13
- data/lib/herb/defaults.yml +3 -0
- data/lib/herb/dev/runner.rb +445 -0
- data/lib/herb/dev/server.rb +207 -0
- data/lib/herb/dev/server_entry.rb +128 -0
- data/lib/herb/diff_operation.rb +34 -0
- data/lib/herb/diff_result.rb +59 -0
- data/lib/herb/engine/compiler.rb +56 -3
- data/lib/herb/engine/validators/render_validator.rb +92 -0
- data/lib/herb/engine.rb +58 -4
- data/lib/herb/html/util.rb +16 -0
- data/lib/herb/project.rb +1 -6
- data/lib/herb/version.rb +1 -1
- data/lib/herb.rb +41 -5
- data/sig/herb/action_view/render_analyzer.rbs +122 -0
- data/sig/herb/ast/erb_render_node.rbs +29 -0
- data/sig/herb/colors.rbs +12 -0
- data/sig/herb/configuration.rbs +20 -1
- data/sig/herb/dev/runner.rbs +59 -0
- data/sig/herb/dev/server.rbs +50 -0
- data/sig/herb/dev/server_entry.rbs +51 -0
- data/sig/herb/diff_operation.rbs +34 -0
- data/sig/herb/diff_result.rbs +34 -0
- data/sig/herb/engine/compiler.rbs +6 -0
- data/sig/herb/engine/validators/render_validator.rbs +21 -0
- data/sig/herb/engine.rbs +15 -0
- data/sig/herb/html/util.rbs +13 -0
- data/sig/herb.rbs +12 -2
- data/sig/herb_c_extension.rbs +1 -1
- data/sig/vendor/did_you_mean.rbs +6 -0
- data/sig/vendor/parallel.rbs +4 -0
- data/src/analyze/action_view/attribute_extraction_helpers.c +3 -2
- data/src/diff/herb_diff.c +137 -0
- data/src/diff/herb_diff_attributes.c +207 -0
- data/src/diff/herb_diff_children.c +518 -0
- data/src/diff/herb_diff_helpers.c +114 -0
- data/src/diff/herb_diff_nodes.c +707 -0
- data/src/diff/herb_hash.c +42 -0
- data/src/diff/herb_hash_index_map.c +47 -0
- data/src/diff/herb_hash_map.c +104 -0
- data/src/diff/herb_hash_tree.c +680 -0
- data/src/include/diff/herb_diff.h +118 -0
- data/src/include/diff/herb_hash.h +25 -0
- data/src/include/diff/herb_hash_index_map.h +32 -0
- data/src/include/diff/herb_hash_map.h +30 -0
- data/src/include/herb.h +1 -0
- data/src/include/version.h +1 -1
- data/templates/javascript/packages/core/src/config.ts.erb +43 -0
- data/templates/rust/src/ast/nodes.rs.erb +1 -1
- data/templates/rust/src/config.rs.erb +50 -0
- data/templates/src/diff/herb_diff_helpers.c.erb +38 -0
- data/templates/src/diff/herb_diff_nodes.c.erb +224 -0
- data/templates/src/diff/herb_hash_tree.c.erb +147 -0
- data/templates/template.rb +4 -4
- metadata +40 -2
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// Merkle tree hashing: each node's hash incorporates the hashes of its children,
|
|
2
|
+
// enabling O(1) subtree equality checks during tree diffing.
|
|
3
|
+
// Based on: Merkle, R. "A Digital Signature Based on a Conventional Encryption
|
|
4
|
+
// Function" (1987), Advances in Cryptology - CRYPTO '87.
|
|
5
|
+
// https://en.wikipedia.org/wiki/Merkle_tree
|
|
6
|
+
|
|
7
|
+
#include "../include/diff/herb_diff.h"
|
|
8
|
+
|
|
9
|
+
static herb_hash_T hash_token(herb_hash_T hash, const token_T* token) {
|
|
10
|
+
if (token == NULL) { return herb_hash_byte(hash, 0); }
|
|
11
|
+
|
|
12
|
+
hash = herb_hash_uint32(hash, (uint32_t) token->type);
|
|
13
|
+
hash = herb_hash_string(hash, token->value);
|
|
14
|
+
|
|
15
|
+
return hash;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static herb_hash_T hash_child_array(herb_hash_T hash, const hb_array_T* children, herb_hash_map_T* hash_map) {
|
|
19
|
+
if (children == NULL) { return herb_hash_byte(hash, 0); }
|
|
20
|
+
|
|
21
|
+
const size_t count = hb_array_size(children);
|
|
22
|
+
hash = herb_hash_uint64(hash, (uint64_t) count);
|
|
23
|
+
|
|
24
|
+
for (size_t index = 0; index < count; index++) {
|
|
25
|
+
const AST_NODE_T* child = (const AST_NODE_T*) hb_array_get(children, index);
|
|
26
|
+
herb_hash_T child_hash = herb_hash_tree(child, hash_map);
|
|
27
|
+
hash = herb_hash_combine(hash, child_hash);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return hash;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
herb_hash_T herb_hash_tree(const AST_NODE_T* node, herb_hash_map_T* hash_map) {
|
|
34
|
+
if (node == NULL) { return HERB_HASH_INIT; }
|
|
35
|
+
|
|
36
|
+
if (herb_hash_map_has(hash_map, node)) { return herb_hash_map_get(hash_map, node); }
|
|
37
|
+
|
|
38
|
+
herb_hash_T hash = HERB_HASH_INIT;
|
|
39
|
+
hash = herb_hash_uint32(hash, (uint32_t) node->type);
|
|
40
|
+
|
|
41
|
+
switch (node->type) {
|
|
42
|
+
<%- nodes.each do |node| -%>
|
|
43
|
+
case <%= node.type %>: {
|
|
44
|
+
<%- hashable_fields = node.fields.reject(&:always_invisible?).reject { |field| field.is_a?(Herb::Template::PrismNodeField) } -%>
|
|
45
|
+
<%- if hashable_fields.any? -%>
|
|
46
|
+
const <%= node.struct_type %>* <%= node.human %> = (const <%= node.struct_type %>*) node;
|
|
47
|
+
<%- hashable_fields.each do |field| -%>
|
|
48
|
+
|
|
49
|
+
<%- case field -%>
|
|
50
|
+
<%- when Herb::Template::TokenField -%>
|
|
51
|
+
hash = hash_token(hash, <%= node.human %>-><%= field.name %>);
|
|
52
|
+
<%- when Herb::Template::StringField, Herb::Template::ElementSourceField -%>
|
|
53
|
+
hash = herb_hash_string(hash, <%= node.human %>-><%= field.name %>);
|
|
54
|
+
<%- when Herb::Template::ArrayField -%>
|
|
55
|
+
hash = hash_child_array(hash, <%= node.human %>-><%= field.name %>, hash_map);
|
|
56
|
+
<%- when Herb::Template::NodeField, Herb::Template::BorrowedNodeField -%>
|
|
57
|
+
hash = herb_hash_combine(hash, herb_hash_tree((const AST_NODE_T*) <%= node.human %>-><%= field.name %>, hash_map));
|
|
58
|
+
<%- when Herb::Template::BooleanField -%>
|
|
59
|
+
hash = herb_hash_bool(hash, <%= node.human %>-><%= field.name %>);
|
|
60
|
+
<%- when Herb::Template::LocationField -%>
|
|
61
|
+
// skip location field: <%= field.name %>
|
|
62
|
+
<%- end -%>
|
|
63
|
+
<%- end -%>
|
|
64
|
+
<%- end -%>
|
|
65
|
+
} break;
|
|
66
|
+
|
|
67
|
+
<%- end -%>
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
herb_hash_map_set(hash_map, node, hash);
|
|
71
|
+
|
|
72
|
+
return hash;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static herb_hash_T identity_hash_attributes(const hb_array_T* attributes, const herb_hash_map_T* hash_map) {
|
|
76
|
+
if (attributes == NULL) { return HERB_HASH_INIT; }
|
|
77
|
+
|
|
78
|
+
const size_t count = hb_array_size(attributes);
|
|
79
|
+
herb_hash_T combined = HERB_HASH_INIT;
|
|
80
|
+
|
|
81
|
+
for (size_t index = 0; index < count; index++) {
|
|
82
|
+
const AST_NODE_T* attribute = (const AST_NODE_T*) hb_array_get(attributes, index);
|
|
83
|
+
herb_hash_T attribute_hash = herb_hash_map_get(hash_map, attribute);
|
|
84
|
+
combined ^= attribute_hash;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return combined;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
herb_hash_T herb_hash_node_move_identity(const AST_NODE_T* node, const herb_hash_map_T* hash_map) {
|
|
91
|
+
if (node == NULL) { return HERB_HASH_INIT; }
|
|
92
|
+
|
|
93
|
+
herb_hash_T hash = HERB_HASH_INIT;
|
|
94
|
+
hash = herb_hash_uint32(hash, (uint32_t) node->type);
|
|
95
|
+
|
|
96
|
+
switch (node->type) {
|
|
97
|
+
case AST_HTML_ELEMENT_NODE: {
|
|
98
|
+
const AST_HTML_ELEMENT_NODE_T* element = (const AST_HTML_ELEMENT_NODE_T*) node;
|
|
99
|
+
hash = hash_token(hash, element->tag_name);
|
|
100
|
+
|
|
101
|
+
if (element->open_tag != NULL) {
|
|
102
|
+
const AST_HTML_OPEN_TAG_NODE_T* open_tag = (const AST_HTML_OPEN_TAG_NODE_T*) element->open_tag;
|
|
103
|
+
hash = herb_hash_combine(hash, identity_hash_attributes(open_tag->children, hash_map));
|
|
104
|
+
}
|
|
105
|
+
} break;
|
|
106
|
+
|
|
107
|
+
case AST_HTML_CONDITIONAL_ELEMENT_NODE: {
|
|
108
|
+
const AST_HTML_CONDITIONAL_ELEMENT_NODE_T* element = (const AST_HTML_CONDITIONAL_ELEMENT_NODE_T*) node;
|
|
109
|
+
hash = hash_token(hash, element->tag_name);
|
|
110
|
+
|
|
111
|
+
if (element->open_tag != NULL) {
|
|
112
|
+
hash = herb_hash_combine(hash, identity_hash_attributes(element->open_tag->children, hash_map));
|
|
113
|
+
}
|
|
114
|
+
} break;
|
|
115
|
+
|
|
116
|
+
default: {
|
|
117
|
+
hash = herb_hash_map_get(hash_map, node);
|
|
118
|
+
} break;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return hash;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
herb_hash_T herb_hash_node_identity(const AST_NODE_T* node, const herb_hash_map_T* hash_map) {
|
|
125
|
+
if (node == NULL) { return HERB_HASH_INIT; }
|
|
126
|
+
|
|
127
|
+
herb_hash_T hash = HERB_HASH_INIT;
|
|
128
|
+
hash = herb_hash_uint32(hash, (uint32_t) node->type);
|
|
129
|
+
|
|
130
|
+
switch (node->type) {
|
|
131
|
+
case AST_HTML_ELEMENT_NODE: {
|
|
132
|
+
const AST_HTML_ELEMENT_NODE_T* element = (const AST_HTML_ELEMENT_NODE_T*) node;
|
|
133
|
+
hash = hash_token(hash, element->tag_name);
|
|
134
|
+
} break;
|
|
135
|
+
|
|
136
|
+
case AST_HTML_CONDITIONAL_ELEMENT_NODE: {
|
|
137
|
+
const AST_HTML_CONDITIONAL_ELEMENT_NODE_T* element = (const AST_HTML_CONDITIONAL_ELEMENT_NODE_T*) node;
|
|
138
|
+
hash = hash_token(hash, element->tag_name);
|
|
139
|
+
} break;
|
|
140
|
+
|
|
141
|
+
default: {
|
|
142
|
+
hash = herb_hash_map_get(hash_map, node);
|
|
143
|
+
} break;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return hash;
|
|
147
|
+
}
|
data/templates/template.rb
CHANGED
|
@@ -66,9 +66,9 @@ module Herb
|
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
class ArrayField < Field
|
|
69
|
-
def initialize(kind:, **
|
|
69
|
+
def initialize(kind:, **)
|
|
70
70
|
@kind = kind
|
|
71
|
-
super(**
|
|
71
|
+
super(**)
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
def ruby_type
|
|
@@ -107,9 +107,9 @@ module Herb
|
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
class NodeField < Field
|
|
110
|
-
def initialize(kind:, **
|
|
110
|
+
def initialize(kind:, **)
|
|
111
111
|
@kind = kind
|
|
112
|
-
super(**
|
|
112
|
+
super(**)
|
|
113
113
|
end
|
|
114
114
|
|
|
115
115
|
def c_type
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: herb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.10.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Marco Roth
|
|
@@ -36,8 +36,10 @@ files:
|
|
|
36
36
|
- herb.gemspec
|
|
37
37
|
- lib/herb.rb
|
|
38
38
|
- lib/herb/action_view/helper_registry.rb
|
|
39
|
+
- lib/herb/action_view/render_analyzer.rb
|
|
39
40
|
- lib/herb/ast.rb
|
|
40
41
|
- lib/herb/ast/erb_content_node.rb
|
|
42
|
+
- lib/herb/ast/erb_render_node.rb
|
|
41
43
|
- lib/herb/ast/helpers.rb
|
|
42
44
|
- lib/herb/ast/node.rb
|
|
43
45
|
- lib/herb/ast/nodes.rb
|
|
@@ -46,6 +48,11 @@ files:
|
|
|
46
48
|
- lib/herb/colors.rb
|
|
47
49
|
- lib/herb/configuration.rb
|
|
48
50
|
- lib/herb/defaults.yml
|
|
51
|
+
- lib/herb/dev/runner.rb
|
|
52
|
+
- lib/herb/dev/server.rb
|
|
53
|
+
- lib/herb/dev/server_entry.rb
|
|
54
|
+
- lib/herb/diff_operation.rb
|
|
55
|
+
- lib/herb/diff_result.rb
|
|
49
56
|
- lib/herb/engine.rb
|
|
50
57
|
- lib/herb/engine/compiler.rb
|
|
51
58
|
- lib/herb/engine/debug_visitor.rb
|
|
@@ -56,8 +63,10 @@ files:
|
|
|
56
63
|
- lib/herb/engine/validator.rb
|
|
57
64
|
- lib/herb/engine/validators/accessibility_validator.rb
|
|
58
65
|
- lib/herb/engine/validators/nesting_validator.rb
|
|
66
|
+
- lib/herb/engine/validators/render_validator.rb
|
|
59
67
|
- lib/herb/engine/validators/security_validator.rb
|
|
60
68
|
- lib/herb/errors.rb
|
|
69
|
+
- lib/herb/html/util.rb
|
|
61
70
|
- lib/herb/lex_result.rb
|
|
62
71
|
- lib/herb/location.rb
|
|
63
72
|
- lib/herb/parse_result.rb
|
|
@@ -74,14 +83,21 @@ files:
|
|
|
74
83
|
- lib/herb/warnings.rb
|
|
75
84
|
- sig/herb.rbs
|
|
76
85
|
- sig/herb/action_view/helper_registry.rbs
|
|
86
|
+
- sig/herb/action_view/render_analyzer.rbs
|
|
77
87
|
- sig/herb/ast.rbs
|
|
78
88
|
- sig/herb/ast/erb_content_node.rbs
|
|
89
|
+
- sig/herb/ast/erb_render_node.rbs
|
|
79
90
|
- sig/herb/ast/helpers.rbs
|
|
80
91
|
- sig/herb/ast/node.rbs
|
|
81
92
|
- sig/herb/ast/nodes.rbs
|
|
82
93
|
- sig/herb/bootstrap.rbs
|
|
83
94
|
- sig/herb/colors.rbs
|
|
84
95
|
- sig/herb/configuration.rbs
|
|
96
|
+
- sig/herb/dev/runner.rbs
|
|
97
|
+
- sig/herb/dev/server.rbs
|
|
98
|
+
- sig/herb/dev/server_entry.rbs
|
|
99
|
+
- sig/herb/diff_operation.rbs
|
|
100
|
+
- sig/herb/diff_result.rbs
|
|
85
101
|
- sig/herb/engine.rbs
|
|
86
102
|
- sig/herb/engine/compiler.rbs
|
|
87
103
|
- sig/herb/engine/debug.rbs
|
|
@@ -93,8 +109,10 @@ files:
|
|
|
93
109
|
- sig/herb/engine/validator.rbs
|
|
94
110
|
- sig/herb/engine/validators/accessibility_validator.rbs
|
|
95
111
|
- sig/herb/engine/validators/nesting_validator.rbs
|
|
112
|
+
- sig/herb/engine/validators/render_validator.rbs
|
|
96
113
|
- sig/herb/engine/validators/security_validator.rbs
|
|
97
114
|
- sig/herb/errors.rbs
|
|
115
|
+
- sig/herb/html/util.rbs
|
|
98
116
|
- sig/herb/lex_result.rbs
|
|
99
117
|
- sig/herb/location.rbs
|
|
100
118
|
- sig/herb/parse_result.rbs
|
|
@@ -113,6 +131,8 @@ files:
|
|
|
113
131
|
- sig/serialized.rbs
|
|
114
132
|
- sig/serialized_ast_errors.rbs
|
|
115
133
|
- sig/serialized_ast_nodes.rbs
|
|
134
|
+
- sig/vendor/did_you_mean.rbs
|
|
135
|
+
- sig/vendor/parallel.rbs
|
|
116
136
|
- src/analyze/action_view/attribute_extraction_helpers.c
|
|
117
137
|
- src/analyze/action_view/generated_handlers.c
|
|
118
138
|
- src/analyze/action_view/generated_handlers.h
|
|
@@ -145,6 +165,15 @@ files:
|
|
|
145
165
|
- src/ast/ast_nodes.c
|
|
146
166
|
- src/ast/ast_pretty_print.c
|
|
147
167
|
- src/ast/pretty_print.c
|
|
168
|
+
- src/diff/herb_diff.c
|
|
169
|
+
- src/diff/herb_diff_attributes.c
|
|
170
|
+
- src/diff/herb_diff_children.c
|
|
171
|
+
- src/diff/herb_diff_helpers.c
|
|
172
|
+
- src/diff/herb_diff_nodes.c
|
|
173
|
+
- src/diff/herb_hash.c
|
|
174
|
+
- src/diff/herb_hash_index_map.c
|
|
175
|
+
- src/diff/herb_hash_map.c
|
|
176
|
+
- src/diff/herb_hash_tree.c
|
|
148
177
|
- src/errors.c
|
|
149
178
|
- src/extract.c
|
|
150
179
|
- src/herb.c
|
|
@@ -170,6 +199,10 @@ files:
|
|
|
170
199
|
- src/include/ast/ast_nodes.h
|
|
171
200
|
- src/include/ast/ast_pretty_print.h
|
|
172
201
|
- src/include/ast/pretty_print.h
|
|
202
|
+
- src/include/diff/herb_diff.h
|
|
203
|
+
- src/include/diff/herb_hash.h
|
|
204
|
+
- src/include/diff/herb_hash_index_map.h
|
|
205
|
+
- src/include/diff/herb_hash_map.h
|
|
173
206
|
- src/include/errors.h
|
|
174
207
|
- src/include/extract.h
|
|
175
208
|
- src/include/herb.h
|
|
@@ -249,6 +282,7 @@ files:
|
|
|
249
282
|
- templates/java/org/herb/ast/Nodes.java.erb
|
|
250
283
|
- templates/java/org/herb/ast/Visitor.java.erb
|
|
251
284
|
- templates/javascript/packages/core/src/action-view-helpers.ts.erb
|
|
285
|
+
- templates/javascript/packages/core/src/config.ts.erb
|
|
252
286
|
- templates/javascript/packages/core/src/errors.ts.erb
|
|
253
287
|
- templates/javascript/packages/core/src/node-type-guards.ts.erb
|
|
254
288
|
- templates/javascript/packages/core/src/nodes.ts.erb
|
|
@@ -263,6 +297,7 @@ files:
|
|
|
263
297
|
- templates/lib/herb/visitor.rb.erb
|
|
264
298
|
- templates/rust/src/action_view_helpers.rs.erb
|
|
265
299
|
- templates/rust/src/ast/nodes.rs.erb
|
|
300
|
+
- templates/rust/src/config.rs.erb
|
|
266
301
|
- templates/rust/src/errors.rs.erb
|
|
267
302
|
- templates/rust/src/nodes.rs.erb
|
|
268
303
|
- templates/rust/src/union_types.rs.erb
|
|
@@ -276,6 +311,9 @@ files:
|
|
|
276
311
|
- templates/src/analyze/transform.c.erb
|
|
277
312
|
- templates/src/ast/ast_nodes.c.erb
|
|
278
313
|
- templates/src/ast/ast_pretty_print.c.erb
|
|
314
|
+
- templates/src/diff/herb_diff_helpers.c.erb
|
|
315
|
+
- templates/src/diff/herb_diff_nodes.c.erb
|
|
316
|
+
- templates/src/diff/herb_hash_tree.c.erb
|
|
279
317
|
- templates/src/errors.c.erb
|
|
280
318
|
- templates/src/include/analyze/action_view/helper_registry.h.erb
|
|
281
319
|
- templates/src/include/ast/ast_nodes.h.erb
|
|
@@ -387,7 +425,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
387
425
|
requirements:
|
|
388
426
|
- - ">="
|
|
389
427
|
- !ruby/object:Gem::Version
|
|
390
|
-
version: 3.
|
|
428
|
+
version: 3.2.0
|
|
391
429
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
392
430
|
requirements:
|
|
393
431
|
- - ">="
|