herb 0.1.0-x86_64-linux-gnu
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/License.txt +21 -0
- data/Makefile +121 -0
- data/README.md +166 -0
- data/Rakefile +184 -0
- data/exe/herb +5 -0
- data/ext/herb/error_helpers.c +302 -0
- data/ext/herb/error_helpers.h +15 -0
- data/ext/herb/extconf.rb +75 -0
- data/ext/herb/extension.c +110 -0
- data/ext/herb/extension.h +6 -0
- data/ext/herb/extension_helpers.c +117 -0
- data/ext/herb/extension_helpers.h +24 -0
- data/ext/herb/nodes.c +936 -0
- data/ext/herb/nodes.h +12 -0
- data/herb.gemspec +49 -0
- data/lib/herb/3.0/herb.so +0 -0
- data/lib/herb/3.1/herb.so +0 -0
- data/lib/herb/3.2/herb.so +0 -0
- data/lib/herb/3.3/herb.so +0 -0
- data/lib/herb/3.4/herb.so +0 -0
- data/lib/herb/ast/node.rb +61 -0
- data/lib/herb/ast/nodes.rb +1542 -0
- data/lib/herb/ast.rb +6 -0
- data/lib/herb/cli.rb +164 -0
- data/lib/herb/errors.rb +352 -0
- data/lib/herb/lex_result.rb +20 -0
- data/lib/herb/libherb/array.rb +48 -0
- data/lib/herb/libherb/ast_node.rb +47 -0
- data/lib/herb/libherb/buffer.rb +53 -0
- data/lib/herb/libherb/extract_result.rb +17 -0
- data/lib/herb/libherb/lex_result.rb +29 -0
- data/lib/herb/libherb/libherb.rb +49 -0
- data/lib/herb/libherb/parse_result.rb +17 -0
- data/lib/herb/libherb/token.rb +43 -0
- data/lib/herb/libherb.rb +32 -0
- data/lib/herb/location.rb +42 -0
- data/lib/herb/parse_result.rb +26 -0
- data/lib/herb/position.rb +36 -0
- data/lib/herb/project.rb +361 -0
- data/lib/herb/range.rb +40 -0
- data/lib/herb/result.rb +21 -0
- data/lib/herb/token.rb +43 -0
- data/lib/herb/token_list.rb +11 -0
- data/lib/herb/version.rb +5 -0
- data/lib/herb.rb +32 -0
- data/src/analyze.c +989 -0
- data/src/analyze_helpers.c +241 -0
- data/src/analyzed_ruby.c +35 -0
- data/src/array.c +137 -0
- data/src/ast_node.c +81 -0
- data/src/ast_nodes.c +866 -0
- data/src/ast_pretty_print.c +588 -0
- data/src/buffer.c +199 -0
- data/src/errors.c +740 -0
- data/src/extract.c +110 -0
- data/src/herb.c +103 -0
- data/src/html_util.c +143 -0
- data/src/include/analyze.h +36 -0
- data/src/include/analyze_helpers.h +43 -0
- data/src/include/analyzed_ruby.h +33 -0
- data/src/include/array.h +33 -0
- data/src/include/ast_node.h +35 -0
- data/src/include/ast_nodes.h +303 -0
- data/src/include/ast_pretty_print.h +17 -0
- data/src/include/buffer.h +36 -0
- data/src/include/errors.h +125 -0
- data/src/include/extract.h +20 -0
- data/src/include/herb.h +32 -0
- data/src/include/html_util.h +13 -0
- data/src/include/io.h +9 -0
- data/src/include/json.h +28 -0
- data/src/include/lexer.h +13 -0
- data/src/include/lexer_peek_helpers.h +23 -0
- data/src/include/lexer_struct.h +32 -0
- data/src/include/location.h +25 -0
- data/src/include/macros.h +10 -0
- data/src/include/memory.h +12 -0
- data/src/include/parser.h +22 -0
- data/src/include/parser_helpers.h +33 -0
- data/src/include/position.h +22 -0
- data/src/include/pretty_print.h +53 -0
- data/src/include/prism_helpers.h +18 -0
- data/src/include/range.h +23 -0
- data/src/include/ruby_parser.h +6 -0
- data/src/include/token.h +25 -0
- data/src/include/token_matchers.h +21 -0
- data/src/include/token_struct.h +51 -0
- data/src/include/util.h +25 -0
- data/src/include/version.h +6 -0
- data/src/include/visitor.h +11 -0
- data/src/io.c +30 -0
- data/src/json.c +205 -0
- data/src/lexer.c +284 -0
- data/src/lexer_peek_helpers.c +59 -0
- data/src/location.c +41 -0
- data/src/main.c +162 -0
- data/src/memory.c +53 -0
- data/src/parser.c +704 -0
- data/src/parser_helpers.c +161 -0
- data/src/position.c +33 -0
- data/src/pretty_print.c +242 -0
- data/src/prism_helpers.c +50 -0
- data/src/range.c +38 -0
- data/src/ruby_parser.c +47 -0
- data/src/token.c +194 -0
- data/src/token_matchers.c +32 -0
- data/src/util.c +128 -0
- data/src/visitor.c +321 -0
- metadata +159 -0
data/src/token.c
ADDED
@@ -0,0 +1,194 @@
|
|
1
|
+
#include "include/token.h"
|
2
|
+
#include "include/json.h"
|
3
|
+
#include "include/lexer.h"
|
4
|
+
#include "include/position.h"
|
5
|
+
#include "include/token_struct.h"
|
6
|
+
#include "include/util.h"
|
7
|
+
|
8
|
+
#include <stdio.h>
|
9
|
+
#include <stdlib.h>
|
10
|
+
#include <string.h>
|
11
|
+
|
12
|
+
size_t token_sizeof(void) {
|
13
|
+
return sizeof(struct TOKEN_STRUCT);
|
14
|
+
}
|
15
|
+
|
16
|
+
token_T* token_init(const char* value, const token_type_T type, lexer_T* lexer) {
|
17
|
+
token_T* token = calloc(1, token_sizeof());
|
18
|
+
|
19
|
+
if (type == TOKEN_NEWLINE) {
|
20
|
+
lexer->current_line++;
|
21
|
+
lexer->current_column = 0;
|
22
|
+
}
|
23
|
+
|
24
|
+
if (value) {
|
25
|
+
token->value = herb_strdup(value);
|
26
|
+
} else {
|
27
|
+
token->value = NULL;
|
28
|
+
}
|
29
|
+
|
30
|
+
token->type = type;
|
31
|
+
token->range = range_init(lexer->previous_position, lexer->current_position);
|
32
|
+
|
33
|
+
token->location =
|
34
|
+
location_from(lexer->previous_line, lexer->previous_column, lexer->current_line, lexer->current_column);
|
35
|
+
|
36
|
+
lexer->previous_line = lexer->current_line;
|
37
|
+
lexer->previous_column = lexer->current_column;
|
38
|
+
lexer->previous_position = lexer->current_position;
|
39
|
+
|
40
|
+
return token;
|
41
|
+
}
|
42
|
+
|
43
|
+
const char* token_type_to_string(const token_type_T type) {
|
44
|
+
switch (type) {
|
45
|
+
case TOKEN_WHITESPACE: return "TOKEN_WHITESPACE";
|
46
|
+
case TOKEN_NBSP: return "TOKEN_NBSP";
|
47
|
+
case TOKEN_NEWLINE: return "TOKEN_NEWLINE";
|
48
|
+
case TOKEN_IDENTIFIER: return "TOKEN_IDENTIFIER";
|
49
|
+
case TOKEN_HTML_DOCTYPE: return "TOKEN_HTML_DOCTYPE";
|
50
|
+
case TOKEN_HTML_TAG_START: return "TOKEN_HTML_TAG_START";
|
51
|
+
case TOKEN_HTML_TAG_END: return "TOKEN_HTML_TAG_END";
|
52
|
+
case TOKEN_HTML_TAG_START_CLOSE: return "TOKEN_HTML_TAG_START_CLOSE";
|
53
|
+
case TOKEN_HTML_TAG_SELF_CLOSE: return "TOKEN_HTML_TAG_SELF_CLOSE";
|
54
|
+
case TOKEN_HTML_COMMENT_START: return "TOKEN_HTML_COMMENT_START";
|
55
|
+
case TOKEN_HTML_COMMENT_END: return "TOKEN_HTML_COMMENT_END";
|
56
|
+
case TOKEN_EQUALS: return "TOKEN_EQUALS";
|
57
|
+
case TOKEN_QUOTE: return "TOKEN_QUOTE";
|
58
|
+
case TOKEN_DASH: return "TOKEN_DASH";
|
59
|
+
case TOKEN_UNDERSCORE: return "TOKEN_UNDERSCORE";
|
60
|
+
case TOKEN_EXCLAMATION: return "TOKEN_EXCLAMATION";
|
61
|
+
case TOKEN_SLASH: return "TOKEN_SLASH";
|
62
|
+
case TOKEN_SEMICOLON: return "TOKEN_SEMICOLON";
|
63
|
+
case TOKEN_COLON: return "TOKEN_COLON";
|
64
|
+
case TOKEN_LT: return "TOKEN_LT";
|
65
|
+
case TOKEN_PERCENT: return "TOKEN_PERCENT";
|
66
|
+
case TOKEN_AMPERSAND: return "TOKEN_AMPERSAND";
|
67
|
+
case TOKEN_ERB_START: return "TOKEN_ERB_START";
|
68
|
+
case TOKEN_ERB_CONTENT: return "TOKEN_ERB_CONTENT";
|
69
|
+
case TOKEN_ERB_END: return "TOKEN_ERB_END";
|
70
|
+
case TOKEN_CHARACTER: return "TOKEN_CHARACTER";
|
71
|
+
case TOKEN_ERROR: return "TOKEN_ERROR";
|
72
|
+
case TOKEN_EOF: return "TOKEN_EOF";
|
73
|
+
}
|
74
|
+
|
75
|
+
return "Unkown token_type_T";
|
76
|
+
}
|
77
|
+
|
78
|
+
char* token_to_string(const token_T* token) {
|
79
|
+
const char* type_string = token_type_to_string(token->type);
|
80
|
+
const char* template = "#<Herb::Token type=\"%s\" value=\"%s\" range=[%d, %d] start=(%d:%d) end=(%d:%d)>";
|
81
|
+
|
82
|
+
char* string = calloc(strlen(type_string) + strlen(template) + strlen(token->value) + 16, sizeof(char));
|
83
|
+
char* escaped;
|
84
|
+
|
85
|
+
if (token->type == TOKEN_EOF) {
|
86
|
+
escaped = herb_strdup("<EOF>");
|
87
|
+
} else {
|
88
|
+
escaped = escape_newlines(token->value);
|
89
|
+
}
|
90
|
+
|
91
|
+
sprintf(
|
92
|
+
string,
|
93
|
+
template,
|
94
|
+
type_string,
|
95
|
+
escaped,
|
96
|
+
token->range->from,
|
97
|
+
token->range->to,
|
98
|
+
token->location->start->line,
|
99
|
+
token->location->start->column,
|
100
|
+
token->location->end->line,
|
101
|
+
token->location->end->column
|
102
|
+
);
|
103
|
+
|
104
|
+
free(escaped);
|
105
|
+
|
106
|
+
return string;
|
107
|
+
}
|
108
|
+
|
109
|
+
char* token_to_json(const token_T* token) {
|
110
|
+
buffer_T json = buffer_new();
|
111
|
+
|
112
|
+
json_start_root_object(&json);
|
113
|
+
json_add_string(&json, "type", token_type_to_string(token->type));
|
114
|
+
json_add_string(&json, "value", token->value);
|
115
|
+
|
116
|
+
buffer_T range = buffer_new();
|
117
|
+
json_start_array(&json, "range");
|
118
|
+
json_add_size_t(&range, NULL, token->range->from);
|
119
|
+
json_add_size_t(&range, NULL, token->range->to);
|
120
|
+
buffer_concat(&json, &range);
|
121
|
+
buffer_free(&range);
|
122
|
+
json_end_array(&json);
|
123
|
+
|
124
|
+
buffer_T start = buffer_new();
|
125
|
+
json_start_object(&json, "start");
|
126
|
+
json_add_size_t(&start, "line", token->location->start->line);
|
127
|
+
json_add_size_t(&start, "column", token->location->start->column);
|
128
|
+
buffer_concat(&json, &start);
|
129
|
+
buffer_free(&start);
|
130
|
+
json_end_object(&json);
|
131
|
+
|
132
|
+
buffer_T end = buffer_new();
|
133
|
+
json_start_object(&json, "end");
|
134
|
+
json_add_size_t(&end, "line", token->location->end->line);
|
135
|
+
json_add_size_t(&end, "column", token->location->end->column);
|
136
|
+
buffer_concat(&json, &end);
|
137
|
+
buffer_free(&end);
|
138
|
+
json_end_object(&json);
|
139
|
+
|
140
|
+
json_end_object(&json);
|
141
|
+
|
142
|
+
return buffer_value(&json);
|
143
|
+
}
|
144
|
+
|
145
|
+
char* token_value(const token_T* token) {
|
146
|
+
return token->value;
|
147
|
+
}
|
148
|
+
|
149
|
+
int token_type(const token_T* token) {
|
150
|
+
return token->type;
|
151
|
+
}
|
152
|
+
|
153
|
+
position_T* token_start_position(token_T* token) {
|
154
|
+
return token->location->start;
|
155
|
+
}
|
156
|
+
|
157
|
+
position_T* token_end_position(token_T* token) {
|
158
|
+
return token->location->end;
|
159
|
+
}
|
160
|
+
|
161
|
+
token_T* token_copy(token_T* token) {
|
162
|
+
if (!token) { return NULL; }
|
163
|
+
|
164
|
+
token_T* new_token = calloc(1, token_sizeof());
|
165
|
+
|
166
|
+
if (!new_token) { return NULL; }
|
167
|
+
|
168
|
+
if (token->value) {
|
169
|
+
new_token->value = herb_strdup(token->value);
|
170
|
+
|
171
|
+
if (!new_token->value) {
|
172
|
+
free(new_token);
|
173
|
+
return NULL;
|
174
|
+
}
|
175
|
+
} else {
|
176
|
+
new_token->value = NULL;
|
177
|
+
}
|
178
|
+
|
179
|
+
new_token->type = token->type;
|
180
|
+
new_token->range = range_copy(token->range);
|
181
|
+
new_token->location = location_copy(token->location);
|
182
|
+
|
183
|
+
return new_token;
|
184
|
+
}
|
185
|
+
|
186
|
+
void token_free(token_T* token) {
|
187
|
+
if (!token) { return; }
|
188
|
+
|
189
|
+
if (token->value != NULL) { free(token->value); }
|
190
|
+
if (token->range != NULL) { range_free(token->range); }
|
191
|
+
if (token->location != NULL) { location_free(token->location); }
|
192
|
+
|
193
|
+
free(token);
|
194
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#include "include/token_matchers.h"
|
2
|
+
#include "include/parser.h"
|
3
|
+
#include "include/token.h"
|
4
|
+
|
5
|
+
#include <stdarg.h>
|
6
|
+
#include <stdbool.h>
|
7
|
+
|
8
|
+
bool token_is(parser_T* parser, token_type_T expected_type) {
|
9
|
+
return parser->current_token->type == expected_type;
|
10
|
+
}
|
11
|
+
|
12
|
+
bool token_is_not(parser_T* parser, token_type_T type) {
|
13
|
+
return parser->current_token->type != type;
|
14
|
+
}
|
15
|
+
|
16
|
+
bool token_matches_any(token_type_T current_token, token_type_T first_token, ...) {
|
17
|
+
if (current_token == first_token) { return true; }
|
18
|
+
|
19
|
+
va_list tokens;
|
20
|
+
va_start(tokens, first_token);
|
21
|
+
token_type_T token;
|
22
|
+
|
23
|
+
while ((token = va_arg(tokens, token_type_T)) != TOKEN_SENTINEL) {
|
24
|
+
if (current_token == token) {
|
25
|
+
va_end(tokens);
|
26
|
+
return true;
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
va_end(tokens);
|
31
|
+
return false;
|
32
|
+
}
|
data/src/util.c
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
#include "include/util.h"
|
2
|
+
|
3
|
+
#include <ctype.h>
|
4
|
+
#include <stdio.h>
|
5
|
+
#include <stdlib.h>
|
6
|
+
#include <string.h>
|
7
|
+
|
8
|
+
int is_whitespace(const int character) {
|
9
|
+
return character == ' ' || character == '\t';
|
10
|
+
}
|
11
|
+
|
12
|
+
int is_newline(const int character) {
|
13
|
+
return character == 13 || character == 10;
|
14
|
+
}
|
15
|
+
|
16
|
+
int count_in_string(const char* string, const char character) {
|
17
|
+
int count = 0;
|
18
|
+
|
19
|
+
while (*string != '\0') {
|
20
|
+
if (*string == character) { count++; }
|
21
|
+
|
22
|
+
string++;
|
23
|
+
}
|
24
|
+
|
25
|
+
return count;
|
26
|
+
}
|
27
|
+
|
28
|
+
int count_newlines(const char* string) {
|
29
|
+
int count = 0;
|
30
|
+
|
31
|
+
while (*string) {
|
32
|
+
if (*string == '\r') {
|
33
|
+
count++;
|
34
|
+
if (*(string + 1) == '\n') { string++; }
|
35
|
+
} else if (*string == '\n') {
|
36
|
+
count++;
|
37
|
+
}
|
38
|
+
|
39
|
+
string++;
|
40
|
+
}
|
41
|
+
|
42
|
+
return count;
|
43
|
+
}
|
44
|
+
|
45
|
+
char* replace_char(char* string, const char find, const char replace) {
|
46
|
+
while (*string != '\0') {
|
47
|
+
if (*string == find) { *string = replace; }
|
48
|
+
|
49
|
+
string++;
|
50
|
+
}
|
51
|
+
|
52
|
+
return string;
|
53
|
+
}
|
54
|
+
|
55
|
+
char* escape_newlines(const char* input) {
|
56
|
+
char* output = calloc(strlen(input) * 2 + 1, sizeof(char));
|
57
|
+
char* orig_output = output;
|
58
|
+
|
59
|
+
while (*input) {
|
60
|
+
if (*input == '\n') {
|
61
|
+
*output++ = '\\';
|
62
|
+
*output++ = 'n';
|
63
|
+
} else if (*input == '\r') {
|
64
|
+
*output++ = '\\';
|
65
|
+
*output++ = 'r';
|
66
|
+
} else {
|
67
|
+
*output++ = *input;
|
68
|
+
}
|
69
|
+
|
70
|
+
input++;
|
71
|
+
}
|
72
|
+
|
73
|
+
*output = '\0';
|
74
|
+
|
75
|
+
return orig_output;
|
76
|
+
}
|
77
|
+
|
78
|
+
char* wrap_string(const char* input, const char character) {
|
79
|
+
if (input == NULL) { return NULL; }
|
80
|
+
|
81
|
+
const size_t length = strlen(input);
|
82
|
+
char* wrapped = malloc(length + 3);
|
83
|
+
|
84
|
+
if (wrapped == NULL) { return NULL; }
|
85
|
+
|
86
|
+
wrapped[0] = character;
|
87
|
+
strcpy(wrapped + 1, input);
|
88
|
+
wrapped[length + 1] = character;
|
89
|
+
wrapped[length + 2] = '\0';
|
90
|
+
|
91
|
+
return wrapped;
|
92
|
+
}
|
93
|
+
|
94
|
+
char* quoted_string(const char* input) {
|
95
|
+
return wrap_string(input, '"');
|
96
|
+
}
|
97
|
+
|
98
|
+
// Check if a string is blank (NULL, empty, or only contains whitespace)
|
99
|
+
bool string_blank(const char* input) {
|
100
|
+
if (input == NULL || input[0] == '\0') { return true; }
|
101
|
+
|
102
|
+
for (const char* p = input; *p != '\0'; p++) {
|
103
|
+
if (!isspace(*p)) { return false; }
|
104
|
+
}
|
105
|
+
|
106
|
+
return true;
|
107
|
+
}
|
108
|
+
|
109
|
+
// Check if a string is present (not blank)
|
110
|
+
bool string_present(const char* input) {
|
111
|
+
return !string_blank(input);
|
112
|
+
}
|
113
|
+
|
114
|
+
char* herb_strdup(const char* s) {
|
115
|
+
size_t len = strlen(s) + 1;
|
116
|
+
char* copy = malloc(len);
|
117
|
+
|
118
|
+
if (copy) { memcpy(copy, s, len); }
|
119
|
+
|
120
|
+
return copy;
|
121
|
+
}
|
122
|
+
|
123
|
+
char* size_t_to_string(const size_t value) {
|
124
|
+
char* buffer = malloc(21);
|
125
|
+
snprintf(buffer, 21, "%zu", value);
|
126
|
+
|
127
|
+
return buffer;
|
128
|
+
}
|
data/src/visitor.c
ADDED
@@ -0,0 +1,321 @@
|
|
1
|
+
// NOTE: This file is generated by the templates/template.rb script and should not
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release/templates/src/visitor.c.erb
|
3
|
+
|
4
|
+
#include <stdio.h>
|
5
|
+
|
6
|
+
#include "include/array.h"
|
7
|
+
#include "include/visitor.h"
|
8
|
+
#include "include/ast_node.h"
|
9
|
+
#include "include/ast_nodes.h"
|
10
|
+
|
11
|
+
void herb_visit_node(const AST_NODE_T* node, bool (*visitor)(const AST_NODE_T*, void*), void* data) {
|
12
|
+
if (visitor(node, data) && node != NULL) {
|
13
|
+
herb_visit_child_nodes(node, visitor, data);
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
void herb_visit_child_nodes(const AST_NODE_T *node, bool (*visitor)(const AST_NODE_T *node, void *data), void *data) {
|
18
|
+
if (node == NULL) {
|
19
|
+
return;
|
20
|
+
}
|
21
|
+
|
22
|
+
switch (node->type) {
|
23
|
+
case AST_DOCUMENT_NODE: {
|
24
|
+
const AST_DOCUMENT_NODE_T* document_node = ((const AST_DOCUMENT_NODE_T *) node);
|
25
|
+
|
26
|
+
if (document_node->children != NULL) {
|
27
|
+
for (size_t index = 0; index < array_size(document_node->children); index++) {
|
28
|
+
herb_visit_node(array_get(document_node->children, index), visitor, data);
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
} break;
|
33
|
+
|
34
|
+
case AST_HTML_OPEN_TAG_NODE: {
|
35
|
+
const AST_HTML_OPEN_TAG_NODE_T* html_open_tag_node = ((const AST_HTML_OPEN_TAG_NODE_T *) node);
|
36
|
+
|
37
|
+
if (html_open_tag_node->children != NULL) {
|
38
|
+
for (size_t index = 0; index < array_size(html_open_tag_node->children); index++) {
|
39
|
+
herb_visit_node(array_get(html_open_tag_node->children, index), visitor, data);
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
} break;
|
44
|
+
|
45
|
+
case AST_HTML_SELF_CLOSE_TAG_NODE: {
|
46
|
+
const AST_HTML_SELF_CLOSE_TAG_NODE_T* html_self_close_tag_node = ((const AST_HTML_SELF_CLOSE_TAG_NODE_T *) node);
|
47
|
+
|
48
|
+
if (html_self_close_tag_node->attributes != NULL) {
|
49
|
+
for (size_t index = 0; index < array_size(html_self_close_tag_node->attributes); index++) {
|
50
|
+
herb_visit_node(array_get(html_self_close_tag_node->attributes, index), visitor, data);
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
} break;
|
55
|
+
|
56
|
+
case AST_HTML_ELEMENT_NODE: {
|
57
|
+
const AST_HTML_ELEMENT_NODE_T* html_element_node = ((const AST_HTML_ELEMENT_NODE_T *) node);
|
58
|
+
|
59
|
+
if (html_element_node->open_tag != NULL) {
|
60
|
+
herb_visit_node((AST_NODE_T *) html_element_node->open_tag, visitor, data);
|
61
|
+
}
|
62
|
+
|
63
|
+
if (html_element_node->body != NULL) {
|
64
|
+
for (size_t index = 0; index < array_size(html_element_node->body); index++) {
|
65
|
+
herb_visit_node(array_get(html_element_node->body, index), visitor, data);
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
if (html_element_node->close_tag != NULL) {
|
70
|
+
herb_visit_node((AST_NODE_T *) html_element_node->close_tag, visitor, data);
|
71
|
+
}
|
72
|
+
|
73
|
+
} break;
|
74
|
+
|
75
|
+
case AST_HTML_ATTRIBUTE_VALUE_NODE: {
|
76
|
+
const AST_HTML_ATTRIBUTE_VALUE_NODE_T* html_attribute_value_node = ((const AST_HTML_ATTRIBUTE_VALUE_NODE_T *) node);
|
77
|
+
|
78
|
+
if (html_attribute_value_node->children != NULL) {
|
79
|
+
for (size_t index = 0; index < array_size(html_attribute_value_node->children); index++) {
|
80
|
+
herb_visit_node(array_get(html_attribute_value_node->children, index), visitor, data);
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
} break;
|
85
|
+
|
86
|
+
case AST_HTML_ATTRIBUTE_NODE: {
|
87
|
+
const AST_HTML_ATTRIBUTE_NODE_T* html_attribute_node = ((const AST_HTML_ATTRIBUTE_NODE_T *) node);
|
88
|
+
|
89
|
+
if (html_attribute_node->name != NULL) {
|
90
|
+
herb_visit_node((AST_NODE_T *) html_attribute_node->name, visitor, data);
|
91
|
+
}
|
92
|
+
|
93
|
+
if (html_attribute_node->value != NULL) {
|
94
|
+
herb_visit_node((AST_NODE_T *) html_attribute_node->value, visitor, data);
|
95
|
+
}
|
96
|
+
|
97
|
+
} break;
|
98
|
+
|
99
|
+
case AST_HTML_COMMENT_NODE: {
|
100
|
+
const AST_HTML_COMMENT_NODE_T* html_comment_node = ((const AST_HTML_COMMENT_NODE_T *) node);
|
101
|
+
|
102
|
+
if (html_comment_node->children != NULL) {
|
103
|
+
for (size_t index = 0; index < array_size(html_comment_node->children); index++) {
|
104
|
+
herb_visit_node(array_get(html_comment_node->children, index), visitor, data);
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
} break;
|
109
|
+
|
110
|
+
case AST_HTML_DOCTYPE_NODE: {
|
111
|
+
const AST_HTML_DOCTYPE_NODE_T* html_doctype_node = ((const AST_HTML_DOCTYPE_NODE_T *) node);
|
112
|
+
|
113
|
+
if (html_doctype_node->children != NULL) {
|
114
|
+
for (size_t index = 0; index < array_size(html_doctype_node->children); index++) {
|
115
|
+
herb_visit_node(array_get(html_doctype_node->children, index), visitor, data);
|
116
|
+
}
|
117
|
+
}
|
118
|
+
|
119
|
+
} break;
|
120
|
+
|
121
|
+
case AST_ERB_ELSE_NODE: {
|
122
|
+
const AST_ERB_ELSE_NODE_T* erb_else_node = ((const AST_ERB_ELSE_NODE_T *) node);
|
123
|
+
|
124
|
+
if (erb_else_node->statements != NULL) {
|
125
|
+
for (size_t index = 0; index < array_size(erb_else_node->statements); index++) {
|
126
|
+
herb_visit_node(array_get(erb_else_node->statements, index), visitor, data);
|
127
|
+
}
|
128
|
+
}
|
129
|
+
|
130
|
+
} break;
|
131
|
+
|
132
|
+
case AST_ERB_IF_NODE: {
|
133
|
+
const AST_ERB_IF_NODE_T* erb_if_node = ((const AST_ERB_IF_NODE_T *) node);
|
134
|
+
|
135
|
+
if (erb_if_node->statements != NULL) {
|
136
|
+
for (size_t index = 0; index < array_size(erb_if_node->statements); index++) {
|
137
|
+
herb_visit_node(array_get(erb_if_node->statements, index), visitor, data);
|
138
|
+
}
|
139
|
+
}
|
140
|
+
|
141
|
+
if (erb_if_node->subsequent != NULL) {
|
142
|
+
herb_visit_node((AST_NODE_T *) erb_if_node->subsequent, visitor, data);
|
143
|
+
}
|
144
|
+
|
145
|
+
if (erb_if_node->end_node != NULL) {
|
146
|
+
herb_visit_node((AST_NODE_T *) erb_if_node->end_node, visitor, data);
|
147
|
+
}
|
148
|
+
|
149
|
+
} break;
|
150
|
+
|
151
|
+
case AST_ERB_BLOCK_NODE: {
|
152
|
+
const AST_ERB_BLOCK_NODE_T* erb_block_node = ((const AST_ERB_BLOCK_NODE_T *) node);
|
153
|
+
|
154
|
+
if (erb_block_node->body != NULL) {
|
155
|
+
for (size_t index = 0; index < array_size(erb_block_node->body); index++) {
|
156
|
+
herb_visit_node(array_get(erb_block_node->body, index), visitor, data);
|
157
|
+
}
|
158
|
+
}
|
159
|
+
|
160
|
+
if (erb_block_node->end_node != NULL) {
|
161
|
+
herb_visit_node((AST_NODE_T *) erb_block_node->end_node, visitor, data);
|
162
|
+
}
|
163
|
+
|
164
|
+
} break;
|
165
|
+
|
166
|
+
case AST_ERB_WHEN_NODE: {
|
167
|
+
const AST_ERB_WHEN_NODE_T* erb_when_node = ((const AST_ERB_WHEN_NODE_T *) node);
|
168
|
+
|
169
|
+
if (erb_when_node->statements != NULL) {
|
170
|
+
for (size_t index = 0; index < array_size(erb_when_node->statements); index++) {
|
171
|
+
herb_visit_node(array_get(erb_when_node->statements, index), visitor, data);
|
172
|
+
}
|
173
|
+
}
|
174
|
+
|
175
|
+
} break;
|
176
|
+
|
177
|
+
case AST_ERB_CASE_NODE: {
|
178
|
+
const AST_ERB_CASE_NODE_T* erb_case_node = ((const AST_ERB_CASE_NODE_T *) node);
|
179
|
+
|
180
|
+
if (erb_case_node->children != NULL) {
|
181
|
+
for (size_t index = 0; index < array_size(erb_case_node->children); index++) {
|
182
|
+
herb_visit_node(array_get(erb_case_node->children, index), visitor, data);
|
183
|
+
}
|
184
|
+
}
|
185
|
+
|
186
|
+
if (erb_case_node->conditions != NULL) {
|
187
|
+
for (size_t index = 0; index < array_size(erb_case_node->conditions); index++) {
|
188
|
+
herb_visit_node(array_get(erb_case_node->conditions, index), visitor, data);
|
189
|
+
}
|
190
|
+
}
|
191
|
+
|
192
|
+
if (erb_case_node->else_clause != NULL) {
|
193
|
+
herb_visit_node((AST_NODE_T *) erb_case_node->else_clause, visitor, data);
|
194
|
+
}
|
195
|
+
|
196
|
+
if (erb_case_node->end_node != NULL) {
|
197
|
+
herb_visit_node((AST_NODE_T *) erb_case_node->end_node, visitor, data);
|
198
|
+
}
|
199
|
+
|
200
|
+
} break;
|
201
|
+
|
202
|
+
case AST_ERB_WHILE_NODE: {
|
203
|
+
const AST_ERB_WHILE_NODE_T* erb_while_node = ((const AST_ERB_WHILE_NODE_T *) node);
|
204
|
+
|
205
|
+
if (erb_while_node->statements != NULL) {
|
206
|
+
for (size_t index = 0; index < array_size(erb_while_node->statements); index++) {
|
207
|
+
herb_visit_node(array_get(erb_while_node->statements, index), visitor, data);
|
208
|
+
}
|
209
|
+
}
|
210
|
+
|
211
|
+
if (erb_while_node->end_node != NULL) {
|
212
|
+
herb_visit_node((AST_NODE_T *) erb_while_node->end_node, visitor, data);
|
213
|
+
}
|
214
|
+
|
215
|
+
} break;
|
216
|
+
|
217
|
+
case AST_ERB_UNTIL_NODE: {
|
218
|
+
const AST_ERB_UNTIL_NODE_T* erb_until_node = ((const AST_ERB_UNTIL_NODE_T *) node);
|
219
|
+
|
220
|
+
if (erb_until_node->statements != NULL) {
|
221
|
+
for (size_t index = 0; index < array_size(erb_until_node->statements); index++) {
|
222
|
+
herb_visit_node(array_get(erb_until_node->statements, index), visitor, data);
|
223
|
+
}
|
224
|
+
}
|
225
|
+
|
226
|
+
if (erb_until_node->end_node != NULL) {
|
227
|
+
herb_visit_node((AST_NODE_T *) erb_until_node->end_node, visitor, data);
|
228
|
+
}
|
229
|
+
|
230
|
+
} break;
|
231
|
+
|
232
|
+
case AST_ERB_FOR_NODE: {
|
233
|
+
const AST_ERB_FOR_NODE_T* erb_for_node = ((const AST_ERB_FOR_NODE_T *) node);
|
234
|
+
|
235
|
+
if (erb_for_node->statements != NULL) {
|
236
|
+
for (size_t index = 0; index < array_size(erb_for_node->statements); index++) {
|
237
|
+
herb_visit_node(array_get(erb_for_node->statements, index), visitor, data);
|
238
|
+
}
|
239
|
+
}
|
240
|
+
|
241
|
+
if (erb_for_node->end_node != NULL) {
|
242
|
+
herb_visit_node((AST_NODE_T *) erb_for_node->end_node, visitor, data);
|
243
|
+
}
|
244
|
+
|
245
|
+
} break;
|
246
|
+
|
247
|
+
case AST_ERB_RESCUE_NODE: {
|
248
|
+
const AST_ERB_RESCUE_NODE_T* erb_rescue_node = ((const AST_ERB_RESCUE_NODE_T *) node);
|
249
|
+
|
250
|
+
if (erb_rescue_node->statements != NULL) {
|
251
|
+
for (size_t index = 0; index < array_size(erb_rescue_node->statements); index++) {
|
252
|
+
herb_visit_node(array_get(erb_rescue_node->statements, index), visitor, data);
|
253
|
+
}
|
254
|
+
}
|
255
|
+
|
256
|
+
if (erb_rescue_node->subsequent != NULL) {
|
257
|
+
herb_visit_node((AST_NODE_T *) erb_rescue_node->subsequent, visitor, data);
|
258
|
+
}
|
259
|
+
|
260
|
+
} break;
|
261
|
+
|
262
|
+
case AST_ERB_ENSURE_NODE: {
|
263
|
+
const AST_ERB_ENSURE_NODE_T* erb_ensure_node = ((const AST_ERB_ENSURE_NODE_T *) node);
|
264
|
+
|
265
|
+
if (erb_ensure_node->statements != NULL) {
|
266
|
+
for (size_t index = 0; index < array_size(erb_ensure_node->statements); index++) {
|
267
|
+
herb_visit_node(array_get(erb_ensure_node->statements, index), visitor, data);
|
268
|
+
}
|
269
|
+
}
|
270
|
+
|
271
|
+
} break;
|
272
|
+
|
273
|
+
case AST_ERB_BEGIN_NODE: {
|
274
|
+
const AST_ERB_BEGIN_NODE_T* erb_begin_node = ((const AST_ERB_BEGIN_NODE_T *) node);
|
275
|
+
|
276
|
+
if (erb_begin_node->statements != NULL) {
|
277
|
+
for (size_t index = 0; index < array_size(erb_begin_node->statements); index++) {
|
278
|
+
herb_visit_node(array_get(erb_begin_node->statements, index), visitor, data);
|
279
|
+
}
|
280
|
+
}
|
281
|
+
|
282
|
+
if (erb_begin_node->rescue_clause != NULL) {
|
283
|
+
herb_visit_node((AST_NODE_T *) erb_begin_node->rescue_clause, visitor, data);
|
284
|
+
}
|
285
|
+
|
286
|
+
if (erb_begin_node->else_clause != NULL) {
|
287
|
+
herb_visit_node((AST_NODE_T *) erb_begin_node->else_clause, visitor, data);
|
288
|
+
}
|
289
|
+
|
290
|
+
if (erb_begin_node->ensure_clause != NULL) {
|
291
|
+
herb_visit_node((AST_NODE_T *) erb_begin_node->ensure_clause, visitor, data);
|
292
|
+
}
|
293
|
+
|
294
|
+
if (erb_begin_node->end_node != NULL) {
|
295
|
+
herb_visit_node((AST_NODE_T *) erb_begin_node->end_node, visitor, data);
|
296
|
+
}
|
297
|
+
|
298
|
+
} break;
|
299
|
+
|
300
|
+
case AST_ERB_UNLESS_NODE: {
|
301
|
+
const AST_ERB_UNLESS_NODE_T* erb_unless_node = ((const AST_ERB_UNLESS_NODE_T *) node);
|
302
|
+
|
303
|
+
if (erb_unless_node->statements != NULL) {
|
304
|
+
for (size_t index = 0; index < array_size(erb_unless_node->statements); index++) {
|
305
|
+
herb_visit_node(array_get(erb_unless_node->statements, index), visitor, data);
|
306
|
+
}
|
307
|
+
}
|
308
|
+
|
309
|
+
if (erb_unless_node->else_clause != NULL) {
|
310
|
+
herb_visit_node((AST_NODE_T *) erb_unless_node->else_clause, visitor, data);
|
311
|
+
}
|
312
|
+
|
313
|
+
if (erb_unless_node->end_node != NULL) {
|
314
|
+
herb_visit_node((AST_NODE_T *) erb_unless_node->end_node, visitor, data);
|
315
|
+
}
|
316
|
+
|
317
|
+
} break;
|
318
|
+
|
319
|
+
default: break;
|
320
|
+
}
|
321
|
+
}
|