herb 0.9.1-aarch64-linux-gnu → 0.9.3-aarch64-linux-gnu
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/config.yml +125 -0
- data/ext/herb/error_helpers.c +172 -2
- data/ext/herb/extconf.rb +6 -0
- data/ext/herb/extension.c +16 -2
- data/ext/herb/extension_helpers.c +6 -5
- data/ext/herb/extension_helpers.h +4 -4
- data/ext/herb/nodes.c +89 -3
- 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/4.0/herb.so +0 -0
- data/lib/herb/ast/erb_content_node.rb +32 -0
- data/lib/herb/ast/nodes.rb +244 -3
- data/lib/herb/cli.rb +12 -2
- data/lib/herb/engine/compiler.rb +136 -97
- data/lib/herb/engine/validators/security_validator.rb +40 -0
- data/lib/herb/engine.rb +21 -0
- data/lib/herb/errors.rb +268 -0
- data/lib/herb/parser_options.rb +7 -2
- data/lib/herb/version.rb +1 -1
- data/lib/herb/visitor.rb +82 -0
- data/lib/herb.rb +1 -0
- data/sig/herb/ast/erb_content_node.rbs +13 -0
- data/sig/herb/ast/nodes.rbs +98 -2
- data/sig/herb/engine/compiler.rbs +18 -3
- data/sig/herb/engine/validators/security_validator.rbs +4 -0
- data/sig/herb/engine.rbs +4 -0
- data/sig/herb/errors.rbs +122 -0
- data/sig/herb/parser_options.rbs +6 -2
- data/sig/herb/visitor.rbs +12 -0
- data/sig/serialized_ast_errors.rbs +29 -0
- data/sig/serialized_ast_nodes.rbs +19 -0
- data/src/analyze/action_view/attribute_extraction_helpers.c +425 -87
- data/src/analyze/action_view/image_tag.c +87 -0
- data/src/analyze/action_view/javascript_include_tag.c +102 -0
- data/src/analyze/action_view/javascript_tag.c +55 -0
- data/src/analyze/action_view/registry.c +10 -3
- data/src/analyze/action_view/tag.c +19 -2
- data/src/analyze/action_view/tag_helper_node_builders.c +119 -37
- data/src/analyze/action_view/tag_helpers.c +1033 -32
- data/src/analyze/analyze.c +165 -10
- data/src/analyze/{helpers.c → analyze_helpers.c} +1 -1
- data/src/analyze/analyzed_ruby.c +1 -1
- data/src/analyze/builders.c +11 -8
- data/src/analyze/conditional_elements.c +6 -7
- data/src/analyze/conditional_open_tags.c +6 -7
- data/src/analyze/control_type.c +4 -2
- data/src/analyze/invalid_structures.c +5 -5
- data/src/analyze/missing_end.c +2 -2
- data/src/analyze/parse_errors.c +5 -5
- data/src/analyze/prism_annotate.c +7 -7
- data/src/analyze/render_nodes.c +6 -26
- data/src/analyze/strict_locals.c +637 -0
- data/src/analyze/transform.c +7 -0
- data/src/{ast_node.c → ast/ast_node.c} +8 -8
- data/src/{ast_nodes.c → ast/ast_nodes.c} +82 -11
- data/src/{ast_pretty_print.c → ast/ast_pretty_print.c} +113 -9
- data/src/{pretty_print.c → ast/pretty_print.c} +9 -9
- data/src/errors.c +398 -8
- data/src/extract.c +5 -5
- data/src/herb.c +15 -5
- data/src/include/analyze/action_view/attribute_extraction_helpers.h +3 -1
- data/src/include/analyze/action_view/tag_helper_handler.h +3 -3
- data/src/include/analyze/action_view/tag_helper_node_builders.h +34 -5
- data/src/include/analyze/action_view/tag_helpers.h +4 -3
- data/src/include/analyze/analyze.h +6 -4
- data/src/include/analyze/analyzed_ruby.h +2 -2
- data/src/include/analyze/builders.h +4 -4
- data/src/include/analyze/conditional_elements.h +2 -2
- data/src/include/analyze/conditional_open_tags.h +2 -2
- data/src/include/analyze/control_type.h +1 -1
- data/src/include/analyze/helpers.h +2 -2
- data/src/include/analyze/invalid_structures.h +1 -1
- data/src/include/analyze/prism_annotate.h +2 -2
- data/src/include/analyze/render_nodes.h +1 -1
- data/src/include/analyze/strict_locals.h +11 -0
- data/src/include/{ast_node.h → ast/ast_node.h} +4 -4
- data/src/include/{ast_nodes.h → ast/ast_nodes.h} +38 -14
- data/src/include/{ast_pretty_print.h → ast/ast_pretty_print.h} +3 -3
- data/src/include/{pretty_print.h → ast/pretty_print.h} +4 -4
- data/src/include/errors.h +65 -7
- data/src/include/extract.h +2 -2
- data/src/include/herb.h +5 -5
- data/src/include/{lex_helpers.h → lexer/lex_helpers.h} +5 -5
- data/src/include/{lexer.h → lexer/lexer.h} +1 -1
- data/src/include/{lexer_peek_helpers.h → lexer/lexer_peek_helpers.h} +2 -2
- data/src/include/{lexer_struct.h → lexer/lexer_struct.h} +2 -2
- data/src/include/{token.h → lexer/token.h} +3 -3
- data/src/include/{token_matchers.h → lexer/token_matchers.h} +1 -1
- data/src/include/{token_struct.h → lexer/token_struct.h} +3 -3
- data/src/include/{util → lib}/hb_foreach.h +1 -1
- data/src/include/{util → lib}/hb_string.h +5 -1
- data/src/include/{location.h → location/location.h} +1 -1
- data/src/include/parser/dot_notation.h +12 -0
- data/src/include/{parser.h → parser/parser.h} +11 -4
- data/src/include/{parser_helpers.h → parser/parser_helpers.h} +6 -6
- data/src/include/{prism_context.h → prism/prism_context.h} +2 -2
- data/src/include/{prism_helpers.h → prism/prism_helpers.h} +6 -6
- data/src/include/{html_util.h → util/html_util.h} +2 -1
- data/src/include/util/ruby_util.h +9 -0
- data/src/include/{utf8.h → util/utf8.h} +1 -1
- data/src/include/{util.h → util/util.h} +1 -1
- data/src/include/version.h +1 -1
- data/src/include/visitor.h +3 -3
- data/src/{lexer_peek_helpers.c → lexer/lexer_peek_helpers.c} +3 -3
- data/src/{token.c → lexer/token.c} +8 -8
- data/src/{token_matchers.c → lexer/token_matchers.c} +2 -2
- data/src/lexer.c +6 -6
- data/src/{util → lib}/hb_allocator.c +2 -2
- data/src/{util → lib}/hb_arena.c +4 -8
- data/src/{util → lib}/hb_arena_debug.c +2 -2
- data/src/{util → lib}/hb_array.c +2 -2
- data/src/{util → lib}/hb_buffer.c +2 -2
- data/src/{util → lib}/hb_narray.c +1 -1
- data/src/{util → lib}/hb_string.c +2 -2
- data/src/{location.c → location/location.c} +2 -2
- data/src/{position.c → location/position.c} +2 -2
- data/src/{range.c → location/range.c} +1 -1
- data/src/main.c +11 -11
- data/src/parser/dot_notation.c +100 -0
- data/src/{parser_match_tags.c → parser/match_tags.c} +34 -5
- data/src/{parser_helpers.c → parser/parser_helpers.c} +10 -10
- data/src/parser.c +68 -32
- data/src/{prism_helpers.c → prism/prism_helpers.c} +7 -7
- data/src/{ruby_parser.c → prism/ruby_parser.c} +1 -1
- data/src/{html_util.c → util/html_util.c} +54 -4
- data/src/{io.c → util/io.c} +3 -3
- data/src/util/ruby_util.c +42 -0
- data/src/{utf8.c → util/utf8.c} +2 -2
- data/src/{util.c → util/util.c} +4 -4
- data/src/visitor.c +35 -3
- data/templates/ext/herb/error_helpers.c.erb +2 -2
- data/templates/ext/herb/nodes.c.erb +1 -1
- data/templates/java/error_helpers.c.erb +1 -1
- data/templates/java/error_helpers.h.erb +2 -2
- data/templates/java/nodes.c.erb +4 -4
- data/templates/java/nodes.h.erb +1 -1
- data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +4 -4
- data/templates/javascript/packages/node/extension/nodes.cpp.erb +4 -4
- data/templates/lib/herb/visitor.rb.erb +14 -0
- data/templates/src/analyze/missing_end.c.erb +2 -2
- data/templates/src/{ast_nodes.c.erb → ast/ast_nodes.c.erb} +9 -9
- data/templates/src/{ast_pretty_print.c.erb → ast/ast_pretty_print.c.erb} +8 -8
- data/templates/src/errors.c.erb +8 -8
- data/templates/src/include/{ast_nodes.h.erb → ast/ast_nodes.h.erb} +11 -12
- data/templates/src/include/{ast_pretty_print.h.erb → ast/ast_pretty_print.h.erb} +2 -2
- data/templates/src/include/errors.h.erb +7 -7
- data/templates/src/{parser_match_tags.c.erb → parser/match_tags.c.erb} +4 -4
- data/templates/src/visitor.c.erb +3 -3
- data/templates/wasm/error_helpers.cpp.erb +4 -4
- data/templates/wasm/nodes.cpp.erb +5 -5
- metadata +78 -68
- data/src/include/element_source.h +0 -10
- /data/src/include/{util → lib}/hb_allocator.h +0 -0
- /data/src/include/{util → lib}/hb_arena.h +0 -0
- /data/src/include/{util → lib}/hb_arena_debug.h +0 -0
- /data/src/include/{util → lib}/hb_array.h +0 -0
- /data/src/include/{util → lib}/hb_buffer.h +0 -0
- /data/src/include/{util → lib}/hb_narray.h +0 -0
- /data/src/include/{util → lib}/string.h +0 -0
- /data/src/include/{position.h → location/position.h} +0 -0
- /data/src/include/{range.h → location/range.h} +0 -0
- /data/src/include/{herb_prism_node.h → prism/herb_prism_node.h} +0 -0
- /data/src/include/{prism_serialized.h → prism/prism_serialized.h} +0 -0
- /data/src/include/{ruby_parser.h → prism/ruby_parser.h} +0 -0
- /data/src/include/{io.h → util/io.h} +0 -0
- /data/templates/src/include/{util → lib}/hb_foreach.h.erb +0 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#include "../../include/analyze/action_view/tag_helper_handler.h"
|
|
2
|
+
#include "../../include/lib/hb_buffer.h"
|
|
3
|
+
|
|
4
|
+
#include <prism.h>
|
|
5
|
+
#include <stdbool.h>
|
|
6
|
+
#include <stdlib.h>
|
|
7
|
+
#include <string.h>
|
|
8
|
+
|
|
9
|
+
bool detect_javascript_include_tag(pm_call_node_t* call_node, pm_parser_t* parser) {
|
|
10
|
+
if (!call_node || !call_node->name) { return false; }
|
|
11
|
+
|
|
12
|
+
pm_constant_t* constant = pm_constant_pool_id_to_constant(&parser->constant_pool, call_node->name);
|
|
13
|
+
return constant && constant->length == 22
|
|
14
|
+
&& strncmp((const char*) constant->start, "javascript_include_tag", 22) == 0;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
char* extract_javascript_include_tag_name(pm_call_node_t* call_node, pm_parser_t* parser, hb_allocator_T* allocator) {
|
|
18
|
+
(void) call_node;
|
|
19
|
+
(void) parser;
|
|
20
|
+
|
|
21
|
+
return hb_allocator_strdup(allocator, "script");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
char* extract_javascript_include_tag_content(
|
|
25
|
+
pm_call_node_t* call_node,
|
|
26
|
+
pm_parser_t* parser,
|
|
27
|
+
hb_allocator_T* allocator
|
|
28
|
+
) {
|
|
29
|
+
(void) call_node;
|
|
30
|
+
(void) parser;
|
|
31
|
+
(void) allocator;
|
|
32
|
+
|
|
33
|
+
return NULL;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
char* extract_javascript_include_tag_src(pm_call_node_t* call_node, pm_parser_t* parser, hb_allocator_T* allocator) {
|
|
37
|
+
(void) parser;
|
|
38
|
+
|
|
39
|
+
if (!call_node || !call_node->arguments) { return NULL; }
|
|
40
|
+
|
|
41
|
+
pm_arguments_node_t* arguments = call_node->arguments;
|
|
42
|
+
if (!arguments->arguments.size) { return NULL; }
|
|
43
|
+
|
|
44
|
+
pm_node_t* first_argument = arguments->arguments.nodes[0];
|
|
45
|
+
|
|
46
|
+
if (first_argument->type == PM_STRING_NODE) {
|
|
47
|
+
pm_string_node_t* string_node = (pm_string_node_t*) first_argument;
|
|
48
|
+
size_t length = pm_string_length(&string_node->unescaped);
|
|
49
|
+
|
|
50
|
+
return hb_allocator_strndup(allocator, (const char*) pm_string_source(&string_node->unescaped), length);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
size_t source_length = first_argument->location.end - first_argument->location.start;
|
|
54
|
+
return hb_allocator_strndup(allocator, (const char*) first_argument->location.start, source_length);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
bool javascript_include_tag_source_is_url(const char* source, size_t length) {
|
|
58
|
+
if (!source || length == 0) { return false; }
|
|
59
|
+
|
|
60
|
+
if (length >= 2 && source[0] == '/' && source[1] == '/') { return true; }
|
|
61
|
+
if (strstr(source, "://") != NULL) { return true; }
|
|
62
|
+
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
char* wrap_in_javascript_path(
|
|
67
|
+
const char* source,
|
|
68
|
+
size_t source_length,
|
|
69
|
+
const char* path_options,
|
|
70
|
+
hb_allocator_T* allocator
|
|
71
|
+
) {
|
|
72
|
+
hb_buffer_T buffer;
|
|
73
|
+
hb_buffer_init(&buffer, source_length + 32, allocator);
|
|
74
|
+
|
|
75
|
+
hb_buffer_append(&buffer, "javascript_path(");
|
|
76
|
+
hb_buffer_append_with_length(&buffer, source, source_length);
|
|
77
|
+
|
|
78
|
+
if (path_options && strlen(path_options) > 0) {
|
|
79
|
+
hb_buffer_append(&buffer, ", ");
|
|
80
|
+
hb_buffer_append(&buffer, path_options);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
hb_buffer_append(&buffer, ")");
|
|
84
|
+
|
|
85
|
+
char* result = hb_allocator_strdup(allocator, hb_buffer_value(&buffer));
|
|
86
|
+
hb_buffer_free(&buffer);
|
|
87
|
+
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
bool javascript_include_tag_supports_block(void) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const tag_helper_handler_T javascript_include_tag_handler = {
|
|
96
|
+
.name = "javascript_include_tag",
|
|
97
|
+
.source = HB_STRING_LITERAL("ActionView::Helpers::AssetTagHelper#javascript_include_tag"),
|
|
98
|
+
.detect = detect_javascript_include_tag,
|
|
99
|
+
.extract_tag_name = extract_javascript_include_tag_name,
|
|
100
|
+
.extract_content = extract_javascript_include_tag_content,
|
|
101
|
+
.supports_block = javascript_include_tag_supports_block
|
|
102
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#include "../../include/analyze/action_view/tag_helper_handler.h"
|
|
2
|
+
|
|
3
|
+
#include <prism.h>
|
|
4
|
+
#include <stdbool.h>
|
|
5
|
+
#include <stdlib.h>
|
|
6
|
+
#include <string.h>
|
|
7
|
+
|
|
8
|
+
bool detect_javascript_tag(pm_call_node_t* call_node, pm_parser_t* parser) {
|
|
9
|
+
if (!call_node || !call_node->name) { return false; }
|
|
10
|
+
|
|
11
|
+
pm_constant_t* constant = pm_constant_pool_id_to_constant(&parser->constant_pool, call_node->name);
|
|
12
|
+
return constant && constant->length == 14 && strncmp((const char*) constant->start, "javascript_tag", 14) == 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
char* extract_javascript_tag_name(pm_call_node_t* call_node, pm_parser_t* parser, hb_allocator_T* allocator) {
|
|
16
|
+
(void) call_node;
|
|
17
|
+
(void) parser;
|
|
18
|
+
|
|
19
|
+
return hb_allocator_strdup(allocator, "script");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
char* extract_javascript_tag_content(pm_call_node_t* call_node, pm_parser_t* parser, hb_allocator_T* allocator) {
|
|
23
|
+
(void) parser;
|
|
24
|
+
|
|
25
|
+
if (!call_node || !call_node->arguments) { return NULL; }
|
|
26
|
+
|
|
27
|
+
pm_arguments_node_t* arguments = call_node->arguments;
|
|
28
|
+
if (!arguments->arguments.size) { return NULL; }
|
|
29
|
+
|
|
30
|
+
pm_node_t* first_argument = arguments->arguments.nodes[0];
|
|
31
|
+
|
|
32
|
+
if (first_argument->type == PM_KEYWORD_HASH_NODE) { return NULL; }
|
|
33
|
+
|
|
34
|
+
if (first_argument->type == PM_STRING_NODE) {
|
|
35
|
+
pm_string_node_t* string_node = (pm_string_node_t*) first_argument;
|
|
36
|
+
size_t length = pm_string_length(&string_node->unescaped);
|
|
37
|
+
return hb_allocator_strndup(allocator, (const char*) pm_string_source(&string_node->unescaped), length);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
size_t source_length = first_argument->location.end - first_argument->location.start;
|
|
41
|
+
return hb_allocator_strndup(allocator, (const char*) first_argument->location.start, source_length);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
bool javascript_tag_supports_block(void) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const tag_helper_handler_T javascript_tag_handler = {
|
|
49
|
+
.name = "javascript_tag",
|
|
50
|
+
.source = HB_STRING_LITERAL("ActionView::Helpers::JavaScriptHelper#javascript_tag"),
|
|
51
|
+
.detect = detect_javascript_tag,
|
|
52
|
+
.extract_tag_name = extract_javascript_tag_name,
|
|
53
|
+
.extract_content = extract_javascript_tag_content,
|
|
54
|
+
.supports_block = javascript_tag_supports_block
|
|
55
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#include "../../include/analyze/action_view/tag_helper_handler.h"
|
|
2
|
-
#include "../../include/
|
|
2
|
+
#include "../../include/lib/hb_allocator.h"
|
|
3
3
|
|
|
4
4
|
#include <stdbool.h>
|
|
5
5
|
#include <stdlib.h>
|
|
@@ -8,8 +8,11 @@ extern const tag_helper_handler_T content_tag_handler;
|
|
|
8
8
|
extern const tag_helper_handler_T tag_dot_handler;
|
|
9
9
|
extern const tag_helper_handler_T link_to_handler;
|
|
10
10
|
extern const tag_helper_handler_T turbo_frame_tag_handler;
|
|
11
|
+
extern const tag_helper_handler_T javascript_tag_handler;
|
|
12
|
+
extern const tag_helper_handler_T javascript_include_tag_handler;
|
|
13
|
+
extern const tag_helper_handler_T image_tag_handler;
|
|
11
14
|
|
|
12
|
-
static size_t handlers_count =
|
|
15
|
+
static size_t handlers_count = 7;
|
|
13
16
|
|
|
14
17
|
tag_helper_info_T* tag_helper_info_init(hb_allocator_T* allocator) {
|
|
15
18
|
tag_helper_info_T* info = hb_allocator_alloc(allocator, sizeof(tag_helper_info_T));
|
|
@@ -41,7 +44,7 @@ void tag_helper_info_free(tag_helper_info_T** info) {
|
|
|
41
44
|
}
|
|
42
45
|
|
|
43
46
|
tag_helper_handler_T* get_tag_helper_handlers(void) {
|
|
44
|
-
static tag_helper_handler_T static_handlers[
|
|
47
|
+
static tag_helper_handler_T static_handlers[7];
|
|
45
48
|
static bool initialized = false;
|
|
46
49
|
|
|
47
50
|
if (!initialized) {
|
|
@@ -49,6 +52,10 @@ tag_helper_handler_T* get_tag_helper_handlers(void) {
|
|
|
49
52
|
static_handlers[1] = tag_dot_handler;
|
|
50
53
|
static_handlers[2] = link_to_handler;
|
|
51
54
|
static_handlers[3] = turbo_frame_tag_handler;
|
|
55
|
+
static_handlers[4] = javascript_tag_handler;
|
|
56
|
+
static_handlers[5] = javascript_include_tag_handler;
|
|
57
|
+
static_handlers[6] = image_tag_handler;
|
|
58
|
+
|
|
52
59
|
initialized = true;
|
|
53
60
|
}
|
|
54
61
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#include "../../include/analyze/action_view/tag_helper_handler.h"
|
|
2
|
+
#include "../../include/util/ruby_util.h"
|
|
2
3
|
|
|
3
4
|
#include <prism.h>
|
|
4
5
|
#include <stdbool.h>
|
|
@@ -23,6 +24,10 @@ char* extract_tag_dot_name(pm_call_node_t* call_node, pm_parser_t* parser, hb_al
|
|
|
23
24
|
pm_constant_t* constant = pm_constant_pool_id_to_constant(&parser->constant_pool, call_node->name);
|
|
24
25
|
if (!constant) { return NULL; }
|
|
25
26
|
|
|
27
|
+
if (is_ruby_introspection_method(hb_string_from_data((const char*) constant->start, constant->length))) {
|
|
28
|
+
return NULL;
|
|
29
|
+
}
|
|
30
|
+
|
|
26
31
|
char* name = hb_allocator_strndup(allocator, (const char*) constant->start, constant->length);
|
|
27
32
|
|
|
28
33
|
for (size_t i = 0; i < constant->length && name[i] != '\0'; i++) {
|
|
@@ -34,10 +39,17 @@ char* extract_tag_dot_name(pm_call_node_t* call_node, pm_parser_t* parser, hb_al
|
|
|
34
39
|
|
|
35
40
|
// TODO: this should probably be an array of nodes
|
|
36
41
|
char* extract_tag_dot_content(pm_call_node_t* call_node, pm_parser_t* parser, hb_allocator_T* allocator) {
|
|
37
|
-
(void) parser;
|
|
38
|
-
|
|
39
42
|
if (!call_node) { return NULL; }
|
|
40
43
|
|
|
44
|
+
if (call_node->name) {
|
|
45
|
+
pm_constant_t* constant = pm_constant_pool_id_to_constant(&parser->constant_pool, call_node->name);
|
|
46
|
+
|
|
47
|
+
if (constant
|
|
48
|
+
&& is_ruby_introspection_method(hb_string_from_data((const char*) constant->start, constant->length))) {
|
|
49
|
+
return NULL;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
41
53
|
char* block_content = extract_inline_block_content(call_node, allocator);
|
|
42
54
|
if (block_content) { return block_content; }
|
|
43
55
|
|
|
@@ -47,11 +59,16 @@ char* extract_tag_dot_content(pm_call_node_t* call_node, pm_parser_t* parser, hb
|
|
|
47
59
|
if (arguments->arguments.size) {
|
|
48
60
|
pm_node_t* first_argument = arguments->arguments.nodes[0];
|
|
49
61
|
|
|
62
|
+
if (first_argument->type == PM_KEYWORD_HASH_NODE) { return NULL; }
|
|
63
|
+
|
|
50
64
|
if (first_argument->type == PM_STRING_NODE) {
|
|
51
65
|
pm_string_node_t* string_node = (pm_string_node_t*) first_argument;
|
|
52
66
|
size_t length = pm_string_length(&string_node->unescaped);
|
|
53
67
|
return hb_allocator_strndup(allocator, (const char*) pm_string_source(&string_node->unescaped), length);
|
|
54
68
|
}
|
|
69
|
+
|
|
70
|
+
size_t source_length = first_argument->location.end - first_argument->location.start;
|
|
71
|
+
return hb_allocator_strndup(allocator, (const char*) first_argument->location.start, source_length);
|
|
55
72
|
}
|
|
56
73
|
}
|
|
57
74
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#include "../../include/analyze/action_view/tag_helper_node_builders.h"
|
|
2
|
-
#include "../../include/ast_nodes.h"
|
|
3
|
-
#include "../../include/
|
|
4
|
-
#include "../../include/
|
|
5
|
-
#include "../../include/
|
|
6
|
-
#include "../../include/
|
|
7
|
-
#include "../../include/
|
|
8
|
-
#include "../../include/
|
|
9
|
-
#include "../../include/
|
|
2
|
+
#include "../../include/ast/ast_nodes.h"
|
|
3
|
+
#include "../../include/lexer/token_struct.h"
|
|
4
|
+
#include "../../include/lib/hb_allocator.h"
|
|
5
|
+
#include "../../include/lib/hb_array.h"
|
|
6
|
+
#include "../../include/lib/hb_string.h"
|
|
7
|
+
#include "../../include/location/location.h"
|
|
8
|
+
#include "../../include/location/position.h"
|
|
9
|
+
#include "../../include/location/range.h"
|
|
10
10
|
|
|
11
11
|
#include <prism.h>
|
|
12
12
|
#include <stdbool.h>
|
|
@@ -26,7 +26,7 @@ token_T* create_synthetic_token(
|
|
|
26
26
|
if (value) {
|
|
27
27
|
size_t length = strlen(value);
|
|
28
28
|
char* copied = hb_allocator_strndup(allocator, value, length);
|
|
29
|
-
token->value = (
|
|
29
|
+
token->value = hb_string_from_data(copied, length);
|
|
30
30
|
} else {
|
|
31
31
|
token->value = HB_STRING_EMPTY;
|
|
32
32
|
}
|
|
@@ -76,32 +76,47 @@ hb_array_T* prepend_attribute(hb_array_T* attributes, AST_NODE_T* attribute, hb_
|
|
|
76
76
|
return new_attributes;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
AST_HTML_ATTRIBUTE_NODE_T*
|
|
79
|
+
AST_HTML_ATTRIBUTE_NODE_T* create_html_attribute_node_precise(
|
|
80
80
|
const char* name_string,
|
|
81
81
|
const char* value_string,
|
|
82
|
-
|
|
83
|
-
position_T end_position,
|
|
82
|
+
attribute_positions_T* positions,
|
|
84
83
|
hb_allocator_T* allocator
|
|
85
84
|
) {
|
|
86
85
|
if (!name_string) { return NULL; }
|
|
87
86
|
|
|
88
87
|
AST_HTML_ATTRIBUTE_NAME_NODE_T* name_node =
|
|
89
|
-
create_attribute_name_node(name_string,
|
|
88
|
+
create_attribute_name_node(name_string, positions->name_start, positions->name_end, allocator);
|
|
89
|
+
|
|
90
|
+
token_T* equals_token = value_string ? create_synthetic_token(
|
|
91
|
+
allocator,
|
|
92
|
+
positions->separator_string,
|
|
93
|
+
positions->separator_type,
|
|
94
|
+
positions->separator_start,
|
|
95
|
+
positions->separator_end
|
|
96
|
+
)
|
|
97
|
+
: NULL;
|
|
90
98
|
|
|
91
|
-
token_T* equals_token = create_synthetic_token(allocator, "=", TOKEN_EQUALS, start_position, end_position);
|
|
92
99
|
AST_HTML_ATTRIBUTE_VALUE_NODE_T* value_node = NULL;
|
|
93
100
|
|
|
94
101
|
if (value_string) {
|
|
95
|
-
token_T* open_quote =
|
|
96
|
-
|
|
102
|
+
token_T* open_quote =
|
|
103
|
+
positions->quoted
|
|
104
|
+
? create_synthetic_token(allocator, "\"", TOKEN_QUOTE, positions->value_start, positions->content_start)
|
|
105
|
+
: NULL;
|
|
106
|
+
|
|
107
|
+
token_T* close_quote =
|
|
108
|
+
positions->quoted
|
|
109
|
+
? create_synthetic_token(allocator, "\"", TOKEN_QUOTE, positions->content_end, positions->value_end)
|
|
110
|
+
: NULL;
|
|
97
111
|
|
|
98
112
|
AST_LITERAL_NODE_T* value_literal = ast_literal_node_init(
|
|
99
113
|
hb_string_from_c_string(value_string),
|
|
100
|
-
|
|
101
|
-
|
|
114
|
+
positions->content_start,
|
|
115
|
+
positions->content_end,
|
|
102
116
|
hb_array_init(0, allocator),
|
|
103
117
|
allocator
|
|
104
118
|
);
|
|
119
|
+
|
|
105
120
|
hb_array_T* value_children = hb_array_init(1, allocator);
|
|
106
121
|
hb_array_append(value_children, (AST_NODE_T*) value_literal);
|
|
107
122
|
|
|
@@ -109,43 +124,50 @@ AST_HTML_ATTRIBUTE_NODE_T* create_html_attribute_node(
|
|
|
109
124
|
open_quote,
|
|
110
125
|
value_children,
|
|
111
126
|
close_quote,
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
127
|
+
positions->quoted,
|
|
128
|
+
positions->value_start,
|
|
129
|
+
positions->value_end,
|
|
115
130
|
hb_array_init(0, allocator),
|
|
116
131
|
allocator
|
|
117
132
|
);
|
|
118
133
|
}
|
|
119
134
|
|
|
135
|
+
position_T attribute_end = value_string ? positions->value_end : positions->name_end;
|
|
136
|
+
|
|
120
137
|
return ast_html_attribute_node_init(
|
|
121
138
|
name_node,
|
|
122
139
|
equals_token,
|
|
123
140
|
value_node,
|
|
124
|
-
|
|
125
|
-
|
|
141
|
+
positions->name_start,
|
|
142
|
+
attribute_end,
|
|
126
143
|
hb_array_init(0, allocator),
|
|
127
144
|
allocator
|
|
128
145
|
);
|
|
129
146
|
}
|
|
130
147
|
|
|
131
|
-
AST_HTML_ATTRIBUTE_NODE_T*
|
|
148
|
+
AST_HTML_ATTRIBUTE_NODE_T* create_html_attribute_with_ruby_literal_precise(
|
|
132
149
|
const char* name_string,
|
|
133
150
|
const char* ruby_content,
|
|
134
|
-
|
|
135
|
-
position_T end_position,
|
|
151
|
+
attribute_positions_T* positions,
|
|
136
152
|
hb_allocator_T* allocator
|
|
137
153
|
) {
|
|
138
154
|
if (!name_string || !ruby_content) { return NULL; }
|
|
139
155
|
|
|
140
156
|
AST_HTML_ATTRIBUTE_NAME_NODE_T* name_node =
|
|
141
|
-
create_attribute_name_node(name_string,
|
|
142
|
-
|
|
143
|
-
token_T* equals_token = create_synthetic_token(
|
|
157
|
+
create_attribute_name_node(name_string, positions->name_start, positions->name_end, allocator);
|
|
158
|
+
|
|
159
|
+
token_T* equals_token = create_synthetic_token(
|
|
160
|
+
allocator,
|
|
161
|
+
positions->separator_string,
|
|
162
|
+
positions->separator_type,
|
|
163
|
+
positions->separator_start,
|
|
164
|
+
positions->separator_end
|
|
165
|
+
);
|
|
144
166
|
|
|
145
167
|
AST_RUBY_LITERAL_NODE_T* ruby_node = ast_ruby_literal_node_init(
|
|
146
168
|
hb_string_from_c_string(ruby_content),
|
|
147
|
-
|
|
148
|
-
|
|
169
|
+
positions->content_start,
|
|
170
|
+
positions->content_end,
|
|
149
171
|
hb_array_init(0, allocator),
|
|
150
172
|
allocator
|
|
151
173
|
);
|
|
@@ -158,8 +180,8 @@ AST_HTML_ATTRIBUTE_NODE_T* create_html_attribute_with_ruby_literal(
|
|
|
158
180
|
value_children,
|
|
159
181
|
NULL,
|
|
160
182
|
false,
|
|
161
|
-
|
|
162
|
-
|
|
183
|
+
positions->content_start,
|
|
184
|
+
positions->content_end,
|
|
163
185
|
hb_array_init(0, allocator),
|
|
164
186
|
allocator
|
|
165
187
|
);
|
|
@@ -168,13 +190,61 @@ AST_HTML_ATTRIBUTE_NODE_T* create_html_attribute_with_ruby_literal(
|
|
|
168
190
|
name_node,
|
|
169
191
|
equals_token,
|
|
170
192
|
value_node,
|
|
171
|
-
|
|
172
|
-
|
|
193
|
+
positions->name_start,
|
|
194
|
+
positions->content_end,
|
|
173
195
|
hb_array_init(0, allocator),
|
|
174
196
|
allocator
|
|
175
197
|
);
|
|
176
198
|
}
|
|
177
199
|
|
|
200
|
+
AST_HTML_ATTRIBUTE_NODE_T* create_html_attribute_node(
|
|
201
|
+
const char* name_string,
|
|
202
|
+
const char* value_string,
|
|
203
|
+
position_T start_position,
|
|
204
|
+
position_T end_position,
|
|
205
|
+
hb_allocator_T* allocator
|
|
206
|
+
) {
|
|
207
|
+
attribute_positions_T positions = {
|
|
208
|
+
.name_start = start_position,
|
|
209
|
+
.name_end = end_position,
|
|
210
|
+
.separator_string = "=",
|
|
211
|
+
.separator_type = TOKEN_EQUALS,
|
|
212
|
+
.separator_start = start_position,
|
|
213
|
+
.separator_end = end_position,
|
|
214
|
+
.value_start = start_position,
|
|
215
|
+
.value_end = end_position,
|
|
216
|
+
.content_start = start_position,
|
|
217
|
+
.content_end = end_position,
|
|
218
|
+
.quoted = true,
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
return create_html_attribute_node_precise(name_string, value_string, &positions, allocator);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
AST_HTML_ATTRIBUTE_NODE_T* create_html_attribute_with_ruby_literal(
|
|
225
|
+
const char* name_string,
|
|
226
|
+
const char* ruby_content,
|
|
227
|
+
position_T start_position,
|
|
228
|
+
position_T end_position,
|
|
229
|
+
hb_allocator_T* allocator
|
|
230
|
+
) {
|
|
231
|
+
attribute_positions_T positions = {
|
|
232
|
+
.name_start = start_position,
|
|
233
|
+
.name_end = end_position,
|
|
234
|
+
.separator_string = ":",
|
|
235
|
+
.separator_type = TOKEN_COLON,
|
|
236
|
+
.separator_start = start_position,
|
|
237
|
+
.separator_end = end_position,
|
|
238
|
+
.value_start = start_position,
|
|
239
|
+
.value_end = end_position,
|
|
240
|
+
.content_start = start_position,
|
|
241
|
+
.content_end = end_position,
|
|
242
|
+
.quoted = false,
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
return create_html_attribute_with_ruby_literal_precise(name_string, ruby_content, &positions, allocator);
|
|
246
|
+
}
|
|
247
|
+
|
|
178
248
|
static AST_HTML_ATTRIBUTE_VALUE_NODE_T* create_interpolated_attribute_value(
|
|
179
249
|
pm_interpolated_string_node_t* interpolated_node,
|
|
180
250
|
position_T start_position,
|
|
@@ -210,8 +280,20 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* create_interpolated_attribute_value(
|
|
|
210
280
|
}
|
|
211
281
|
}
|
|
212
282
|
} else if (part->type == PM_EMBEDDED_STATEMENTS_NODE) {
|
|
213
|
-
|
|
214
|
-
|
|
283
|
+
pm_embedded_statements_node_t* embedded = (pm_embedded_statements_node_t*) part;
|
|
284
|
+
const uint8_t* content_start;
|
|
285
|
+
const uint8_t* content_end;
|
|
286
|
+
|
|
287
|
+
if (embedded->statements) {
|
|
288
|
+
content_start = embedded->statements->base.location.start;
|
|
289
|
+
content_end = embedded->statements->base.location.end;
|
|
290
|
+
} else {
|
|
291
|
+
content_start = part->location.start;
|
|
292
|
+
content_end = part->location.end;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
size_t ruby_length = content_end - content_start;
|
|
296
|
+
char* ruby_content = hb_allocator_strndup(allocator, (const char*) content_start, ruby_length);
|
|
215
297
|
|
|
216
298
|
if (ruby_content) {
|
|
217
299
|
AST_RUBY_LITERAL_NODE_T* ruby_node = ast_ruby_literal_node_init(
|