herb 0.3.1-arm-linux-gnu → 0.4.2-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/LICENSE.txt +2 -2
- data/README.md +80 -115
- data/ext/herb/error_helpers.c +1 -1
- data/ext/herb/error_helpers.h +1 -1
- data/ext/herb/nodes.c +2 -2
- data/ext/herb/nodes.h +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/node.rb +6 -1
- data/lib/herb/ast/nodes.rb +1 -1
- data/lib/herb/cli.rb +18 -2
- data/lib/herb/errors.rb +1 -1
- data/lib/herb/parse_result.rb +7 -2
- data/lib/herb/project.rb +79 -33
- data/lib/herb/version.rb +1 -1
- data/lib/herb/visitor.rb +1 -1
- data/sig/herb/ast/node.rbs +3 -0
- data/sig/herb/parse_result.rbs +3 -0
- data/sig/serialized_ast_errors.rbs +1 -1
- data/sig/serialized_ast_nodes.rbs +1 -1
- data/src/analyze.c +61 -16
- data/src/analyze_helpers.c +15 -6
- data/src/ast_nodes.c +1 -1
- data/src/ast_pretty_print.c +1 -1
- data/src/errors.c +1 -1
- data/src/extract.c +6 -2
- data/src/include/analyze_helpers.h +1 -1
- data/src/include/ast_nodes.h +1 -1
- data/src/include/ast_pretty_print.h +1 -1
- data/src/include/errors.h +1 -1
- data/src/include/parser_helpers.h +7 -2
- data/src/include/pretty_print.h +48 -8
- data/src/include/prism_helpers.h +4 -1
- data/src/include/token_struct.h +2 -1
- data/src/include/version.h +1 -1
- data/src/lexer.c +12 -2
- data/src/parser.c +13 -4
- data/src/parser_helpers.c +10 -3
- data/src/pretty_print.c +50 -10
- data/src/prism_helpers.c +4 -1
- data/src/token.c +1 -0
- data/src/visitor.c +1 -1
- metadata +2 -2
data/sig/herb/parse_result.rbs
CHANGED
@@ -7,6 +7,9 @@ module Herb
|
|
7
7
|
# : (Herb::AST::DocumentNode, String, Array[Herb::Warnings::Warning], Array[Herb::Errors::Error]) -> void
|
8
8
|
def initialize: (Herb::AST::DocumentNode, String, Array[Herb::Warnings::Warning], Array[Herb::Errors::Error]) -> void
|
9
9
|
|
10
|
+
# : () -> Array[Herb::Errors::Error]
|
11
|
+
def errors: () -> Array[Herb::Errors::Error]
|
12
|
+
|
10
13
|
# : () -> bool
|
11
14
|
def failed?: () -> bool
|
12
15
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# typed: true
|
3
3
|
|
4
4
|
# NOTE: This file is generated by the templates/template.rb script and should not be
|
5
|
-
# modified manually. See /Users/marcoroth/Development/herb-release/templates/sig/serialized_ast_errors.rbs.erb
|
5
|
+
# modified manually. See /Users/marcoroth/Development/herb-release-6/templates/sig/serialized_ast_errors.rbs.erb
|
6
6
|
|
7
7
|
module Herb
|
8
8
|
type serialized_unexpected_error = serialized_error & {
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# typed: true
|
3
3
|
|
4
4
|
# NOTE: This file is generated by the templates/template.rb script and should not be
|
5
|
-
# modified manually. See /Users/marcoroth/Development/herb-release/templates/sig/serialized_ast_nodes.rbs.erb
|
5
|
+
# modified manually. See /Users/marcoroth/Development/herb-release-6/templates/sig/serialized_ast_nodes.rbs.erb
|
6
6
|
|
7
7
|
module Herb
|
8
8
|
type serialized_document_node = serialized_node & {
|
data/src/analyze.c
CHANGED
@@ -39,7 +39,7 @@ static analyzed_ruby_T* herb_analyze_ruby(char* source) {
|
|
39
39
|
search_in_nodes(analyzed);
|
40
40
|
search_rescue_nodes(analyzed);
|
41
41
|
search_ensure_nodes(analyzed);
|
42
|
-
search_yield_nodes(analyzed);
|
42
|
+
search_yield_nodes(analyzed->root, analyzed);
|
43
43
|
search_block_closing_nodes(analyzed);
|
44
44
|
|
45
45
|
return analyzed;
|
@@ -49,13 +49,20 @@ static bool analyze_erb_content(const AST_NODE_T* node, void* data) {
|
|
49
49
|
if (node->type == AST_ERB_CONTENT_NODE) {
|
50
50
|
AST_ERB_CONTENT_NODE_T* erb_content_node = (AST_ERB_CONTENT_NODE_T*) node;
|
51
51
|
|
52
|
-
|
52
|
+
const char* opening = erb_content_node->tag_opening->value;
|
53
|
+
if (strcmp(opening, "<%%") != 0 && strcmp(opening, "<%%=") != 0) {
|
54
|
+
analyzed_ruby_T* analyzed = herb_analyze_ruby(erb_content_node->content->value);
|
53
55
|
|
54
|
-
|
56
|
+
if (false) { pretty_print_analyed_ruby(analyzed, erb_content_node->content->value); }
|
55
57
|
|
56
|
-
|
57
|
-
|
58
|
-
|
58
|
+
erb_content_node->parsed = true;
|
59
|
+
erb_content_node->valid = analyzed->valid;
|
60
|
+
erb_content_node->analyzed_ruby = analyzed;
|
61
|
+
} else {
|
62
|
+
erb_content_node->parsed = false;
|
63
|
+
erb_content_node->valid = true;
|
64
|
+
erb_content_node->analyzed_ruby = NULL;
|
65
|
+
}
|
59
66
|
}
|
60
67
|
|
61
68
|
herb_visit_child_nodes(node, analyze_erb_content, data);
|
@@ -64,12 +71,20 @@ static bool analyze_erb_content(const AST_NODE_T* node, void* data) {
|
|
64
71
|
}
|
65
72
|
|
66
73
|
static size_t process_block_children(
|
67
|
-
AST_NODE_T* node,
|
74
|
+
AST_NODE_T* node,
|
75
|
+
array_T* array,
|
76
|
+
size_t index,
|
77
|
+
array_T* children_array,
|
78
|
+
analyze_ruby_context_T* context,
|
68
79
|
control_type_t parent_type
|
69
80
|
);
|
70
81
|
|
71
82
|
static size_t process_subsequent_block(
|
72
|
-
AST_NODE_T* node,
|
83
|
+
AST_NODE_T* node,
|
84
|
+
array_T* array,
|
85
|
+
size_t index,
|
86
|
+
AST_NODE_T** subsequent_out,
|
87
|
+
analyze_ruby_context_T* context,
|
73
88
|
control_type_t parent_type
|
74
89
|
);
|
75
90
|
|
@@ -80,8 +95,13 @@ static control_type_t detect_control_type(AST_ERB_CONTENT_NODE_T* erb_node) {
|
|
80
95
|
|
81
96
|
if (!ruby) { return CONTROL_TYPE_UNKNOWN; }
|
82
97
|
|
83
|
-
if (ruby->valid) {
|
98
|
+
if (ruby->valid) {
|
99
|
+
if (has_yield_node(ruby)) { return CONTROL_TYPE_YIELD; }
|
100
|
+
return CONTROL_TYPE_UNKNOWN;
|
101
|
+
}
|
84
102
|
|
103
|
+
if (has_yield_node(ruby)) { return CONTROL_TYPE_YIELD; }
|
104
|
+
if (has_block_node(ruby)) { return CONTROL_TYPE_BLOCK; }
|
85
105
|
if (has_if_node(ruby)) { return CONTROL_TYPE_IF; }
|
86
106
|
if (has_elsif_node(ruby)) { return CONTROL_TYPE_ELSIF; }
|
87
107
|
if (has_else_node(ruby)) { return CONTROL_TYPE_ELSE; }
|
@@ -97,8 +117,6 @@ static control_type_t detect_control_type(AST_ERB_CONTENT_NODE_T* erb_node) {
|
|
97
117
|
if (has_while_node(ruby)) { return CONTROL_TYPE_WHILE; }
|
98
118
|
if (has_until_node(ruby)) { return CONTROL_TYPE_UNTIL; }
|
99
119
|
if (has_for_node(ruby)) { return CONTROL_TYPE_FOR; }
|
100
|
-
if (has_block_node(ruby)) { return CONTROL_TYPE_BLOCK; }
|
101
|
-
if (has_yield_node(ruby)) { return CONTROL_TYPE_YIELD; }
|
102
120
|
if (has_block_closing(ruby)) { return CONTROL_TYPE_BLOCK_CLOSE; }
|
103
121
|
|
104
122
|
return CONTROL_TYPE_UNKNOWN;
|
@@ -132,7 +150,10 @@ static bool is_terminator_type(control_type_t parent_type, control_type_t child_
|
|
132
150
|
}
|
133
151
|
|
134
152
|
static AST_NODE_T* create_control_node(
|
135
|
-
AST_ERB_CONTENT_NODE_T* erb_node,
|
153
|
+
AST_ERB_CONTENT_NODE_T* erb_node,
|
154
|
+
array_T* children,
|
155
|
+
AST_NODE_T* subsequent,
|
156
|
+
AST_ERB_END_NODE_T* end_node,
|
136
157
|
control_type_t control_type
|
137
158
|
) {
|
138
159
|
array_T* errors = array_init(8);
|
@@ -362,7 +383,11 @@ static AST_NODE_T* create_control_node(
|
|
362
383
|
}
|
363
384
|
|
364
385
|
static size_t process_control_structure(
|
365
|
-
AST_NODE_T* node,
|
386
|
+
AST_NODE_T* node,
|
387
|
+
array_T* array,
|
388
|
+
size_t index,
|
389
|
+
array_T* output_array,
|
390
|
+
analyze_ruby_context_T* context,
|
366
391
|
control_type_t initial_type
|
367
392
|
) {
|
368
393
|
AST_ERB_CONTENT_NODE_T* erb_node = (AST_ERB_CONTENT_NODE_T*) array_get(array, index);
|
@@ -858,7 +883,11 @@ static size_t process_control_structure(
|
|
858
883
|
}
|
859
884
|
|
860
885
|
static size_t process_subsequent_block(
|
861
|
-
AST_NODE_T* node,
|
886
|
+
AST_NODE_T* node,
|
887
|
+
array_T* array,
|
888
|
+
size_t index,
|
889
|
+
AST_NODE_T** subsequent_out,
|
890
|
+
analyze_ruby_context_T* context,
|
862
891
|
control_type_t parent_type
|
863
892
|
) {
|
864
893
|
AST_ERB_CONTENT_NODE_T* erb_node = (AST_ERB_CONTENT_NODE_T*) array_get(array, index);
|
@@ -922,7 +951,11 @@ static size_t process_subsequent_block(
|
|
922
951
|
}
|
923
952
|
|
924
953
|
static size_t process_block_children(
|
925
|
-
AST_NODE_T* node,
|
954
|
+
AST_NODE_T* node,
|
955
|
+
array_T* array,
|
956
|
+
size_t index,
|
957
|
+
array_T* children_array,
|
958
|
+
analyze_ruby_context_T* context,
|
926
959
|
control_type_t parent_type
|
927
960
|
) {
|
928
961
|
while (index < array_size(array)) {
|
@@ -990,10 +1023,22 @@ static array_T* rewrite_node_array(AST_NODE_T* node, array_T* array, analyze_rub
|
|
990
1023
|
case CONTROL_TYPE_UNTIL:
|
991
1024
|
case CONTROL_TYPE_FOR:
|
992
1025
|
case CONTROL_TYPE_BLOCK:
|
993
|
-
case CONTROL_TYPE_YIELD:
|
994
1026
|
index = process_control_structure(node, array, index, new_array, context, type);
|
995
1027
|
continue;
|
996
1028
|
|
1029
|
+
case CONTROL_TYPE_YIELD: {
|
1030
|
+
AST_NODE_T* yield_node = create_control_node(erb_node, array_init(8), NULL, NULL, type);
|
1031
|
+
|
1032
|
+
if (yield_node) {
|
1033
|
+
array_append(new_array, yield_node);
|
1034
|
+
} else {
|
1035
|
+
array_append(new_array, item);
|
1036
|
+
}
|
1037
|
+
|
1038
|
+
index++;
|
1039
|
+
break;
|
1040
|
+
}
|
1041
|
+
|
997
1042
|
default:
|
998
1043
|
array_append(new_array, item);
|
999
1044
|
index++;
|
data/src/analyze_helpers.c
CHANGED
@@ -89,12 +89,17 @@ bool search_if_nodes(const pm_node_t* node, void* data) {
|
|
89
89
|
analyzed_ruby_T* analyzed = (analyzed_ruby_T*) data;
|
90
90
|
|
91
91
|
if (node->type == PM_IF_NODE) {
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
92
|
+
const pm_if_node_t* if_node = (const pm_if_node_t*) node;
|
93
|
+
|
94
|
+
// Handle ternary
|
95
|
+
if (if_node->if_keyword_loc.start != NULL && if_node->if_keyword_loc.end != NULL) {
|
96
|
+
analyzed->has_if_node = true;
|
97
|
+
return true;
|
98
|
+
}
|
96
99
|
}
|
97
100
|
|
101
|
+
pm_visit_child_nodes(node, search_if_nodes, analyzed);
|
102
|
+
|
98
103
|
return false;
|
99
104
|
}
|
100
105
|
|
@@ -274,10 +279,14 @@ bool search_ensure_nodes(analyzed_ruby_T* analyzed) {
|
|
274
279
|
return false;
|
275
280
|
}
|
276
281
|
|
277
|
-
bool search_yield_nodes(
|
278
|
-
|
282
|
+
bool search_yield_nodes(const pm_node_t* node, void* data) {
|
283
|
+
analyzed_ruby_T* analyzed = (analyzed_ruby_T*) data;
|
284
|
+
|
285
|
+
if (node->type == PM_YIELD_NODE) {
|
279
286
|
analyzed->has_yield_node = true;
|
280
287
|
return true;
|
288
|
+
} else {
|
289
|
+
pm_visit_child_nodes(node, search_yield_nodes, analyzed);
|
281
290
|
}
|
282
291
|
|
283
292
|
return false;
|
data/src/ast_nodes.c
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
2
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release/templates/src/ast_nodes.c.erb
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-6/templates/src/ast_nodes.c.erb
|
3
3
|
|
4
4
|
#include <stdio.h>
|
5
5
|
#include <stdbool.h>
|
data/src/ast_pretty_print.c
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
2
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release/templates/src/ast_pretty_print.c.erb
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-6/templates/src/ast_pretty_print.c.erb
|
3
3
|
|
4
4
|
#include "include/ast_node.h"
|
5
5
|
#include "include/ast_nodes.h"
|
data/src/errors.c
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
2
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release/templates/src/errors.c.erb
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-6/templates/src/errors.c.erb
|
3
3
|
|
4
4
|
#include "include/array.h"
|
5
5
|
#include "include/errors.h"
|
data/src/extract.c
CHANGED
@@ -20,7 +20,9 @@ void herb_extract_ruby_to_buffer_with_semicolons(const char* source, buffer_T* o
|
|
20
20
|
}
|
21
21
|
|
22
22
|
case TOKEN_ERB_START: {
|
23
|
-
if (strcmp(token->value, "<%#") == 0)
|
23
|
+
if (strcmp(token->value, "<%#") == 0 || strcmp(token->value, "<%%") == 0 || strcmp(token->value, "<%%=") == 0) {
|
24
|
+
skip_erb_content = true;
|
25
|
+
}
|
24
26
|
|
25
27
|
buffer_append_whitespace(output, range_length(token->range));
|
26
28
|
break;
|
@@ -67,7 +69,9 @@ void herb_extract_ruby_to_buffer(const char* source, buffer_T* output) {
|
|
67
69
|
}
|
68
70
|
|
69
71
|
case TOKEN_ERB_START: {
|
70
|
-
if (strcmp(token->value, "<%#") == 0)
|
72
|
+
if (strcmp(token->value, "<%#") == 0 || strcmp(token->value, "<%%") == 0 || strcmp(token->value, "<%%=") == 0) {
|
73
|
+
skip_erb_content = true;
|
74
|
+
}
|
71
75
|
|
72
76
|
buffer_append_whitespace(output, range_length(token->range));
|
73
77
|
break;
|
@@ -44,6 +44,6 @@ bool search_when_nodes(analyzed_ruby_T* analyzed);
|
|
44
44
|
bool search_in_nodes(analyzed_ruby_T* analyzed);
|
45
45
|
bool search_rescue_nodes(analyzed_ruby_T* analyzed);
|
46
46
|
bool search_ensure_nodes(analyzed_ruby_T* analyzed);
|
47
|
-
bool search_yield_nodes(
|
47
|
+
bool search_yield_nodes(const pm_node_t* node, void* data);
|
48
48
|
|
49
49
|
#endif
|
data/src/include/ast_nodes.h
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
2
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release/templates/src/include/ast_nodes.h.erb
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-6/templates/src/include/ast_nodes.h.erb
|
3
3
|
|
4
4
|
#ifndef HERB_AST_NODES_H
|
5
5
|
#define HERB_AST_NODES_H
|
@@ -1,5 +1,5 @@
|
|
1
1
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
2
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release/templates/src/include/ast_pretty_print.h.erb
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-6/templates/src/include/ast_pretty_print.h.erb
|
3
3
|
|
4
4
|
#ifndef HERB_AST_PRETTY_PRINT_H
|
5
5
|
#define HERB_AST_PRETTY_PRINT_H
|
data/src/include/errors.h
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
2
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release/templates/src/include/errors.h.erb
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-6/templates/src/include/errors.h.erb
|
3
3
|
|
4
4
|
#ifndef HERB_ERRORS_H
|
5
5
|
#define HERB_ERRORS_H
|
@@ -16,7 +16,10 @@ void parser_append_unexpected_error(parser_T* parser, const char* description, c
|
|
16
16
|
void parser_append_unexpected_token_error(parser_T* parser, token_type_T expected_type, array_T* errors);
|
17
17
|
|
18
18
|
void parser_append_literal_node_from_buffer(
|
19
|
-
const parser_T* parser,
|
19
|
+
const parser_T* parser,
|
20
|
+
buffer_T* buffer,
|
21
|
+
array_T* children,
|
22
|
+
position_T* start
|
20
23
|
);
|
21
24
|
|
22
25
|
bool parser_in_svg_context(const parser_T* parser);
|
@@ -26,7 +29,9 @@ token_T* parser_consume_if_present(parser_T* parser, token_type_T type);
|
|
26
29
|
token_T* parser_consume_expected(parser_T* parser, token_type_T type, array_T* array);
|
27
30
|
|
28
31
|
AST_HTML_ELEMENT_NODE_T* parser_handle_missing_close_tag(
|
29
|
-
AST_HTML_OPEN_TAG_NODE_T* open_tag,
|
32
|
+
AST_HTML_OPEN_TAG_NODE_T* open_tag,
|
33
|
+
array_T* body,
|
34
|
+
array_T* errors
|
30
35
|
);
|
31
36
|
void parser_handle_mismatched_tags(const parser_T* parser, const AST_HTML_CLOSE_TAG_NODE_T* close_tag, array_T* errors);
|
32
37
|
|
data/src/include/pretty_print.h
CHANGED
@@ -13,37 +13,77 @@ void pretty_print_newline(size_t indent, size_t relative_indent, buffer_T* buffe
|
|
13
13
|
void pretty_print_label(const char* name, size_t indent, size_t relative_indent, bool last_property, buffer_T* buffer);
|
14
14
|
|
15
15
|
void pretty_print_position_property(
|
16
|
-
position_T* position,
|
16
|
+
position_T* position,
|
17
|
+
const char* name,
|
18
|
+
size_t indent,
|
19
|
+
size_t relative_indent,
|
20
|
+
bool last_property,
|
21
|
+
buffer_T* buffer
|
17
22
|
);
|
18
23
|
|
19
24
|
void pretty_print_location(location_T* location, buffer_T* buffer);
|
20
25
|
|
21
26
|
void pretty_print_property(
|
22
|
-
const char* name,
|
27
|
+
const char* name,
|
28
|
+
const char* value,
|
29
|
+
size_t indent,
|
30
|
+
size_t relative_indent,
|
31
|
+
bool last_property,
|
32
|
+
buffer_T* buffer
|
23
33
|
);
|
24
34
|
|
25
35
|
void pretty_print_size_t_property(
|
26
|
-
size_t value,
|
36
|
+
size_t value,
|
37
|
+
const char* name,
|
38
|
+
size_t indent,
|
39
|
+
size_t relative_indent,
|
40
|
+
bool last_property,
|
41
|
+
buffer_T* buffer
|
27
42
|
);
|
28
43
|
|
29
44
|
void pretty_print_string_property(
|
30
|
-
const char* string,
|
45
|
+
const char* string,
|
46
|
+
const char* name,
|
47
|
+
size_t indent,
|
48
|
+
size_t relative_indent,
|
49
|
+
bool last_property,
|
50
|
+
buffer_T* buffer
|
31
51
|
);
|
32
52
|
|
33
53
|
void pretty_print_quoted_property(
|
34
|
-
const char* name,
|
54
|
+
const char* name,
|
55
|
+
const char* value,
|
56
|
+
size_t indent,
|
57
|
+
size_t relative_indent,
|
58
|
+
bool last_property,
|
59
|
+
buffer_T* buffer
|
35
60
|
);
|
36
61
|
|
37
62
|
void pretty_print_boolean_property(
|
38
|
-
const char* name,
|
63
|
+
const char* name,
|
64
|
+
bool value,
|
65
|
+
size_t indent,
|
66
|
+
size_t relative_indent,
|
67
|
+
bool last_property,
|
68
|
+
buffer_T* buffer
|
39
69
|
);
|
40
70
|
|
41
71
|
void pretty_print_token_property(
|
42
|
-
token_T* token,
|
72
|
+
token_T* token,
|
73
|
+
const char* name,
|
74
|
+
size_t indent,
|
75
|
+
size_t relative_indent,
|
76
|
+
bool last_property,
|
77
|
+
buffer_T* buffer
|
43
78
|
);
|
44
79
|
|
45
80
|
void pretty_print_array(
|
46
|
-
const char* name,
|
81
|
+
const char* name,
|
82
|
+
array_T* array,
|
83
|
+
size_t indent,
|
84
|
+
size_t relative_indent,
|
85
|
+
bool last_property,
|
86
|
+
buffer_T* buffer
|
47
87
|
);
|
48
88
|
|
49
89
|
void pretty_print_errors(AST_NODE_T* node, size_t indent, size_t relative_indent, bool last_property, buffer_T* buffer);
|
data/src/include/prism_helpers.h
CHANGED
@@ -10,7 +10,10 @@
|
|
10
10
|
const char* pm_error_level_to_string(pm_error_level_t level);
|
11
11
|
|
12
12
|
RUBY_PARSE_ERROR_T* ruby_parse_error_from_prism_error(
|
13
|
-
const pm_diagnostic_t* error,
|
13
|
+
const pm_diagnostic_t* error,
|
14
|
+
const AST_NODE_T* node,
|
15
|
+
const char* source,
|
16
|
+
pm_parser_t* parser
|
14
17
|
);
|
15
18
|
|
16
19
|
position_T* position_from_source_with_offset(const char* source, size_t offset);
|
data/src/include/token_struct.h
CHANGED
@@ -20,7 +20,7 @@ typedef enum {
|
|
20
20
|
TOKEN_HTML_COMMENT_START, // <!--
|
21
21
|
TOKEN_HTML_COMMENT_END, // -->
|
22
22
|
|
23
|
-
TOKEN_ERB_START, // <%, <%=, <%#, <%-, <%==, <%%
|
23
|
+
TOKEN_ERB_START, // <%, <%=, <%%=, <%#, <%-, <%==, <%%
|
24
24
|
TOKEN_ERB_CONTENT, // Ruby Code
|
25
25
|
TOKEN_ERB_END, // %>, -%>, %%>
|
26
26
|
|
@@ -33,6 +33,7 @@ typedef enum {
|
|
33
33
|
TOKEN_EXCLAMATION, // !
|
34
34
|
TOKEN_SEMICOLON, // ;
|
35
35
|
TOKEN_COLON, // :
|
36
|
+
TOKEN_AT, // @
|
36
37
|
TOKEN_PERCENT, // %
|
37
38
|
TOKEN_AMPERSAND, // &
|
38
39
|
|
data/src/include/version.h
CHANGED
data/src/lexer.c
CHANGED
@@ -163,7 +163,7 @@ static token_T* lexer_parse_identifier(lexer_T* lexer) {
|
|
163
163
|
// ===== ERB Parsing
|
164
164
|
|
165
165
|
static token_T* lexer_parse_erb_open(lexer_T* lexer) {
|
166
|
-
const char* erb_patterns[] = { "<%==", "<%=", "<%#", "<%-", "<%%", "<%" };
|
166
|
+
const char* erb_patterns[] = { "<%==", "<%%=", "<%=", "<%#", "<%-", "<%%", "<%" };
|
167
167
|
|
168
168
|
lexer->state = STATE_ERB_CONTENT;
|
169
169
|
|
@@ -184,7 +184,16 @@ static token_T* lexer_parse_erb_content(lexer_T* lexer) {
|
|
184
184
|
}
|
185
185
|
|
186
186
|
buffer_append_char(&buffer, lexer->current_character);
|
187
|
-
|
187
|
+
|
188
|
+
if (is_newline(lexer->current_character)) {
|
189
|
+
lexer->current_line++;
|
190
|
+
lexer->current_column = 0;
|
191
|
+
} else {
|
192
|
+
lexer->current_column++;
|
193
|
+
}
|
194
|
+
|
195
|
+
lexer->current_position++;
|
196
|
+
lexer->current_character = lexer->source[lexer->current_position];
|
188
197
|
}
|
189
198
|
|
190
199
|
lexer->state = STATE_ERB_CLOSE;
|
@@ -260,6 +269,7 @@ token_T* lexer_next_token(lexer_T* lexer) {
|
|
260
269
|
case '>': return lexer_advance_current(lexer, TOKEN_HTML_TAG_END);
|
261
270
|
case '_': return lexer_advance_current(lexer, TOKEN_UNDERSCORE);
|
262
271
|
case ':': return lexer_advance_current(lexer, TOKEN_COLON);
|
272
|
+
case '@': return lexer_advance_current(lexer, TOKEN_AT);
|
263
273
|
case ';': return lexer_advance_current(lexer, TOKEN_SEMICOLON);
|
264
274
|
case '&': return lexer_advance_current(lexer, TOKEN_AMPERSAND);
|
265
275
|
case '!': return lexer_advance_current(lexer, TOKEN_EXCLAMATION);
|
data/src/parser.c
CHANGED
@@ -197,13 +197,19 @@ static AST_HTML_ATTRIBUTE_NAME_NODE_T* parser_parse_html_attribute_name(parser_T
|
|
197
197
|
}
|
198
198
|
|
199
199
|
static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_quoted_html_attribute_value(
|
200
|
-
parser_T* parser,
|
200
|
+
parser_T* parser,
|
201
|
+
array_T* children,
|
202
|
+
array_T* errors
|
201
203
|
) {
|
202
204
|
buffer_T buffer = buffer_new();
|
203
205
|
token_T* opening_quote = parser_consume_expected(parser, TOKEN_QUOTE, errors);
|
204
206
|
position_T* start = position_copy(parser->current_token->location->start);
|
205
207
|
|
206
|
-
while (
|
208
|
+
while (!token_is(parser, TOKEN_EOF)
|
209
|
+
&& !(
|
210
|
+
token_is(parser, TOKEN_QUOTE) && opening_quote != NULL
|
211
|
+
&& strcmp(parser->current_token->value, opening_quote->value) == 0
|
212
|
+
)) {
|
207
213
|
if (token_is(parser, TOKEN_ERB_START)) {
|
208
214
|
parser_append_literal_node_from_buffer(parser, &buffer, children, start);
|
209
215
|
|
@@ -472,7 +478,8 @@ static AST_HTML_CLOSE_TAG_NODE_T* parser_parse_html_close_tag(parser_T* parser)
|
|
472
478
|
|
473
479
|
// TODO: this should probably be AST_HTML_ELEMENT_NODE_T with a AST_HTML_SELF_CLOSING_TAG_NODE_T
|
474
480
|
static AST_HTML_ELEMENT_NODE_T* parser_parse_html_self_closing_element(
|
475
|
-
const parser_T* parser,
|
481
|
+
const parser_T* parser,
|
482
|
+
AST_HTML_OPEN_TAG_NODE_T* open_tag
|
476
483
|
) {
|
477
484
|
return ast_html_element_node_init(
|
478
485
|
open_tag,
|
@@ -487,7 +494,8 @@ static AST_HTML_ELEMENT_NODE_T* parser_parse_html_self_closing_element(
|
|
487
494
|
}
|
488
495
|
|
489
496
|
static AST_HTML_ELEMENT_NODE_T* parser_parse_html_regular_element(
|
490
|
-
parser_T* parser,
|
497
|
+
parser_T* parser,
|
498
|
+
AST_HTML_OPEN_TAG_NODE_T* open_tag
|
491
499
|
) {
|
492
500
|
array_T* errors = array_init(8);
|
493
501
|
array_T* body = array_init(8);
|
@@ -618,6 +626,7 @@ static void parser_parse_in_data_state(parser_T* parser, array_T* children, arra
|
|
618
626
|
TOKEN_IDENTIFIER,
|
619
627
|
TOKEN_NEWLINE,
|
620
628
|
TOKEN_PERCENT,
|
629
|
+
TOKEN_QUOTE,
|
621
630
|
TOKEN_SEMICOLON,
|
622
631
|
TOKEN_SLASH,
|
623
632
|
TOKEN_UNDERSCORE,
|
data/src/parser_helpers.c
CHANGED
@@ -80,7 +80,10 @@ void parser_append_unexpected_token_error(parser_T* parser, token_type_T expecte
|
|
80
80
|
}
|
81
81
|
|
82
82
|
void parser_append_literal_node_from_buffer(
|
83
|
-
const parser_T* parser,
|
83
|
+
const parser_T* parser,
|
84
|
+
buffer_T* buffer,
|
85
|
+
array_T* children,
|
86
|
+
position_T* start
|
84
87
|
) {
|
85
88
|
if (buffer_length(buffer) == 0) { return; }
|
86
89
|
|
@@ -115,7 +118,9 @@ token_T* parser_consume_expected(parser_T* parser, const token_type_T expected_t
|
|
115
118
|
}
|
116
119
|
|
117
120
|
AST_HTML_ELEMENT_NODE_T* parser_handle_missing_close_tag(
|
118
|
-
AST_HTML_OPEN_TAG_NODE_T* open_tag,
|
121
|
+
AST_HTML_OPEN_TAG_NODE_T* open_tag,
|
122
|
+
array_T* body,
|
123
|
+
array_T* errors
|
119
124
|
) {
|
120
125
|
append_missing_closing_tag_error(
|
121
126
|
open_tag->tag_name,
|
@@ -137,7 +142,9 @@ AST_HTML_ELEMENT_NODE_T* parser_handle_missing_close_tag(
|
|
137
142
|
}
|
138
143
|
|
139
144
|
void parser_handle_mismatched_tags(
|
140
|
-
const parser_T* parser,
|
145
|
+
const parser_T* parser,
|
146
|
+
const AST_HTML_CLOSE_TAG_NODE_T* close_tag,
|
147
|
+
array_T* errors
|
141
148
|
) {
|
142
149
|
if (array_size(parser->open_tags_stack) > 0) {
|
143
150
|
token_T* expected_tag = array_last(parser->open_tags_stack);
|