herb 0.8.4-x86_64-linux-gnu → 0.8.5-x86_64-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 +7 -0
- data/ext/herb/error_helpers.c +25 -0
- data/ext/herb/nodes.c +1 -1
- 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/ast/helpers.rb +5 -0
- data/lib/herb/engine/compiler.rb +1 -0
- data/lib/herb/errors.rb +53 -44
- data/lib/herb/version.rb +1 -1
- data/sig/herb/ast/helpers.rbs +3 -0
- data/sig/herb/errors.rbs +10 -0
- data/sig/serialized_ast_errors.rbs +3 -0
- data/src/analyze.c +12 -1
- data/src/analyze_helpers.c +179 -84
- data/src/analyzed_ruby.c +26 -25
- data/src/ast_pretty_print.c +16 -15
- data/src/errors.c +37 -0
- data/src/extract.c +2 -1
- data/src/include/analyze_helpers.h +1 -0
- data/src/include/analyzed_ruby.h +19 -18
- data/src/include/errors.h +8 -0
- data/src/include/version.h +1 -1
- data/src/lexer.c +3 -3
- data/src/parser.c +4 -2
- data/src/parser_helpers.c +5 -5
- data/templates/lib/herb/errors.rb.erb +8 -5
- data/templates/src/ast_pretty_print.c.erb +16 -15
- metadata +1 -1
data/src/include/analyzed_ruby.h
CHANGED
|
@@ -11,24 +11,25 @@ typedef struct ANALYZED_RUBY_STRUCT {
|
|
|
11
11
|
pm_node_t* root;
|
|
12
12
|
bool valid;
|
|
13
13
|
bool parsed;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
14
|
+
int if_node_count;
|
|
15
|
+
int elsif_node_count;
|
|
16
|
+
int else_node_count;
|
|
17
|
+
int end_count;
|
|
18
|
+
int block_closing_count;
|
|
19
|
+
int block_node_count;
|
|
20
|
+
int case_node_count;
|
|
21
|
+
int case_match_node_count;
|
|
22
|
+
int when_node_count;
|
|
23
|
+
int in_node_count;
|
|
24
|
+
int for_node_count;
|
|
25
|
+
int while_node_count;
|
|
26
|
+
int until_node_count;
|
|
27
|
+
int begin_node_count;
|
|
28
|
+
int rescue_node_count;
|
|
29
|
+
int ensure_node_count;
|
|
30
|
+
int unless_node_count;
|
|
31
|
+
int yield_node_count;
|
|
32
|
+
int unclosed_control_flow_count;
|
|
32
33
|
} analyzed_ruby_T;
|
|
33
34
|
|
|
34
35
|
analyzed_ruby_T* init_analyzed_ruby(hb_string_T source);
|
data/src/include/errors.h
CHANGED
|
@@ -23,6 +23,7 @@ typedef enum {
|
|
|
23
23
|
RUBY_PARSE_ERROR,
|
|
24
24
|
ERB_CONTROL_FLOW_SCOPE_ERROR,
|
|
25
25
|
MISSINGERB_END_TAG_ERROR,
|
|
26
|
+
ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR,
|
|
26
27
|
} error_type_T;
|
|
27
28
|
|
|
28
29
|
typedef struct ERROR_STRUCT {
|
|
@@ -96,6 +97,11 @@ typedef struct {
|
|
|
96
97
|
const char* keyword;
|
|
97
98
|
} MISSINGERB_END_TAG_ERROR_T;
|
|
98
99
|
|
|
100
|
+
typedef struct {
|
|
101
|
+
ERROR_T base;
|
|
102
|
+
/* no additional fields */
|
|
103
|
+
} ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T;
|
|
104
|
+
|
|
99
105
|
UNEXPECTED_ERROR_T* unexpected_error_init(const char* description, const char* expected, const char* found, position_T start, position_T end);
|
|
100
106
|
void append_unexpected_error(const char* description, const char* expected, const char* found, position_T start, position_T end, hb_array_T* errors);
|
|
101
107
|
UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error_init(token_type_T expected_type, token_T* found, position_T start, position_T end);
|
|
@@ -118,6 +124,8 @@ ERB_CONTROL_FLOW_SCOPE_ERROR_T* erb_control_flow_scope_error_init(const char* ke
|
|
|
118
124
|
void append_erb_control_flow_scope_error(const char* keyword, position_T start, position_T end, hb_array_T* errors);
|
|
119
125
|
MISSINGERB_END_TAG_ERROR_T* missingerb_end_tag_error_init(const char* keyword, position_T start, position_T end);
|
|
120
126
|
void append_missingerb_end_tag_error(const char* keyword, position_T start, position_T end, hb_array_T* errors);
|
|
127
|
+
ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T* erb_multiple_blocks_in_tag_error_init(position_T start, position_T end);
|
|
128
|
+
void append_erb_multiple_blocks_in_tag_error(position_T start, position_T end, hb_array_T* errors);
|
|
121
129
|
|
|
122
130
|
void error_init(ERROR_T* error, error_type_T type, position_T start, position_T end);
|
|
123
131
|
|
data/src/include/version.h
CHANGED
data/src/lexer.c
CHANGED
|
@@ -185,8 +185,8 @@ static token_T* lexer_parse_identifier(lexer_T* lexer) {
|
|
|
185
185
|
// ===== ERB Parsing
|
|
186
186
|
|
|
187
187
|
static token_T* lexer_parse_erb_open(lexer_T* lexer) {
|
|
188
|
-
hb_string_T erb_patterns[] = { hb_string("<%=="), hb_string("<%%="), hb_string("<%="),
|
|
189
|
-
hb_string("<%-"), hb_string("<%%"), hb_string("<%") };
|
|
188
|
+
hb_string_T erb_patterns[] = { hb_string("<%=="), hb_string("<%%="), hb_string("<%="), hb_string("<%#"),
|
|
189
|
+
hb_string("<%-"), hb_string("<%%"), hb_string("<%graphql"), hb_string("<%") };
|
|
190
190
|
|
|
191
191
|
lexer->state = STATE_ERB_CONTENT;
|
|
192
192
|
|
|
@@ -278,7 +278,7 @@ token_T* lexer_next_token(lexer_T* lexer) {
|
|
|
278
278
|
return lexer_advance_with_next(lexer, strlen("<![CDATA["), TOKEN_CDATA_START);
|
|
279
279
|
}
|
|
280
280
|
|
|
281
|
-
if (
|
|
281
|
+
if (isalpha(lexer_peek(lexer, 1))) { return lexer_advance_current(lexer, TOKEN_HTML_TAG_START); }
|
|
282
282
|
|
|
283
283
|
if (lexer_peek_for_html_comment_start(lexer, 0)) {
|
|
284
284
|
return lexer_advance_with(lexer, hb_string("<!--"), TOKEN_HTML_COMMENT_START);
|
data/src/parser.c
CHANGED
|
@@ -1115,7 +1115,9 @@ static void parser_parse_in_data_state(parser_T* parser, hb_array_T* children, h
|
|
|
1115
1115
|
TOKEN_DASH,
|
|
1116
1116
|
TOKEN_EQUALS,
|
|
1117
1117
|
TOKEN_EXCLAMATION,
|
|
1118
|
+
TOKEN_HTML_TAG_END,
|
|
1118
1119
|
TOKEN_IDENTIFIER,
|
|
1120
|
+
TOKEN_LT,
|
|
1119
1121
|
TOKEN_NBSP,
|
|
1120
1122
|
TOKEN_NEWLINE,
|
|
1121
1123
|
TOKEN_PERCENT,
|
|
@@ -1149,11 +1151,11 @@ static size_t find_matching_close_tag(hb_array_T* nodes, size_t start_idx, hb_st
|
|
|
1149
1151
|
if (node->type == AST_HTML_OPEN_TAG_NODE) {
|
|
1150
1152
|
AST_HTML_OPEN_TAG_NODE_T* open = (AST_HTML_OPEN_TAG_NODE_T*) node;
|
|
1151
1153
|
|
|
1152
|
-
if (
|
|
1154
|
+
if (hb_string_equals_case_insensitive(hb_string(open->tag_name->value), tag_name)) { depth++; }
|
|
1153
1155
|
} else if (node->type == AST_HTML_CLOSE_TAG_NODE) {
|
|
1154
1156
|
AST_HTML_CLOSE_TAG_NODE_T* close = (AST_HTML_CLOSE_TAG_NODE_T*) node;
|
|
1155
1157
|
|
|
1156
|
-
if (
|
|
1158
|
+
if (hb_string_equals_case_insensitive(hb_string(close->tag_name->value), tag_name)) {
|
|
1157
1159
|
if (depth == 0) { return i; }
|
|
1158
1160
|
depth--;
|
|
1159
1161
|
}
|
data/src/parser_helpers.c
CHANGED
|
@@ -24,7 +24,7 @@ bool parser_check_matching_tag(const parser_T* parser, hb_string_T tag_name) {
|
|
|
24
24
|
token_T* top_token = hb_array_last(parser->open_tags_stack);
|
|
25
25
|
if (top_token == NULL || top_token->value == NULL) { return false; };
|
|
26
26
|
|
|
27
|
-
return
|
|
27
|
+
return hb_string_equals_case_insensitive(hb_string(top_token->value), tag_name);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
token_T* parser_pop_open_tag(const parser_T* parser) {
|
|
@@ -49,7 +49,7 @@ bool parser_in_svg_context(const parser_T* parser) {
|
|
|
49
49
|
|
|
50
50
|
if (tag && tag->value) {
|
|
51
51
|
hb_string_T tag_value_string = hb_string(tag->value);
|
|
52
|
-
if (
|
|
52
|
+
if (hb_string_equals_case_insensitive(tag_value_string, hb_string("svg"))) { return true; }
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -61,8 +61,8 @@ bool parser_in_svg_context(const parser_T* parser) {
|
|
|
61
61
|
foreign_content_type_T parser_get_foreign_content_type(hb_string_T tag_name) {
|
|
62
62
|
if (hb_string_is_empty(tag_name)) { return FOREIGN_CONTENT_UNKNOWN; }
|
|
63
63
|
|
|
64
|
-
if (
|
|
65
|
-
if (
|
|
64
|
+
if (hb_string_equals_case_insensitive(tag_name, hb_string("script"))) { return FOREIGN_CONTENT_SCRIPT; }
|
|
65
|
+
if (hb_string_equals_case_insensitive(tag_name, hb_string("style"))) { return FOREIGN_CONTENT_STYLE; }
|
|
66
66
|
|
|
67
67
|
return FOREIGN_CONTENT_UNKNOWN;
|
|
68
68
|
}
|
|
@@ -217,5 +217,5 @@ bool parser_is_expected_closing_tag_name(hb_string_T tag_name, foreign_content_t
|
|
|
217
217
|
|
|
218
218
|
if (hb_string_is_empty(tag_name) || hb_string_is_empty(expected_tag_name)) { return false; }
|
|
219
219
|
|
|
220
|
-
return
|
|
220
|
+
return hb_string_equals_case_insensitive(expected_tag_name, tag_name);
|
|
221
221
|
}
|
|
@@ -46,6 +46,7 @@ module Herb
|
|
|
46
46
|
<%- errors.each do |error| -%>
|
|
47
47
|
class <%= error.name -%> < Error
|
|
48
48
|
include Colors
|
|
49
|
+
<%- if error.fields.any? -%>
|
|
49
50
|
|
|
50
51
|
<%- error.fields.each do |field| -%>
|
|
51
52
|
attr_reader :<%= field.name %> #: <%= field.ruby_type %>
|
|
@@ -54,25 +55,27 @@ module Herb
|
|
|
54
55
|
#: (<%= [*base_arguments.map(&:last), *error.fields.map(&:ruby_type)].join(", ") %>) -> void
|
|
55
56
|
def initialize(<%= [*base_arguments.map(&:first), *error.fields.map(&:name)].join(", ") %>)
|
|
56
57
|
super(<%= base_arguments.map(&:first).join(", ") %>)
|
|
57
|
-
|
|
58
58
|
<%- error.fields.each do |field| -%>
|
|
59
59
|
@<%= field.name %> = <%= field.name %>
|
|
60
60
|
<%- end -%>
|
|
61
61
|
end
|
|
62
|
+
<%- end -%>
|
|
62
63
|
|
|
63
64
|
#: () -> String
|
|
64
65
|
def inspect
|
|
65
66
|
tree_inspect.rstrip.gsub(/\s+$/, "")
|
|
66
67
|
end
|
|
68
|
+
<%- if error.fields.any? -%>
|
|
67
69
|
|
|
68
70
|
#: () -> serialized_<%= error.human %>
|
|
69
71
|
def to_hash
|
|
70
|
-
super.merge(
|
|
71
|
-
<%- error.fields.
|
|
72
|
-
<%= field.name %>: <%= field.name
|
|
72
|
+
super.merge(
|
|
73
|
+
<%- error.fields.each_with_index do |field, index| -%>
|
|
74
|
+
<%= field.name %>: <%= field.name %><%= index < error.fields.size - 1 ? "," : "" %>
|
|
73
75
|
<%- end -%>
|
|
74
|
-
|
|
76
|
+
) #: Herb::serialized_<%= error.human %>
|
|
75
77
|
end
|
|
78
|
+
<%- end -%>
|
|
76
79
|
|
|
77
80
|
#: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
|
|
78
81
|
def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#include "include/analyze_helpers.h"
|
|
1
2
|
#include "include/ast_node.h"
|
|
2
3
|
#include "include/ast_nodes.h"
|
|
3
4
|
#include "include/errors.h"
|
|
@@ -62,21 +63,21 @@ void ast_pretty_print_node(AST_NODE_T* node, const size_t indent, const size_t r
|
|
|
62
63
|
|
|
63
64
|
<%- when Herb::Template::AnalyzedRubyField -%>
|
|
64
65
|
if (<%= node.human %>-><%= field.name %>) {
|
|
65
|
-
pretty_print_boolean_property(hb_string("if_node"), <%= node.human %>-><%= field.name
|
|
66
|
-
pretty_print_boolean_property(hb_string("elsif_node"), <%= node.human %>-><%= field.name
|
|
67
|
-
pretty_print_boolean_property(hb_string("else_node"), <%= node.human %>-><%= field.name
|
|
68
|
-
pretty_print_boolean_property(hb_string("end"), <%= node.human %>-><%= field.name
|
|
69
|
-
pretty_print_boolean_property(hb_string("block_node"), <%= node.human %>-><%= field.name
|
|
70
|
-
pretty_print_boolean_property(hb_string("block_closing"), <%= node.human %>-><%= field.name
|
|
71
|
-
pretty_print_boolean_property(hb_string("case_node"), <%= node.human %>-><%= field.name
|
|
72
|
-
pretty_print_boolean_property(hb_string("when_node"), <%= node.human %>-><%= field.name
|
|
73
|
-
pretty_print_boolean_property(hb_string("for_node"), <%= node.human %>-><%= field.name
|
|
74
|
-
pretty_print_boolean_property(hb_string("while_node"), <%= node.human %>-><%= field.name
|
|
75
|
-
pretty_print_boolean_property(hb_string("until_node"), <%= node.human %>-><%= field.name
|
|
76
|
-
pretty_print_boolean_property(hb_string("begin_node"), <%= node.human %>-><%= field.name
|
|
77
|
-
pretty_print_boolean_property(hb_string("rescue_node"), <%= node.human %>-><%= field.name
|
|
78
|
-
pretty_print_boolean_property(hb_string("ensure_node"), <%= node.human %>-><%= field.name
|
|
79
|
-
pretty_print_boolean_property(hb_string("unless_node"), <%= node.human %>-><%= field.name
|
|
66
|
+
pretty_print_boolean_property(hb_string("if_node"), has_if_node(<%= node.human %>-><%= field.name %>), indent, relative_indent, false, buffer);
|
|
67
|
+
pretty_print_boolean_property(hb_string("elsif_node"), has_elsif_node(<%= node.human %>-><%= field.name %>), indent, relative_indent, false, buffer);
|
|
68
|
+
pretty_print_boolean_property(hb_string("else_node"), has_else_node(<%= node.human %>-><%= field.name %>), indent, relative_indent, false, buffer);
|
|
69
|
+
pretty_print_boolean_property(hb_string("end"), has_end(<%= node.human %>-><%= field.name %>), indent, relative_indent, false, buffer);
|
|
70
|
+
pretty_print_boolean_property(hb_string("block_node"), has_block_node(<%= node.human %>-><%= field.name %>), indent, relative_indent, false, buffer);
|
|
71
|
+
pretty_print_boolean_property(hb_string("block_closing"), has_block_closing(<%= node.human %>-><%= field.name %>), indent, relative_indent, false, buffer);
|
|
72
|
+
pretty_print_boolean_property(hb_string("case_node"), has_case_node(<%= node.human %>-><%= field.name %>), indent, relative_indent, false, buffer);
|
|
73
|
+
pretty_print_boolean_property(hb_string("when_node"), has_when_node(<%= node.human %>-><%= field.name %>), indent, relative_indent, false, buffer);
|
|
74
|
+
pretty_print_boolean_property(hb_string("for_node"), has_for_node(<%= node.human %>-><%= field.name %>), indent, relative_indent, false, buffer);
|
|
75
|
+
pretty_print_boolean_property(hb_string("while_node"), has_while_node(<%= node.human %>-><%= field.name %>), indent, relative_indent, false, buffer);
|
|
76
|
+
pretty_print_boolean_property(hb_string("until_node"), has_until_node(<%= node.human %>-><%= field.name %>), indent, relative_indent, false, buffer);
|
|
77
|
+
pretty_print_boolean_property(hb_string("begin_node"), has_begin_node(<%= node.human %>-><%= field.name %>), indent, relative_indent, false, buffer);
|
|
78
|
+
pretty_print_boolean_property(hb_string("rescue_node"), has_rescue_node(<%= node.human %>-><%= field.name %>), indent, relative_indent, false, buffer);
|
|
79
|
+
pretty_print_boolean_property(hb_string("ensure_node"), has_ensure_node(<%= node.human %>-><%= field.name %>), indent, relative_indent, false, buffer);
|
|
80
|
+
pretty_print_boolean_property(hb_string("unless_node"), has_unless_node(<%= node.human %>-><%= field.name %>), indent, relative_indent, false, buffer);
|
|
80
81
|
} else {
|
|
81
82
|
pretty_print_label(hb_string("<%= field.name %>"), indent, relative_indent, <%= last %>, buffer);
|
|
82
83
|
hb_buffer_append(buffer, " ∅\n");
|