herb 0.7.4-aarch64-linux-gnu → 0.8.0-aarch64-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 +8 -5
- data/config.yml +40 -20
- data/ext/herb/error_helpers.c +57 -3
- data/ext/herb/error_helpers.h +1 -1
- data/ext/herb/extconf.rb +1 -0
- data/ext/herb/extension.c +10 -24
- data/ext/herb/extension_helpers.c +12 -18
- data/ext/herb/extension_helpers.h +4 -4
- data/ext/herb/nodes.c +72 -37
- data/herb.gemspec +0 -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/ast/helpers.rb +11 -0
- data/lib/herb/ast/node.rb +15 -6
- data/lib/herb/ast/nodes.rb +609 -392
- data/lib/herb/cli.rb +31 -0
- data/lib/herb/colors.rb +82 -0
- data/lib/herb/engine/compiler.rb +140 -14
- data/lib/herb/engine/debug_visitor.rb +1 -5
- data/lib/herb/engine/parser_error_overlay.rb +1 -1
- data/lib/herb/engine.rb +18 -20
- data/lib/herb/errors.rb +166 -56
- data/lib/herb/location.rb +2 -2
- data/lib/herb/project.rb +86 -21
- data/lib/herb/token.rb +14 -2
- data/lib/herb/version.rb +1 -1
- data/lib/herb.rb +1 -0
- data/sig/herb/ast/helpers.rbs +3 -0
- data/sig/herb/ast/node.rbs +12 -5
- data/sig/herb/ast/nodes.rbs +124 -62
- data/sig/herb/colors.rbs +35 -0
- data/sig/herb/engine/compiler.rbs +23 -1
- data/sig/herb/errors.rbs +74 -20
- data/sig/herb/token.rbs +8 -0
- data/sig/herb_c_extension.rbs +1 -1
- data/sig/serialized_ast_errors.rbs +8 -0
- data/src/analyze.c +461 -249
- data/src/analyze_helpers.c +5 -0
- data/src/analyze_missing_end.c +147 -0
- data/src/analyze_transform.c +196 -0
- data/src/analyzed_ruby.c +23 -2
- data/src/ast_node.c +14 -17
- data/src/ast_nodes.c +179 -181
- data/src/ast_pretty_print.c +232 -232
- data/src/element_source.c +7 -6
- data/src/errors.c +272 -152
- data/src/extract.c +92 -34
- data/src/herb.c +37 -49
- data/src/html_util.c +34 -96
- data/src/include/analyze.h +10 -2
- data/src/include/analyze_helpers.h +3 -0
- data/src/include/analyzed_ruby.h +4 -2
- data/src/include/ast_node.h +4 -4
- data/src/include/ast_nodes.h +68 -67
- data/src/include/ast_pretty_print.h +2 -2
- data/src/include/element_source.h +3 -1
- data/src/include/errors.h +42 -26
- data/src/include/extract.h +4 -4
- data/src/include/herb.h +6 -7
- data/src/include/html_util.h +4 -5
- data/src/include/lexer.h +1 -3
- data/src/include/lexer_peek_helpers.h +21 -19
- data/src/include/lexer_struct.h +12 -10
- data/src/include/location.h +10 -13
- data/src/include/macros.h +4 -0
- data/src/include/parser.h +12 -6
- data/src/include/parser_helpers.h +26 -16
- data/src/include/position.h +3 -14
- data/src/include/pretty_print.h +38 -28
- data/src/include/prism_helpers.h +1 -1
- data/src/include/range.h +4 -13
- data/src/include/token.h +5 -11
- data/src/include/token_struct.h +2 -2
- data/src/include/utf8.h +3 -2
- data/src/include/util/hb_arena.h +31 -0
- data/src/include/util/hb_arena_debug.h +8 -0
- data/src/include/util/hb_array.h +33 -0
- data/src/include/util/hb_buffer.h +34 -0
- data/src/include/util/hb_string.h +29 -0
- data/src/include/util/hb_system.h +9 -0
- data/src/include/util.h +3 -14
- data/src/include/version.h +1 -1
- data/src/include/visitor.h +1 -1
- data/src/io.c +7 -4
- data/src/lexer.c +62 -88
- data/src/lexer_peek_helpers.c +42 -38
- data/src/location.c +9 -37
- data/src/main.c +19 -23
- data/src/parser.c +373 -313
- data/src/parser_helpers.c +60 -54
- data/src/parser_match_tags.c +316 -0
- data/src/pretty_print.c +88 -117
- data/src/prism_helpers.c +7 -7
- data/src/range.c +2 -35
- data/src/token.c +36 -87
- data/src/utf8.c +4 -4
- data/src/util/hb_arena.c +179 -0
- data/src/util/hb_arena_debug.c +237 -0
- data/src/{array.c → util/hb_array.c} +26 -27
- data/src/util/hb_buffer.c +203 -0
- data/src/util/hb_string.c +85 -0
- data/src/util/hb_system.c +30 -0
- data/src/util.c +29 -99
- data/src/visitor.c +54 -54
- data/templates/ext/herb/error_helpers.c.erb +3 -3
- data/templates/ext/herb/error_helpers.h.erb +1 -1
- data/templates/ext/herb/nodes.c.erb +11 -6
- data/templates/java/error_helpers.c.erb +75 -0
- data/templates/java/error_helpers.h.erb +20 -0
- data/templates/java/nodes.c.erb +97 -0
- data/templates/java/nodes.h.erb +23 -0
- data/templates/java/org/herb/ast/Errors.java.erb +121 -0
- data/templates/java/org/herb/ast/NodeVisitor.java.erb +14 -0
- data/templates/java/org/herb/ast/Nodes.java.erb +220 -0
- data/templates/java/org/herb/ast/Visitor.java.erb +56 -0
- data/templates/javascript/packages/core/src/visitor.ts.erb +29 -1
- data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +8 -8
- data/templates/javascript/packages/node/extension/error_helpers.h.erb +1 -1
- data/templates/javascript/packages/node/extension/nodes.cpp.erb +9 -9
- data/templates/javascript/packages/node/extension/nodes.h.erb +1 -1
- data/templates/lib/herb/ast/nodes.rb.erb +28 -16
- data/templates/lib/herb/errors.rb.erb +17 -12
- data/templates/rust/src/ast/nodes.rs.erb +220 -0
- data/templates/rust/src/errors.rs.erb +216 -0
- data/templates/rust/src/nodes.rs.erb +374 -0
- data/templates/src/analyze_missing_end.c.erb +36 -0
- data/templates/src/analyze_transform.c.erb +24 -0
- data/templates/src/ast_nodes.c.erb +14 -16
- data/templates/src/ast_pretty_print.c.erb +36 -36
- data/templates/src/errors.c.erb +36 -38
- data/templates/src/include/ast_nodes.h.erb +11 -10
- data/templates/src/include/ast_pretty_print.h.erb +2 -2
- data/templates/src/include/errors.h.erb +9 -9
- data/templates/src/parser_match_tags.c.erb +38 -0
- data/templates/src/visitor.c.erb +4 -4
- data/templates/template.rb +22 -3
- data/templates/wasm/error_helpers.cpp.erb +9 -9
- data/templates/wasm/error_helpers.h.erb +1 -1
- data/templates/wasm/nodes.cpp.erb +9 -9
- data/templates/wasm/nodes.h.erb +1 -1
- data/vendor/prism/Rakefile +4 -1
- data/vendor/prism/config.yml +2 -1
- data/vendor/prism/include/prism/ast.h +31 -1
- data/vendor/prism/include/prism/diagnostic.h +1 -0
- data/vendor/prism/include/prism/version.h +3 -3
- data/vendor/prism/src/diagnostic.c +3 -1
- data/vendor/prism/src/prism.c +130 -71
- data/vendor/prism/src/util/pm_string.c +6 -8
- data/vendor/prism/templates/include/prism/ast.h.erb +2 -0
- data/vendor/prism/templates/java/org/prism/Loader.java.erb +2 -2
- data/vendor/prism/templates/javascript/src/deserialize.js.erb +2 -2
- data/vendor/prism/templates/lib/prism/serialize.rb.erb +2 -2
- data/vendor/prism/templates/sig/prism.rbs.erb +4 -0
- data/vendor/prism/templates/src/diagnostic.c.erb +1 -0
- metadata +34 -21
- data/lib/herb/libherb/array.rb +0 -51
- data/lib/herb/libherb/ast_node.rb +0 -50
- data/lib/herb/libherb/buffer.rb +0 -56
- data/lib/herb/libherb/extract_result.rb +0 -20
- data/lib/herb/libherb/lex_result.rb +0 -32
- data/lib/herb/libherb/libherb.rb +0 -52
- data/lib/herb/libherb/parse_result.rb +0 -20
- data/lib/herb/libherb/token.rb +0 -46
- data/lib/herb/libherb.rb +0 -35
- data/src/buffer.c +0 -232
- data/src/include/array.h +0 -33
- data/src/include/buffer.h +0 -39
- data/src/include/json.h +0 -28
- data/src/include/memory.h +0 -12
- data/src/json.c +0 -205
- data/src/memory.c +0 -53
- data/src/position.c +0 -33
data/src/analyze.c
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
#include "include/analyze.h"
|
|
2
2
|
#include "include/analyze_helpers.h"
|
|
3
3
|
#include "include/analyzed_ruby.h"
|
|
4
|
-
#include "include/
|
|
4
|
+
#include "include/ast_node.h"
|
|
5
5
|
#include "include/ast_nodes.h"
|
|
6
6
|
#include "include/errors.h"
|
|
7
7
|
#include "include/extract.h"
|
|
8
8
|
#include "include/location.h"
|
|
9
|
+
#include "include/parser.h"
|
|
9
10
|
#include "include/position.h"
|
|
10
11
|
#include "include/pretty_print.h"
|
|
11
12
|
#include "include/prism_helpers.h"
|
|
12
13
|
#include "include/token_struct.h"
|
|
13
14
|
#include "include/util.h"
|
|
15
|
+
#include "include/util/hb_array.h"
|
|
16
|
+
#include "include/util/hb_string.h"
|
|
14
17
|
#include "include/visitor.h"
|
|
15
18
|
|
|
16
19
|
#include <prism.h>
|
|
@@ -19,7 +22,7 @@
|
|
|
19
22
|
#include <stdlib.h>
|
|
20
23
|
#include <string.h>
|
|
21
24
|
|
|
22
|
-
static analyzed_ruby_T* herb_analyze_ruby(
|
|
25
|
+
static analyzed_ruby_T* herb_analyze_ruby(hb_string_T source) {
|
|
23
26
|
analyzed_ruby_T* analyzed = init_analyzed_ruby(source);
|
|
24
27
|
|
|
25
28
|
pm_visit_node(analyzed->root, search_if_nodes, analyzed);
|
|
@@ -52,9 +55,7 @@ static bool analyze_erb_content(const AST_NODE_T* node, void* data) {
|
|
|
52
55
|
const char* opening = erb_content_node->tag_opening->value;
|
|
53
56
|
|
|
54
57
|
if (strcmp(opening, "<%%") != 0 && strcmp(opening, "<%%=") != 0 && strcmp(opening, "<%#") != 0) {
|
|
55
|
-
analyzed_ruby_T* analyzed = herb_analyze_ruby(erb_content_node->content->value);
|
|
56
|
-
|
|
57
|
-
if (false) { pretty_print_analyzed_ruby(analyzed, erb_content_node->content->value); }
|
|
58
|
+
analyzed_ruby_T* analyzed = herb_analyze_ruby(hb_string(erb_content_node->content->value));
|
|
58
59
|
|
|
59
60
|
erb_content_node->parsed = true;
|
|
60
61
|
erb_content_node->valid = analyzed->valid;
|
|
@@ -73,16 +74,16 @@ static bool analyze_erb_content(const AST_NODE_T* node, void* data) {
|
|
|
73
74
|
|
|
74
75
|
static size_t process_block_children(
|
|
75
76
|
AST_NODE_T* node,
|
|
76
|
-
|
|
77
|
+
hb_array_T* array,
|
|
77
78
|
size_t index,
|
|
78
|
-
|
|
79
|
+
hb_array_T* children_array,
|
|
79
80
|
analyze_ruby_context_T* context,
|
|
80
81
|
control_type_t parent_type
|
|
81
82
|
);
|
|
82
83
|
|
|
83
84
|
static size_t process_subsequent_block(
|
|
84
85
|
AST_NODE_T* node,
|
|
85
|
-
|
|
86
|
+
hb_array_T* array,
|
|
86
87
|
size_t index,
|
|
87
88
|
AST_NODE_T** subsequent_out,
|
|
88
89
|
analyze_ruby_context_T* context,
|
|
@@ -96,12 +97,8 @@ static control_type_t detect_control_type(AST_ERB_CONTENT_NODE_T* erb_node) {
|
|
|
96
97
|
|
|
97
98
|
if (!ruby) { return CONTROL_TYPE_UNKNOWN; }
|
|
98
99
|
|
|
99
|
-
if (ruby->valid) {
|
|
100
|
-
if (has_yield_node(ruby)) { return CONTROL_TYPE_YIELD; }
|
|
101
|
-
return CONTROL_TYPE_UNKNOWN;
|
|
102
|
-
}
|
|
100
|
+
if (ruby->valid) { return CONTROL_TYPE_UNKNOWN; }
|
|
103
101
|
|
|
104
|
-
if (has_yield_node(ruby)) { return CONTROL_TYPE_YIELD; }
|
|
105
102
|
if (has_block_node(ruby)) { return CONTROL_TYPE_BLOCK; }
|
|
106
103
|
if (has_if_node(ruby)) { return CONTROL_TYPE_IF; }
|
|
107
104
|
if (has_elsif_node(ruby)) { return CONTROL_TYPE_ELSIF; }
|
|
@@ -119,6 +116,7 @@ static control_type_t detect_control_type(AST_ERB_CONTENT_NODE_T* erb_node) {
|
|
|
119
116
|
if (has_until_node(ruby)) { return CONTROL_TYPE_UNTIL; }
|
|
120
117
|
if (has_for_node(ruby)) { return CONTROL_TYPE_FOR; }
|
|
121
118
|
if (has_block_closing(ruby)) { return CONTROL_TYPE_BLOCK_CLOSE; }
|
|
119
|
+
if (has_yield_node(ruby)) { return CONTROL_TYPE_YIELD; }
|
|
122
120
|
|
|
123
121
|
return CONTROL_TYPE_UNKNOWN;
|
|
124
122
|
}
|
|
@@ -152,22 +150,24 @@ static bool is_terminator_type(control_type_t parent_type, control_type_t child_
|
|
|
152
150
|
|
|
153
151
|
static AST_NODE_T* create_control_node(
|
|
154
152
|
AST_ERB_CONTENT_NODE_T* erb_node,
|
|
155
|
-
|
|
153
|
+
hb_array_T* children,
|
|
156
154
|
AST_NODE_T* subsequent,
|
|
157
155
|
AST_ERB_END_NODE_T* end_node,
|
|
158
156
|
control_type_t control_type
|
|
159
157
|
) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
158
|
+
hb_array_T* errors = erb_node->base.errors;
|
|
159
|
+
erb_node->base.errors = NULL;
|
|
160
|
+
|
|
161
|
+
position_T start_position = erb_node->tag_opening->location.start;
|
|
162
|
+
position_T end_position = erb_node->tag_closing->location.end;
|
|
163
163
|
|
|
164
164
|
if (end_node) {
|
|
165
|
-
end_position = end_node->base.location
|
|
166
|
-
} else if (children &&
|
|
167
|
-
AST_NODE_T* last_child =
|
|
168
|
-
end_position = last_child->location
|
|
165
|
+
end_position = end_node->base.location.end;
|
|
166
|
+
} else if (children && hb_array_size(children) > 0) {
|
|
167
|
+
AST_NODE_T* last_child = hb_array_get(children, hb_array_size(children) - 1);
|
|
168
|
+
end_position = last_child->location.end;
|
|
169
169
|
} else if (subsequent) {
|
|
170
|
-
end_position = subsequent->location
|
|
170
|
+
end_position = subsequent->location.end;
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
token_T* tag_opening = erb_node->tag_opening;
|
|
@@ -176,7 +176,7 @@ static AST_NODE_T* create_control_node(
|
|
|
176
176
|
|
|
177
177
|
switch (control_type) {
|
|
178
178
|
case CONTROL_TYPE_IF:
|
|
179
|
-
case CONTROL_TYPE_ELSIF:
|
|
179
|
+
case CONTROL_TYPE_ELSIF: {
|
|
180
180
|
return (AST_NODE_T*) ast_erb_if_node_init(
|
|
181
181
|
tag_opening,
|
|
182
182
|
content,
|
|
@@ -188,32 +188,40 @@ static AST_NODE_T* create_control_node(
|
|
|
188
188
|
end_position,
|
|
189
189
|
errors
|
|
190
190
|
);
|
|
191
|
+
}
|
|
191
192
|
|
|
192
|
-
case CONTROL_TYPE_ELSE:
|
|
193
|
-
return (
|
|
194
|
-
|
|
193
|
+
case CONTROL_TYPE_ELSE: {
|
|
194
|
+
return (
|
|
195
|
+
AST_NODE_T*
|
|
196
|
+
) ast_erb_else_node_init(tag_opening, content, tag_closing, children, start_position, end_position, errors);
|
|
197
|
+
}
|
|
195
198
|
|
|
196
199
|
case CONTROL_TYPE_CASE:
|
|
197
200
|
case CONTROL_TYPE_CASE_MATCH: {
|
|
198
201
|
AST_ERB_ELSE_NODE_T* else_node = NULL;
|
|
199
202
|
if (subsequent && subsequent->type == AST_ERB_ELSE_NODE) { else_node = (AST_ERB_ELSE_NODE_T*) subsequent; }
|
|
200
203
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
+
hb_array_T* when_conditions = hb_array_init(8);
|
|
205
|
+
hb_array_T* in_conditions = hb_array_init(8);
|
|
206
|
+
hb_array_T* non_when_non_in_children = hb_array_init(8);
|
|
207
|
+
|
|
208
|
+
for (size_t i = 0; i < hb_array_size(children); i++) {
|
|
209
|
+
AST_NODE_T* child = hb_array_get(children, i);
|
|
204
210
|
|
|
205
|
-
for (size_t i = 0; i < array_size(children); i++) {
|
|
206
|
-
AST_NODE_T* child = array_get(children, i);
|
|
207
211
|
if (child && child->type == AST_ERB_WHEN_NODE) {
|
|
208
|
-
|
|
212
|
+
hb_array_append(when_conditions, child);
|
|
209
213
|
} else if (child && child->type == AST_ERB_IN_NODE) {
|
|
210
|
-
|
|
214
|
+
hb_array_append(in_conditions, child);
|
|
211
215
|
} else {
|
|
212
|
-
|
|
216
|
+
hb_array_append(non_when_non_in_children, child);
|
|
213
217
|
}
|
|
214
218
|
}
|
|
215
219
|
|
|
216
|
-
|
|
220
|
+
hb_array_free(&children);
|
|
221
|
+
|
|
222
|
+
if (hb_array_size(in_conditions) > 0) {
|
|
223
|
+
hb_array_free(&when_conditions);
|
|
224
|
+
|
|
217
225
|
return (AST_NODE_T*) ast_erb_case_match_node_init(
|
|
218
226
|
tag_opening,
|
|
219
227
|
content,
|
|
@@ -226,30 +234,34 @@ static AST_NODE_T* create_control_node(
|
|
|
226
234
|
end_position,
|
|
227
235
|
errors
|
|
228
236
|
);
|
|
229
|
-
}
|
|
237
|
+
} else {
|
|
238
|
+
hb_array_free(&in_conditions);
|
|
230
239
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
240
|
+
return (AST_NODE_T*) ast_erb_case_node_init(
|
|
241
|
+
tag_opening,
|
|
242
|
+
content,
|
|
243
|
+
tag_closing,
|
|
244
|
+
non_when_non_in_children,
|
|
245
|
+
when_conditions,
|
|
246
|
+
else_node,
|
|
247
|
+
end_node,
|
|
248
|
+
start_position,
|
|
249
|
+
end_position,
|
|
250
|
+
errors
|
|
251
|
+
);
|
|
252
|
+
}
|
|
243
253
|
}
|
|
244
254
|
|
|
245
255
|
case CONTROL_TYPE_WHEN: {
|
|
246
|
-
return (
|
|
247
|
-
|
|
256
|
+
return (
|
|
257
|
+
AST_NODE_T*
|
|
258
|
+
) ast_erb_when_node_init(tag_opening, content, tag_closing, children, start_position, end_position, errors);
|
|
248
259
|
}
|
|
249
260
|
|
|
250
261
|
case CONTROL_TYPE_IN: {
|
|
251
|
-
return (
|
|
252
|
-
|
|
262
|
+
return (
|
|
263
|
+
AST_NODE_T*
|
|
264
|
+
) ast_erb_in_node_init(tag_opening, content, tag_closing, children, start_position, end_position, errors);
|
|
253
265
|
}
|
|
254
266
|
|
|
255
267
|
case CONTROL_TYPE_BEGIN: {
|
|
@@ -300,8 +312,9 @@ static AST_NODE_T* create_control_node(
|
|
|
300
312
|
}
|
|
301
313
|
|
|
302
314
|
case CONTROL_TYPE_ENSURE: {
|
|
303
|
-
return (
|
|
304
|
-
|
|
315
|
+
return (
|
|
316
|
+
AST_NODE_T*
|
|
317
|
+
) ast_erb_ensure_node_init(tag_opening, content, tag_closing, children, start_position, end_position, errors);
|
|
305
318
|
}
|
|
306
319
|
|
|
307
320
|
case CONTROL_TYPE_UNLESS: {
|
|
@@ -375,34 +388,35 @@ static AST_NODE_T* create_control_node(
|
|
|
375
388
|
}
|
|
376
389
|
|
|
377
390
|
case CONTROL_TYPE_YIELD: {
|
|
378
|
-
return (
|
|
379
|
-
|
|
391
|
+
return (
|
|
392
|
+
AST_NODE_T*
|
|
393
|
+
) ast_erb_yield_node_init(tag_opening, content, tag_closing, start_position, end_position, errors);
|
|
380
394
|
}
|
|
381
395
|
|
|
382
|
-
default:
|
|
396
|
+
default: return NULL;
|
|
383
397
|
}
|
|
384
398
|
}
|
|
385
399
|
|
|
386
400
|
static size_t process_control_structure(
|
|
387
401
|
AST_NODE_T* node,
|
|
388
|
-
|
|
402
|
+
hb_array_T* array,
|
|
389
403
|
size_t index,
|
|
390
|
-
|
|
404
|
+
hb_array_T* output_array,
|
|
391
405
|
analyze_ruby_context_T* context,
|
|
392
406
|
control_type_t initial_type
|
|
393
407
|
) {
|
|
394
|
-
AST_ERB_CONTENT_NODE_T* erb_node = (AST_ERB_CONTENT_NODE_T*)
|
|
395
|
-
|
|
408
|
+
AST_ERB_CONTENT_NODE_T* erb_node = (AST_ERB_CONTENT_NODE_T*) hb_array_get(array, index);
|
|
409
|
+
hb_array_T* children = hb_array_init(8);
|
|
396
410
|
|
|
397
411
|
index++;
|
|
398
412
|
|
|
399
413
|
if (initial_type == CONTROL_TYPE_CASE || initial_type == CONTROL_TYPE_CASE_MATCH) {
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
414
|
+
hb_array_T* when_conditions = hb_array_init(8);
|
|
415
|
+
hb_array_T* in_conditions = hb_array_init(8);
|
|
416
|
+
hb_array_T* non_when_non_in_children = hb_array_init(8);
|
|
403
417
|
|
|
404
|
-
while (index <
|
|
405
|
-
AST_NODE_T* next_node =
|
|
418
|
+
while (index < hb_array_size(array)) {
|
|
419
|
+
AST_NODE_T* next_node = hb_array_get(array, index);
|
|
406
420
|
|
|
407
421
|
if (!next_node) { break; }
|
|
408
422
|
|
|
@@ -413,17 +427,17 @@ static size_t process_control_structure(
|
|
|
413
427
|
if (next_type == CONTROL_TYPE_WHEN || next_type == CONTROL_TYPE_IN) { break; }
|
|
414
428
|
}
|
|
415
429
|
|
|
416
|
-
|
|
430
|
+
hb_array_append(non_when_non_in_children, next_node);
|
|
417
431
|
index++;
|
|
418
432
|
}
|
|
419
433
|
|
|
420
|
-
while (index <
|
|
421
|
-
AST_NODE_T* next_node =
|
|
434
|
+
while (index < hb_array_size(array)) {
|
|
435
|
+
AST_NODE_T* next_node = hb_array_get(array, index);
|
|
422
436
|
|
|
423
437
|
if (!next_node) { break; }
|
|
424
438
|
|
|
425
439
|
if (next_node->type != AST_ERB_CONTENT_NODE) {
|
|
426
|
-
|
|
440
|
+
hb_array_append(non_when_non_in_children, next_node);
|
|
427
441
|
index++;
|
|
428
442
|
continue;
|
|
429
443
|
}
|
|
@@ -432,101 +446,77 @@ static size_t process_control_structure(
|
|
|
432
446
|
control_type_t next_type = detect_control_type(erb_content);
|
|
433
447
|
|
|
434
448
|
if (next_type == CONTROL_TYPE_WHEN) {
|
|
435
|
-
|
|
449
|
+
hb_array_T* when_statements = hb_array_init(8);
|
|
436
450
|
index++;
|
|
437
451
|
|
|
438
|
-
|
|
439
|
-
AST_NODE_T* child = array_get(array, index);
|
|
440
|
-
|
|
441
|
-
if (!child) { break; }
|
|
452
|
+
index = process_block_children(node, array, index, when_statements, context, CONTROL_TYPE_WHEN);
|
|
442
453
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
control_type_t child_type = detect_control_type(child_erb);
|
|
446
|
-
|
|
447
|
-
if (child_type == CONTROL_TYPE_WHEN || child_type == CONTROL_TYPE_IN || child_type == CONTROL_TYPE_ELSE
|
|
448
|
-
|| child_type == CONTROL_TYPE_END) {
|
|
449
|
-
break;
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
array_append(when_statements, child);
|
|
454
|
-
index++;
|
|
455
|
-
}
|
|
454
|
+
hb_array_T* when_errors = erb_content->base.errors;
|
|
455
|
+
erb_content->base.errors = NULL;
|
|
456
456
|
|
|
457
457
|
AST_ERB_WHEN_NODE_T* when_node = ast_erb_when_node_init(
|
|
458
458
|
erb_content->tag_opening,
|
|
459
459
|
erb_content->content,
|
|
460
460
|
erb_content->tag_closing,
|
|
461
461
|
when_statements,
|
|
462
|
-
erb_content->tag_opening->location
|
|
463
|
-
erb_content->tag_closing->location
|
|
464
|
-
|
|
462
|
+
erb_content->tag_opening->location.start,
|
|
463
|
+
erb_content->tag_closing->location.end,
|
|
464
|
+
when_errors
|
|
465
465
|
);
|
|
466
466
|
|
|
467
|
-
|
|
467
|
+
ast_node_free((AST_NODE_T*) erb_content);
|
|
468
|
+
|
|
469
|
+
hb_array_append(when_conditions, (AST_NODE_T*) when_node);
|
|
468
470
|
|
|
469
471
|
continue;
|
|
470
472
|
} else if (next_type == CONTROL_TYPE_IN) {
|
|
471
|
-
|
|
473
|
+
hb_array_T* in_statements = hb_array_init(8);
|
|
472
474
|
index++;
|
|
473
475
|
|
|
474
|
-
|
|
475
|
-
AST_NODE_T* child = array_get(array, index);
|
|
476
|
-
|
|
477
|
-
if (!child) { break; }
|
|
478
|
-
|
|
479
|
-
if (child->type == AST_ERB_CONTENT_NODE) {
|
|
480
|
-
AST_ERB_CONTENT_NODE_T* child_erb = (AST_ERB_CONTENT_NODE_T*) child;
|
|
481
|
-
control_type_t child_type = detect_control_type(child_erb);
|
|
476
|
+
index = process_block_children(node, array, index, in_statements, context, CONTROL_TYPE_IN);
|
|
482
477
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
break;
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
array_append(in_statements, child);
|
|
490
|
-
index++;
|
|
491
|
-
}
|
|
478
|
+
hb_array_T* in_errors = erb_content->base.errors;
|
|
479
|
+
erb_content->base.errors = NULL;
|
|
492
480
|
|
|
493
481
|
AST_ERB_IN_NODE_T* in_node = ast_erb_in_node_init(
|
|
494
482
|
erb_content->tag_opening,
|
|
495
483
|
erb_content->content,
|
|
496
484
|
erb_content->tag_closing,
|
|
497
485
|
in_statements,
|
|
498
|
-
erb_content->tag_opening->location
|
|
499
|
-
erb_content->tag_closing->location
|
|
500
|
-
|
|
486
|
+
erb_content->tag_opening->location.start,
|
|
487
|
+
erb_content->tag_closing->location.end,
|
|
488
|
+
in_errors
|
|
501
489
|
);
|
|
502
490
|
|
|
503
|
-
|
|
491
|
+
ast_node_free((AST_NODE_T*) erb_content);
|
|
492
|
+
|
|
493
|
+
hb_array_append(in_conditions, (AST_NODE_T*) in_node);
|
|
504
494
|
|
|
505
495
|
continue;
|
|
506
496
|
} else if (next_type == CONTROL_TYPE_ELSE || next_type == CONTROL_TYPE_END) {
|
|
507
497
|
break;
|
|
508
498
|
} else {
|
|
509
|
-
|
|
499
|
+
hb_array_append(non_when_non_in_children, next_node);
|
|
510
500
|
index++;
|
|
511
501
|
}
|
|
512
502
|
}
|
|
513
503
|
|
|
514
504
|
AST_ERB_ELSE_NODE_T* else_clause = NULL;
|
|
515
505
|
|
|
516
|
-
if (index <
|
|
517
|
-
AST_NODE_T* next_node =
|
|
506
|
+
if (index < hb_array_size(array)) {
|
|
507
|
+
AST_NODE_T* next_node = hb_array_get(array, index);
|
|
518
508
|
|
|
519
509
|
if (next_node && next_node->type == AST_ERB_CONTENT_NODE) {
|
|
520
510
|
AST_ERB_CONTENT_NODE_T* next_erb = (AST_ERB_CONTENT_NODE_T*) next_node;
|
|
521
511
|
control_type_t next_type = detect_control_type(next_erb);
|
|
522
512
|
|
|
523
513
|
if (next_type == CONTROL_TYPE_ELSE) {
|
|
524
|
-
|
|
514
|
+
hb_array_T* else_children = hb_array_init(8);
|
|
525
515
|
|
|
526
516
|
index++;
|
|
527
517
|
|
|
528
|
-
while (index <
|
|
529
|
-
AST_NODE_T* child =
|
|
518
|
+
while (index < hb_array_size(array)) {
|
|
519
|
+
AST_NODE_T* child = hb_array_get(array, index);
|
|
530
520
|
|
|
531
521
|
if (!child) { break; }
|
|
532
522
|
|
|
@@ -537,62 +527,75 @@ static size_t process_control_structure(
|
|
|
537
527
|
if (child_type == CONTROL_TYPE_END) { break; }
|
|
538
528
|
}
|
|
539
529
|
|
|
540
|
-
|
|
530
|
+
hb_array_append(else_children, child);
|
|
541
531
|
index++;
|
|
542
532
|
}
|
|
543
533
|
|
|
534
|
+
hb_array_T* else_errors = next_erb->base.errors;
|
|
535
|
+
next_erb->base.errors = NULL;
|
|
536
|
+
|
|
544
537
|
else_clause = ast_erb_else_node_init(
|
|
545
538
|
next_erb->tag_opening,
|
|
546
539
|
next_erb->content,
|
|
547
540
|
next_erb->tag_closing,
|
|
548
541
|
else_children,
|
|
549
|
-
next_erb->tag_opening->location
|
|
550
|
-
next_erb->tag_closing->location
|
|
551
|
-
|
|
542
|
+
next_erb->tag_opening->location.start,
|
|
543
|
+
next_erb->tag_closing->location.end,
|
|
544
|
+
else_errors
|
|
552
545
|
);
|
|
546
|
+
|
|
547
|
+
ast_node_free((AST_NODE_T*) next_erb);
|
|
553
548
|
}
|
|
554
549
|
}
|
|
555
550
|
}
|
|
556
551
|
|
|
557
552
|
AST_ERB_END_NODE_T* end_node = NULL;
|
|
558
553
|
|
|
559
|
-
if (index <
|
|
560
|
-
AST_NODE_T* potential_end =
|
|
554
|
+
if (index < hb_array_size(array)) {
|
|
555
|
+
AST_NODE_T* potential_end = hb_array_get(array, index);
|
|
561
556
|
|
|
562
557
|
if (potential_end && potential_end->type == AST_ERB_CONTENT_NODE) {
|
|
563
558
|
AST_ERB_CONTENT_NODE_T* end_erb = (AST_ERB_CONTENT_NODE_T*) potential_end;
|
|
564
559
|
|
|
565
560
|
if (detect_control_type(end_erb) == CONTROL_TYPE_END) {
|
|
561
|
+
hb_array_T* end_errors = end_erb->base.errors;
|
|
562
|
+
end_erb->base.errors = NULL;
|
|
563
|
+
|
|
566
564
|
end_node = ast_erb_end_node_init(
|
|
567
565
|
end_erb->tag_opening,
|
|
568
566
|
end_erb->content,
|
|
569
567
|
end_erb->tag_closing,
|
|
570
|
-
end_erb->tag_opening->location
|
|
571
|
-
end_erb->tag_closing->location
|
|
572
|
-
|
|
568
|
+
end_erb->tag_opening->location.start,
|
|
569
|
+
end_erb->tag_closing->location.end,
|
|
570
|
+
end_errors
|
|
573
571
|
);
|
|
574
572
|
|
|
573
|
+
ast_node_free((AST_NODE_T*) end_erb);
|
|
574
|
+
|
|
575
575
|
index++;
|
|
576
576
|
}
|
|
577
577
|
}
|
|
578
578
|
}
|
|
579
579
|
|
|
580
|
-
position_T
|
|
581
|
-
position_T
|
|
580
|
+
position_T start_position = erb_node->tag_opening->location.start;
|
|
581
|
+
position_T end_position = erb_node->tag_closing->location.end;
|
|
582
582
|
|
|
583
583
|
if (end_node) {
|
|
584
|
-
end_position = end_node->base.location
|
|
584
|
+
end_position = end_node->base.location.end;
|
|
585
585
|
} else if (else_clause) {
|
|
586
|
-
end_position = else_clause->base.location
|
|
587
|
-
} else if (
|
|
588
|
-
AST_NODE_T* last_when =
|
|
589
|
-
end_position = last_when->location
|
|
590
|
-
} else if (
|
|
591
|
-
AST_NODE_T* last_in =
|
|
592
|
-
end_position = last_in->location
|
|
586
|
+
end_position = else_clause->base.location.end;
|
|
587
|
+
} else if (hb_array_size(when_conditions) > 0) {
|
|
588
|
+
AST_NODE_T* last_when = hb_array_get(when_conditions, hb_array_size(when_conditions) - 1);
|
|
589
|
+
end_position = last_when->location.end;
|
|
590
|
+
} else if (hb_array_size(in_conditions) > 0) {
|
|
591
|
+
AST_NODE_T* last_in = hb_array_get(in_conditions, hb_array_size(in_conditions) - 1);
|
|
592
|
+
end_position = last_in->location.end;
|
|
593
593
|
}
|
|
594
594
|
|
|
595
|
-
if (
|
|
595
|
+
if (hb_array_size(in_conditions) > 0) {
|
|
596
|
+
hb_array_T* case_match_errors = erb_node->base.errors;
|
|
597
|
+
erb_node->base.errors = NULL;
|
|
598
|
+
|
|
596
599
|
AST_ERB_CASE_MATCH_NODE_T* case_match_node = ast_erb_case_match_node_init(
|
|
597
600
|
erb_node->tag_opening,
|
|
598
601
|
erb_node->content,
|
|
@@ -603,13 +606,21 @@ static size_t process_control_structure(
|
|
|
603
606
|
end_node,
|
|
604
607
|
start_position,
|
|
605
608
|
end_position,
|
|
606
|
-
|
|
609
|
+
case_match_errors
|
|
607
610
|
);
|
|
608
611
|
|
|
609
|
-
|
|
612
|
+
ast_node_free((AST_NODE_T*) erb_node);
|
|
613
|
+
|
|
614
|
+
hb_array_append(output_array, (AST_NODE_T*) case_match_node);
|
|
615
|
+
hb_array_free(&when_conditions);
|
|
616
|
+
hb_array_free(&children);
|
|
617
|
+
|
|
610
618
|
return index;
|
|
611
619
|
}
|
|
612
620
|
|
|
621
|
+
hb_array_T* case_errors = erb_node->base.errors;
|
|
622
|
+
erb_node->base.errors = NULL;
|
|
623
|
+
|
|
613
624
|
AST_ERB_CASE_NODE_T* case_node = ast_erb_case_node_init(
|
|
614
625
|
erb_node->tag_opening,
|
|
615
626
|
erb_node->content,
|
|
@@ -620,10 +631,15 @@ static size_t process_control_structure(
|
|
|
620
631
|
end_node,
|
|
621
632
|
start_position,
|
|
622
633
|
end_position,
|
|
623
|
-
|
|
634
|
+
case_errors
|
|
624
635
|
);
|
|
625
636
|
|
|
626
|
-
|
|
637
|
+
ast_node_free((AST_NODE_T*) erb_node);
|
|
638
|
+
|
|
639
|
+
hb_array_append(output_array, (AST_NODE_T*) case_node);
|
|
640
|
+
hb_array_free(&in_conditions);
|
|
641
|
+
hb_array_free(&children);
|
|
642
|
+
|
|
627
643
|
return index;
|
|
628
644
|
}
|
|
629
645
|
|
|
@@ -634,8 +650,8 @@ static size_t process_control_structure(
|
|
|
634
650
|
AST_ERB_ELSE_NODE_T* else_clause = NULL;
|
|
635
651
|
AST_ERB_ENSURE_NODE_T* ensure_clause = NULL;
|
|
636
652
|
|
|
637
|
-
if (index <
|
|
638
|
-
AST_NODE_T* next_node =
|
|
653
|
+
if (index < hb_array_size(array)) {
|
|
654
|
+
AST_NODE_T* next_node = hb_array_get(array, index);
|
|
639
655
|
|
|
640
656
|
if (next_node && next_node->type == AST_ERB_CONTENT_NODE) {
|
|
641
657
|
AST_ERB_CONTENT_NODE_T* next_erb = (AST_ERB_CONTENT_NODE_T*) next_node;
|
|
@@ -649,20 +665,20 @@ static size_t process_control_structure(
|
|
|
649
665
|
}
|
|
650
666
|
}
|
|
651
667
|
|
|
652
|
-
if (index <
|
|
653
|
-
AST_NODE_T* next_node =
|
|
668
|
+
if (index < hb_array_size(array)) {
|
|
669
|
+
AST_NODE_T* next_node = hb_array_get(array, index);
|
|
654
670
|
|
|
655
671
|
if (next_node && next_node->type == AST_ERB_CONTENT_NODE) {
|
|
656
672
|
AST_ERB_CONTENT_NODE_T* next_erb = (AST_ERB_CONTENT_NODE_T*) next_node;
|
|
657
673
|
control_type_t next_type = detect_control_type(next_erb);
|
|
658
674
|
|
|
659
675
|
if (next_type == CONTROL_TYPE_ELSE) {
|
|
660
|
-
|
|
676
|
+
hb_array_T* else_children = hb_array_init(8);
|
|
661
677
|
|
|
662
678
|
index++;
|
|
663
679
|
|
|
664
|
-
while (index <
|
|
665
|
-
AST_NODE_T* child =
|
|
680
|
+
while (index < hb_array_size(array)) {
|
|
681
|
+
AST_NODE_T* child = hb_array_get(array, index);
|
|
666
682
|
|
|
667
683
|
if (!child) { break; }
|
|
668
684
|
|
|
@@ -673,37 +689,42 @@ static size_t process_control_structure(
|
|
|
673
689
|
if (child_type == CONTROL_TYPE_ENSURE || child_type == CONTROL_TYPE_END) { break; }
|
|
674
690
|
}
|
|
675
691
|
|
|
676
|
-
|
|
692
|
+
hb_array_append(else_children, child);
|
|
677
693
|
index++;
|
|
678
694
|
}
|
|
679
695
|
|
|
696
|
+
hb_array_T* else_errors = next_erb->base.errors;
|
|
697
|
+
next_erb->base.errors = NULL;
|
|
698
|
+
|
|
680
699
|
else_clause = ast_erb_else_node_init(
|
|
681
700
|
next_erb->tag_opening,
|
|
682
701
|
next_erb->content,
|
|
683
702
|
next_erb->tag_closing,
|
|
684
703
|
else_children,
|
|
685
|
-
next_erb->tag_opening->location
|
|
686
|
-
next_erb->tag_closing->location
|
|
687
|
-
|
|
704
|
+
next_erb->tag_opening->location.start,
|
|
705
|
+
next_erb->tag_closing->location.end,
|
|
706
|
+
else_errors
|
|
688
707
|
);
|
|
708
|
+
|
|
709
|
+
ast_node_free((AST_NODE_T*) next_erb);
|
|
689
710
|
}
|
|
690
711
|
}
|
|
691
712
|
}
|
|
692
713
|
|
|
693
|
-
if (index <
|
|
694
|
-
AST_NODE_T* next_node =
|
|
714
|
+
if (index < hb_array_size(array)) {
|
|
715
|
+
AST_NODE_T* next_node = hb_array_get(array, index);
|
|
695
716
|
|
|
696
717
|
if (next_node && next_node->type == AST_ERB_CONTENT_NODE) {
|
|
697
718
|
AST_ERB_CONTENT_NODE_T* next_erb = (AST_ERB_CONTENT_NODE_T*) next_node;
|
|
698
719
|
control_type_t next_type = detect_control_type(next_erb);
|
|
699
720
|
|
|
700
721
|
if (next_type == CONTROL_TYPE_ENSURE) {
|
|
701
|
-
|
|
722
|
+
hb_array_T* ensure_children = hb_array_init(8);
|
|
702
723
|
|
|
703
724
|
index++;
|
|
704
725
|
|
|
705
|
-
while (index <
|
|
706
|
-
AST_NODE_T* child =
|
|
726
|
+
while (index < hb_array_size(array)) {
|
|
727
|
+
AST_NODE_T* child = hb_array_get(array, index);
|
|
707
728
|
|
|
708
729
|
if (!child) { break; }
|
|
709
730
|
|
|
@@ -714,59 +735,72 @@ static size_t process_control_structure(
|
|
|
714
735
|
if (child_type == CONTROL_TYPE_END) { break; }
|
|
715
736
|
}
|
|
716
737
|
|
|
717
|
-
|
|
738
|
+
hb_array_append(ensure_children, child);
|
|
718
739
|
index++;
|
|
719
740
|
}
|
|
720
741
|
|
|
742
|
+
hb_array_T* ensure_errors = next_erb->base.errors;
|
|
743
|
+
next_erb->base.errors = NULL;
|
|
744
|
+
|
|
721
745
|
ensure_clause = ast_erb_ensure_node_init(
|
|
722
746
|
next_erb->tag_opening,
|
|
723
747
|
next_erb->content,
|
|
724
748
|
next_erb->tag_closing,
|
|
725
749
|
ensure_children,
|
|
726
|
-
next_erb->tag_opening->location
|
|
727
|
-
next_erb->tag_closing->location
|
|
728
|
-
|
|
750
|
+
next_erb->tag_opening->location.start,
|
|
751
|
+
next_erb->tag_closing->location.end,
|
|
752
|
+
ensure_errors
|
|
729
753
|
);
|
|
754
|
+
|
|
755
|
+
ast_node_free((AST_NODE_T*) next_erb);
|
|
730
756
|
}
|
|
731
757
|
}
|
|
732
758
|
}
|
|
733
759
|
|
|
734
760
|
AST_ERB_END_NODE_T* end_node = NULL;
|
|
735
761
|
|
|
736
|
-
if (index <
|
|
737
|
-
AST_NODE_T* potential_end =
|
|
762
|
+
if (index < hb_array_size(array)) {
|
|
763
|
+
AST_NODE_T* potential_end = hb_array_get(array, index);
|
|
738
764
|
|
|
739
765
|
if (potential_end && potential_end->type == AST_ERB_CONTENT_NODE) {
|
|
740
766
|
AST_ERB_CONTENT_NODE_T* end_erb = (AST_ERB_CONTENT_NODE_T*) potential_end;
|
|
741
767
|
|
|
742
768
|
if (detect_control_type(end_erb) == CONTROL_TYPE_END) {
|
|
769
|
+
hb_array_T* end_errors = end_erb->base.errors;
|
|
770
|
+
end_erb->base.errors = NULL;
|
|
771
|
+
|
|
743
772
|
end_node = ast_erb_end_node_init(
|
|
744
773
|
end_erb->tag_opening,
|
|
745
774
|
end_erb->content,
|
|
746
775
|
end_erb->tag_closing,
|
|
747
|
-
end_erb->tag_opening->location
|
|
748
|
-
end_erb->tag_closing->location
|
|
749
|
-
|
|
776
|
+
end_erb->tag_opening->location.start,
|
|
777
|
+
end_erb->tag_closing->location.end,
|
|
778
|
+
end_errors
|
|
750
779
|
);
|
|
751
780
|
|
|
781
|
+
ast_node_free((AST_NODE_T*) end_erb);
|
|
782
|
+
|
|
752
783
|
index++;
|
|
753
784
|
}
|
|
754
785
|
}
|
|
755
786
|
}
|
|
756
787
|
|
|
757
|
-
position_T
|
|
758
|
-
position_T
|
|
788
|
+
position_T start_position = erb_node->tag_opening->location.start;
|
|
789
|
+
position_T end_position = erb_node->tag_closing->location.end;
|
|
759
790
|
|
|
760
791
|
if (end_node) {
|
|
761
|
-
end_position = end_node->base.location
|
|
792
|
+
end_position = end_node->base.location.end;
|
|
762
793
|
} else if (ensure_clause) {
|
|
763
|
-
end_position = ensure_clause->base.location
|
|
794
|
+
end_position = ensure_clause->base.location.end;
|
|
764
795
|
} else if (else_clause) {
|
|
765
|
-
end_position = else_clause->base.location
|
|
796
|
+
end_position = else_clause->base.location.end;
|
|
766
797
|
} else if (rescue_clause) {
|
|
767
|
-
end_position = rescue_clause->base.location
|
|
798
|
+
end_position = rescue_clause->base.location.end;
|
|
768
799
|
}
|
|
769
800
|
|
|
801
|
+
hb_array_T* begin_errors = erb_node->base.errors;
|
|
802
|
+
erb_node->base.errors = NULL;
|
|
803
|
+
|
|
770
804
|
AST_ERB_BEGIN_NODE_T* begin_node = ast_erb_begin_node_init(
|
|
771
805
|
erb_node->tag_opening,
|
|
772
806
|
erb_node->content,
|
|
@@ -778,10 +812,12 @@ static size_t process_control_structure(
|
|
|
778
812
|
end_node,
|
|
779
813
|
start_position,
|
|
780
814
|
end_position,
|
|
781
|
-
|
|
815
|
+
begin_errors
|
|
782
816
|
);
|
|
783
817
|
|
|
784
|
-
|
|
818
|
+
ast_node_free((AST_NODE_T*) erb_node);
|
|
819
|
+
|
|
820
|
+
hb_array_append(output_array, (AST_NODE_T*) begin_node);
|
|
785
821
|
return index;
|
|
786
822
|
}
|
|
787
823
|
|
|
@@ -790,38 +826,46 @@ static size_t process_control_structure(
|
|
|
790
826
|
|
|
791
827
|
AST_ERB_END_NODE_T* end_node = NULL;
|
|
792
828
|
|
|
793
|
-
if (index <
|
|
794
|
-
AST_NODE_T* potential_close =
|
|
829
|
+
if (index < hb_array_size(array)) {
|
|
830
|
+
AST_NODE_T* potential_close = hb_array_get(array, index);
|
|
795
831
|
|
|
796
832
|
if (potential_close && potential_close->type == AST_ERB_CONTENT_NODE) {
|
|
797
833
|
AST_ERB_CONTENT_NODE_T* close_erb = (AST_ERB_CONTENT_NODE_T*) potential_close;
|
|
798
834
|
control_type_t close_type = detect_control_type(close_erb);
|
|
799
835
|
|
|
800
836
|
if (close_type == CONTROL_TYPE_BLOCK_CLOSE || close_type == CONTROL_TYPE_END) {
|
|
837
|
+
hb_array_T* end_errors = close_erb->base.errors;
|
|
838
|
+
close_erb->base.errors = NULL;
|
|
839
|
+
|
|
801
840
|
end_node = ast_erb_end_node_init(
|
|
802
841
|
close_erb->tag_opening,
|
|
803
842
|
close_erb->content,
|
|
804
843
|
close_erb->tag_closing,
|
|
805
|
-
close_erb->tag_opening->location
|
|
806
|
-
close_erb->tag_closing->location
|
|
807
|
-
|
|
844
|
+
close_erb->tag_opening->location.start,
|
|
845
|
+
close_erb->tag_closing->location.end,
|
|
846
|
+
end_errors
|
|
808
847
|
);
|
|
809
848
|
|
|
849
|
+
ast_node_free((AST_NODE_T*) close_erb);
|
|
850
|
+
|
|
810
851
|
index++;
|
|
811
852
|
}
|
|
812
853
|
}
|
|
813
854
|
}
|
|
814
855
|
|
|
815
|
-
position_T
|
|
816
|
-
position_T
|
|
856
|
+
position_T start_position = erb_node->tag_opening->location.start;
|
|
857
|
+
position_T end_position = erb_node->tag_closing->location.end;
|
|
817
858
|
|
|
818
859
|
if (end_node) {
|
|
819
|
-
end_position = end_node->base.location
|
|
820
|
-
} else if (children &&
|
|
821
|
-
AST_NODE_T* last_child =
|
|
822
|
-
end_position = last_child->location
|
|
860
|
+
end_position = end_node->base.location.end;
|
|
861
|
+
} else if (children && hb_array_size(children) > 0) {
|
|
862
|
+
AST_NODE_T* last_child = hb_array_get(children, hb_array_size(children) - 1);
|
|
863
|
+
end_position = last_child->location.end;
|
|
823
864
|
}
|
|
824
865
|
|
|
866
|
+
hb_array_T* block_errors = erb_node->base.errors;
|
|
867
|
+
erb_node->base.errors = NULL;
|
|
868
|
+
|
|
825
869
|
AST_ERB_BLOCK_NODE_T* block_node = ast_erb_block_node_init(
|
|
826
870
|
erb_node->tag_opening,
|
|
827
871
|
erb_node->content,
|
|
@@ -830,10 +874,12 @@ static size_t process_control_structure(
|
|
|
830
874
|
end_node,
|
|
831
875
|
start_position,
|
|
832
876
|
end_position,
|
|
833
|
-
|
|
877
|
+
block_errors
|
|
834
878
|
);
|
|
835
879
|
|
|
836
|
-
|
|
880
|
+
ast_node_free((AST_NODE_T*) erb_node);
|
|
881
|
+
|
|
882
|
+
hb_array_append(output_array, (AST_NODE_T*) block_node);
|
|
837
883
|
return index;
|
|
838
884
|
}
|
|
839
885
|
|
|
@@ -842,8 +888,8 @@ static size_t process_control_structure(
|
|
|
842
888
|
AST_NODE_T* subsequent = NULL;
|
|
843
889
|
AST_ERB_END_NODE_T* end_node = NULL;
|
|
844
890
|
|
|
845
|
-
if (index <
|
|
846
|
-
AST_NODE_T* next_node =
|
|
891
|
+
if (index < hb_array_size(array)) {
|
|
892
|
+
AST_NODE_T* next_node = hb_array_get(array, index);
|
|
847
893
|
|
|
848
894
|
if (next_node && next_node->type == AST_ERB_CONTENT_NODE) {
|
|
849
895
|
AST_ERB_CONTENT_NODE_T* next_erb = (AST_ERB_CONTENT_NODE_T*) next_node;
|
|
@@ -855,22 +901,27 @@ static size_t process_control_structure(
|
|
|
855
901
|
}
|
|
856
902
|
}
|
|
857
903
|
|
|
858
|
-
if (index <
|
|
859
|
-
AST_NODE_T* potential_end =
|
|
904
|
+
if (index < hb_array_size(array)) {
|
|
905
|
+
AST_NODE_T* potential_end = hb_array_get(array, index);
|
|
860
906
|
|
|
861
907
|
if (potential_end && potential_end->type == AST_ERB_CONTENT_NODE) {
|
|
862
908
|
AST_ERB_CONTENT_NODE_T* end_erb = (AST_ERB_CONTENT_NODE_T*) potential_end;
|
|
863
909
|
|
|
864
910
|
if (detect_control_type(end_erb) == CONTROL_TYPE_END) {
|
|
911
|
+
hb_array_T* end_errors = end_erb->base.errors;
|
|
912
|
+
end_erb->base.errors = NULL;
|
|
913
|
+
|
|
865
914
|
end_node = ast_erb_end_node_init(
|
|
866
915
|
end_erb->tag_opening,
|
|
867
916
|
end_erb->content,
|
|
868
917
|
end_erb->tag_closing,
|
|
869
|
-
end_erb->tag_opening->location
|
|
870
|
-
end_erb->tag_closing->location
|
|
871
|
-
|
|
918
|
+
end_erb->tag_opening->location.start,
|
|
919
|
+
end_erb->tag_closing->location.end,
|
|
920
|
+
end_errors
|
|
872
921
|
);
|
|
873
922
|
|
|
923
|
+
ast_node_free((AST_NODE_T*) end_erb);
|
|
924
|
+
|
|
874
925
|
index++;
|
|
875
926
|
}
|
|
876
927
|
}
|
|
@@ -878,22 +929,27 @@ static size_t process_control_structure(
|
|
|
878
929
|
|
|
879
930
|
AST_NODE_T* control_node = create_control_node(erb_node, children, subsequent, end_node, initial_type);
|
|
880
931
|
|
|
881
|
-
if (control_node) {
|
|
932
|
+
if (control_node) {
|
|
933
|
+
ast_node_free((AST_NODE_T*) erb_node);
|
|
934
|
+
hb_array_append(output_array, control_node);
|
|
935
|
+
} else {
|
|
936
|
+
hb_array_free(&children);
|
|
937
|
+
}
|
|
882
938
|
|
|
883
939
|
return index;
|
|
884
940
|
}
|
|
885
941
|
|
|
886
942
|
static size_t process_subsequent_block(
|
|
887
943
|
AST_NODE_T* node,
|
|
888
|
-
|
|
944
|
+
hb_array_T* array,
|
|
889
945
|
size_t index,
|
|
890
946
|
AST_NODE_T** subsequent_out,
|
|
891
947
|
analyze_ruby_context_T* context,
|
|
892
948
|
control_type_t parent_type
|
|
893
949
|
) {
|
|
894
|
-
AST_ERB_CONTENT_NODE_T* erb_node = (AST_ERB_CONTENT_NODE_T*)
|
|
950
|
+
AST_ERB_CONTENT_NODE_T* erb_node = (AST_ERB_CONTENT_NODE_T*) hb_array_get(array, index);
|
|
895
951
|
control_type_t type = detect_control_type(erb_node);
|
|
896
|
-
|
|
952
|
+
hb_array_T* children = hb_array_init(8);
|
|
897
953
|
|
|
898
954
|
index++;
|
|
899
955
|
|
|
@@ -901,8 +957,14 @@ static size_t process_subsequent_block(
|
|
|
901
957
|
|
|
902
958
|
AST_NODE_T* subsequent_node = create_control_node(erb_node, children, NULL, NULL, type);
|
|
903
959
|
|
|
904
|
-
if (
|
|
905
|
-
AST_NODE_T*
|
|
960
|
+
if (subsequent_node) {
|
|
961
|
+
ast_node_free((AST_NODE_T*) erb_node);
|
|
962
|
+
} else {
|
|
963
|
+
hb_array_free(&children);
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
if (index < hb_array_size(array)) {
|
|
967
|
+
AST_NODE_T* next_node = hb_array_get(array, index);
|
|
906
968
|
|
|
907
969
|
if (next_node && next_node->type == AST_ERB_CONTENT_NODE) {
|
|
908
970
|
AST_ERB_CONTENT_NODE_T* next_erb = (AST_ERB_CONTENT_NODE_T*) next_node;
|
|
@@ -953,19 +1015,19 @@ static size_t process_subsequent_block(
|
|
|
953
1015
|
|
|
954
1016
|
static size_t process_block_children(
|
|
955
1017
|
AST_NODE_T* node,
|
|
956
|
-
|
|
1018
|
+
hb_array_T* array,
|
|
957
1019
|
size_t index,
|
|
958
|
-
|
|
1020
|
+
hb_array_T* children_array,
|
|
959
1021
|
analyze_ruby_context_T* context,
|
|
960
1022
|
control_type_t parent_type
|
|
961
1023
|
) {
|
|
962
|
-
while (index <
|
|
963
|
-
AST_NODE_T* child =
|
|
1024
|
+
while (index < hb_array_size(array)) {
|
|
1025
|
+
AST_NODE_T* child = hb_array_get(array, index);
|
|
964
1026
|
|
|
965
1027
|
if (!child) { break; }
|
|
966
1028
|
|
|
967
1029
|
if (child->type != AST_ERB_CONTENT_NODE) {
|
|
968
|
-
|
|
1030
|
+
hb_array_append(children_array, child);
|
|
969
1031
|
index++;
|
|
970
1032
|
continue;
|
|
971
1033
|
}
|
|
@@ -978,35 +1040,35 @@ static size_t process_block_children(
|
|
|
978
1040
|
if (child_type == CONTROL_TYPE_IF || child_type == CONTROL_TYPE_CASE || child_type == CONTROL_TYPE_CASE_MATCH
|
|
979
1041
|
|| child_type == CONTROL_TYPE_BEGIN || child_type == CONTROL_TYPE_UNLESS || child_type == CONTROL_TYPE_WHILE
|
|
980
1042
|
|| child_type == CONTROL_TYPE_UNTIL || child_type == CONTROL_TYPE_FOR || child_type == CONTROL_TYPE_BLOCK) {
|
|
981
|
-
|
|
1043
|
+
hb_array_T* temp_array = hb_array_init(1);
|
|
982
1044
|
size_t new_index = process_control_structure(node, array, index, temp_array, context, child_type);
|
|
983
1045
|
|
|
984
|
-
if (
|
|
1046
|
+
if (hb_array_size(temp_array) > 0) { hb_array_append(children_array, hb_array_get(temp_array, 0)); }
|
|
985
1047
|
|
|
986
|
-
|
|
1048
|
+
hb_array_free(&temp_array);
|
|
987
1049
|
|
|
988
1050
|
index = new_index;
|
|
989
1051
|
continue;
|
|
990
1052
|
}
|
|
991
1053
|
|
|
992
|
-
|
|
1054
|
+
hb_array_append(children_array, child);
|
|
993
1055
|
index++;
|
|
994
1056
|
}
|
|
995
1057
|
|
|
996
1058
|
return index;
|
|
997
1059
|
}
|
|
998
1060
|
|
|
999
|
-
|
|
1000
|
-
|
|
1061
|
+
hb_array_T* rewrite_node_array(AST_NODE_T* node, hb_array_T* array, analyze_ruby_context_T* context) {
|
|
1062
|
+
hb_array_T* new_array = hb_array_init(hb_array_size(array));
|
|
1001
1063
|
size_t index = 0;
|
|
1002
1064
|
|
|
1003
|
-
while (index <
|
|
1004
|
-
AST_NODE_T* item =
|
|
1065
|
+
while (index < hb_array_size(array)) {
|
|
1066
|
+
AST_NODE_T* item = hb_array_get(array, index);
|
|
1005
1067
|
|
|
1006
1068
|
if (!item) { break; }
|
|
1007
1069
|
|
|
1008
1070
|
if (item->type != AST_ERB_CONTENT_NODE) {
|
|
1009
|
-
|
|
1071
|
+
hb_array_append(new_array, item);
|
|
1010
1072
|
index++;
|
|
1011
1073
|
continue;
|
|
1012
1074
|
}
|
|
@@ -1028,12 +1090,13 @@ static array_T* rewrite_node_array(AST_NODE_T* node, array_T* array, analyze_rub
|
|
|
1028
1090
|
continue;
|
|
1029
1091
|
|
|
1030
1092
|
case CONTROL_TYPE_YIELD: {
|
|
1031
|
-
AST_NODE_T* yield_node = create_control_node(erb_node,
|
|
1093
|
+
AST_NODE_T* yield_node = create_control_node(erb_node, NULL, NULL, NULL, type);
|
|
1032
1094
|
|
|
1033
1095
|
if (yield_node) {
|
|
1034
|
-
|
|
1096
|
+
ast_node_free((AST_NODE_T*) erb_node);
|
|
1097
|
+
hb_array_append(new_array, yield_node);
|
|
1035
1098
|
} else {
|
|
1036
|
-
|
|
1099
|
+
hb_array_append(new_array, item);
|
|
1037
1100
|
}
|
|
1038
1101
|
|
|
1039
1102
|
index++;
|
|
@@ -1041,7 +1104,7 @@ static array_T* rewrite_node_array(AST_NODE_T* node, array_T* array, analyze_rub
|
|
|
1041
1104
|
}
|
|
1042
1105
|
|
|
1043
1106
|
default:
|
|
1044
|
-
|
|
1107
|
+
hb_array_append(new_array, item);
|
|
1045
1108
|
index++;
|
|
1046
1109
|
break;
|
|
1047
1110
|
}
|
|
@@ -1050,41 +1113,178 @@ static array_T* rewrite_node_array(AST_NODE_T* node, array_T* array, analyze_rub
|
|
|
1050
1113
|
return new_array;
|
|
1051
1114
|
}
|
|
1052
1115
|
|
|
1053
|
-
static bool
|
|
1054
|
-
|
|
1055
|
-
|
|
1116
|
+
static bool detect_invalid_erb_structures(const AST_NODE_T* node, void* data) {
|
|
1117
|
+
invalid_erb_context_T* context = (invalid_erb_context_T*) data;
|
|
1118
|
+
|
|
1119
|
+
if (node->type == AST_HTML_ATTRIBUTE_NAME_NODE) { return false; }
|
|
1120
|
+
|
|
1121
|
+
bool is_loop_node =
|
|
1122
|
+
(node->type == AST_ERB_WHILE_NODE || node->type == AST_ERB_UNTIL_NODE || node->type == AST_ERB_FOR_NODE
|
|
1123
|
+
|| node->type == AST_ERB_BLOCK_NODE);
|
|
1124
|
+
|
|
1125
|
+
bool is_begin_node = (node->type == AST_ERB_BEGIN_NODE);
|
|
1126
|
+
|
|
1127
|
+
if (is_loop_node) { context->loop_depth++; }
|
|
1128
|
+
|
|
1129
|
+
if (is_begin_node) { context->rescue_depth++; }
|
|
1130
|
+
|
|
1131
|
+
if (node->type == AST_ERB_CONTENT_NODE) {
|
|
1132
|
+
const AST_ERB_CONTENT_NODE_T* content_node = (const AST_ERB_CONTENT_NODE_T*) node;
|
|
1133
|
+
|
|
1134
|
+
if (content_node->parsed && !content_node->valid && content_node->analyzed_ruby != NULL) {
|
|
1135
|
+
analyzed_ruby_T* analyzed = content_node->analyzed_ruby;
|
|
1136
|
+
|
|
1137
|
+
// =begin
|
|
1138
|
+
if (has_error_message(analyzed, "embedded document meets end of file")) {
|
|
1139
|
+
if (is_loop_node) { context->loop_depth--; }
|
|
1140
|
+
if (is_begin_node) { context->rescue_depth--; }
|
|
1141
|
+
|
|
1142
|
+
return true;
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
// =end
|
|
1146
|
+
if (has_error_message(analyzed, "unexpected '=', ignoring it")
|
|
1147
|
+
&& has_error_message(analyzed, "unexpected 'end', ignoring it")) {
|
|
1148
|
+
if (is_loop_node) { context->loop_depth--; }
|
|
1149
|
+
if (is_begin_node) { context->rescue_depth--; }
|
|
1150
|
+
|
|
1151
|
+
return true;
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
const char* keyword = NULL;
|
|
1155
|
+
|
|
1156
|
+
if (context->loop_depth == 0) {
|
|
1157
|
+
if (has_error_message(analyzed, "Invalid break")) {
|
|
1158
|
+
keyword = "`<% break %>`";
|
|
1159
|
+
} else if (has_error_message(analyzed, "Invalid next")) {
|
|
1160
|
+
keyword = "`<% next %>`";
|
|
1161
|
+
} else if (has_error_message(analyzed, "Invalid redo")) {
|
|
1162
|
+
keyword = "`<% redo %>`";
|
|
1163
|
+
}
|
|
1164
|
+
} else {
|
|
1165
|
+
if (has_error_message(analyzed, "Invalid redo") || has_error_message(analyzed, "Invalid break")
|
|
1166
|
+
|| has_error_message(analyzed, "Invalid next")) {
|
|
1167
|
+
|
|
1168
|
+
if (is_loop_node) { context->loop_depth--; }
|
|
1169
|
+
if (is_begin_node) { context->rescue_depth--; }
|
|
1170
|
+
|
|
1171
|
+
return true;
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
if (context->rescue_depth == 0) {
|
|
1176
|
+
if (has_error_message(analyzed, "Invalid retry without rescue")) { keyword = "`<% retry %>`"; }
|
|
1177
|
+
} else {
|
|
1178
|
+
if (has_error_message(analyzed, "Invalid retry without rescue")) {
|
|
1179
|
+
if (is_loop_node) { context->loop_depth--; }
|
|
1180
|
+
if (is_begin_node) { context->rescue_depth--; }
|
|
1181
|
+
|
|
1182
|
+
return true;
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
if (keyword == NULL) { keyword = erb_keyword_from_analyzed_ruby(analyzed); }
|
|
1187
|
+
|
|
1188
|
+
if (keyword != NULL && !token_value_empty(content_node->tag_closing)) {
|
|
1189
|
+
append_erb_control_flow_scope_error(keyword, node->location.start, node->location.end, node->errors);
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
if (node->type == AST_ERB_IF_NODE) {
|
|
1195
|
+
const AST_ERB_IF_NODE_T* if_node = (const AST_ERB_IF_NODE_T*) node;
|
|
1196
|
+
|
|
1197
|
+
if (if_node->end_node == NULL) { check_erb_node_for_missing_end(node); }
|
|
1056
1198
|
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1199
|
+
if (if_node->statements != NULL) {
|
|
1200
|
+
for (size_t i = 0; i < hb_array_size(if_node->statements); i++) {
|
|
1201
|
+
AST_NODE_T* statement = (AST_NODE_T*) hb_array_get(if_node->statements, i);
|
|
1202
|
+
|
|
1203
|
+
if (statement != NULL) { herb_visit_node(statement, detect_invalid_erb_structures, context); }
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
AST_NODE_T* subsequent = if_node->subsequent;
|
|
1208
|
+
|
|
1209
|
+
while (subsequent != NULL) {
|
|
1210
|
+
if (subsequent->type == AST_ERB_CONTENT_NODE) {
|
|
1211
|
+
const AST_ERB_CONTENT_NODE_T* content_node = (const AST_ERB_CONTENT_NODE_T*) subsequent;
|
|
1212
|
+
|
|
1213
|
+
if (content_node->parsed && !content_node->valid && content_node->analyzed_ruby != NULL) {
|
|
1214
|
+
analyzed_ruby_T* analyzed = content_node->analyzed_ruby;
|
|
1215
|
+
const char* keyword = erb_keyword_from_analyzed_ruby(analyzed);
|
|
1216
|
+
|
|
1217
|
+
if (!token_value_empty(content_node->tag_closing)) {
|
|
1218
|
+
append_erb_control_flow_scope_error(
|
|
1219
|
+
keyword,
|
|
1220
|
+
subsequent->location.start,
|
|
1221
|
+
subsequent->location.end,
|
|
1222
|
+
subsequent->errors
|
|
1223
|
+
);
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
if (subsequent->type == AST_ERB_IF_NODE) {
|
|
1229
|
+
const AST_ERB_IF_NODE_T* elsif_node = (const AST_ERB_IF_NODE_T*) subsequent;
|
|
1230
|
+
|
|
1231
|
+
if (elsif_node->statements != NULL) {
|
|
1232
|
+
for (size_t i = 0; i < hb_array_size(elsif_node->statements); i++) {
|
|
1233
|
+
AST_NODE_T* statement = (AST_NODE_T*) hb_array_get(elsif_node->statements, i);
|
|
1234
|
+
|
|
1235
|
+
if (statement != NULL) { herb_visit_node(statement, detect_invalid_erb_structures, context); }
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
subsequent = elsif_node->subsequent;
|
|
1240
|
+
} else if (subsequent->type == AST_ERB_ELSE_NODE) {
|
|
1241
|
+
const AST_ERB_ELSE_NODE_T* else_node = (const AST_ERB_ELSE_NODE_T*) subsequent;
|
|
1242
|
+
|
|
1243
|
+
if (else_node->statements != NULL) {
|
|
1244
|
+
for (size_t i = 0; i < hb_array_size(else_node->statements); i++) {
|
|
1245
|
+
AST_NODE_T* statement = (AST_NODE_T*) hb_array_get(else_node->statements, i);
|
|
1246
|
+
|
|
1247
|
+
if (statement != NULL) { herb_visit_node(statement, detect_invalid_erb_structures, context); }
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
break;
|
|
1252
|
+
} else {
|
|
1253
|
+
break;
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1062
1256
|
}
|
|
1063
1257
|
|
|
1064
|
-
if (node->type ==
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
array_free(&old_array);
|
|
1258
|
+
if (node->type == AST_ERB_UNLESS_NODE || node->type == AST_ERB_WHILE_NODE || node->type == AST_ERB_UNTIL_NODE
|
|
1259
|
+
|| node->type == AST_ERB_FOR_NODE || node->type == AST_ERB_CASE_NODE || node->type == AST_ERB_CASE_MATCH_NODE
|
|
1260
|
+
|| node->type == AST_ERB_BEGIN_NODE || node->type == AST_ERB_BLOCK_NODE || node->type == AST_ERB_ELSE_NODE) {
|
|
1261
|
+
herb_visit_child_nodes(node, detect_invalid_erb_structures, context);
|
|
1069
1262
|
}
|
|
1070
1263
|
|
|
1071
|
-
if (node->type ==
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1264
|
+
if (node->type == AST_ERB_UNLESS_NODE || node->type == AST_ERB_WHILE_NODE || node->type == AST_ERB_UNTIL_NODE
|
|
1265
|
+
|| node->type == AST_ERB_FOR_NODE || node->type == AST_ERB_CASE_NODE || node->type == AST_ERB_CASE_MATCH_NODE
|
|
1266
|
+
|| node->type == AST_ERB_BEGIN_NODE || node->type == AST_ERB_BLOCK_NODE || node->type == AST_ERB_ELSE_NODE) {
|
|
1267
|
+
check_erb_node_for_missing_end(node);
|
|
1268
|
+
|
|
1269
|
+
if (is_loop_node) { context->loop_depth--; }
|
|
1270
|
+
if (is_begin_node) { context->rescue_depth--; }
|
|
1271
|
+
|
|
1272
|
+
return false;
|
|
1076
1273
|
}
|
|
1077
1274
|
|
|
1078
|
-
if (node->type ==
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1275
|
+
if (node->type == AST_ERB_IF_NODE) {
|
|
1276
|
+
if (is_loop_node) { context->loop_depth--; }
|
|
1277
|
+
if (is_begin_node) { context->rescue_depth--; }
|
|
1278
|
+
|
|
1279
|
+
return false;
|
|
1083
1280
|
}
|
|
1084
1281
|
|
|
1085
|
-
|
|
1282
|
+
bool result = true;
|
|
1086
1283
|
|
|
1087
|
-
|
|
1284
|
+
if (is_loop_node) { context->loop_depth--; }
|
|
1285
|
+
if (is_begin_node) { context->rescue_depth--; }
|
|
1286
|
+
|
|
1287
|
+
return result;
|
|
1088
1288
|
}
|
|
1089
1289
|
|
|
1090
1290
|
void herb_analyze_parse_tree(AST_DOCUMENT_NODE_T* document, const char* source) {
|
|
@@ -1093,19 +1293,31 @@ void herb_analyze_parse_tree(AST_DOCUMENT_NODE_T* document, const char* source)
|
|
|
1093
1293
|
analyze_ruby_context_T* context = malloc(sizeof(analyze_ruby_context_T));
|
|
1094
1294
|
context->document = document;
|
|
1095
1295
|
context->parent = NULL;
|
|
1096
|
-
context->ruby_context_stack =
|
|
1296
|
+
context->ruby_context_stack = hb_array_init(8);
|
|
1097
1297
|
|
|
1098
1298
|
herb_visit_node((AST_NODE_T*) document, transform_erb_nodes, context);
|
|
1099
1299
|
|
|
1300
|
+
invalid_erb_context_T* invalid_context = malloc(sizeof(invalid_erb_context_T));
|
|
1301
|
+
invalid_context->loop_depth = 0;
|
|
1302
|
+
invalid_context->rescue_depth = 0;
|
|
1303
|
+
|
|
1304
|
+
herb_visit_node((AST_NODE_T*) document, detect_invalid_erb_structures, invalid_context);
|
|
1305
|
+
|
|
1100
1306
|
herb_analyze_parse_errors(document, source);
|
|
1101
1307
|
|
|
1102
|
-
|
|
1308
|
+
herb_parser_match_html_tags_post_analyze(document);
|
|
1309
|
+
|
|
1310
|
+
hb_array_free(&context->ruby_context_stack);
|
|
1311
|
+
|
|
1103
1312
|
free(context);
|
|
1313
|
+
free(invalid_context);
|
|
1104
1314
|
}
|
|
1105
1315
|
|
|
1106
1316
|
void herb_analyze_parse_errors(AST_DOCUMENT_NODE_T* document, const char* source) {
|
|
1107
1317
|
char* extracted_ruby = herb_extract_ruby_with_semicolons(source);
|
|
1108
1318
|
|
|
1319
|
+
if (!extracted_ruby) { return; }
|
|
1320
|
+
|
|
1109
1321
|
pm_parser_t parser;
|
|
1110
1322
|
pm_options_t options = { 0, .partial_script = true };
|
|
1111
1323
|
pm_parser_init(&parser, (const uint8_t*) extracted_ruby, strlen(extracted_ruby), &options);
|
|
@@ -1116,7 +1328,7 @@ void herb_analyze_parse_errors(AST_DOCUMENT_NODE_T* document, const char* source
|
|
|
1116
1328
|
error = (const pm_diagnostic_t*) error->node.next) {
|
|
1117
1329
|
|
|
1118
1330
|
RUBY_PARSE_ERROR_T* parse_error = ruby_parse_error_from_prism_error(error, (AST_NODE_T*) document, source, &parser);
|
|
1119
|
-
|
|
1331
|
+
hb_array_append(document->base.errors, parse_error);
|
|
1120
1332
|
}
|
|
1121
1333
|
|
|
1122
1334
|
pm_node_destroy(&parser, root);
|