@herb-tools/node 0.8.7 → 0.8.9
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.
- package/dist/herb-node.esm.js +1 -1
- package/extension/error_helpers.cpp +1 -1
- package/extension/error_helpers.h +1 -1
- package/extension/libherb/analyze.c +112 -15
- package/extension/libherb/analyze_helpers.c +80 -12
- package/extension/libherb/analyze_helpers.h +7 -0
- package/extension/libherb/analyze_missing_end.c +1 -1
- package/extension/libherb/analyze_transform.c +1 -1
- package/extension/libherb/analyzed_ruby.c +1 -0
- package/extension/libherb/analyzed_ruby.h +1 -0
- package/extension/libherb/ast_nodes.c +13 -5
- package/extension/libherb/ast_nodes.h +9 -5
- package/extension/libherb/ast_pretty_print.c +53 -1
- package/extension/libherb/ast_pretty_print.h +1 -1
- package/extension/libherb/errors.c +1 -1
- package/extension/libherb/errors.h +1 -1
- package/extension/libherb/include/analyze_helpers.h +7 -0
- package/extension/libherb/include/analyzed_ruby.h +1 -0
- package/extension/libherb/include/ast_nodes.h +9 -5
- package/extension/libherb/include/ast_pretty_print.h +1 -1
- package/extension/libherb/include/errors.h +1 -1
- package/extension/libherb/include/location.h +4 -0
- package/extension/libherb/include/prism_helpers.h +6 -0
- package/extension/libherb/include/version.h +1 -1
- package/extension/libherb/location.c +16 -0
- package/extension/libherb/location.h +4 -0
- package/extension/libherb/parser_match_tags.c +1 -1
- package/extension/libherb/prism_helpers.c +188 -0
- package/extension/libherb/prism_helpers.h +6 -0
- package/extension/libherb/version.h +1 -1
- package/extension/libherb/visitor.c +1 -1
- package/extension/nodes.cpp +33 -1
- package/extension/nodes.h +1 -1
- package/extension/prism/include/prism/version.h +2 -2
- package/extension/prism/src/prism.c +48 -27
- package/package.json +2 -2
|
@@ -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-0.8.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.9/templates/src/ast_pretty_print.c.erb
|
|
3
3
|
|
|
4
4
|
#include "include/analyze_helpers.h"
|
|
5
5
|
#include "include/ast_node.h"
|
|
@@ -265,6 +265,19 @@ void ast_pretty_print_node(AST_NODE_T* node, const size_t indent, const size_t r
|
|
|
265
265
|
pretty_print_token_property(erb_if_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
|
|
266
266
|
pretty_print_token_property(erb_if_node->content, hb_string("content"), indent, relative_indent, false, buffer);
|
|
267
267
|
pretty_print_token_property(erb_if_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
|
|
268
|
+
pretty_print_label(hb_string("then_keyword"), indent, relative_indent, false, buffer);
|
|
269
|
+
if (erb_if_node->then_keyword) {
|
|
270
|
+
char then_keyword_location_string[128];
|
|
271
|
+
sprintf(then_keyword_location_string, " (location: (%u:%u)-(%u:%u))\n",
|
|
272
|
+
erb_if_node->then_keyword->start.line,
|
|
273
|
+
erb_if_node->then_keyword->start.column,
|
|
274
|
+
erb_if_node->then_keyword->end.line,
|
|
275
|
+
erb_if_node->then_keyword->end.column);
|
|
276
|
+
hb_buffer_append(buffer, then_keyword_location_string);
|
|
277
|
+
} else {
|
|
278
|
+
hb_buffer_append(buffer, " ∅\n");
|
|
279
|
+
}
|
|
280
|
+
|
|
268
281
|
pretty_print_array(hb_string("statements"), erb_if_node->statements, indent, relative_indent, false, buffer);
|
|
269
282
|
|
|
270
283
|
pretty_print_label(hb_string("subsequent"), indent, relative_indent, false, buffer);
|
|
@@ -330,6 +343,19 @@ void ast_pretty_print_node(AST_NODE_T* node, const size_t indent, const size_t r
|
|
|
330
343
|
pretty_print_token_property(erb_when_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
|
|
331
344
|
pretty_print_token_property(erb_when_node->content, hb_string("content"), indent, relative_indent, false, buffer);
|
|
332
345
|
pretty_print_token_property(erb_when_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
|
|
346
|
+
pretty_print_label(hb_string("then_keyword"), indent, relative_indent, false, buffer);
|
|
347
|
+
if (erb_when_node->then_keyword) {
|
|
348
|
+
char then_keyword_location_string[128];
|
|
349
|
+
sprintf(then_keyword_location_string, " (location: (%u:%u)-(%u:%u))\n",
|
|
350
|
+
erb_when_node->then_keyword->start.line,
|
|
351
|
+
erb_when_node->then_keyword->start.column,
|
|
352
|
+
erb_when_node->then_keyword->end.line,
|
|
353
|
+
erb_when_node->then_keyword->end.column);
|
|
354
|
+
hb_buffer_append(buffer, then_keyword_location_string);
|
|
355
|
+
} else {
|
|
356
|
+
hb_buffer_append(buffer, " ∅\n");
|
|
357
|
+
}
|
|
358
|
+
|
|
333
359
|
pretty_print_array(hb_string("statements"), erb_when_node->statements, indent, relative_indent, true, buffer);
|
|
334
360
|
} break;
|
|
335
361
|
|
|
@@ -602,6 +628,19 @@ void ast_pretty_print_node(AST_NODE_T* node, const size_t indent, const size_t r
|
|
|
602
628
|
pretty_print_token_property(erb_unless_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
|
|
603
629
|
pretty_print_token_property(erb_unless_node->content, hb_string("content"), indent, relative_indent, false, buffer);
|
|
604
630
|
pretty_print_token_property(erb_unless_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
|
|
631
|
+
pretty_print_label(hb_string("then_keyword"), indent, relative_indent, false, buffer);
|
|
632
|
+
if (erb_unless_node->then_keyword) {
|
|
633
|
+
char then_keyword_location_string[128];
|
|
634
|
+
sprintf(then_keyword_location_string, " (location: (%u:%u)-(%u:%u))\n",
|
|
635
|
+
erb_unless_node->then_keyword->start.line,
|
|
636
|
+
erb_unless_node->then_keyword->start.column,
|
|
637
|
+
erb_unless_node->then_keyword->end.line,
|
|
638
|
+
erb_unless_node->then_keyword->end.column);
|
|
639
|
+
hb_buffer_append(buffer, then_keyword_location_string);
|
|
640
|
+
} else {
|
|
641
|
+
hb_buffer_append(buffer, " ∅\n");
|
|
642
|
+
}
|
|
643
|
+
|
|
605
644
|
pretty_print_array(hb_string("statements"), erb_unless_node->statements, indent, relative_indent, false, buffer);
|
|
606
645
|
|
|
607
646
|
pretty_print_label(hb_string("else_clause"), indent, relative_indent, false, buffer);
|
|
@@ -651,6 +690,19 @@ void ast_pretty_print_node(AST_NODE_T* node, const size_t indent, const size_t r
|
|
|
651
690
|
pretty_print_token_property(erb_in_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
|
|
652
691
|
pretty_print_token_property(erb_in_node->content, hb_string("content"), indent, relative_indent, false, buffer);
|
|
653
692
|
pretty_print_token_property(erb_in_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
|
|
693
|
+
pretty_print_label(hb_string("then_keyword"), indent, relative_indent, false, buffer);
|
|
694
|
+
if (erb_in_node->then_keyword) {
|
|
695
|
+
char then_keyword_location_string[128];
|
|
696
|
+
sprintf(then_keyword_location_string, " (location: (%u:%u)-(%u:%u))\n",
|
|
697
|
+
erb_in_node->then_keyword->start.line,
|
|
698
|
+
erb_in_node->then_keyword->start.column,
|
|
699
|
+
erb_in_node->then_keyword->end.line,
|
|
700
|
+
erb_in_node->then_keyword->end.column);
|
|
701
|
+
hb_buffer_append(buffer, then_keyword_location_string);
|
|
702
|
+
} else {
|
|
703
|
+
hb_buffer_append(buffer, " ∅\n");
|
|
704
|
+
}
|
|
705
|
+
|
|
654
706
|
pretty_print_array(hb_string("statements"), erb_in_node->statements, indent, relative_indent, true, buffer);
|
|
655
707
|
} break;
|
|
656
708
|
|
|
@@ -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-0.8.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.9/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
|
|
@@ -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-0.8.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.9/templates/src/errors.c.erb
|
|
3
3
|
|
|
4
4
|
#include "include/errors.h"
|
|
5
5
|
#include "include/location.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-0.8.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.9/templates/src/include/errors.h.erb
|
|
3
3
|
|
|
4
4
|
#ifndef HERB_ERRORS_H
|
|
5
5
|
#define HERB_ERRORS_H
|
|
@@ -25,9 +25,15 @@ bool has_rescue_node(analyzed_ruby_T* analyzed);
|
|
|
25
25
|
bool has_ensure_node(analyzed_ruby_T* analyzed);
|
|
26
26
|
bool has_unless_node(analyzed_ruby_T* analyzed);
|
|
27
27
|
bool has_yield_node(analyzed_ruby_T* analyzed);
|
|
28
|
+
bool has_then_keyword(analyzed_ruby_T* analyzed);
|
|
28
29
|
|
|
29
30
|
bool has_error_message(analyzed_ruby_T* anlayzed, const char* message);
|
|
30
31
|
|
|
32
|
+
bool is_do_block(pm_location_t opening_location);
|
|
33
|
+
bool is_brace_block(pm_location_t opening_location);
|
|
34
|
+
bool is_closing_brace(pm_location_t location);
|
|
35
|
+
bool has_valid_block_closing(pm_location_t opening_loc, pm_location_t closing_loc);
|
|
36
|
+
|
|
31
37
|
bool search_if_nodes(const pm_node_t* node, void* data);
|
|
32
38
|
bool search_block_nodes(const pm_node_t* node, void* data);
|
|
33
39
|
bool search_case_nodes(const pm_node_t* node, void* data);
|
|
@@ -46,6 +52,7 @@ bool search_in_nodes(analyzed_ruby_T* analyzed);
|
|
|
46
52
|
bool search_rescue_nodes(analyzed_ruby_T* analyzed);
|
|
47
53
|
bool search_ensure_nodes(analyzed_ruby_T* analyzed);
|
|
48
54
|
bool search_yield_nodes(const pm_node_t* node, void* data);
|
|
55
|
+
bool search_then_keywords(const pm_node_t* node, void* data);
|
|
49
56
|
bool search_unclosed_control_flows(const pm_node_t* node, void* data);
|
|
50
57
|
|
|
51
58
|
void check_erb_node_for_missing_end(const AST_NODE_T* node);
|
|
@@ -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-0.8.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.9/templates/src/include/ast_nodes.h.erb
|
|
3
3
|
|
|
4
4
|
#ifndef HERB_AST_NODES_H
|
|
5
5
|
#define HERB_AST_NODES_H
|
|
@@ -183,6 +183,7 @@ typedef struct AST_ERB_IF_NODE_STRUCT {
|
|
|
183
183
|
token_T* tag_opening;
|
|
184
184
|
token_T* content;
|
|
185
185
|
token_T* tag_closing;
|
|
186
|
+
location_T* then_keyword;
|
|
186
187
|
hb_array_T* statements;
|
|
187
188
|
struct AST_NODE_STRUCT* subsequent;
|
|
188
189
|
struct AST_ERB_END_NODE_STRUCT* end_node;
|
|
@@ -202,6 +203,7 @@ typedef struct AST_ERB_WHEN_NODE_STRUCT {
|
|
|
202
203
|
token_T* tag_opening;
|
|
203
204
|
token_T* content;
|
|
204
205
|
token_T* tag_closing;
|
|
206
|
+
location_T* then_keyword;
|
|
205
207
|
hb_array_T* statements;
|
|
206
208
|
} AST_ERB_WHEN_NODE_T;
|
|
207
209
|
|
|
@@ -288,6 +290,7 @@ typedef struct AST_ERB_UNLESS_NODE_STRUCT {
|
|
|
288
290
|
token_T* tag_opening;
|
|
289
291
|
token_T* content;
|
|
290
292
|
token_T* tag_closing;
|
|
293
|
+
location_T* then_keyword;
|
|
291
294
|
hb_array_T* statements;
|
|
292
295
|
struct AST_ERB_ELSE_NODE_STRUCT* else_clause;
|
|
293
296
|
struct AST_ERB_END_NODE_STRUCT* end_node;
|
|
@@ -305,6 +308,7 @@ typedef struct AST_ERB_IN_NODE_STRUCT {
|
|
|
305
308
|
token_T* tag_opening;
|
|
306
309
|
token_T* content;
|
|
307
310
|
token_T* tag_closing;
|
|
311
|
+
location_T* then_keyword;
|
|
308
312
|
hb_array_T* statements;
|
|
309
313
|
} AST_ERB_IN_NODE_T;
|
|
310
314
|
|
|
@@ -325,9 +329,9 @@ AST_WHITESPACE_NODE_T* ast_whitespace_node_init(token_T* value, position_T start
|
|
|
325
329
|
AST_ERB_CONTENT_NODE_T* ast_erb_content_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, analyzed_ruby_T* analyzed_ruby, bool parsed, bool valid, position_T start_position, position_T end_position, hb_array_T* errors);
|
|
326
330
|
AST_ERB_END_NODE_T* ast_erb_end_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, position_T start_position, position_T end_position, hb_array_T* errors);
|
|
327
331
|
AST_ERB_ELSE_NODE_T* ast_erb_else_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, hb_array_T* statements, position_T start_position, position_T end_position, hb_array_T* errors);
|
|
328
|
-
AST_ERB_IF_NODE_T* ast_erb_if_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, hb_array_T* statements, struct AST_NODE_STRUCT* subsequent, struct AST_ERB_END_NODE_STRUCT* end_node, position_T start_position, position_T end_position, hb_array_T* errors);
|
|
332
|
+
AST_ERB_IF_NODE_T* ast_erb_if_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, location_T* then_keyword, hb_array_T* statements, struct AST_NODE_STRUCT* subsequent, struct AST_ERB_END_NODE_STRUCT* end_node, position_T start_position, position_T end_position, hb_array_T* errors);
|
|
329
333
|
AST_ERB_BLOCK_NODE_T* ast_erb_block_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, hb_array_T* body, struct AST_ERB_END_NODE_STRUCT* end_node, position_T start_position, position_T end_position, hb_array_T* errors);
|
|
330
|
-
AST_ERB_WHEN_NODE_T* ast_erb_when_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, hb_array_T* statements, position_T start_position, position_T end_position, hb_array_T* errors);
|
|
334
|
+
AST_ERB_WHEN_NODE_T* ast_erb_when_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, location_T* then_keyword, hb_array_T* statements, position_T start_position, position_T end_position, hb_array_T* errors);
|
|
331
335
|
AST_ERB_CASE_NODE_T* ast_erb_case_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, hb_array_T* children, hb_array_T* conditions, struct AST_ERB_ELSE_NODE_STRUCT* else_clause, struct AST_ERB_END_NODE_STRUCT* end_node, position_T start_position, position_T end_position, hb_array_T* errors);
|
|
332
336
|
AST_ERB_CASE_MATCH_NODE_T* ast_erb_case_match_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, hb_array_T* children, hb_array_T* conditions, struct AST_ERB_ELSE_NODE_STRUCT* else_clause, struct AST_ERB_END_NODE_STRUCT* end_node, position_T start_position, position_T end_position, hb_array_T* errors);
|
|
333
337
|
AST_ERB_WHILE_NODE_T* ast_erb_while_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, hb_array_T* statements, struct AST_ERB_END_NODE_STRUCT* end_node, position_T start_position, position_T end_position, hb_array_T* errors);
|
|
@@ -336,9 +340,9 @@ AST_ERB_FOR_NODE_T* ast_erb_for_node_init(token_T* tag_opening, token_T* content
|
|
|
336
340
|
AST_ERB_RESCUE_NODE_T* ast_erb_rescue_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, hb_array_T* statements, struct AST_ERB_RESCUE_NODE_STRUCT* subsequent, position_T start_position, position_T end_position, hb_array_T* errors);
|
|
337
341
|
AST_ERB_ENSURE_NODE_T* ast_erb_ensure_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, hb_array_T* statements, position_T start_position, position_T end_position, hb_array_T* errors);
|
|
338
342
|
AST_ERB_BEGIN_NODE_T* ast_erb_begin_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, hb_array_T* statements, struct AST_ERB_RESCUE_NODE_STRUCT* rescue_clause, struct AST_ERB_ELSE_NODE_STRUCT* else_clause, struct AST_ERB_ENSURE_NODE_STRUCT* ensure_clause, struct AST_ERB_END_NODE_STRUCT* end_node, position_T start_position, position_T end_position, hb_array_T* errors);
|
|
339
|
-
AST_ERB_UNLESS_NODE_T* ast_erb_unless_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, hb_array_T* statements, struct AST_ERB_ELSE_NODE_STRUCT* else_clause, struct AST_ERB_END_NODE_STRUCT* end_node, position_T start_position, position_T end_position, hb_array_T* errors);
|
|
343
|
+
AST_ERB_UNLESS_NODE_T* ast_erb_unless_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, location_T* then_keyword, hb_array_T* statements, struct AST_ERB_ELSE_NODE_STRUCT* else_clause, struct AST_ERB_END_NODE_STRUCT* end_node, position_T start_position, position_T end_position, hb_array_T* errors);
|
|
340
344
|
AST_ERB_YIELD_NODE_T* ast_erb_yield_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, position_T start_position, position_T end_position, hb_array_T* errors);
|
|
341
|
-
AST_ERB_IN_NODE_T* ast_erb_in_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, hb_array_T* statements, position_T start_position, position_T end_position, hb_array_T* errors);
|
|
345
|
+
AST_ERB_IN_NODE_T* ast_erb_in_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, location_T* then_keyword, hb_array_T* statements, position_T start_position, position_T end_position, hb_array_T* errors);
|
|
342
346
|
|
|
343
347
|
hb_string_T ast_node_type_to_string(AST_NODE_T* node);
|
|
344
348
|
hb_string_T ast_node_human_type(AST_NODE_T* node);
|
|
@@ -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-0.8.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.9/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
|
|
@@ -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-0.8.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.9/templates/src/include/errors.h.erb
|
|
3
3
|
|
|
4
4
|
#ifndef HERB_ERRORS_H
|
|
5
5
|
#define HERB_ERRORS_H
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
#ifndef HERB_PRISM_HELPERS_H
|
|
2
2
|
#define HERB_PRISM_HELPERS_H
|
|
3
3
|
|
|
4
|
+
#include "analyzed_ruby.h"
|
|
4
5
|
#include "ast_nodes.h"
|
|
5
6
|
#include "errors.h"
|
|
7
|
+
#include "location.h"
|
|
6
8
|
#include "position.h"
|
|
7
9
|
|
|
8
10
|
#include <prism.h>
|
|
@@ -22,4 +24,8 @@ RUBY_PARSE_ERROR_T* ruby_parse_error_from_prism_error_with_positions(
|
|
|
22
24
|
position_T end
|
|
23
25
|
);
|
|
24
26
|
|
|
27
|
+
location_T* get_then_keyword_location(analyzed_ruby_T* analyzed, const char* source);
|
|
28
|
+
location_T* get_then_keyword_location_wrapped(const char* source, bool is_in_clause);
|
|
29
|
+
location_T* get_then_keyword_location_elsif_wrapped(const char* source);
|
|
30
|
+
|
|
25
31
|
#endif
|
|
@@ -11,3 +11,19 @@ void location_from(
|
|
|
11
11
|
location->start = (position_T) { .line = start_line, .column = start_column };
|
|
12
12
|
location->end = (position_T) { .line = end_line, .column = end_column };
|
|
13
13
|
}
|
|
14
|
+
|
|
15
|
+
void location_from_positions(location_T* location, position_T start, position_T end) {
|
|
16
|
+
location->start = start;
|
|
17
|
+
location->end = end;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
location_T* location_create(position_T start, position_T end) {
|
|
21
|
+
location_T* location = malloc(sizeof(location_T));
|
|
22
|
+
|
|
23
|
+
if (location != NULL) {
|
|
24
|
+
location->start = start;
|
|
25
|
+
location->end = end;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return location;
|
|
29
|
+
}
|
|
@@ -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-0.8.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.9/templates/src/parser_match_tags.c.erb
|
|
3
3
|
|
|
4
4
|
#include "include/parser.h"
|
|
5
5
|
#include "include/ast_nodes.h"
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
#include "include/prism_helpers.h"
|
|
2
2
|
#include "include/ast_nodes.h"
|
|
3
3
|
#include "include/errors.h"
|
|
4
|
+
#include "include/location.h"
|
|
4
5
|
#include "include/position.h"
|
|
5
6
|
#include "include/util.h"
|
|
7
|
+
#include "include/util/hb_buffer.h"
|
|
6
8
|
|
|
7
9
|
#include <prism.h>
|
|
10
|
+
#include <stdlib.h>
|
|
11
|
+
#include <string.h>
|
|
8
12
|
|
|
9
13
|
const char* pm_error_level_to_string(pm_error_level_t level) {
|
|
10
14
|
switch (level) {
|
|
@@ -50,3 +54,187 @@ RUBY_PARSE_ERROR_T* ruby_parse_error_from_prism_error_with_positions(
|
|
|
50
54
|
end
|
|
51
55
|
);
|
|
52
56
|
}
|
|
57
|
+
|
|
58
|
+
typedef struct {
|
|
59
|
+
pm_location_t then_keyword_loc;
|
|
60
|
+
bool found;
|
|
61
|
+
} then_keyword_search_context_T;
|
|
62
|
+
|
|
63
|
+
static bool has_pm_location(pm_location_t location) {
|
|
64
|
+
return location.start != NULL && location.end != NULL && (location.end - location.start) > 0;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static bool search_then_keyword_location(const pm_node_t* node, void* data) {
|
|
68
|
+
then_keyword_search_context_T* context = (then_keyword_search_context_T*) data;
|
|
69
|
+
|
|
70
|
+
if (context->found) { return false; }
|
|
71
|
+
|
|
72
|
+
switch (node->type) {
|
|
73
|
+
case PM_IF_NODE: {
|
|
74
|
+
const pm_if_node_t* if_node = (const pm_if_node_t*) node;
|
|
75
|
+
if (has_pm_location(if_node->then_keyword_loc)) {
|
|
76
|
+
context->then_keyword_loc = if_node->then_keyword_loc;
|
|
77
|
+
context->found = true;
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
case PM_UNLESS_NODE: {
|
|
84
|
+
const pm_unless_node_t* unless_node = (const pm_unless_node_t*) node;
|
|
85
|
+
if (has_pm_location(unless_node->then_keyword_loc)) {
|
|
86
|
+
context->then_keyword_loc = unless_node->then_keyword_loc;
|
|
87
|
+
context->found = true;
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
case PM_WHEN_NODE: {
|
|
94
|
+
const pm_when_node_t* when_node = (const pm_when_node_t*) node;
|
|
95
|
+
if (has_pm_location(when_node->then_keyword_loc)) {
|
|
96
|
+
context->then_keyword_loc = when_node->then_keyword_loc;
|
|
97
|
+
context->found = true;
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
case PM_IN_NODE: {
|
|
104
|
+
const pm_in_node_t* in_node = (const pm_in_node_t*) node;
|
|
105
|
+
if (has_pm_location(in_node->then_loc)) {
|
|
106
|
+
context->then_keyword_loc = in_node->then_loc;
|
|
107
|
+
context->found = true;
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
default: break;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
pm_visit_child_nodes(node, search_then_keyword_location, context);
|
|
117
|
+
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
location_T* get_then_keyword_location(analyzed_ruby_T* analyzed, const char* source) {
|
|
122
|
+
if (analyzed == NULL || analyzed->root == NULL || source == NULL) { return NULL; }
|
|
123
|
+
|
|
124
|
+
then_keyword_search_context_T context = { .then_keyword_loc = { .start = NULL, .end = NULL }, .found = false };
|
|
125
|
+
|
|
126
|
+
pm_visit_child_nodes(analyzed->root, search_then_keyword_location, &context);
|
|
127
|
+
|
|
128
|
+
if (!context.found) { return NULL; }
|
|
129
|
+
|
|
130
|
+
size_t start_offset = (size_t) (context.then_keyword_loc.start - analyzed->parser.start);
|
|
131
|
+
size_t end_offset = (size_t) (context.then_keyword_loc.end - analyzed->parser.start);
|
|
132
|
+
|
|
133
|
+
position_T start_position = position_from_source_with_offset(source, start_offset);
|
|
134
|
+
position_T end_position = position_from_source_with_offset(source, end_offset);
|
|
135
|
+
|
|
136
|
+
return location_create(start_position, end_position);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
static location_T* parse_wrapped_and_find_then_keyword(
|
|
140
|
+
hb_buffer_T* buffer,
|
|
141
|
+
const char* source,
|
|
142
|
+
size_t source_length,
|
|
143
|
+
size_t prefix_length,
|
|
144
|
+
size_t adjustment_threshold,
|
|
145
|
+
size_t adjustment_amount
|
|
146
|
+
) {
|
|
147
|
+
pm_parser_t parser;
|
|
148
|
+
pm_parser_init(&parser, (const uint8_t*) hb_buffer_value(buffer), hb_buffer_length(buffer), NULL);
|
|
149
|
+
pm_node_t* root = pm_parse(&parser);
|
|
150
|
+
|
|
151
|
+
if (root == NULL) {
|
|
152
|
+
pm_parser_free(&parser);
|
|
153
|
+
|
|
154
|
+
return NULL;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
then_keyword_search_context_T context = { .then_keyword_loc = { .start = NULL, .end = NULL }, .found = false };
|
|
158
|
+
|
|
159
|
+
pm_visit_child_nodes(root, search_then_keyword_location, &context);
|
|
160
|
+
|
|
161
|
+
location_T* location = NULL;
|
|
162
|
+
|
|
163
|
+
if (context.found) {
|
|
164
|
+
size_t start_offset = (size_t) (context.then_keyword_loc.start - parser.start);
|
|
165
|
+
size_t end_offset = (size_t) (context.then_keyword_loc.end - parser.start);
|
|
166
|
+
|
|
167
|
+
if (start_offset >= prefix_length && end_offset >= prefix_length) {
|
|
168
|
+
start_offset -= prefix_length;
|
|
169
|
+
end_offset -= prefix_length;
|
|
170
|
+
|
|
171
|
+
if (start_offset > adjustment_threshold) {
|
|
172
|
+
start_offset += adjustment_amount;
|
|
173
|
+
end_offset += adjustment_amount;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (start_offset <= source_length && end_offset <= source_length) {
|
|
177
|
+
position_T start_position = position_from_source_with_offset(source, start_offset);
|
|
178
|
+
position_T end_position = position_from_source_with_offset(source, end_offset);
|
|
179
|
+
|
|
180
|
+
location = location_create(start_position, end_position);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
pm_node_destroy(&parser, root);
|
|
186
|
+
pm_parser_free(&parser);
|
|
187
|
+
|
|
188
|
+
return location;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
location_T* get_then_keyword_location_wrapped(const char* source, bool is_in_clause) {
|
|
192
|
+
if (source == NULL) { return NULL; }
|
|
193
|
+
|
|
194
|
+
size_t source_length = strlen(source);
|
|
195
|
+
|
|
196
|
+
hb_buffer_T buffer;
|
|
197
|
+
|
|
198
|
+
if (!hb_buffer_init(&buffer, source_length + 16)) { return NULL; }
|
|
199
|
+
|
|
200
|
+
hb_buffer_append(&buffer, "case x\n");
|
|
201
|
+
size_t prefix_length = hb_buffer_length(&buffer);
|
|
202
|
+
hb_buffer_append(&buffer, source);
|
|
203
|
+
hb_buffer_append(&buffer, "\nend");
|
|
204
|
+
|
|
205
|
+
location_T* location =
|
|
206
|
+
parse_wrapped_and_find_then_keyword(&buffer, source, source_length, prefix_length, SIZE_MAX, 0);
|
|
207
|
+
|
|
208
|
+
free(buffer.value);
|
|
209
|
+
|
|
210
|
+
return location;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
location_T* get_then_keyword_location_elsif_wrapped(const char* source) {
|
|
214
|
+
if (source == NULL) { return NULL; }
|
|
215
|
+
|
|
216
|
+
const char* elsif_position = strstr(source, "elsif");
|
|
217
|
+
|
|
218
|
+
if (elsif_position == NULL) { return NULL; }
|
|
219
|
+
|
|
220
|
+
size_t source_length = strlen(source);
|
|
221
|
+
size_t elsif_offset = (size_t) (elsif_position - source);
|
|
222
|
+
size_t replacement_diff = strlen("elsif") - strlen("if");
|
|
223
|
+
|
|
224
|
+
hb_buffer_T buffer;
|
|
225
|
+
|
|
226
|
+
if (!hb_buffer_init(&buffer, source_length + 8)) { return NULL; }
|
|
227
|
+
|
|
228
|
+
hb_buffer_append_with_length(&buffer, source, elsif_offset);
|
|
229
|
+
hb_buffer_append(&buffer, "if");
|
|
230
|
+
size_t if_end_offset = hb_buffer_length(&buffer);
|
|
231
|
+
hb_buffer_append(&buffer, source + elsif_offset + strlen("elsif"));
|
|
232
|
+
hb_buffer_append(&buffer, "\nend");
|
|
233
|
+
|
|
234
|
+
location_T* location =
|
|
235
|
+
parse_wrapped_and_find_then_keyword(&buffer, source, source_length, 0, if_end_offset, replacement_diff);
|
|
236
|
+
|
|
237
|
+
free(buffer.value);
|
|
238
|
+
|
|
239
|
+
return location;
|
|
240
|
+
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
#ifndef HERB_PRISM_HELPERS_H
|
|
2
2
|
#define HERB_PRISM_HELPERS_H
|
|
3
3
|
|
|
4
|
+
#include "analyzed_ruby.h"
|
|
4
5
|
#include "ast_nodes.h"
|
|
5
6
|
#include "errors.h"
|
|
7
|
+
#include "location.h"
|
|
6
8
|
#include "position.h"
|
|
7
9
|
|
|
8
10
|
#include <prism.h>
|
|
@@ -22,4 +24,8 @@ RUBY_PARSE_ERROR_T* ruby_parse_error_from_prism_error_with_positions(
|
|
|
22
24
|
position_T end
|
|
23
25
|
);
|
|
24
26
|
|
|
27
|
+
location_T* get_then_keyword_location(analyzed_ruby_T* analyzed, const char* source);
|
|
28
|
+
location_T* get_then_keyword_location_wrapped(const char* source, bool is_in_clause);
|
|
29
|
+
location_T* get_then_keyword_location_elsif_wrapped(const char* source);
|
|
30
|
+
|
|
25
31
|
#endif
|
|
@@ -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-0.8.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.9/templates/src/visitor.c.erb
|
|
3
3
|
|
|
4
4
|
#include <stdio.h>
|
|
5
5
|
|
package/extension/nodes.cpp
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-0.8.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.9/templates/javascript/packages/node/extension/nodes.cpp.erb
|
|
3
3
|
|
|
4
4
|
#include <node_api.h>
|
|
5
5
|
#include "error_helpers.h"
|
|
@@ -581,6 +581,14 @@ napi_value erb_if_nodeNodeFromCStruct(napi_env env, AST_ERB_IF_NODE_T* erb_if_no
|
|
|
581
581
|
napi_value tag_closing = CreateToken(env, erb_if_node->tag_closing);
|
|
582
582
|
napi_set_named_property(env, result, "tag_closing", tag_closing);
|
|
583
583
|
|
|
584
|
+
napi_value then_keyword;
|
|
585
|
+
if (erb_if_node->then_keyword != NULL) {
|
|
586
|
+
then_keyword = CreateLocation(env, *erb_if_node->then_keyword);
|
|
587
|
+
} else {
|
|
588
|
+
napi_get_null(env, &then_keyword);
|
|
589
|
+
}
|
|
590
|
+
napi_set_named_property(env, result, "then_keyword", then_keyword);
|
|
591
|
+
|
|
584
592
|
napi_value statements = NodesArrayFromCArray(env, erb_if_node->statements);
|
|
585
593
|
napi_set_named_property(env, result, "statements", statements);
|
|
586
594
|
|
|
@@ -658,6 +666,14 @@ napi_value erb_when_nodeNodeFromCStruct(napi_env env, AST_ERB_WHEN_NODE_T* erb_w
|
|
|
658
666
|
napi_value tag_closing = CreateToken(env, erb_when_node->tag_closing);
|
|
659
667
|
napi_set_named_property(env, result, "tag_closing", tag_closing);
|
|
660
668
|
|
|
669
|
+
napi_value then_keyword;
|
|
670
|
+
if (erb_when_node->then_keyword != NULL) {
|
|
671
|
+
then_keyword = CreateLocation(env, *erb_when_node->then_keyword);
|
|
672
|
+
} else {
|
|
673
|
+
napi_get_null(env, &then_keyword);
|
|
674
|
+
}
|
|
675
|
+
napi_set_named_property(env, result, "then_keyword", then_keyword);
|
|
676
|
+
|
|
661
677
|
napi_value statements = NodesArrayFromCArray(env, erb_when_node->statements);
|
|
662
678
|
napi_set_named_property(env, result, "statements", statements);
|
|
663
679
|
|
|
@@ -1006,6 +1022,14 @@ napi_value erb_unless_nodeNodeFromCStruct(napi_env env, AST_ERB_UNLESS_NODE_T* e
|
|
|
1006
1022
|
napi_value tag_closing = CreateToken(env, erb_unless_node->tag_closing);
|
|
1007
1023
|
napi_set_named_property(env, result, "tag_closing", tag_closing);
|
|
1008
1024
|
|
|
1025
|
+
napi_value then_keyword;
|
|
1026
|
+
if (erb_unless_node->then_keyword != NULL) {
|
|
1027
|
+
then_keyword = CreateLocation(env, *erb_unless_node->then_keyword);
|
|
1028
|
+
} else {
|
|
1029
|
+
napi_get_null(env, &then_keyword);
|
|
1030
|
+
}
|
|
1031
|
+
napi_set_named_property(env, result, "then_keyword", then_keyword);
|
|
1032
|
+
|
|
1009
1033
|
napi_value statements = NodesArrayFromCArray(env, erb_unless_node->statements);
|
|
1010
1034
|
napi_set_named_property(env, result, "statements", statements);
|
|
1011
1035
|
|
|
@@ -1077,6 +1101,14 @@ napi_value erb_in_nodeNodeFromCStruct(napi_env env, AST_ERB_IN_NODE_T* erb_in_no
|
|
|
1077
1101
|
napi_value tag_closing = CreateToken(env, erb_in_node->tag_closing);
|
|
1078
1102
|
napi_set_named_property(env, result, "tag_closing", tag_closing);
|
|
1079
1103
|
|
|
1104
|
+
napi_value then_keyword;
|
|
1105
|
+
if (erb_in_node->then_keyword != NULL) {
|
|
1106
|
+
then_keyword = CreateLocation(env, *erb_in_node->then_keyword);
|
|
1107
|
+
} else {
|
|
1108
|
+
napi_get_null(env, &then_keyword);
|
|
1109
|
+
}
|
|
1110
|
+
napi_set_named_property(env, result, "then_keyword", then_keyword);
|
|
1111
|
+
|
|
1080
1112
|
napi_value statements = NodesArrayFromCArray(env, erb_in_node->statements);
|
|
1081
1113
|
napi_set_named_property(env, result, "statements", statements);
|
|
1082
1114
|
|
package/extension/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-0.8.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.9/templates/javascript/packages/node/extension/nodes.h.erb
|
|
3
3
|
|
|
4
4
|
#ifndef HERB_EXTENSION_NODES_H
|
|
5
5
|
#define HERB_EXTENSION_NODES_H
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
/**
|
|
15
15
|
* The minor version of the Prism library as an int.
|
|
16
16
|
*/
|
|
17
|
-
#define PRISM_VERSION_MINOR
|
|
17
|
+
#define PRISM_VERSION_MINOR 8
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* The patch version of the Prism library as an int.
|
|
@@ -24,6 +24,6 @@
|
|
|
24
24
|
/**
|
|
25
25
|
* The version of the Prism library as a constant string.
|
|
26
26
|
*/
|
|
27
|
-
#define PRISM_VERSION "1.
|
|
27
|
+
#define PRISM_VERSION "1.8.0"
|
|
28
28
|
|
|
29
29
|
#endif
|