@herb-tools/node 0.8.9 → 0.9.0
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/CHANGELOG.md +19 -0
- package/binding.gyp +26 -8
- package/dist/herb-node.cjs +41 -12
- package/dist/herb-node.cjs.map +1 -1
- package/dist/herb-node.esm.js +8 -1
- package/dist/herb-node.esm.js.map +1 -1
- package/dist/types/node-backend.d.ts +3 -1
- package/extension/error_helpers.cpp +419 -71
- package/extension/error_helpers.h +14 -3
- package/extension/extension_helpers.cpp +38 -35
- package/extension/extension_helpers.h +2 -2
- package/extension/herb.cpp +183 -64
- package/extension/libherb/analyze/action_view/attribute_extraction_helpers.c +290 -0
- package/extension/libherb/analyze/action_view/attribute_extraction_helpers.h +36 -0
- package/extension/libherb/analyze/action_view/content_tag.c +70 -0
- package/extension/libherb/analyze/action_view/link_to.c +143 -0
- package/extension/libherb/analyze/action_view/registry.c +60 -0
- package/extension/libherb/analyze/action_view/tag.c +64 -0
- package/extension/libherb/analyze/action_view/tag_helper_handler.h +41 -0
- package/extension/libherb/analyze/action_view/tag_helper_node_builders.c +305 -0
- package/extension/libherb/analyze/action_view/tag_helper_node_builders.h +70 -0
- package/extension/libherb/analyze/action_view/tag_helpers.c +748 -0
- package/extension/libherb/analyze/action_view/tag_helpers.h +38 -0
- package/extension/libherb/analyze/action_view/turbo_frame_tag.c +88 -0
- package/extension/libherb/analyze/analyze.c +882 -0
- package/extension/libherb/{include → analyze}/analyze.h +14 -4
- package/extension/libherb/{analyzed_ruby.c → analyze/analyzed_ruby.c} +13 -11
- package/extension/libherb/{analyzed_ruby.h → analyze/analyzed_ruby.h} +3 -3
- package/extension/libherb/analyze/builders.c +343 -0
- package/extension/libherb/analyze/builders.h +27 -0
- package/extension/libherb/analyze/conditional_elements.c +594 -0
- package/extension/libherb/analyze/conditional_elements.h +9 -0
- package/extension/libherb/analyze/conditional_open_tags.c +640 -0
- package/extension/libherb/analyze/conditional_open_tags.h +9 -0
- package/extension/libherb/analyze/control_type.c +250 -0
- package/extension/libherb/analyze/control_type.h +14 -0
- package/extension/libherb/{analyze_helpers.c → analyze/helpers.c} +79 -31
- package/extension/libherb/{analyze_helpers.h → analyze/helpers.h} +22 -17
- package/extension/libherb/analyze/invalid_structures.c +193 -0
- package/extension/libherb/analyze/invalid_structures.h +11 -0
- package/extension/libherb/{analyze_missing_end.c → analyze/missing_end.c} +33 -22
- package/extension/libherb/analyze/parse_errors.c +84 -0
- package/extension/libherb/analyze/prism_annotate.c +397 -0
- package/extension/libherb/analyze/prism_annotate.h +16 -0
- package/extension/libherb/{analyze_transform.c → analyze/transform.c} +17 -3
- package/extension/libherb/ast_node.c +17 -7
- package/extension/libherb/ast_node.h +11 -5
- package/extension/libherb/ast_nodes.c +663 -388
- package/extension/libherb/ast_nodes.h +118 -39
- package/extension/libherb/ast_pretty_print.c +191 -7
- package/extension/libherb/ast_pretty_print.h +6 -1
- package/extension/libherb/element_source.h +3 -8
- package/extension/libherb/errors.c +1100 -507
- package/extension/libherb/errors.h +155 -54
- package/extension/libherb/extract.c +148 -49
- package/extension/libherb/extract.h +21 -5
- package/extension/libherb/herb.c +52 -34
- package/extension/libherb/herb.h +18 -6
- package/extension/libherb/herb_prism_node.h +13 -0
- package/extension/libherb/html_util.c +241 -12
- package/extension/libherb/html_util.h +7 -2
- package/extension/libherb/include/analyze/action_view/attribute_extraction_helpers.h +36 -0
- package/extension/libherb/include/analyze/action_view/tag_helper_handler.h +41 -0
- package/extension/libherb/include/analyze/action_view/tag_helper_node_builders.h +70 -0
- package/extension/libherb/include/analyze/action_view/tag_helpers.h +38 -0
- package/extension/libherb/{analyze.h → include/analyze/analyze.h} +14 -4
- package/extension/libherb/include/{analyzed_ruby.h → analyze/analyzed_ruby.h} +3 -3
- package/extension/libherb/include/analyze/builders.h +27 -0
- package/extension/libherb/include/analyze/conditional_elements.h +9 -0
- package/extension/libherb/include/analyze/conditional_open_tags.h +9 -0
- package/extension/libherb/include/analyze/control_type.h +14 -0
- package/extension/libherb/include/{analyze_helpers.h → analyze/helpers.h} +22 -17
- package/extension/libherb/include/analyze/invalid_structures.h +11 -0
- package/extension/libherb/include/analyze/prism_annotate.h +16 -0
- package/extension/libherb/include/ast_node.h +11 -5
- package/extension/libherb/include/ast_nodes.h +118 -39
- package/extension/libherb/include/ast_pretty_print.h +6 -1
- package/extension/libherb/include/element_source.h +3 -8
- package/extension/libherb/include/errors.h +155 -54
- package/extension/libherb/include/extract.h +21 -5
- package/extension/libherb/include/herb.h +18 -6
- package/extension/libherb/include/herb_prism_node.h +13 -0
- package/extension/libherb/include/html_util.h +7 -2
- package/extension/libherb/include/io.h +3 -1
- package/extension/libherb/include/lex_helpers.h +29 -0
- package/extension/libherb/include/lexer.h +1 -1
- package/extension/libherb/include/lexer_peek_helpers.h +87 -13
- package/extension/libherb/include/lexer_struct.h +2 -0
- package/extension/libherb/include/location.h +2 -1
- package/extension/libherb/include/parser.h +27 -2
- package/extension/libherb/include/parser_helpers.h +19 -3
- package/extension/libherb/include/pretty_print.h +10 -5
- package/extension/libherb/include/prism_context.h +45 -0
- package/extension/libherb/include/prism_helpers.h +10 -7
- package/extension/libherb/include/prism_serialized.h +12 -0
- package/extension/libherb/include/token.h +16 -4
- package/extension/libherb/include/token_struct.h +10 -3
- package/extension/libherb/include/utf8.h +2 -1
- package/extension/libherb/include/util/hb_allocator.h +78 -0
- package/extension/libherb/include/util/hb_arena.h +6 -1
- package/extension/libherb/include/util/hb_arena_debug.h +12 -1
- package/extension/libherb/include/util/hb_array.h +7 -3
- package/extension/libherb/include/util/hb_buffer.h +6 -4
- package/extension/libherb/include/util/hb_foreach.h +79 -0
- package/extension/libherb/include/util/hb_narray.h +8 -4
- package/extension/libherb/include/util/hb_string.h +56 -9
- package/extension/libherb/include/util/string.h +11 -0
- package/extension/libherb/include/util.h +6 -3
- package/extension/libherb/include/version.h +1 -1
- package/extension/libherb/io.c +3 -2
- package/extension/libherb/io.h +3 -1
- package/extension/libherb/lex_helpers.h +29 -0
- package/extension/libherb/lexer.c +42 -30
- package/extension/libherb/lexer.h +1 -1
- package/extension/libherb/lexer_peek_helpers.c +12 -74
- package/extension/libherb/lexer_peek_helpers.h +87 -13
- package/extension/libherb/lexer_struct.h +2 -0
- package/extension/libherb/location.c +2 -2
- package/extension/libherb/location.h +2 -1
- package/extension/libherb/main.c +79 -66
- package/extension/libherb/parser.c +784 -247
- package/extension/libherb/parser.h +27 -2
- package/extension/libherb/parser_helpers.c +110 -23
- package/extension/libherb/parser_helpers.h +19 -3
- package/extension/libherb/parser_match_tags.c +110 -49
- package/extension/libherb/pretty_print.c +29 -24
- package/extension/libherb/pretty_print.h +10 -5
- package/extension/libherb/prism_context.h +45 -0
- package/extension/libherb/prism_helpers.c +30 -27
- package/extension/libherb/prism_helpers.h +10 -7
- package/extension/libherb/prism_serialized.h +12 -0
- package/extension/libherb/ruby_parser.c +2 -0
- package/extension/libherb/token.c +151 -66
- package/extension/libherb/token.h +16 -4
- package/extension/libherb/token_matchers.c +0 -1
- package/extension/libherb/token_struct.h +10 -3
- package/extension/libherb/utf8.c +7 -6
- package/extension/libherb/utf8.h +2 -1
- package/extension/libherb/util/hb_allocator.c +341 -0
- package/extension/libherb/util/hb_allocator.h +78 -0
- package/extension/libherb/util/hb_arena.c +81 -56
- package/extension/libherb/util/hb_arena.h +6 -1
- package/extension/libherb/util/hb_arena_debug.c +32 -17
- package/extension/libherb/util/hb_arena_debug.h +12 -1
- package/extension/libherb/util/hb_array.c +30 -15
- package/extension/libherb/util/hb_array.h +7 -3
- package/extension/libherb/util/hb_buffer.c +17 -21
- package/extension/libherb/util/hb_buffer.h +6 -4
- package/extension/libherb/util/hb_foreach.h +79 -0
- package/extension/libherb/util/hb_narray.c +22 -7
- package/extension/libherb/util/hb_narray.h +8 -4
- package/extension/libherb/util/hb_string.c +49 -35
- package/extension/libherb/util/hb_string.h +56 -9
- package/extension/libherb/util/string.h +11 -0
- package/extension/libherb/util.c +21 -11
- package/extension/libherb/util.h +6 -3
- package/extension/libherb/version.h +1 -1
- package/extension/libherb/visitor.c +48 -1
- package/extension/nodes.cpp +451 -6
- package/extension/nodes.h +8 -1
- package/extension/prism/include/prism/ast.h +4 -4
- package/extension/prism/include/prism/version.h +2 -2
- package/extension/prism/src/prism.c +1 -1
- package/package.json +12 -8
- package/src/node-backend.ts +11 -1
- package/dist/types/index-cjs.d.cts +0 -1
- package/extension/libherb/analyze.c +0 -1594
- package/extension/libherb/element_source.c +0 -12
- package/extension/libherb/include/util/hb_system.h +0 -9
- package/extension/libherb/util/hb_system.c +0 -30
- package/extension/libherb/util/hb_system.h +0 -9
- package/src/index-cjs.cts +0 -22
- /package/dist/types/{index-esm.d.mts → index.d.ts} +0 -0
- /package/src/{index-esm.mts → index.ts} +0 -0
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
#include "../include/analyze/prism_annotate.h"
|
|
2
|
+
#include "../include/ast_node.h"
|
|
3
|
+
#include "../include/ast_nodes.h"
|
|
4
|
+
#include "../include/extract.h"
|
|
5
|
+
#include "../include/herb_prism_node.h"
|
|
6
|
+
#include "../include/prism_context.h"
|
|
7
|
+
#include "../include/util/hb_allocator.h"
|
|
8
|
+
#include "../include/util/hb_buffer.h"
|
|
9
|
+
#include "../include/util/hb_narray.h"
|
|
10
|
+
#include "../include/visitor.h"
|
|
11
|
+
|
|
12
|
+
#include <prism.h>
|
|
13
|
+
#include <string.h>
|
|
14
|
+
|
|
15
|
+
typedef struct {
|
|
16
|
+
uint32_t from;
|
|
17
|
+
uint32_t to;
|
|
18
|
+
} content_range_T;
|
|
19
|
+
|
|
20
|
+
typedef struct {
|
|
21
|
+
pm_parser_t* parser;
|
|
22
|
+
pm_parser_t* structural_parser;
|
|
23
|
+
hb_narray_T* node_list;
|
|
24
|
+
hb_narray_T* structural_node_list;
|
|
25
|
+
bool prism_nodes_deep;
|
|
26
|
+
} prism_annotate_context_T;
|
|
27
|
+
|
|
28
|
+
static void collect_prism_nodes(pm_node_t* node, hb_narray_T* list);
|
|
29
|
+
|
|
30
|
+
static void collect_from_statements(pm_statements_node_t* statements, hb_narray_T* list) {
|
|
31
|
+
if (!statements) { return; }
|
|
32
|
+
|
|
33
|
+
for (size_t i = 0; i < statements->body.size; i++) {
|
|
34
|
+
hb_narray_push(list, &statements->body.nodes[i]);
|
|
35
|
+
collect_prism_nodes(statements->body.nodes[i], list);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static void collect_prism_nodes(pm_node_t* node, hb_narray_T* list) {
|
|
40
|
+
if (!node) { return; }
|
|
41
|
+
|
|
42
|
+
switch (PM_NODE_TYPE(node)) {
|
|
43
|
+
case PM_PROGRAM_NODE: {
|
|
44
|
+
collect_from_statements(((pm_program_node_t*) node)->statements, list);
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
case PM_IF_NODE: {
|
|
49
|
+
pm_if_node_t* if_node = (pm_if_node_t*) node;
|
|
50
|
+
collect_from_statements(if_node->statements, list);
|
|
51
|
+
if (if_node->subsequent) { collect_prism_nodes(if_node->subsequent, list); }
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
case PM_UNLESS_NODE: {
|
|
56
|
+
pm_unless_node_t* unless_node = (pm_unless_node_t*) node;
|
|
57
|
+
collect_from_statements(unless_node->statements, list);
|
|
58
|
+
if (unless_node->else_clause) { collect_prism_nodes((pm_node_t*) unless_node->else_clause, list); }
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
case PM_ELSE_NODE: {
|
|
63
|
+
collect_from_statements(((pm_else_node_t*) node)->statements, list);
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
case PM_WHILE_NODE: {
|
|
68
|
+
collect_from_statements(((pm_while_node_t*) node)->statements, list);
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
case PM_UNTIL_NODE: {
|
|
73
|
+
collect_from_statements(((pm_until_node_t*) node)->statements, list);
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
case PM_FOR_NODE: {
|
|
78
|
+
collect_from_statements(((pm_for_node_t*) node)->statements, list);
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
case PM_CASE_NODE: {
|
|
83
|
+
pm_case_node_t* case_node = (pm_case_node_t*) node;
|
|
84
|
+
|
|
85
|
+
for (size_t i = 0; i < case_node->conditions.size; i++) {
|
|
86
|
+
collect_prism_nodes(case_node->conditions.nodes[i], list);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (case_node->else_clause) { collect_prism_nodes((pm_node_t*) case_node->else_clause, list); }
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
case PM_CASE_MATCH_NODE: {
|
|
94
|
+
pm_case_match_node_t* case_match_node = (pm_case_match_node_t*) node;
|
|
95
|
+
|
|
96
|
+
for (size_t i = 0; i < case_match_node->conditions.size; i++) {
|
|
97
|
+
collect_prism_nodes(case_match_node->conditions.nodes[i], list);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (case_match_node->else_clause) { collect_prism_nodes((pm_node_t*) case_match_node->else_clause, list); }
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
case PM_WHEN_NODE: {
|
|
105
|
+
collect_from_statements(((pm_when_node_t*) node)->statements, list);
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
case PM_IN_NODE: {
|
|
110
|
+
collect_from_statements(((pm_in_node_t*) node)->statements, list);
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
case PM_BEGIN_NODE: {
|
|
115
|
+
pm_begin_node_t* begin_node = (pm_begin_node_t*) node;
|
|
116
|
+
|
|
117
|
+
collect_from_statements(begin_node->statements, list);
|
|
118
|
+
|
|
119
|
+
if (begin_node->rescue_clause) { collect_prism_nodes((pm_node_t*) begin_node->rescue_clause, list); }
|
|
120
|
+
if (begin_node->else_clause) { collect_prism_nodes((pm_node_t*) begin_node->else_clause, list); }
|
|
121
|
+
if (begin_node->ensure_clause) { collect_prism_nodes((pm_node_t*) begin_node->ensure_clause, list); }
|
|
122
|
+
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
case PM_RESCUE_NODE: {
|
|
127
|
+
pm_rescue_node_t* rescue_node = (pm_rescue_node_t*) node;
|
|
128
|
+
|
|
129
|
+
collect_from_statements(rescue_node->statements, list);
|
|
130
|
+
|
|
131
|
+
if (rescue_node->subsequent) { collect_prism_nodes((pm_node_t*) rescue_node->subsequent, list); }
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
case PM_ENSURE_NODE: {
|
|
136
|
+
collect_from_statements(((pm_ensure_node_t*) node)->statements, list);
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
case PM_CALL_NODE: {
|
|
141
|
+
pm_call_node_t* call_node = (pm_call_node_t*) node;
|
|
142
|
+
|
|
143
|
+
if (call_node->block && PM_NODE_TYPE(call_node->block) == PM_BLOCK_NODE) {
|
|
144
|
+
pm_block_node_t* block = (pm_block_node_t*) call_node->block;
|
|
145
|
+
|
|
146
|
+
if (block->body && PM_NODE_TYPE(block->body) == PM_STATEMENTS_NODE) {
|
|
147
|
+
collect_from_statements((pm_statements_node_t*) block->body, list);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
case PM_LAMBDA_NODE: {
|
|
155
|
+
pm_lambda_node_t* lambda_node = (pm_lambda_node_t*) node;
|
|
156
|
+
|
|
157
|
+
if (lambda_node->body && PM_NODE_TYPE(lambda_node->body) == PM_STATEMENTS_NODE) {
|
|
158
|
+
collect_from_statements((pm_statements_node_t*) lambda_node->body, list);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
default: break;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
static token_T* get_content_token(const AST_NODE_T* node) {
|
|
169
|
+
switch (node->type) {
|
|
170
|
+
case AST_ERB_CONTENT_NODE: return ((AST_ERB_CONTENT_NODE_T*) node)->content;
|
|
171
|
+
case AST_ERB_IF_NODE: return ((AST_ERB_IF_NODE_T*) node)->content;
|
|
172
|
+
case AST_ERB_BLOCK_NODE: return ((AST_ERB_BLOCK_NODE_T*) node)->content;
|
|
173
|
+
case AST_ERB_CASE_NODE: return ((AST_ERB_CASE_NODE_T*) node)->content;
|
|
174
|
+
case AST_ERB_CASE_MATCH_NODE: return ((AST_ERB_CASE_MATCH_NODE_T*) node)->content;
|
|
175
|
+
case AST_ERB_WHILE_NODE: return ((AST_ERB_WHILE_NODE_T*) node)->content;
|
|
176
|
+
case AST_ERB_UNTIL_NODE: return ((AST_ERB_UNTIL_NODE_T*) node)->content;
|
|
177
|
+
case AST_ERB_FOR_NODE: return ((AST_ERB_FOR_NODE_T*) node)->content;
|
|
178
|
+
case AST_ERB_BEGIN_NODE: return ((AST_ERB_BEGIN_NODE_T*) node)->content;
|
|
179
|
+
case AST_ERB_UNLESS_NODE: return ((AST_ERB_UNLESS_NODE_T*) node)->content;
|
|
180
|
+
default: return NULL;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
static void set_prism_node(AST_NODE_T* node, herb_prism_node_T prism_ref) {
|
|
185
|
+
switch (node->type) {
|
|
186
|
+
case AST_ERB_CONTENT_NODE: ((AST_ERB_CONTENT_NODE_T*) node)->prism_node = prism_ref; break;
|
|
187
|
+
case AST_ERB_IF_NODE: ((AST_ERB_IF_NODE_T*) node)->prism_node = prism_ref; break;
|
|
188
|
+
case AST_ERB_BLOCK_NODE: ((AST_ERB_BLOCK_NODE_T*) node)->prism_node = prism_ref; break;
|
|
189
|
+
case AST_ERB_CASE_NODE: ((AST_ERB_CASE_NODE_T*) node)->prism_node = prism_ref; break;
|
|
190
|
+
case AST_ERB_CASE_MATCH_NODE: ((AST_ERB_CASE_MATCH_NODE_T*) node)->prism_node = prism_ref; break;
|
|
191
|
+
case AST_ERB_WHILE_NODE: ((AST_ERB_WHILE_NODE_T*) node)->prism_node = prism_ref; break;
|
|
192
|
+
case AST_ERB_UNTIL_NODE: ((AST_ERB_UNTIL_NODE_T*) node)->prism_node = prism_ref; break;
|
|
193
|
+
case AST_ERB_FOR_NODE: ((AST_ERB_FOR_NODE_T*) node)->prism_node = prism_ref; break;
|
|
194
|
+
case AST_ERB_BEGIN_NODE: ((AST_ERB_BEGIN_NODE_T*) node)->prism_node = prism_ref; break;
|
|
195
|
+
case AST_ERB_UNLESS_NODE: ((AST_ERB_UNLESS_NODE_T*) node)->prism_node = prism_ref; break;
|
|
196
|
+
default: break;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
static herb_prism_node_T find_prism_node_for_herb_node(
|
|
201
|
+
pm_parser_t* parser,
|
|
202
|
+
hb_narray_T* node_list,
|
|
203
|
+
const AST_NODE_T* node
|
|
204
|
+
) {
|
|
205
|
+
herb_prism_node_T result = HERB_PRISM_NODE_EMPTY;
|
|
206
|
+
|
|
207
|
+
token_T* content = get_content_token(node);
|
|
208
|
+
if (!content || hb_string_is_empty(content->value)) { return result; }
|
|
209
|
+
|
|
210
|
+
uint32_t content_from = content->range.from;
|
|
211
|
+
uint32_t content_to = content->range.to;
|
|
212
|
+
|
|
213
|
+
for (size_t i = 0; i < hb_narray_size(node_list); i++) {
|
|
214
|
+
pm_node_t* prism_node = *(pm_node_t**) hb_narray_get(node_list, i);
|
|
215
|
+
size_t prism_start = (size_t) (prism_node->location.start - parser->start);
|
|
216
|
+
|
|
217
|
+
if (prism_start >= content_from && prism_start < content_to) {
|
|
218
|
+
result.node = prism_node;
|
|
219
|
+
result.parser = parser;
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return result;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
static bool annotate_visitor(const AST_NODE_T* node, void* data) {
|
|
228
|
+
prism_annotate_context_T* context = (prism_annotate_context_T*) data;
|
|
229
|
+
|
|
230
|
+
if (!get_content_token(node)) { return true; }
|
|
231
|
+
|
|
232
|
+
pm_parser_t* parser;
|
|
233
|
+
hb_narray_T* node_list;
|
|
234
|
+
|
|
235
|
+
if (node->type == AST_ERB_CONTENT_NODE || context->prism_nodes_deep) {
|
|
236
|
+
parser = context->parser;
|
|
237
|
+
node_list = context->node_list;
|
|
238
|
+
} else {
|
|
239
|
+
parser = context->structural_parser;
|
|
240
|
+
node_list = context->structural_node_list;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
herb_prism_node_T prism_ref = find_prism_node_for_herb_node(parser, node_list, node);
|
|
244
|
+
|
|
245
|
+
if (prism_ref.node) { set_prism_node((AST_NODE_T*) node, prism_ref); }
|
|
246
|
+
|
|
247
|
+
return true;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
static bool collect_content_ranges_visitor(const AST_NODE_T* node, void* data) {
|
|
251
|
+
if (node->type != AST_ERB_CONTENT_NODE) { return true; }
|
|
252
|
+
|
|
253
|
+
hb_narray_T* ranges = (hb_narray_T*) data;
|
|
254
|
+
token_T* content = get_content_token(node);
|
|
255
|
+
|
|
256
|
+
if (!content || hb_string_is_empty(content->value)) { return true; }
|
|
257
|
+
|
|
258
|
+
content_range_T range = { .from = content->range.from, .to = content->range.to };
|
|
259
|
+
hb_narray_push(ranges, &range);
|
|
260
|
+
|
|
261
|
+
return true;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
void herb_annotate_prism_nodes(
|
|
265
|
+
AST_DOCUMENT_NODE_T* document,
|
|
266
|
+
const char* source,
|
|
267
|
+
bool prism_nodes,
|
|
268
|
+
bool prism_nodes_deep,
|
|
269
|
+
bool prism_program,
|
|
270
|
+
hb_allocator_T* allocator
|
|
271
|
+
) {
|
|
272
|
+
if (!document || !source) { return; }
|
|
273
|
+
|
|
274
|
+
size_t source_len = strlen(source);
|
|
275
|
+
|
|
276
|
+
herb_prism_context_T* context = hb_allocator_alloc(allocator, sizeof(herb_prism_context_T));
|
|
277
|
+
if (!context) { return; }
|
|
278
|
+
|
|
279
|
+
memset(context, 0, sizeof(herb_prism_context_T));
|
|
280
|
+
|
|
281
|
+
context->allocator = allocator;
|
|
282
|
+
context->has_structural = false;
|
|
283
|
+
|
|
284
|
+
if (!hb_buffer_init(&context->ruby_buf, source_len, allocator)) {
|
|
285
|
+
hb_allocator_dealloc(allocator, context);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
herb_extract_ruby_options_T extract_options = {
|
|
290
|
+
.semicolons = true,
|
|
291
|
+
.comments = false,
|
|
292
|
+
.preserve_positions = true,
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
herb_extract_ruby_to_buffer_with_options(source, &context->ruby_buf, &extract_options, allocator);
|
|
296
|
+
|
|
297
|
+
if (!context->ruby_buf.value || context->ruby_buf.length == 0) {
|
|
298
|
+
hb_buffer_free(&context->ruby_buf);
|
|
299
|
+
hb_allocator_dealloc(allocator, context);
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
memset(&context->pm_opts, 0, sizeof(pm_options_t));
|
|
304
|
+
pm_options_partial_script_set(&context->pm_opts, true);
|
|
305
|
+
pm_parser_init(
|
|
306
|
+
&context->parser,
|
|
307
|
+
(const uint8_t*) context->ruby_buf.value,
|
|
308
|
+
context->ruby_buf.length,
|
|
309
|
+
&context->pm_opts
|
|
310
|
+
);
|
|
311
|
+
context->root = pm_parse(&context->parser);
|
|
312
|
+
|
|
313
|
+
if (!context->root || context->root->type != PM_PROGRAM_NODE) {
|
|
314
|
+
pm_node_destroy(&context->parser, context->root);
|
|
315
|
+
context->root = NULL;
|
|
316
|
+
|
|
317
|
+
pm_parser_free(&context->parser);
|
|
318
|
+
pm_options_free(&context->pm_opts);
|
|
319
|
+
|
|
320
|
+
hb_buffer_free(&context->ruby_buf);
|
|
321
|
+
hb_allocator_dealloc(allocator, context);
|
|
322
|
+
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
document->prism_context = context;
|
|
327
|
+
|
|
328
|
+
if (prism_program) {
|
|
329
|
+
herb_prism_node_T program_ref = {
|
|
330
|
+
.node = context->root,
|
|
331
|
+
.parser = &context->parser,
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
document->prism_node = program_ref;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
hb_narray_T node_list;
|
|
338
|
+
hb_narray_pointer_init(&node_list, 32, allocator);
|
|
339
|
+
|
|
340
|
+
hb_narray_T structural_node_list;
|
|
341
|
+
hb_narray_pointer_init(&structural_node_list, 32, allocator);
|
|
342
|
+
|
|
343
|
+
if (prism_nodes) {
|
|
344
|
+
collect_prism_nodes(context->root, &node_list);
|
|
345
|
+
|
|
346
|
+
if (!prism_nodes_deep) {
|
|
347
|
+
hb_narray_T content_ranges;
|
|
348
|
+
hb_narray_init(&content_ranges, sizeof(content_range_T), 32, allocator);
|
|
349
|
+
herb_visit_node((AST_NODE_T*) document, collect_content_ranges_visitor, &content_ranges);
|
|
350
|
+
|
|
351
|
+
if (hb_buffer_init(&context->structural_buf, context->ruby_buf.length, allocator)) {
|
|
352
|
+
memcpy(context->structural_buf.value, context->ruby_buf.value, context->ruby_buf.length);
|
|
353
|
+
context->structural_buf.length = context->ruby_buf.length;
|
|
354
|
+
|
|
355
|
+
for (size_t i = 0; i < hb_narray_size(&content_ranges); i++) {
|
|
356
|
+
content_range_T* range = (content_range_T*) hb_narray_get(&content_ranges, i);
|
|
357
|
+
|
|
358
|
+
for (uint32_t j = range->from; j < range->to && j < context->structural_buf.length; j++) {
|
|
359
|
+
context->structural_buf.value[j] = ' ';
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
memset(&context->structural_pm_opts, 0, sizeof(pm_options_t));
|
|
364
|
+
pm_options_partial_script_set(&context->structural_pm_opts, true);
|
|
365
|
+
|
|
366
|
+
pm_parser_init(
|
|
367
|
+
&context->structural_parser,
|
|
368
|
+
(const uint8_t*) context->structural_buf.value,
|
|
369
|
+
context->structural_buf.length,
|
|
370
|
+
&context->structural_pm_opts
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
context->structural_root = pm_parse(&context->structural_parser);
|
|
374
|
+
context->has_structural = true;
|
|
375
|
+
|
|
376
|
+
if (context->structural_root && context->structural_root->type == PM_PROGRAM_NODE) {
|
|
377
|
+
collect_prism_nodes(context->structural_root, &structural_node_list);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
hb_narray_deinit(&content_ranges);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
prism_annotate_context_T annotate_context = {
|
|
385
|
+
.parser = &context->parser,
|
|
386
|
+
.structural_parser = prism_nodes_deep ? &context->parser : &context->structural_parser,
|
|
387
|
+
.node_list = &node_list,
|
|
388
|
+
.structural_node_list = prism_nodes_deep ? &node_list : &structural_node_list,
|
|
389
|
+
.prism_nodes_deep = prism_nodes_deep,
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
herb_visit_node((AST_NODE_T*) document, annotate_visitor, &annotate_context);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
hb_narray_deinit(&node_list);
|
|
396
|
+
hb_narray_deinit(&structural_node_list);
|
|
397
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#ifndef HERB_PRISM_ANNOTATE_H
|
|
2
|
+
#define HERB_PRISM_ANNOTATE_H
|
|
3
|
+
|
|
4
|
+
#include "../ast_nodes.h"
|
|
5
|
+
#include "../util/hb_allocator.h"
|
|
6
|
+
|
|
7
|
+
void herb_annotate_prism_nodes(
|
|
8
|
+
AST_DOCUMENT_NODE_T* document,
|
|
9
|
+
const char* source,
|
|
10
|
+
bool prism_nodes,
|
|
11
|
+
bool prism_nodes_deep,
|
|
12
|
+
bool prism_program,
|
|
13
|
+
hb_allocator_T* allocator
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
#endif
|
|
@@ -1,8 +1,8 @@
|
|
|
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.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.9.0/templates/src/analyze/transform.c.erb
|
|
3
3
|
|
|
4
|
-
#include "include/analyze.h"
|
|
5
|
-
#include "include/visitor.h"
|
|
4
|
+
#include "../include/analyze/analyze.h"
|
|
5
|
+
#include "../include/visitor.h"
|
|
6
6
|
|
|
7
7
|
bool transform_erb_nodes(const AST_NODE_T* node, void* data) {
|
|
8
8
|
analyze_ruby_context_T* context = (analyze_ruby_context_T*) data;
|
|
@@ -36,6 +36,13 @@ bool transform_erb_nodes(const AST_NODE_T* node, void* data) {
|
|
|
36
36
|
hb_array_free(&old_array);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
if (node->type == AST_HTML_CONDITIONAL_ELEMENT_NODE) {
|
|
40
|
+
AST_HTML_CONDITIONAL_ELEMENT_NODE_T* html_conditional_element_node = (AST_HTML_CONDITIONAL_ELEMENT_NODE_T*) node;
|
|
41
|
+
hb_array_T* old_array = html_conditional_element_node->body;
|
|
42
|
+
html_conditional_element_node->body = rewrite_node_array((AST_NODE_T*) node, html_conditional_element_node->body, context);
|
|
43
|
+
hb_array_free(&old_array);
|
|
44
|
+
}
|
|
45
|
+
|
|
39
46
|
if (node->type == AST_HTML_ATTRIBUTE_VALUE_NODE) {
|
|
40
47
|
AST_HTML_ATTRIBUTE_VALUE_NODE_T* html_attribute_value_node = (AST_HTML_ATTRIBUTE_VALUE_NODE_T*) node;
|
|
41
48
|
hb_array_T* old_array = html_attribute_value_node->children;
|
|
@@ -50,6 +57,13 @@ bool transform_erb_nodes(const AST_NODE_T* node, void* data) {
|
|
|
50
57
|
hb_array_free(&old_array);
|
|
51
58
|
}
|
|
52
59
|
|
|
60
|
+
if (node->type == AST_ERB_OPEN_TAG_NODE) {
|
|
61
|
+
AST_ERB_OPEN_TAG_NODE_T* erb_open_tag_node = (AST_ERB_OPEN_TAG_NODE_T*) node;
|
|
62
|
+
hb_array_T* old_array = erb_open_tag_node->children;
|
|
63
|
+
erb_open_tag_node->children = rewrite_node_array((AST_NODE_T*) node, erb_open_tag_node->children, context);
|
|
64
|
+
hb_array_free(&old_array);
|
|
65
|
+
}
|
|
66
|
+
|
|
53
67
|
if (node->type == AST_HTML_COMMENT_NODE) {
|
|
54
68
|
AST_HTML_COMMENT_NODE_T* html_comment_node = (AST_HTML_COMMENT_NODE_T*) node;
|
|
55
69
|
hb_array_T* old_array = html_comment_node->children;
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
#include "include/ast_nodes.h"
|
|
3
3
|
#include "include/errors.h"
|
|
4
4
|
#include "include/position.h"
|
|
5
|
-
#include "include/token.h"
|
|
6
5
|
#include "include/util.h"
|
|
6
|
+
#include "include/util/hb_allocator.h"
|
|
7
|
+
#include "include/util/hb_string.h"
|
|
7
8
|
#include "include/visitor.h"
|
|
8
9
|
|
|
9
10
|
#include <prism.h>
|
|
@@ -14,7 +15,14 @@ size_t ast_node_sizeof(void) {
|
|
|
14
15
|
return sizeof(struct AST_NODE_STRUCT);
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
void ast_node_init(
|
|
18
|
+
void ast_node_init(
|
|
19
|
+
AST_NODE_T* node,
|
|
20
|
+
const ast_node_type_T type,
|
|
21
|
+
position_T start,
|
|
22
|
+
position_T end,
|
|
23
|
+
hb_array_T* errors,
|
|
24
|
+
hb_allocator_T* allocator
|
|
25
|
+
) {
|
|
18
26
|
if (!node) { return; }
|
|
19
27
|
|
|
20
28
|
node->type = type;
|
|
@@ -22,18 +30,20 @@ void ast_node_init(AST_NODE_T* node, const ast_node_type_T type, position_T star
|
|
|
22
30
|
node->location.end = end;
|
|
23
31
|
|
|
24
32
|
if (errors == NULL) {
|
|
25
|
-
node->errors = hb_array_init(
|
|
33
|
+
node->errors = hb_array_init(0, allocator);
|
|
26
34
|
} else {
|
|
27
35
|
node->errors = errors;
|
|
28
36
|
}
|
|
29
37
|
}
|
|
30
38
|
|
|
31
|
-
AST_LITERAL_NODE_T* ast_literal_node_init_from_token(const token_T* token) {
|
|
32
|
-
AST_LITERAL_NODE_T* literal =
|
|
39
|
+
AST_LITERAL_NODE_T* ast_literal_node_init_from_token(const token_T* token, hb_allocator_T* allocator) {
|
|
40
|
+
AST_LITERAL_NODE_T* literal = hb_allocator_alloc(allocator, sizeof(AST_LITERAL_NODE_T));
|
|
33
41
|
|
|
34
|
-
|
|
42
|
+
if (!literal) { return NULL; }
|
|
35
43
|
|
|
36
|
-
literal->
|
|
44
|
+
ast_node_init(&literal->base, AST_LITERAL_NODE, token->location.start, token->location.end, NULL, allocator);
|
|
45
|
+
|
|
46
|
+
literal->content = hb_string_copy(token->value, allocator);
|
|
37
47
|
|
|
38
48
|
return literal;
|
|
39
49
|
}
|
|
@@ -5,19 +5,25 @@
|
|
|
5
5
|
#include "errors.h"
|
|
6
6
|
#include "position.h"
|
|
7
7
|
#include "token_struct.h"
|
|
8
|
+
#include "util/hb_allocator.h"
|
|
8
9
|
|
|
9
|
-
void ast_node_init(
|
|
10
|
-
|
|
10
|
+
void ast_node_init(
|
|
11
|
+
AST_NODE_T* node,
|
|
12
|
+
ast_node_type_T type,
|
|
13
|
+
position_T start,
|
|
14
|
+
position_T end,
|
|
15
|
+
hb_array_T* errors,
|
|
16
|
+
hb_allocator_T* allocator
|
|
17
|
+
);
|
|
18
|
+
void ast_node_free(AST_NODE_T* node, hb_allocator_T* allocator);
|
|
11
19
|
|
|
12
|
-
AST_LITERAL_NODE_T* ast_literal_node_init_from_token(const token_T* token);
|
|
20
|
+
AST_LITERAL_NODE_T* ast_literal_node_init_from_token(const token_T* token, hb_allocator_T* allocator);
|
|
13
21
|
|
|
14
22
|
size_t ast_node_sizeof(void);
|
|
15
23
|
size_t ast_node_child_count(AST_NODE_T* node);
|
|
16
24
|
|
|
17
25
|
ast_node_type_T ast_node_type(const AST_NODE_T* node);
|
|
18
26
|
|
|
19
|
-
char* ast_node_name(AST_NODE_T* node);
|
|
20
|
-
|
|
21
27
|
void ast_node_set_start(AST_NODE_T* node, position_T position);
|
|
22
28
|
void ast_node_set_end(AST_NODE_T* node, position_T position);
|
|
23
29
|
|