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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -0
  3. data/ext/herb/extconf.rb +1 -0
  4. data/ext/herb/extension.c +108 -0
  5. data/herb.gemspec +1 -1
  6. data/lib/herb/action_view/render_analyzer.rb +1057 -0
  7. data/lib/herb/ast/erb_render_node.rb +155 -0
  8. data/lib/herb/bootstrap.rb +0 -1
  9. data/lib/herb/cli.rb +253 -19
  10. data/lib/herb/colors.rb +18 -0
  11. data/lib/herb/configuration.rb +49 -13
  12. data/lib/herb/defaults.yml +3 -0
  13. data/lib/herb/dev/runner.rb +445 -0
  14. data/lib/herb/dev/server.rb +207 -0
  15. data/lib/herb/dev/server_entry.rb +128 -0
  16. data/lib/herb/diff_operation.rb +34 -0
  17. data/lib/herb/diff_result.rb +59 -0
  18. data/lib/herb/engine/compiler.rb +56 -3
  19. data/lib/herb/engine/validators/render_validator.rb +92 -0
  20. data/lib/herb/engine.rb +58 -4
  21. data/lib/herb/html/util.rb +16 -0
  22. data/lib/herb/project.rb +1 -6
  23. data/lib/herb/version.rb +1 -1
  24. data/lib/herb.rb +41 -5
  25. data/sig/herb/action_view/render_analyzer.rbs +122 -0
  26. data/sig/herb/ast/erb_render_node.rbs +29 -0
  27. data/sig/herb/colors.rbs +12 -0
  28. data/sig/herb/configuration.rbs +20 -1
  29. data/sig/herb/dev/runner.rbs +59 -0
  30. data/sig/herb/dev/server.rbs +50 -0
  31. data/sig/herb/dev/server_entry.rbs +51 -0
  32. data/sig/herb/diff_operation.rbs +34 -0
  33. data/sig/herb/diff_result.rbs +34 -0
  34. data/sig/herb/engine/compiler.rbs +6 -0
  35. data/sig/herb/engine/validators/render_validator.rbs +21 -0
  36. data/sig/herb/engine.rbs +15 -0
  37. data/sig/herb/html/util.rbs +13 -0
  38. data/sig/herb.rbs +12 -2
  39. data/sig/herb_c_extension.rbs +1 -1
  40. data/sig/vendor/did_you_mean.rbs +6 -0
  41. data/sig/vendor/parallel.rbs +4 -0
  42. data/src/analyze/action_view/attribute_extraction_helpers.c +3 -2
  43. data/src/diff/herb_diff.c +137 -0
  44. data/src/diff/herb_diff_attributes.c +207 -0
  45. data/src/diff/herb_diff_children.c +518 -0
  46. data/src/diff/herb_diff_helpers.c +114 -0
  47. data/src/diff/herb_diff_nodes.c +707 -0
  48. data/src/diff/herb_hash.c +42 -0
  49. data/src/diff/herb_hash_index_map.c +47 -0
  50. data/src/diff/herb_hash_map.c +104 -0
  51. data/src/diff/herb_hash_tree.c +680 -0
  52. data/src/include/diff/herb_diff.h +118 -0
  53. data/src/include/diff/herb_hash.h +25 -0
  54. data/src/include/diff/herb_hash_index_map.h +32 -0
  55. data/src/include/diff/herb_hash_map.h +30 -0
  56. data/src/include/herb.h +1 -0
  57. data/src/include/version.h +1 -1
  58. data/templates/javascript/packages/core/src/config.ts.erb +43 -0
  59. data/templates/rust/src/ast/nodes.rs.erb +1 -1
  60. data/templates/rust/src/config.rs.erb +50 -0
  61. data/templates/src/diff/herb_diff_helpers.c.erb +38 -0
  62. data/templates/src/diff/herb_diff_nodes.c.erb +224 -0
  63. data/templates/src/diff/herb_hash_tree.c.erb +147 -0
  64. data/templates/template.rb +4 -4
  65. 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
+ }
@@ -66,9 +66,9 @@ module Herb
66
66
  end
67
67
 
68
68
  class ArrayField < Field
69
- def initialize(kind:, **options)
69
+ def initialize(kind:, **)
70
70
  @kind = kind
71
- super(**options)
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:, **options)
110
+ def initialize(kind:, **)
111
111
  @kind = kind
112
- super(**options)
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.9.7
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.0.0
428
+ version: 3.2.0
391
429
  required_rubygems_version: !ruby/object:Gem::Requirement
392
430
  requirements:
393
431
  - - ">="