herb 0.8.10-arm-linux-gnu → 0.9.0-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/Makefile +11 -3
- data/README.md +64 -34
- data/Rakefile +48 -40
- data/config.yml +317 -34
- data/ext/herb/error_helpers.c +367 -140
- data/ext/herb/error_helpers.h +1 -0
- data/ext/herb/extconf.rb +67 -28
- data/ext/herb/extension.c +317 -51
- data/ext/herb/extension.h +1 -0
- data/ext/herb/extension_helpers.c +23 -14
- data/ext/herb/extension_helpers.h +2 -2
- data/ext/herb/nodes.c +537 -270
- data/ext/herb/nodes.h +1 -0
- data/herb.gemspec +3 -2
- 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/helpers.rb +3 -3
- data/lib/herb/ast/node.rb +15 -2
- data/lib/herb/ast/nodes.rb +1132 -157
- data/lib/herb/bootstrap.rb +87 -0
- data/lib/herb/cli.rb +341 -31
- data/lib/herb/configuration.rb +248 -0
- data/lib/herb/defaults.yml +32 -0
- data/lib/herb/engine/compiler.rb +78 -11
- data/lib/herb/engine/debug_visitor.rb +13 -3
- data/lib/herb/engine/error_formatter.rb +13 -9
- data/lib/herb/engine/parser_error_overlay.rb +10 -6
- data/lib/herb/engine/validator.rb +8 -3
- data/lib/herb/engine/validators/nesting_validator.rb +2 -2
- data/lib/herb/engine.rb +82 -35
- data/lib/herb/errors.rb +563 -88
- data/lib/herb/lex_result.rb +1 -0
- data/lib/herb/location.rb +7 -3
- data/lib/herb/parse_result.rb +12 -2
- data/lib/herb/parser_options.rb +57 -0
- data/lib/herb/position.rb +1 -0
- data/lib/herb/prism_inspect.rb +116 -0
- data/lib/herb/project.rb +923 -331
- data/lib/herb/range.rb +1 -0
- data/lib/herb/token.rb +7 -1
- data/lib/herb/version.rb +1 -1
- data/lib/herb/visitor.rb +37 -2
- data/lib/herb/warnings.rb +6 -1
- data/lib/herb.rb +35 -3
- data/sig/herb/ast/helpers.rbs +2 -2
- data/sig/herb/ast/node.rbs +12 -2
- data/sig/herb/ast/nodes.rbs +641 -128
- data/sig/herb/bootstrap.rbs +31 -0
- data/sig/herb/configuration.rbs +89 -0
- data/sig/herb/engine/compiler.rbs +9 -1
- data/sig/herb/engine/debug_visitor.rbs +2 -0
- data/sig/herb/engine/validator.rbs +5 -1
- data/sig/herb/engine.rbs +17 -3
- data/sig/herb/errors.rbs +258 -63
- data/sig/herb/location.rbs +4 -0
- data/sig/herb/parse_result.rbs +4 -2
- data/sig/herb/parser_options.rbs +42 -0
- data/sig/herb/position.rbs +1 -0
- data/sig/herb/prism_inspect.rbs +28 -0
- data/sig/herb/range.rbs +1 -0
- data/sig/herb/token.rbs +6 -0
- data/sig/herb/visitor.rbs +25 -4
- data/sig/herb/warnings.rbs +6 -1
- data/sig/herb.rbs +14 -0
- data/sig/herb_c_extension.rbs +5 -2
- data/sig/serialized_ast_errors.rbs +54 -6
- data/sig/serialized_ast_nodes.rbs +60 -6
- data/src/analyze/action_view/attribute_extraction_helpers.c +290 -0
- data/src/analyze/action_view/content_tag.c +70 -0
- data/src/analyze/action_view/link_to.c +143 -0
- data/src/analyze/action_view/registry.c +60 -0
- data/src/analyze/action_view/tag.c +64 -0
- data/src/analyze/action_view/tag_helper_node_builders.c +305 -0
- data/src/analyze/action_view/tag_helpers.c +748 -0
- data/src/analyze/action_view/turbo_frame_tag.c +88 -0
- data/src/analyze/analyze.c +882 -0
- data/src/{analyzed_ruby.c → analyze/analyzed_ruby.c} +13 -11
- data/src/analyze/builders.c +343 -0
- data/src/analyze/conditional_elements.c +594 -0
- data/src/analyze/conditional_open_tags.c +640 -0
- data/src/analyze/control_type.c +250 -0
- data/src/{analyze_helpers.c → analyze/helpers.c} +48 -23
- data/src/analyze/invalid_structures.c +193 -0
- data/src/{analyze_missing_end.c → analyze/missing_end.c} +33 -22
- data/src/analyze/parse_errors.c +84 -0
- data/src/analyze/prism_annotate.c +397 -0
- data/src/{analyze_transform.c → analyze/transform.c} +17 -3
- data/src/ast_node.c +17 -7
- data/src/ast_nodes.c +662 -387
- data/src/ast_pretty_print.c +190 -6
- data/src/errors.c +1076 -520
- data/src/extract.c +145 -49
- data/src/herb.c +52 -34
- data/src/html_util.c +241 -12
- data/src/include/analyze/action_view/attribute_extraction_helpers.h +36 -0
- data/src/include/analyze/action_view/tag_helper_handler.h +41 -0
- data/src/include/analyze/action_view/tag_helper_node_builders.h +70 -0
- data/src/include/analyze/action_view/tag_helpers.h +38 -0
- data/src/include/{analyze.h → analyze/analyze.h} +14 -4
- data/src/include/{analyzed_ruby.h → analyze/analyzed_ruby.h} +3 -3
- data/src/include/analyze/builders.h +27 -0
- data/src/include/analyze/conditional_elements.h +9 -0
- data/src/include/analyze/conditional_open_tags.h +9 -0
- data/src/include/analyze/control_type.h +14 -0
- data/src/include/{analyze_helpers.h → analyze/helpers.h} +4 -2
- data/src/include/analyze/invalid_structures.h +11 -0
- data/src/include/analyze/prism_annotate.h +16 -0
- data/src/include/ast_node.h +11 -5
- data/src/include/ast_nodes.h +117 -38
- data/src/include/ast_pretty_print.h +5 -0
- data/src/include/element_source.h +3 -8
- data/src/include/errors.h +148 -55
- data/src/include/extract.h +21 -5
- data/src/include/herb.h +18 -6
- data/src/include/herb_prism_node.h +13 -0
- data/src/include/html_util.h +7 -2
- data/src/include/io.h +3 -1
- data/src/include/lex_helpers.h +29 -0
- data/src/include/lexer.h +1 -1
- data/src/include/lexer_peek_helpers.h +87 -13
- data/src/include/lexer_struct.h +2 -0
- data/src/include/location.h +2 -1
- data/src/include/parser.h +27 -2
- data/src/include/parser_helpers.h +19 -3
- data/src/include/pretty_print.h +10 -5
- data/src/include/prism_context.h +45 -0
- data/src/include/prism_helpers.h +10 -7
- data/src/include/prism_serialized.h +12 -0
- data/src/include/token.h +16 -4
- data/src/include/token_struct.h +10 -3
- data/src/include/utf8.h +2 -1
- data/src/include/util/hb_allocator.h +78 -0
- data/src/include/util/hb_arena.h +6 -1
- data/src/include/util/hb_arena_debug.h +12 -1
- data/src/include/util/hb_array.h +7 -3
- data/src/include/util/hb_buffer.h +6 -4
- data/src/include/util/hb_foreach.h +79 -0
- data/src/include/util/hb_narray.h +8 -4
- data/src/include/util/hb_string.h +56 -9
- data/src/include/util.h +6 -3
- data/src/include/version.h +1 -1
- data/src/io.c +3 -2
- data/src/lexer.c +42 -30
- data/src/lexer_peek_helpers.c +12 -74
- data/src/location.c +2 -2
- data/src/main.c +53 -28
- data/src/parser.c +783 -247
- data/src/parser_helpers.c +110 -23
- data/src/parser_match_tags.c +109 -48
- data/src/pretty_print.c +29 -24
- data/src/prism_helpers.c +30 -27
- data/src/ruby_parser.c +2 -0
- data/src/token.c +151 -66
- data/src/token_matchers.c +0 -1
- data/src/utf8.c +7 -6
- data/src/util/hb_allocator.c +341 -0
- data/src/util/hb_arena.c +81 -56
- data/src/util/hb_arena_debug.c +32 -17
- data/src/util/hb_array.c +30 -15
- data/src/util/hb_buffer.c +17 -21
- data/src/util/hb_narray.c +22 -7
- data/src/util/hb_string.c +49 -35
- data/src/util.c +21 -11
- data/src/visitor.c +47 -0
- data/templates/ext/herb/error_helpers.c.erb +24 -11
- data/templates/ext/herb/error_helpers.h.erb +1 -0
- data/templates/ext/herb/nodes.c.erb +50 -16
- data/templates/ext/herb/nodes.h.erb +1 -0
- data/templates/java/error_helpers.c.erb +1 -1
- data/templates/java/nodes.c.erb +30 -8
- data/templates/java/org/herb/ast/Errors.java.erb +24 -1
- data/templates/java/org/herb/ast/Nodes.java.erb +80 -21
- data/templates/javascript/packages/core/src/errors.ts.erb +16 -3
- data/templates/javascript/packages/core/src/node-type-guards.ts.erb +3 -1
- data/templates/javascript/packages/core/src/nodes.ts.erb +109 -32
- data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +13 -4
- data/templates/javascript/packages/node/extension/nodes.cpp.erb +43 -4
- data/templates/lib/herb/ast/nodes.rb.erb +88 -31
- data/templates/lib/herb/errors.rb.erb +15 -3
- data/templates/lib/herb/visitor.rb.erb +2 -2
- data/templates/rust/src/ast/nodes.rs.erb +97 -44
- data/templates/rust/src/errors.rs.erb +2 -1
- data/templates/rust/src/nodes.rs.erb +167 -15
- data/templates/rust/src/union_types.rs.erb +60 -0
- data/templates/rust/src/visitor.rs.erb +81 -0
- data/templates/src/{analyze_missing_end.c.erb → analyze/missing_end.c.erb} +9 -6
- data/templates/src/{analyze_transform.c.erb → analyze/transform.c.erb} +2 -2
- data/templates/src/ast_nodes.c.erb +34 -26
- data/templates/src/ast_pretty_print.c.erb +24 -5
- data/templates/src/errors.c.erb +60 -54
- data/templates/src/include/ast_nodes.h.erb +6 -2
- data/templates/src/include/ast_pretty_print.h.erb +5 -0
- data/templates/src/include/errors.h.erb +15 -11
- data/templates/src/include/util/hb_foreach.h.erb +20 -0
- data/templates/src/parser_match_tags.c.erb +10 -4
- data/templates/src/visitor.c.erb +2 -2
- data/templates/template.rb +204 -29
- data/templates/wasm/error_helpers.cpp.erb +9 -5
- data/templates/wasm/nodes.cpp.erb +41 -4
- metadata +57 -16
- data/src/analyze.c +0 -1608
- data/src/element_source.c +0 -12
- data/src/include/util/hb_system.h +0 -9
- data/src/util/hb_system.c +0 -30
|
@@ -5,8 +5,10 @@
|
|
|
5
5
|
#include "location.h"
|
|
6
6
|
#include "position.h"
|
|
7
7
|
#include "token.h"
|
|
8
|
+
#include "util/hb_allocator.h"
|
|
8
9
|
#include "util/hb_array.h"
|
|
9
10
|
#include "util/hb_buffer.h"
|
|
11
|
+
#include "util/hb_string.h"
|
|
10
12
|
|
|
11
13
|
typedef enum {
|
|
12
14
|
<%- errors.each do |error| -%>
|
|
@@ -17,7 +19,7 @@ typedef enum {
|
|
|
17
19
|
typedef struct ERROR_STRUCT {
|
|
18
20
|
error_type_T type;
|
|
19
21
|
location_T location;
|
|
20
|
-
|
|
22
|
+
hb_string_T message;
|
|
21
23
|
} ERROR_T;
|
|
22
24
|
|
|
23
25
|
<%- errors.each do |error| -%>
|
|
@@ -31,7 +33,7 @@ typedef struct {
|
|
|
31
33
|
|
|
32
34
|
<%- errors.each do |error| -%>
|
|
33
35
|
<%- error_arguments = error.fields.any? ? error.fields.map { |field| [field.c_type, " ", field.name].join } : [] -%>
|
|
34
|
-
<%- arguments = error_arguments + ["position_T start", "position_T end"] -%>
|
|
36
|
+
<%- arguments = error_arguments + ["position_T start", "position_T end", "hb_allocator_T* allocator"] -%>
|
|
35
37
|
<%= error.struct_type %>* <%= error.human %>_init(<%= arguments.join(", ") %>);
|
|
36
38
|
void append_<%= error.human %>(<%= (arguments << "hb_array_T* errors").join(", ") %>);
|
|
37
39
|
<%- end -%>
|
|
@@ -41,18 +43,20 @@ void error_init(ERROR_T* error, error_type_T type, position_T start, position_T
|
|
|
41
43
|
size_t error_sizeof(void);
|
|
42
44
|
error_type_T error_type(ERROR_T* error);
|
|
43
45
|
|
|
44
|
-
|
|
46
|
+
hb_string_T error_message(ERROR_T* error);
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
hb_string_T error_type_to_string(ERROR_T* error);
|
|
49
|
+
hb_string_T error_human_type(ERROR_T* error);
|
|
48
50
|
|
|
49
|
-
void error_free(ERROR_T* error);
|
|
51
|
+
void error_free(ERROR_T* error, hb_allocator_T* allocator);
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
#ifndef HERB_EXCLUDE_PRETTYPRINT
|
|
54
|
+
void error_pretty_print(ERROR_T* error, size_t indent, size_t relative_indent, hb_buffer_T* buffer);
|
|
52
55
|
|
|
53
|
-
void error_pretty_print_array(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
);
|
|
56
|
+
void error_pretty_print_array(
|
|
57
|
+
const char* name, hb_array_T* array, size_t indent, size_t relative_indent, bool last_property,
|
|
58
|
+
hb_buffer_T* buffer
|
|
59
|
+
);
|
|
60
|
+
#endif
|
|
57
61
|
|
|
58
62
|
#endif
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<% max = 64 -%>
|
|
2
|
+
#ifndef HB_FOREACH_H
|
|
3
|
+
#define HB_FOREACH_H
|
|
4
|
+
|
|
5
|
+
#define HB_ARG<%= max %>(<%= (1..max).map { |i| "_#{i}" }.join(",") %>,count,...) count
|
|
6
|
+
#define HB_NARGS(...) HB_ARG<%= max %>(__VA_ARGS__,<%= max.downto(1).to_a.join(",") %>)
|
|
7
|
+
|
|
8
|
+
<% (1..max).each do |i| -%>
|
|
9
|
+
<% if i == 1 -%>
|
|
10
|
+
#define HB_FOR_EACH_1(macro, head) macro(head)
|
|
11
|
+
<% else -%>
|
|
12
|
+
#define HB_FOR_EACH_<%= i %>(macro, head, ...) macro(head), HB_FOR_EACH_<%= i - 1 %>(macro, __VA_ARGS__)
|
|
13
|
+
<% end -%>
|
|
14
|
+
<% end -%>
|
|
15
|
+
|
|
16
|
+
#define HB_CONCAT(left, right) left ## right
|
|
17
|
+
#define HB_FOR_EACH_N(count) HB_CONCAT(HB_FOR_EACH_, count)
|
|
18
|
+
#define HB_FOR_EACH(macro, ...) HB_FOR_EACH_N(HB_NARGS(__VA_ARGS__))(macro, __VA_ARGS__)
|
|
19
|
+
|
|
20
|
+
#endif
|
|
@@ -4,14 +4,20 @@
|
|
|
4
4
|
#include "include/visitor.h"
|
|
5
5
|
|
|
6
6
|
bool match_tags_visitor(const AST_NODE_T* node, void* data) {
|
|
7
|
-
|
|
7
|
+
match_tags_context_T* context = (match_tags_context_T*) data;
|
|
8
8
|
|
|
9
9
|
if (node == NULL) { return false; }
|
|
10
10
|
|
|
11
11
|
switch (node->type) {
|
|
12
12
|
<%- nodes.each do |node| -%>
|
|
13
13
|
<%- array_fields = node.fields.select { |f| f.is_a?(Herb::Template::ArrayField) && f.name != "errors" } -%>
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
<%- skip_fields = case node.name
|
|
16
|
+
when "HTMLConditionalElementNode" then ["open_tag", "close_tag", "open_conditional", "close_conditional"]
|
|
17
|
+
when "HTMLConditionalOpenTagNode" then ["conditional"]
|
|
18
|
+
else []
|
|
19
|
+
end -%>
|
|
20
|
+
<%- single_node_fields = node.fields.select { |f| f.is_a?(Herb::Template::NodeField) && !skip_fields.include?(f.name) } -%>
|
|
15
21
|
|
|
16
22
|
<%- if array_fields.any? || single_node_fields.any? -%>
|
|
17
23
|
case <%= node.type %>: {
|
|
@@ -19,12 +25,12 @@ bool match_tags_visitor(const AST_NODE_T* node, void* data) {
|
|
|
19
25
|
|
|
20
26
|
<%- array_fields.each do |field| -%>
|
|
21
27
|
if (<%= node.human %>-><%= field.name %> != NULL) {
|
|
22
|
-
match_tags_in_node_array(<%= node.human %>-><%= field.name %>, errors);
|
|
28
|
+
match_tags_in_node_array(<%= node.human %>-><%= field.name %>, context->errors, context->options, context->allocator);
|
|
23
29
|
}
|
|
24
30
|
<%- end -%>
|
|
25
31
|
<%- single_node_fields.each do |field| -%>
|
|
26
32
|
if (<%= node.human %>-><%= field.name %> != NULL) {
|
|
27
|
-
herb_visit_node((AST_NODE_T*) <%= node.human %>-><%= field.name %>, match_tags_visitor,
|
|
33
|
+
herb_visit_node((AST_NODE_T*) <%= node.human %>-><%= field.name %>, match_tags_visitor, context);
|
|
28
34
|
}
|
|
29
35
|
<%- end -%>
|
|
30
36
|
} break;
|
data/templates/src/visitor.c.erb
CHANGED
|
@@ -18,13 +18,13 @@ void herb_visit_child_nodes(const AST_NODE_T *node, bool (*visitor)(const AST_NO
|
|
|
18
18
|
|
|
19
19
|
switch (node->type) {
|
|
20
20
|
<%- nodes.each do |node| -%>
|
|
21
|
-
<%- if node.fields.count { |field| [Herb::Template::NodeField, Herb::Template::ArrayField].include?(field.class) }.positive? -%>
|
|
21
|
+
<%- if node.fields.count { |field| [Herb::Template::NodeField, Herb::Template::BorrowedNodeField, Herb::Template::ArrayField].include?(field.class) }.positive? -%>
|
|
22
22
|
case <%= node.type %>: {
|
|
23
23
|
const <%= node.struct_type %>* <%= node.human %> = ((const <%= node.struct_type %> *) node);
|
|
24
24
|
|
|
25
25
|
<%- node.fields.each do |field| -%>
|
|
26
26
|
<%- case field -%>
|
|
27
|
-
<%- when Herb::Template::NodeField -%>
|
|
27
|
+
<%- when Herb::Template::NodeField, Herb::Template::BorrowedNodeField -%>
|
|
28
28
|
if (<%= node.human %>-><%= field.name %> != NULL) {
|
|
29
29
|
herb_visit_node((AST_NODE_T *) <%= node.human %>-><%= field.name %>, visitor, data);
|
|
30
30
|
}
|
data/templates/template.rb
CHANGED
|
@@ -7,6 +7,16 @@ require "yaml"
|
|
|
7
7
|
|
|
8
8
|
module Herb
|
|
9
9
|
module Template
|
|
10
|
+
def self.underscore(name)
|
|
11
|
+
name
|
|
12
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
|
13
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
ALWAYS_INVISIBLE_FIELD_CLASSES = ["PrismContextField", "AnalyzedRubyField"].freeze
|
|
17
|
+
CONDITIONALLY_INVISIBLE_FIELD_CLASSES = ["PrismSerializedField", "PrismNodeField"].freeze
|
|
18
|
+
ALL_INVISIBLE_FIELD_CLASSES = (ALWAYS_INVISIBLE_FIELD_CLASSES + CONDITIONALLY_INVISIBLE_FIELD_CLASSES).freeze
|
|
19
|
+
|
|
10
20
|
class Field
|
|
11
21
|
attr_reader :name, :options
|
|
12
22
|
|
|
@@ -14,6 +24,45 @@ module Herb
|
|
|
14
24
|
@name = name
|
|
15
25
|
@options = options
|
|
16
26
|
end
|
|
27
|
+
|
|
28
|
+
def always_invisible?
|
|
29
|
+
ALWAYS_INVISIBLE_FIELD_CLASSES.include?(self.class.name.split("::").last)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def conditionally_invisible?
|
|
33
|
+
CONDITIONALLY_INVISIBLE_FIELD_CLASSES.include?(self.class.name.split("::").last)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def invisible?
|
|
37
|
+
ALL_INVISIBLE_FIELD_CLASSES.include?(self.class.name.split("::").last)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
class FieldVisibility
|
|
42
|
+
attr_reader :field, :prism_field_name
|
|
43
|
+
|
|
44
|
+
def initialize(field:, static_last:, dynamic_last:, prism_field_name:)
|
|
45
|
+
@field = field
|
|
46
|
+
@static_last = static_last
|
|
47
|
+
@dynamic_last = dynamic_last
|
|
48
|
+
@prism_field_name = prism_field_name
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def static_last?
|
|
52
|
+
@static_last
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def dynamic_last?
|
|
56
|
+
@dynamic_last
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def symbol
|
|
60
|
+
@static_last ? "└── " : "├── "
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def prefix
|
|
64
|
+
@static_last ? " " : "│ "
|
|
65
|
+
end
|
|
17
66
|
end
|
|
18
67
|
|
|
19
68
|
class ArrayField < Field
|
|
@@ -23,10 +72,17 @@ module Herb
|
|
|
23
72
|
end
|
|
24
73
|
|
|
25
74
|
def ruby_type
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
75
|
+
if specific_kind
|
|
76
|
+
if specific_kind.end_with?("Node")
|
|
77
|
+
"Array[Herb::AST::#{specific_kind}]"
|
|
78
|
+
else
|
|
79
|
+
"Array[#{specific_kind}]"
|
|
80
|
+
end
|
|
81
|
+
elsif union_kind
|
|
82
|
+
"Array[(#{union_kind.map { |k| "Herb::AST::#{k}" }.join(" | ")})]"
|
|
83
|
+
else
|
|
84
|
+
"Array"
|
|
85
|
+
end
|
|
30
86
|
end
|
|
31
87
|
|
|
32
88
|
def c_type
|
|
@@ -35,7 +91,7 @@ module Herb
|
|
|
35
91
|
|
|
36
92
|
def c_item_type
|
|
37
93
|
if specific_kind
|
|
38
|
-
"AST_#{
|
|
94
|
+
"AST_#{Template.underscore(specific_kind).upcase}_T*"
|
|
39
95
|
else
|
|
40
96
|
"void*"
|
|
41
97
|
end
|
|
@@ -58,14 +114,20 @@ module Herb
|
|
|
58
114
|
|
|
59
115
|
def c_type
|
|
60
116
|
if specific_kind
|
|
61
|
-
"struct AST_#{
|
|
117
|
+
"struct AST_#{Template.underscore(specific_kind).upcase}_STRUCT*"
|
|
62
118
|
else
|
|
63
119
|
"AST_NODE_T*"
|
|
64
120
|
end
|
|
65
121
|
end
|
|
66
122
|
|
|
67
123
|
def ruby_type
|
|
68
|
-
|
|
124
|
+
if specific_kind
|
|
125
|
+
"Herb::AST::#{specific_kind}"
|
|
126
|
+
elsif union_kind
|
|
127
|
+
"(#{union_kind.map { |k| "Herb::AST::#{k}" }.join(" | ")})"
|
|
128
|
+
else
|
|
129
|
+
"Herb::AST::Node"
|
|
130
|
+
end
|
|
69
131
|
end
|
|
70
132
|
|
|
71
133
|
def specific_kind
|
|
@@ -75,6 +137,29 @@ module Herb
|
|
|
75
137
|
def union_kind
|
|
76
138
|
@kind if @kind.is_a?(Array)
|
|
77
139
|
end
|
|
140
|
+
|
|
141
|
+
def union_type_name
|
|
142
|
+
return nil unless union_kind
|
|
143
|
+
|
|
144
|
+
union_kind.sort.join("Or")
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def rust_type
|
|
148
|
+
if specific_kind && specific_kind != "Node"
|
|
149
|
+
"Option<Box<#{specific_kind}>>"
|
|
150
|
+
elsif union_kind
|
|
151
|
+
"Option<#{union_type_name}>"
|
|
152
|
+
else
|
|
153
|
+
"Option<Box<AnyNode>>"
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def java_type
|
|
158
|
+
specific_kind || "Node" # Java uses base type for union_kind, could use sealed interface in future
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
class BorrowedNodeField < NodeField
|
|
78
163
|
end
|
|
79
164
|
|
|
80
165
|
class TokenField < Field
|
|
@@ -103,7 +188,7 @@ module Herb
|
|
|
103
188
|
end
|
|
104
189
|
|
|
105
190
|
def c_type
|
|
106
|
-
"
|
|
191
|
+
"hb_string_T"
|
|
107
192
|
end
|
|
108
193
|
end
|
|
109
194
|
|
|
@@ -113,7 +198,7 @@ module Herb
|
|
|
113
198
|
end
|
|
114
199
|
|
|
115
200
|
def c_type
|
|
116
|
-
"position_T
|
|
201
|
+
"position_T"
|
|
117
202
|
end
|
|
118
203
|
end
|
|
119
204
|
|
|
@@ -159,11 +244,33 @@ module Herb
|
|
|
159
244
|
|
|
160
245
|
class PrismNodeField < Field
|
|
161
246
|
def ruby_type
|
|
162
|
-
"
|
|
247
|
+
"String"
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def c_type
|
|
251
|
+
"herb_prism_node_T"
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def rust_type
|
|
255
|
+
"Option<Vec<u8>>"
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def java_type
|
|
259
|
+
"byte[]"
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def js_type
|
|
263
|
+
"Uint8Array | null"
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
class PrismContextField < Field
|
|
268
|
+
def ruby_type
|
|
269
|
+
"nil"
|
|
163
270
|
end
|
|
164
271
|
|
|
165
272
|
def c_type
|
|
166
|
-
"
|
|
273
|
+
"herb_prism_context_T*"
|
|
167
274
|
end
|
|
168
275
|
end
|
|
169
276
|
|
|
@@ -187,13 +294,35 @@ module Herb
|
|
|
187
294
|
end
|
|
188
295
|
end
|
|
189
296
|
|
|
297
|
+
class PrismSerializedField < Field
|
|
298
|
+
def ruby_type
|
|
299
|
+
"String"
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
def c_type
|
|
303
|
+
"prism_serialized_T"
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def java_type
|
|
307
|
+
"byte[]"
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def rust_type
|
|
311
|
+
"Option<Vec<u8>>"
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
def js_type
|
|
315
|
+
"Uint8Array | null"
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
|
|
190
319
|
class ElementSourceField < Field
|
|
191
320
|
def ruby_type
|
|
192
321
|
"String"
|
|
193
322
|
end
|
|
194
323
|
|
|
195
324
|
def c_type
|
|
196
|
-
"
|
|
325
|
+
"hb_string_T"
|
|
197
326
|
end
|
|
198
327
|
end
|
|
199
328
|
|
|
@@ -214,19 +343,22 @@ module Herb
|
|
|
214
343
|
|
|
215
344
|
def field_type_for(name)
|
|
216
345
|
case name
|
|
217
|
-
when "array"
|
|
218
|
-
when "node"
|
|
219
|
-
when "
|
|
220
|
-
when "
|
|
221
|
-
when "
|
|
222
|
-
when "
|
|
223
|
-
when "
|
|
224
|
-
when "
|
|
225
|
-
when "
|
|
226
|
-
when "
|
|
227
|
-
when "
|
|
228
|
-
when "
|
|
229
|
-
when "
|
|
346
|
+
when "array" then ArrayField
|
|
347
|
+
when "node" then NodeField
|
|
348
|
+
when "borrowed_node" then BorrowedNodeField
|
|
349
|
+
when "token" then TokenField
|
|
350
|
+
when "token_type" then TokenTypeField
|
|
351
|
+
when "string" then StringField
|
|
352
|
+
when "position" then PositionField
|
|
353
|
+
when "location" then LocationField
|
|
354
|
+
when "size_t" then SizeTField
|
|
355
|
+
when "boolean" then BooleanField
|
|
356
|
+
when "prism_node" then PrismNodeField
|
|
357
|
+
when "prism_context" then PrismContextField
|
|
358
|
+
when "analyzed_ruby" then AnalyzedRubyField
|
|
359
|
+
when "prism_serialized" then PrismSerializedField
|
|
360
|
+
when "element_source" then ElementSourceField
|
|
361
|
+
when "void*" then VoidPointerField
|
|
230
362
|
else raise("Unknown field type: #{name.inspect}")
|
|
231
363
|
end
|
|
232
364
|
end
|
|
@@ -242,7 +374,7 @@ module Herb
|
|
|
242
374
|
@message_template = config.dig("message", "template")
|
|
243
375
|
@message_arguments = config.dig("message", "arguments")
|
|
244
376
|
|
|
245
|
-
camelized = @name
|
|
377
|
+
camelized = Template.underscore(@name)
|
|
246
378
|
@type = camelized.upcase
|
|
247
379
|
@struct_type = "#{camelized.upcase}_T"
|
|
248
380
|
@struct_name = "#{camelized.upcase}_STRUCT"
|
|
@@ -269,7 +401,7 @@ module Herb
|
|
|
269
401
|
|
|
270
402
|
def initialize(config)
|
|
271
403
|
@name = config.fetch("name")
|
|
272
|
-
camelized = @name
|
|
404
|
+
camelized = Template.underscore(@name)
|
|
273
405
|
@type = "AST_#{camelized.upcase}"
|
|
274
406
|
@struct_type = "AST_#{camelized.upcase}_T"
|
|
275
407
|
@struct_name = "AST_#{camelized.upcase}_STRUCT"
|
|
@@ -287,6 +419,34 @@ module Herb
|
|
|
287
419
|
def c_type
|
|
288
420
|
@struct_type
|
|
289
421
|
end
|
|
422
|
+
|
|
423
|
+
def field_visibilities
|
|
424
|
+
@field_visibilities ||= begin
|
|
425
|
+
prism_fields = @fields.select(&:conditionally_invisible?)
|
|
426
|
+
last_prism_field_name = prism_fields.last&.name
|
|
427
|
+
|
|
428
|
+
@fields.each_with_index.map do |field, index|
|
|
429
|
+
remaining = @fields[(index + 1)..] || []
|
|
430
|
+
all_remaining_always_invisible = remaining.all?(&:always_invisible?)
|
|
431
|
+
all_remaining_invisible = remaining.all?(&:invisible?)
|
|
432
|
+
any_remaining_conditionally_invisible = remaining.any?(&:conditionally_invisible?)
|
|
433
|
+
|
|
434
|
+
static_last = all_remaining_always_invisible
|
|
435
|
+
dynamic_last = !static_last && all_remaining_invisible && any_remaining_conditionally_invisible
|
|
436
|
+
|
|
437
|
+
FieldVisibility.new(
|
|
438
|
+
field: field,
|
|
439
|
+
static_last: static_last,
|
|
440
|
+
dynamic_last: dynamic_last,
|
|
441
|
+
prism_field_name: dynamic_last ? last_prism_field_name : nil
|
|
442
|
+
)
|
|
443
|
+
end
|
|
444
|
+
end
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
def field_visibility(index)
|
|
448
|
+
field_visibilities[index]
|
|
449
|
+
end
|
|
290
450
|
end
|
|
291
451
|
|
|
292
452
|
class PrintfMessageTemplate
|
|
@@ -308,7 +468,7 @@ module Herb
|
|
|
308
468
|
base_length = template.length
|
|
309
469
|
total_size = base_length
|
|
310
470
|
|
|
311
|
-
format_specifiers = template.scan(/%[
|
|
471
|
+
format_specifiers = template.scan(/%(?:zu|llu|lf|ld|[sdulf])/)
|
|
312
472
|
|
|
313
473
|
format_specifiers.each_with_index do |specifier, _i|
|
|
314
474
|
estimated_size = ESTIMATED_SIZES[specifier] || 16 # Default extra buffer
|
|
@@ -381,7 +541,7 @@ module Herb
|
|
|
381
541
|
)
|
|
382
542
|
end
|
|
383
543
|
|
|
384
|
-
rendered_template = read_template(template_path.to_s).result_with_hash({ nodes: nodes, errors: errors })
|
|
544
|
+
rendered_template = read_template(template_path.to_s).result_with_hash({ nodes: nodes, errors: errors, union_kinds: union_kinds })
|
|
385
545
|
content = heading_for(name, template_file) + rendered_template
|
|
386
546
|
|
|
387
547
|
check_gitignore(name)
|
|
@@ -425,6 +585,21 @@ module Herb
|
|
|
425
585
|
(config.dig("nodes", "types") || []).map { |node| NodeType.new(node) }
|
|
426
586
|
end
|
|
427
587
|
|
|
588
|
+
# Collect all unique union kinds from node fields
|
|
589
|
+
def self.union_kinds
|
|
590
|
+
union_kinds_set = Set.new
|
|
591
|
+
|
|
592
|
+
nodes.each do |node|
|
|
593
|
+
node.fields.each do |field|
|
|
594
|
+
if field.respond_to?(:union_kind) && field.union_kind
|
|
595
|
+
union_kinds_set.add(field.union_kind.sort)
|
|
596
|
+
end
|
|
597
|
+
end
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
union_kinds_set.to_a.sort
|
|
601
|
+
end
|
|
602
|
+
|
|
428
603
|
def self.errors
|
|
429
604
|
(config.dig("errors", "types") || []).map { |node| ErrorType.new(node) }
|
|
430
605
|
end
|
|
@@ -18,7 +18,7 @@ extern "C" {
|
|
|
18
18
|
|
|
19
19
|
using namespace emscripten;
|
|
20
20
|
|
|
21
|
-
val CreateLocation(location_T
|
|
21
|
+
val CreateLocation(location_T location);
|
|
22
22
|
val CreateToken(token_T* token);
|
|
23
23
|
val NodeFromCStruct(AST_NODE_T* node);
|
|
24
24
|
val NodesArrayFromCArray(hb_array_T* array);
|
|
@@ -34,21 +34,25 @@ val <%= error.name %>FromCStruct(<%= error.struct_type %>* <%= error.human %>) {
|
|
|
34
34
|
val Object = val::global("Object");
|
|
35
35
|
val result = Object.new_();
|
|
36
36
|
|
|
37
|
-
result.set("type",
|
|
38
|
-
result.set("message",
|
|
37
|
+
result.set("type", CreateStringFromHbString(error_type_to_string(&<%= error.human %>->base)));
|
|
38
|
+
result.set("message", CreateStringFromHbString(<%= error.human %>->base.message));
|
|
39
39
|
result.set("location", CreateLocation(<%= error.human %>->base.location));
|
|
40
40
|
<%- error.fields.each do |field| -%>
|
|
41
41
|
<%- case field -%>
|
|
42
42
|
<%- when Herb::Template::StringField -%>
|
|
43
|
-
result.set("<%= field.name %>",
|
|
43
|
+
result.set("<%= field.name %>", CreateStringFromHbString(<%= error.human %>-><%= field.name %>));
|
|
44
44
|
<%- when Herb::Template::NodeField -%>
|
|
45
45
|
result.set("<%= field.name %>", NodeFromCStruct((AST_NODE_T*)<%= error.human %>-><%= field.name %>));
|
|
46
46
|
<%- when Herb::Template::TokenField -%>
|
|
47
47
|
result.set("<%= field.name %>", CreateToken(<%= error.human %>-><%= field.name %>));
|
|
48
48
|
<%- when Herb::Template::TokenTypeField -%>
|
|
49
|
-
result.set("<%= field.name %>",
|
|
49
|
+
result.set("<%= field.name %>", CreateStringFromHbString(token_type_to_string(<%= error.human %>-><%= field.name %>)));
|
|
50
50
|
<%- when Herb::Template::BooleanField -%>
|
|
51
51
|
result.set("<%= field.name %>", <%= error.human %>-><%= field.name %>);
|
|
52
|
+
<%- when Herb::Template::PositionField -%>
|
|
53
|
+
result.set("<%= field.name %>", CreatePosition(<%= error.human %>-><%= field.name %>));
|
|
54
|
+
<%- when Herb::Template::SizeTField -%>
|
|
55
|
+
result.set("<%= field.name %>", val((double)<%= error.human %>-><%= field.name %>));
|
|
52
56
|
<%- when Herb::Template::ArrayField -%>
|
|
53
57
|
result.set("<%= field.name %>", NodesArrayFromCArray(<%= error.human %>-><%= field.name %>));
|
|
54
58
|
<%- else -%>
|
|
@@ -28,8 +28,8 @@ val <%= node.name %>FromCStruct(<%= node.struct_type %>* <%= node.human %>) {
|
|
|
28
28
|
<%- node.fields.each do |field| -%>
|
|
29
29
|
<%- case field -%>
|
|
30
30
|
<%- when Herb::Template::StringField -%>
|
|
31
|
-
result.set("<%= field.name %>",
|
|
32
|
-
<%- when Herb::Template::NodeField -%>
|
|
31
|
+
result.set("<%= field.name %>", CreateStringFromHbString(<%= node.human %>-><%= field.name %>));
|
|
32
|
+
<%- when Herb::Template::NodeField, Herb::Template::BorrowedNodeField -%>
|
|
33
33
|
result.set("<%= field.name %>", NodeFromCStruct((AST_NODE_T*) <%= node.human %>-><%= field.name %>));
|
|
34
34
|
<%- when Herb::Template::TokenField -%>
|
|
35
35
|
result.set("<%= field.name %>", CreateToken(<%= node.human %>-><%= field.name %>));
|
|
@@ -38,14 +38,51 @@ val <%= node.name %>FromCStruct(<%= node.struct_type %>* <%= node.human %>) {
|
|
|
38
38
|
<%- when Herb::Template::ArrayField -%>
|
|
39
39
|
result.set("<%= field.name %>", NodesArrayFromCArray(<%= node.human %>-><%= field.name %>));
|
|
40
40
|
<%- when Herb::Template::ElementSourceField -%>
|
|
41
|
-
result.set("<%= field.name %>", CreateStringFromHbString(
|
|
41
|
+
result.set("<%= field.name %>", CreateStringFromHbString(<%= node.human %>-><%= field.name %>));
|
|
42
42
|
<%- when Herb::Template::LocationField -%>
|
|
43
43
|
if (<%= node.human %>-><%= field.name %>) {
|
|
44
44
|
result.set("<%= field.name %>", CreateLocation(*<%= node.human %>-><%= field.name %>));
|
|
45
45
|
} else {
|
|
46
46
|
result.set("<%= field.name %>", val::null());
|
|
47
47
|
}
|
|
48
|
+
<%- when Herb::Template::PrismSerializedField -%>
|
|
49
|
+
if (<%= node.human %>-><%= field.name %>.data != NULL && <%= node.human %>-><%= field.name %>.length > 0) {
|
|
50
|
+
val jsArray = val::array();
|
|
51
|
+
|
|
52
|
+
for (size_t i = 0; i < <%= node.human %>-><%= field.name %>.length; i++) {
|
|
53
|
+
jsArray.call<void>("push", (int)<%= node.human %>-><%= field.name %>.data[i]);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
result.set("<%= field.name %>", jsArray);
|
|
57
|
+
} else {
|
|
58
|
+
result.set("<%= field.name %>", val::null());
|
|
59
|
+
}
|
|
60
|
+
<%- when Herb::Template::PrismNodeField -%>
|
|
61
|
+
if (<%= node.human %>-><%= field.name %>.node != NULL && <%= node.human %>-><%= field.name %>.parser != NULL) {
|
|
62
|
+
pm_buffer_t pm_buffer = { 0 };
|
|
63
|
+
pm_serialize(<%= node.human %>-><%= field.name %>.parser, <%= node.human %>-><%= field.name %>.node, &pm_buffer);
|
|
64
|
+
|
|
65
|
+
if (pm_buffer.length > 0) {
|
|
66
|
+
val jsArray = val::array();
|
|
67
|
+
|
|
68
|
+
for (size_t i = 0; i < pm_buffer.length; i++) {
|
|
69
|
+
jsArray.call<void>("push", (int)((uint8_t*)pm_buffer.value)[i]);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
result.set("<%= field.name %>", jsArray);
|
|
73
|
+
} else {
|
|
74
|
+
result.set("<%= field.name %>", val::null());
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
pm_buffer_free(&pm_buffer);
|
|
78
|
+
} else {
|
|
79
|
+
result.set("<%= field.name %>", val::null());
|
|
80
|
+
}
|
|
81
|
+
<%- when Herb::Template::AnalyzedRubyField, Herb::Template::PrismContextField, Herb::Template::VoidPointerField -%>
|
|
82
|
+
/* <%= field.name %> is internal parser state, not exposed to JavaScript */
|
|
83
|
+
result.set("<%= field.name %>", val::null());
|
|
48
84
|
<%- else -%>
|
|
85
|
+
/* Unhandled field type: <%= field.class.name %> */
|
|
49
86
|
result.set("<%= field.name %>", val::null());
|
|
50
87
|
<%- end -%>
|
|
51
88
|
<%- end -%>
|
|
@@ -77,7 +114,7 @@ val NodesArrayFromCArray(hb_array_T* array) {
|
|
|
77
114
|
AST_NODE_T* child_node = (AST_NODE_T*) hb_array_get(array, i);
|
|
78
115
|
|
|
79
116
|
if (child_node) {
|
|
80
|
-
jsArray.
|
|
117
|
+
jsArray.call<void>("push", NodeFromCStruct(child_node));
|
|
81
118
|
}
|
|
82
119
|
}
|
|
83
120
|
|