herb 0.11.0-arm-linux-gnu → 0.11.2-arm-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/Rakefile +4 -2
- data/config.yml +9 -0
- data/ext/herb/extconf.rb +8 -31
- data/ext/herb/nodes.c +90 -73
- data/ext/herb/parser_options_helpers.c +26 -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/analysis/partial_index.rb +1 -1
- data/lib/herb/analysis/partial_resolution.rb +27 -0
- data/lib/herb/ast/helpers.rb +1 -1
- data/lib/herb/ast/nodes.rb +32 -6
- data/lib/herb/bootstrap.rb +6 -2
- data/lib/herb/configuration.rb +11 -1
- data/lib/herb/dev/classifier.rb +1 -1
- data/lib/herb/dev/runner.rb +6 -1
- data/lib/herb/engine/compiler.rb +52 -19
- data/lib/herb/engine/slots/dynamics_compiler.rb +63 -14
- data/lib/herb/engine/slots/markers.rb +24 -0
- data/lib/herb/engine/slots/state_compiler.rb +1 -2
- data/lib/herb/engine/slots/subtree_compiler.rb +1 -1
- data/lib/herb/engine/slots/visitor.rb +71 -32
- data/lib/herb/engine/visitors/instrumentation_visitor.rb +18 -6
- data/lib/herb/engine.rb +0 -2
- data/lib/herb/parser_options.rb +6 -3
- data/lib/herb/project.rb +19 -8
- data/lib/herb/version.rb +1 -1
- data/lib/herb.rb +1 -1
- data/sig/herb/analysis/partial_resolution.rbs +8 -0
- data/sig/herb/ast/nodes.rbs +10 -4
- data/sig/herb/bootstrap.rbs +2 -0
- data/sig/herb/configuration.rbs +3 -0
- data/sig/herb/dev/runner.rbs +3 -0
- data/sig/herb/engine/compiler.rbs +14 -3
- data/sig/herb/engine/slots/dynamics_compiler.rbs +27 -7
- data/sig/herb/engine/slots/markers.rbs +14 -0
- data/sig/herb/engine/slots/visitor.rbs +31 -13
- data/sig/herb/engine/visitors/instrumentation_visitor.rbs +5 -1
- data/sig/herb/parser_options.rbs +6 -4
- data/sig/herb.rbs +2 -2
- data/sig/serialized_ast_nodes.rbs +1 -0
- data/src/analyze/action_view/attribute_extraction_helpers.c +40 -21
- data/src/analyze/action_view/generated_handlers.c +36 -36
- data/src/analyze/action_view/image_tag.c +7 -3
- data/src/analyze/action_view/javascript_include_tag.c +6 -3
- data/src/analyze/action_view/link_to.c +23 -23
- data/src/analyze/action_view/registry.c +7 -3
- data/src/analyze/action_view/tag_helper_node_builders.c +12 -16
- data/src/analyze/action_view/tag_helpers.c +215 -110
- data/src/analyze/action_view/turbo_frame_tag.c +5 -4
- data/src/analyze/analyze.c +41 -45
- data/src/analyze/analyze_helpers.c +240 -405
- data/src/analyze/analyzed_ruby.c +10 -7
- data/src/analyze/builders.c +1 -0
- data/src/analyze/control_type.c +46 -29
- data/src/analyze/herb_directives.c +16 -20
- data/src/analyze/iteration_nodes.c +69 -24
- data/src/analyze/parse_errors.c +32 -22
- data/src/analyze/postfix_conditionals.c +23 -13
- data/src/analyze/prism_annotate.c +56 -32
- data/src/analyze/render_nodes.c +51 -41
- data/src/analyze/strict_locals.c +14 -15
- data/src/analyze/ternary_conditionals.c +14 -10
- data/src/ast/ast_nodes.c +3 -1
- data/src/ast/ast_pretty_print.c +5 -1
- data/src/extract.c +204 -143
- data/src/herb.c +10 -8
- data/src/include/analyze/action_view/tag_helper_handler.h +1 -1
- data/src/include/analyze/action_view/tag_helper_node_builders.h +1 -0
- data/src/include/analyze/action_view/tag_helpers.h +1 -1
- data/src/include/analyze/analyze.h +3 -24
- data/src/include/analyze/analyzed_ruby.h +29 -2
- data/src/include/analyze/helpers.h +7 -27
- data/src/include/ast/ast_nodes.h +2 -1
- data/src/include/herb.h +3 -2
- data/src/include/lexer/lexer.h +1 -0
- data/src/include/parser/parser_options.h +5 -0
- data/src/include/prism/herb_prism_node.h +6 -1
- data/src/include/prism/prism_context.h +12 -12
- data/src/include/prism/prism_helpers.h +30 -0
- data/src/include/prism_version.h +11 -0
- data/src/include/version.h +1 -1
- data/src/lexer.c +32 -0
- data/src/parser/parser_helpers.c +1 -2
- data/src/parser.c +6 -7
- data/src/parser_options_defaults.c +1 -0
- data/src/prism/prism_helpers.c +167 -42
- data/src/prism/ruby_parser.c +20 -20
- data/templates/ext/herb/nodes.c.erb +5 -5
- data/templates/ext/herb/parser_options_helpers.c.erb +33 -0
- data/templates/java/nodes.c.erb +6 -6
- data/templates/java/parser_options_helpers.c.erb +41 -2
- data/templates/java/parser_options_helpers.h.erb +2 -1
- data/templates/javascript/packages/core/src/nodes.ts.erb +21 -1
- data/templates/javascript/packages/node/extension/nodes.cpp.erb +5 -5
- data/templates/javascript/packages/node/extension/parser_options_helpers.cpp.erb +34 -2
- data/templates/javascript/packages/node/extension/parser_options_helpers.h.erb +1 -1
- data/templates/lib/herb/parser_options.rb.erb +1 -1
- data/templates/rust/src/ast/nodes.rs.erb +1 -4
- data/templates/rust/src/prism/generated_deserialize.rs.erb +90 -44
- data/templates/rust/src/prism/generated_prettyprint.rs.erb +18 -27
- data/templates/src/analyze/action_view/generated_handlers.c.erb +23 -22
- data/templates/src/include/parser/parser_options.h.erb +10 -0
- data/templates/src/include/prism_version.h.erb +17 -0
- data/templates/src/parser_options_defaults.c.erb +1 -1
- data/templates/template.rb +17 -2
- data/templates/wasm/nodes.cpp.erb +8 -18
- data/templates/wasm/parser_options_helpers.cpp.erb +24 -0
- data/vendor/prism/Rakefile +76 -7
- data/vendor/prism/config.yml +174 -161
- data/vendor/prism/include/prism/arena.h +45 -0
- data/vendor/prism/include/prism/arena.hpp +42 -0
- data/vendor/prism/include/prism/ast.h +2738 -611
- data/vendor/prism/include/prism/ast.hpp +641 -0
- data/vendor/prism/include/prism/buffer.h +60 -0
- data/vendor/prism/include/prism/buffer.hpp +55 -0
- data/vendor/prism/include/prism/comments.h +72 -0
- data/vendor/prism/include/prism/compiler/accel.h +26 -0
- data/vendor/prism/include/prism/compiler/align.h +36 -0
- data/vendor/prism/include/prism/compiler/assume.h +25 -0
- data/vendor/prism/include/prism/compiler/branch.h +26 -0
- data/vendor/prism/include/prism/compiler/bswap.h +46 -0
- data/vendor/prism/include/prism/compiler/cplusplus.hpp +16 -0
- data/vendor/prism/include/prism/compiler/endianness.h +34 -0
- data/vendor/prism/include/prism/compiler/exceptions.hpp +17 -0
- data/vendor/prism/include/prism/compiler/exported.h +24 -0
- data/vendor/prism/include/prism/compiler/fallthrough.h +22 -0
- data/vendor/prism/include/prism/compiler/filesystem.h +32 -0
- data/vendor/prism/include/prism/compiler/flex_array.h +19 -0
- data/vendor/prism/include/prism/compiler/force_inline.h +21 -0
- data/vendor/prism/include/prism/compiler/format.h +27 -0
- data/vendor/prism/include/prism/compiler/inline.h +17 -0
- data/vendor/prism/include/prism/compiler/lifetimebound.hpp +25 -0
- data/vendor/prism/include/prism/compiler/nodiscard.h +22 -0
- data/vendor/prism/include/prism/compiler/nonnull.h +18 -0
- data/vendor/prism/include/prism/compiler/unused.h +18 -0
- data/vendor/prism/include/prism/constant_pool.h +106 -0
- data/vendor/prism/include/prism/diagnostic.h +55 -402
- data/vendor/prism/include/prism/errors_format.h +61 -0
- data/vendor/prism/include/prism/excludes.h +29 -0
- data/vendor/prism/include/prism/integer.h +41 -0
- data/vendor/prism/include/prism/internal/allocator.h +68 -0
- data/vendor/prism/include/prism/internal/allocator_debug.h +88 -0
- data/vendor/prism/include/prism/internal/arena.h +108 -0
- data/vendor/prism/include/prism/internal/bit.h +42 -0
- data/vendor/prism/include/prism/internal/buffer.h +94 -0
- data/vendor/prism/include/prism/internal/char.h +145 -0
- data/vendor/prism/include/prism/internal/comments.h +54 -0
- data/vendor/prism/include/prism/internal/constant_pool.h +152 -0
- data/vendor/prism/include/prism/internal/diagnostic.h +389 -0
- data/vendor/prism/include/prism/{encoding.h → internal/encoding.h} +27 -68
- data/vendor/prism/include/prism/internal/integer.h +68 -0
- data/vendor/prism/include/prism/internal/isinf.h +16 -0
- data/vendor/prism/include/prism/internal/line_offset_list.h +34 -0
- data/vendor/prism/include/prism/{util/pm_list.h → internal/list.h} +11 -52
- data/vendor/prism/include/prism/internal/magic_comments.h +23 -0
- data/vendor/prism/include/prism/internal/memchr.h +15 -0
- data/vendor/prism/include/prism/internal/node.h +42 -0
- data/vendor/prism/include/prism/internal/options.h +232 -0
- data/vendor/prism/include/prism/internal/parser.h +1015 -0
- data/vendor/prism/include/prism/internal/regexp.h +26 -0
- data/vendor/prism/include/prism/internal/serialize.h +39 -0
- data/vendor/prism/include/prism/internal/source.h +72 -0
- data/vendor/prism/include/prism/internal/static_literals.h +60 -0
- data/vendor/prism/include/prism/internal/stringy.h +30 -0
- data/vendor/prism/include/prism/{util/pm_strncasecmp.h → internal/strncasecmp.h} +3 -17
- data/vendor/prism/include/prism/{util/pm_strpbrk.h → internal/strpbrk.h} +7 -20
- data/vendor/prism/include/prism/internal/tokens.h +11 -0
- data/vendor/prism/include/prism/internal/xxh3.h +16 -0
- data/vendor/prism/include/prism/json.h +40 -0
- data/vendor/prism/include/prism/line_offset_list.h +69 -0
- data/vendor/prism/include/prism/magic_comments.h +53 -0
- data/vendor/prism/include/prism/node.h +59 -49
- data/vendor/prism/include/prism/node.hpp +272 -0
- data/vendor/prism/include/prism/node_type.hpp +38 -0
- data/vendor/prism/include/prism/options.h +154 -279
- data/vendor/prism/include/prism/options.hpp +43 -0
- data/vendor/prism/include/prism/parser.h +367 -870
- data/vendor/prism/include/prism/parser.hpp +274 -0
- data/vendor/prism/include/prism/prettyprint.h +14 -9
- data/vendor/prism/include/prism/serialize.h +123 -0
- data/vendor/prism/include/prism/source.h +163 -0
- data/vendor/prism/include/prism/stream.h +36 -0
- data/vendor/prism/include/prism/string_query.h +82 -0
- data/vendor/prism/include/prism/stringy.h +61 -0
- data/vendor/prism/include/prism/stringy.hpp +31 -0
- data/vendor/prism/include/prism/version.h +20 -3
- data/vendor/prism/include/prism.h +35 -320
- data/vendor/prism/include/prism.hpp +24 -0
- data/vendor/prism/src/arena.c +122 -0
- data/vendor/prism/src/{util/pm_buffer.c → buffer.c} +53 -21
- data/vendor/prism/src/{util/pm_char.c → char.c} +28 -57
- data/vendor/prism/src/comments.c +455 -0
- data/vendor/prism/src/constant_pool.c +406 -0
- data/vendor/prism/src/diagnostic.c +120 -68
- data/vendor/prism/src/encoding.c +8 -3
- data/vendor/prism/src/errors_format.c +519 -0
- data/vendor/prism/src/{util/pm_integer.c → integer.c} +38 -22
- data/vendor/prism/src/json.c +5733 -0
- data/vendor/prism/src/line_offset_list.c +100 -0
- data/vendor/prism/src/list.c +24 -0
- data/vendor/prism/src/{util/pm_memchr.c → memchr.c} +8 -6
- data/vendor/prism/src/node.c +3465 -7787
- data/vendor/prism/src/options.c +161 -54
- data/vendor/prism/src/parser.c +371 -0
- data/vendor/prism/src/prettyprint.c +421 -354
- data/vendor/prism/src/prism.c +8522 -7280
- data/vendor/prism/src/regexp.c +960 -45
- data/vendor/prism/src/serialize.c +2434 -2048
- data/vendor/prism/src/source.c +524 -0
- data/vendor/prism/src/static_literals.c +303 -360
- data/vendor/prism/src/string_query.c +180 -0
- data/vendor/prism/src/stringy.c +61 -0
- data/vendor/prism/src/{util/pm_strncasecmp.c → strncasecmp.c} +5 -4
- data/vendor/prism/src/strpbrk.c +447 -0
- data/vendor/prism/src/{token_type.c → tokens.c} +39 -18
- data/vendor/prism/src/xxh3.c +292 -0
- data/vendor/prism/templates/ext/prism/api_node.c.erb +58 -44
- data/vendor/prism/templates/include/prism/ast.h.erb +67 -17
- data/vendor/prism/templates/include/prism/ast.hpp.erb +31 -0
- data/vendor/prism/templates/include/prism/internal/diagnostic.h.erb +60 -0
- data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/AbstractNodeVisitor.java.erb +1 -1
- data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/Loader.java.erb +232 -133
- data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/Nodes.java.erb +62 -23
- data/vendor/prism/templates/javascript/src/deserialize.js.erb +153 -146
- data/vendor/prism/templates/javascript/src/nodes.js.erb +4 -9
- data/vendor/prism/templates/lib/prism/compiler.rb.erb +14 -5
- data/vendor/prism/templates/lib/prism/dispatcher.rb.erb +20 -12
- data/vendor/prism/templates/lib/prism/dot_visitor.rb.erb +37 -11
- data/vendor/prism/templates/lib/prism/dsl.rb.erb +43 -4
- data/vendor/prism/templates/lib/prism/inspect_visitor.rb.erb +26 -10
- data/vendor/prism/templates/lib/prism/mutation_compiler.rb.erb +5 -2
- data/vendor/prism/templates/lib/prism/node.rb.erb +283 -105
- data/vendor/prism/templates/lib/prism/reflection.rb.erb +11 -2
- data/vendor/prism/templates/lib/prism/serialize.rb.erb +291 -134
- data/vendor/prism/templates/lib/prism/visitor.rb.erb +18 -0
- data/vendor/prism/templates/src/diagnostic.c.erb +114 -63
- data/vendor/prism/templates/src/json.c.erb +130 -0
- data/vendor/prism/templates/src/node.c.erb +79 -236
- data/vendor/prism/templates/src/prettyprint.c.erb +24 -13
- data/vendor/prism/templates/src/serialize.c.erb +369 -183
- data/vendor/prism/templates/src/{token_type.c.erb → tokens.c.erb} +22 -11
- data/vendor/prism/templates/template.rb +193 -91
- metadata +100 -42
- data/vendor/prism/include/prism/defines.h +0 -260
- data/vendor/prism/include/prism/pack.h +0 -163
- data/vendor/prism/include/prism/regexp.h +0 -43
- data/vendor/prism/include/prism/static_literals.h +0 -121
- data/vendor/prism/include/prism/util/pm_buffer.h +0 -236
- data/vendor/prism/include/prism/util/pm_char.h +0 -204
- data/vendor/prism/include/prism/util/pm_constant_pool.h +0 -218
- data/vendor/prism/include/prism/util/pm_integer.h +0 -130
- data/vendor/prism/include/prism/util/pm_memchr.h +0 -29
- data/vendor/prism/include/prism/util/pm_newline_list.h +0 -113
- data/vendor/prism/include/prism/util/pm_string.h +0 -200
- data/vendor/prism/src/pack.c +0 -509
- data/vendor/prism/src/util/pm_constant_pool.c +0 -342
- data/vendor/prism/src/util/pm_list.c +0 -49
- data/vendor/prism/src/util/pm_newline_list.c +0 -125
- data/vendor/prism/src/util/pm_string.c +0 -381
- data/vendor/prism/src/util/pm_strpbrk.c +0 -206
- data/vendor/prism/templates/include/prism/diagnostic.h.erb +0 -130
- data/vendor/prism/templates/rbi/prism/dsl.rbi.erb +0 -68
- data/vendor/prism/templates/rbi/prism/node.rbi.erb +0 -167
- data/vendor/prism/templates/rbi/prism/visitor.rbi.erb +0 -18
- data/vendor/prism/templates/sig/prism/_private/dot_visitor.rbs.erb +0 -45
- data/vendor/prism/templates/sig/prism/dsl.rbs.erb +0 -31
- data/vendor/prism/templates/sig/prism/mutation_compiler.rbs.erb +0 -7
- data/vendor/prism/templates/sig/prism/node.rbs.erb +0 -136
- data/vendor/prism/templates/sig/prism/visitor.rbs.erb +0 -17
- data/vendor/prism/templates/sig/prism.rbs.erb +0 -92
data/src/prism/prism_helpers.c
CHANGED
|
@@ -7,9 +7,47 @@
|
|
|
7
7
|
#include "../include/location/position.h"
|
|
8
8
|
|
|
9
9
|
#include <prism.h>
|
|
10
|
+
#include <prism/internal/comments.h>
|
|
11
|
+
#include <prism/internal/parser.h>
|
|
10
12
|
#include <stdlib.h>
|
|
11
13
|
#include <string.h>
|
|
12
14
|
|
|
15
|
+
bool herb_ruby_version_supported(const char* value, size_t length) {
|
|
16
|
+
if (value == NULL || length == 0 || length >= HERB_PARSER_OPTIONS_STRING_CAPACITY) { return false; }
|
|
17
|
+
|
|
18
|
+
pm_options_t* options = pm_options_new();
|
|
19
|
+
bool supported = pm_options_version_set(options, value, length);
|
|
20
|
+
pm_options_free(options);
|
|
21
|
+
|
|
22
|
+
return supported;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
void herb_prism_options_set_ruby_version(pm_options_t* options, const parser_options_T* parser_options) {
|
|
26
|
+
if (options == NULL || parser_options == NULL || parser_options->ruby_version[0] == '\0') { return; }
|
|
27
|
+
|
|
28
|
+
const char* version = parser_options->ruby_version;
|
|
29
|
+
pm_options_version_set(options, version, strnlen(version, HERB_PARSER_OPTIONS_STRING_CAPACITY));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
pm_parser_t* herb_prism_parser_new(
|
|
33
|
+
pm_arena_t* arena,
|
|
34
|
+
const uint8_t* source,
|
|
35
|
+
size_t length,
|
|
36
|
+
const parser_options_T* parser_options
|
|
37
|
+
) {
|
|
38
|
+
if (parser_options == NULL || parser_options->ruby_version[0] == '\0') {
|
|
39
|
+
return pm_parser_new(arena, source, length, NULL);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
pm_options_t* options = pm_options_new();
|
|
43
|
+
herb_prism_options_set_ruby_version(options, parser_options);
|
|
44
|
+
|
|
45
|
+
pm_parser_t* parser = pm_parser_new(arena, source, length, options);
|
|
46
|
+
pm_options_free(options);
|
|
47
|
+
|
|
48
|
+
return parser;
|
|
49
|
+
}
|
|
50
|
+
|
|
13
51
|
hb_string_T pm_error_level_to_string(pm_error_level_t level) {
|
|
14
52
|
switch (level) {
|
|
15
53
|
case PM_ERROR_LEVEL_SYNTAX: return hb_string("syntax");
|
|
@@ -25,16 +63,17 @@ RUBY_PARSE_ERROR_T* ruby_parse_error_from_prism_error(
|
|
|
25
63
|
pm_parser_t* parser,
|
|
26
64
|
hb_allocator_T* allocator
|
|
27
65
|
) {
|
|
28
|
-
|
|
29
|
-
size_t end_offset = (size_t) (error->location.end - parser->start);
|
|
66
|
+
(void) parser;
|
|
30
67
|
|
|
31
|
-
|
|
32
|
-
|
|
68
|
+
pm_location_t location = pm_diagnostic_location(error);
|
|
69
|
+
|
|
70
|
+
position_T start = position_from_source_with_offset(source, location.start);
|
|
71
|
+
position_T end = position_from_source_with_offset(source, herb_prism_location_end(location));
|
|
33
72
|
|
|
34
73
|
return ruby_parse_error_init(
|
|
35
|
-
hb_string(error
|
|
36
|
-
hb_string(
|
|
37
|
-
pm_error_level_to_string(error
|
|
74
|
+
hb_string(pm_diagnostic_message(error)),
|
|
75
|
+
hb_string(pm_diagnostic_type(error)),
|
|
76
|
+
pm_error_level_to_string(pm_diagnostic_error_level(error)),
|
|
38
77
|
start,
|
|
39
78
|
end,
|
|
40
79
|
allocator
|
|
@@ -48,9 +87,9 @@ RUBY_PARSE_ERROR_T* ruby_parse_error_from_prism_error_with_positions(
|
|
|
48
87
|
hb_allocator_T* allocator
|
|
49
88
|
) {
|
|
50
89
|
return ruby_parse_error_init(
|
|
51
|
-
hb_string(error
|
|
52
|
-
hb_string(
|
|
53
|
-
pm_error_level_to_string(error
|
|
90
|
+
hb_string(pm_diagnostic_message(error)),
|
|
91
|
+
hb_string(pm_diagnostic_type(error)),
|
|
92
|
+
pm_error_level_to_string(pm_diagnostic_error_level(error)),
|
|
54
93
|
start,
|
|
55
94
|
end,
|
|
56
95
|
allocator
|
|
@@ -62,55 +101,51 @@ typedef struct {
|
|
|
62
101
|
bool found;
|
|
63
102
|
} then_keyword_search_context_T;
|
|
64
103
|
|
|
65
|
-
static
|
|
66
|
-
return location.start != NULL && location.end != NULL && (location.end - location.start) > 0;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
static bool search_then_keyword_location(const pm_node_t* node, void* data) {
|
|
104
|
+
static pm_visit_result_t search_then_keyword_location(const pm_node_t* node, void* data) {
|
|
70
105
|
then_keyword_search_context_T* context = (then_keyword_search_context_T*) data;
|
|
71
106
|
|
|
72
|
-
if (context->found) { return
|
|
107
|
+
if (context->found) { return PM_VISIT_SKIP; }
|
|
73
108
|
|
|
74
109
|
switch (node->type) {
|
|
75
110
|
case PM_IF_NODE: {
|
|
76
111
|
const pm_if_node_t* if_node = (const pm_if_node_t*) node;
|
|
77
112
|
|
|
78
|
-
if (!
|
|
113
|
+
if (!herb_prism_location_present(if_node->if_keyword_loc)) { break; }
|
|
79
114
|
|
|
80
|
-
if (
|
|
115
|
+
if (herb_prism_location_present(if_node->then_keyword_loc)) {
|
|
81
116
|
context->then_keyword_loc = if_node->then_keyword_loc;
|
|
82
117
|
context->found = true;
|
|
83
|
-
return
|
|
118
|
+
return PM_VISIT_SKIP;
|
|
84
119
|
}
|
|
85
120
|
break;
|
|
86
121
|
}
|
|
87
122
|
|
|
88
123
|
case PM_UNLESS_NODE: {
|
|
89
124
|
const pm_unless_node_t* unless_node = (const pm_unless_node_t*) node;
|
|
90
|
-
if (
|
|
125
|
+
if (herb_prism_location_present(unless_node->then_keyword_loc)) {
|
|
91
126
|
context->then_keyword_loc = unless_node->then_keyword_loc;
|
|
92
127
|
context->found = true;
|
|
93
|
-
return
|
|
128
|
+
return PM_VISIT_SKIP;
|
|
94
129
|
}
|
|
95
130
|
break;
|
|
96
131
|
}
|
|
97
132
|
|
|
98
133
|
case PM_WHEN_NODE: {
|
|
99
134
|
const pm_when_node_t* when_node = (const pm_when_node_t*) node;
|
|
100
|
-
if (
|
|
135
|
+
if (herb_prism_location_present(when_node->then_keyword_loc)) {
|
|
101
136
|
context->then_keyword_loc = when_node->then_keyword_loc;
|
|
102
137
|
context->found = true;
|
|
103
|
-
return
|
|
138
|
+
return PM_VISIT_SKIP;
|
|
104
139
|
}
|
|
105
140
|
break;
|
|
106
141
|
}
|
|
107
142
|
|
|
108
143
|
case PM_IN_NODE: {
|
|
109
144
|
const pm_in_node_t* in_node = (const pm_in_node_t*) node;
|
|
110
|
-
if (
|
|
111
|
-
context->then_keyword_loc = in_node->
|
|
145
|
+
if (herb_prism_location_present(in_node->then_keyword_loc)) {
|
|
146
|
+
context->then_keyword_loc = in_node->then_keyword_loc;
|
|
112
147
|
context->found = true;
|
|
113
|
-
return
|
|
148
|
+
return PM_VISIT_SKIP;
|
|
114
149
|
}
|
|
115
150
|
break;
|
|
116
151
|
}
|
|
@@ -120,23 +155,20 @@ static bool search_then_keyword_location(const pm_node_t* node, void* data) {
|
|
|
120
155
|
|
|
121
156
|
pm_visit_child_nodes(node, search_then_keyword_location, context);
|
|
122
157
|
|
|
123
|
-
return
|
|
158
|
+
return PM_VISIT_SKIP;
|
|
124
159
|
}
|
|
125
160
|
|
|
126
161
|
location_T* get_then_keyword_location(analyzed_ruby_T* analyzed, const char* source, hb_allocator_T* allocator) {
|
|
127
162
|
if (analyzed == NULL || analyzed->root == NULL || source == NULL) { return NULL; }
|
|
128
163
|
|
|
129
|
-
then_keyword_search_context_T context = { .then_keyword_loc = { .start =
|
|
164
|
+
then_keyword_search_context_T context = { .then_keyword_loc = { .start = 0, .length = 0 }, .found = false };
|
|
130
165
|
|
|
131
166
|
pm_visit_child_nodes(analyzed->root, search_then_keyword_location, &context);
|
|
132
167
|
|
|
133
168
|
if (!context.found) { return NULL; }
|
|
134
169
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
position_T start_position = position_from_source_with_offset(source, start_offset);
|
|
139
|
-
position_T end_position = position_from_source_with_offset(source, end_offset);
|
|
170
|
+
position_T start_position = position_from_source_with_offset(source, context.then_keyword_loc.start);
|
|
171
|
+
position_T end_position = position_from_source_with_offset(source, herb_prism_location_end(context.then_keyword_loc));
|
|
140
172
|
|
|
141
173
|
return location_create(start_position, end_position, allocator);
|
|
142
174
|
}
|
|
@@ -150,25 +182,26 @@ static location_T* parse_wrapped_and_find_then_keyword(
|
|
|
150
182
|
size_t adjustment_amount,
|
|
151
183
|
hb_allocator_T* allocator
|
|
152
184
|
) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
pm_node_t* root = pm_parse(
|
|
185
|
+
pm_arena_t* arena = pm_arena_new();
|
|
186
|
+
pm_parser_t* parser = pm_parser_new(arena, (const uint8_t*) hb_buffer_value(buffer), hb_buffer_length(buffer), NULL);
|
|
187
|
+
pm_node_t* root = pm_parse(parser);
|
|
156
188
|
|
|
157
189
|
if (root == NULL) {
|
|
158
|
-
pm_parser_free(
|
|
190
|
+
pm_parser_free(parser);
|
|
191
|
+
pm_arena_free(arena);
|
|
159
192
|
|
|
160
193
|
return NULL;
|
|
161
194
|
}
|
|
162
195
|
|
|
163
|
-
then_keyword_search_context_T context = { .then_keyword_loc = { .start =
|
|
196
|
+
then_keyword_search_context_T context = { .then_keyword_loc = { .start = 0, .length = 0 }, .found = false };
|
|
164
197
|
|
|
165
198
|
pm_visit_child_nodes(root, search_then_keyword_location, &context);
|
|
166
199
|
|
|
167
200
|
location_T* location = NULL;
|
|
168
201
|
|
|
169
202
|
if (context.found) {
|
|
170
|
-
size_t start_offset =
|
|
171
|
-
size_t end_offset = (
|
|
203
|
+
size_t start_offset = context.then_keyword_loc.start;
|
|
204
|
+
size_t end_offset = herb_prism_location_end(context.then_keyword_loc);
|
|
172
205
|
|
|
173
206
|
if (start_offset >= prefix_length && end_offset >= prefix_length) {
|
|
174
207
|
start_offset -= prefix_length;
|
|
@@ -188,8 +221,8 @@ static location_T* parse_wrapped_and_find_then_keyword(
|
|
|
188
221
|
}
|
|
189
222
|
}
|
|
190
223
|
|
|
191
|
-
|
|
192
|
-
|
|
224
|
+
pm_parser_free(parser);
|
|
225
|
+
pm_arena_free(arena);
|
|
193
226
|
|
|
194
227
|
return location;
|
|
195
228
|
}
|
|
@@ -244,3 +277,95 @@ location_T* get_then_keyword_location_elsif_wrapped(const char* source, hb_alloc
|
|
|
244
277
|
|
|
245
278
|
return location;
|
|
246
279
|
}
|
|
280
|
+
|
|
281
|
+
static size_t newline_index_for_offset(const pm_line_offset_list_t* newlines, size_t offset) {
|
|
282
|
+
size_t low = 0;
|
|
283
|
+
size_t high = newlines->size;
|
|
284
|
+
|
|
285
|
+
while (low < high) {
|
|
286
|
+
size_t middle = low + (high - low) / 2;
|
|
287
|
+
|
|
288
|
+
if (newlines->offsets[middle] <= offset) {
|
|
289
|
+
low = middle + 1;
|
|
290
|
+
} else {
|
|
291
|
+
high = middle;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
return low > 0 ? low - 1 : 0;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
void herb_prism_node_serialize(herb_prism_node_T prism_node, pm_buffer_t* buffer) {
|
|
299
|
+
if (!prism_node.node || !prism_node.parser) { return; }
|
|
300
|
+
|
|
301
|
+
pm_parser_t* parser = prism_node.parser;
|
|
302
|
+
|
|
303
|
+
if (prism_node.source_end == 0 || parser->line_offsets.size == 0) {
|
|
304
|
+
pm_serialize(parser, prism_node.node, buffer);
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const pm_line_offset_list_t* newlines = &parser->line_offsets;
|
|
309
|
+
size_t first_line = newline_index_for_offset(newlines, prism_node.source_start);
|
|
310
|
+
size_t last_line = newline_index_for_offset(newlines, prism_node.source_end);
|
|
311
|
+
size_t line_count = last_line - first_line + 1;
|
|
312
|
+
|
|
313
|
+
if (last_line + 1 < newlines->size) { line_count++; }
|
|
314
|
+
|
|
315
|
+
pm_parser_t view = *parser;
|
|
316
|
+
|
|
317
|
+
view.line_offsets.offsets = newlines->offsets + first_line;
|
|
318
|
+
view.line_offsets.size = line_count;
|
|
319
|
+
view.line_offsets.capacity = line_count;
|
|
320
|
+
view.start_line = parser->start_line + (int32_t) first_line;
|
|
321
|
+
|
|
322
|
+
memset(&view.magic_comment_list, 0, sizeof(pm_list_t));
|
|
323
|
+
memset(&view.error_list, 0, sizeof(pm_list_t));
|
|
324
|
+
memset(&view.warning_list, 0, sizeof(pm_list_t));
|
|
325
|
+
memset(&view.comment_list, 0, sizeof(pm_list_t));
|
|
326
|
+
memset(&view.comment_attachments, 0, sizeof(view.comment_attachments));
|
|
327
|
+
|
|
328
|
+
size_t comment_count = 0;
|
|
329
|
+
|
|
330
|
+
for (pm_list_node_t* entry = parser->comment_list.head; entry; entry = entry->next) {
|
|
331
|
+
pm_comment_t* comment = (pm_comment_t*) entry;
|
|
332
|
+
size_t start = comment->location.start;
|
|
333
|
+
|
|
334
|
+
if (start >= prism_node.source_start && start < prism_node.source_end) { comment_count++; }
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
pm_comment_t* comments = NULL;
|
|
338
|
+
|
|
339
|
+
if (comment_count > 0) {
|
|
340
|
+
comments = malloc(comment_count * sizeof(pm_comment_t));
|
|
341
|
+
|
|
342
|
+
if (!comments) {
|
|
343
|
+
pm_serialize(parser, prism_node.node, buffer);
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
size_t index = 0;
|
|
348
|
+
|
|
349
|
+
for (pm_list_node_t* entry = parser->comment_list.head; entry; entry = entry->next) {
|
|
350
|
+
pm_comment_t* comment = (pm_comment_t*) entry;
|
|
351
|
+
size_t start = comment->location.start;
|
|
352
|
+
|
|
353
|
+
if (start < prism_node.source_start || start >= prism_node.source_end) { continue; }
|
|
354
|
+
|
|
355
|
+
comments[index] = *comment;
|
|
356
|
+
comments[index].node.next = NULL;
|
|
357
|
+
|
|
358
|
+
if (index > 0) { comments[index - 1].node.next = &comments[index].node; }
|
|
359
|
+
|
|
360
|
+
index++;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
view.comment_list.size = comment_count;
|
|
364
|
+
view.comment_list.head = &comments[0].node;
|
|
365
|
+
view.comment_list.tail = &comments[comment_count - 1].node;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
pm_serialize(&view, prism_node.node, buffer);
|
|
369
|
+
|
|
370
|
+
free(comments);
|
|
371
|
+
}
|
data/src/prism/ruby_parser.c
CHANGED
|
@@ -2,51 +2,51 @@
|
|
|
2
2
|
|
|
3
3
|
#include <prism.h>
|
|
4
4
|
#include <stdbool.h>
|
|
5
|
+
#include <stdio.h>
|
|
5
6
|
#include <stdlib.h>
|
|
6
7
|
#include <string.h>
|
|
7
8
|
|
|
8
|
-
static
|
|
9
|
+
static pm_visit_result_t herb_prism_visit(const pm_node_t* node, void* data) {
|
|
9
10
|
const size_t* indent = (size_t*) data;
|
|
10
11
|
|
|
11
12
|
for (size_t i = 0; i < *indent * 2; i++) {
|
|
12
13
|
putc(' ', stdout);
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
printf("%s\n",
|
|
16
|
+
printf("%s\n", pm_node_type(node->type));
|
|
16
17
|
|
|
17
18
|
size_t next_indent = *indent + 1;
|
|
18
19
|
size_t* next_data = &next_indent;
|
|
19
20
|
pm_visit_child_nodes(node, herb_prism_visit, next_data);
|
|
20
21
|
|
|
21
|
-
return
|
|
22
|
+
return PM_VISIT_SKIP;
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
void herb_parse_ruby_to_stdout(char* source) {
|
|
25
26
|
size_t length = strlen(source);
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
pm_arena_t* arena = pm_arena_new();
|
|
29
|
+
pm_parser_t* parser = pm_parser_new(arena, (const uint8_t*) source, length, NULL);
|
|
29
30
|
|
|
30
|
-
pm_buffer_t buffer;
|
|
31
|
-
pm_buffer_init(&buffer);
|
|
31
|
+
pm_buffer_t* buffer = pm_buffer_new();
|
|
32
32
|
|
|
33
33
|
size_t indent = 0;
|
|
34
|
-
pm_node_t* root = pm_parse(
|
|
34
|
+
pm_node_t* root = pm_parse(parser);
|
|
35
35
|
size_t* data = &indent;
|
|
36
36
|
|
|
37
|
-
const char* root_type =
|
|
37
|
+
const char* root_type = pm_node_type(root->type);
|
|
38
38
|
printf("Root Type: %s\n", root_type);
|
|
39
39
|
|
|
40
40
|
pm_visit_node(root, herb_prism_visit, data);
|
|
41
41
|
|
|
42
42
|
#ifndef PRISM_EXCLUDE_PRETTYPRINT
|
|
43
|
-
pm_prettyprint(
|
|
44
|
-
printf("
|
|
43
|
+
pm_prettyprint(buffer, parser, root);
|
|
44
|
+
printf("%.*s\n", (int) pm_buffer_length(buffer), pm_buffer_value(buffer));
|
|
45
45
|
#endif
|
|
46
46
|
|
|
47
|
-
pm_buffer_free(
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
pm_buffer_free(buffer);
|
|
48
|
+
pm_parser_free(parser);
|
|
49
|
+
pm_arena_free(arena);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
static const char* const RUBY_FRAGMENT_PREFIXES[] = {
|
|
@@ -56,14 +56,14 @@ static const char* const RUBY_FRAGMENT_PREFIXES[] = {
|
|
|
56
56
|
static const char* const RUBY_FRAGMENT_SUFFIXES[] = { "", "\nend", "", "\nend", "\nend", "\nend" };
|
|
57
57
|
|
|
58
58
|
static bool ruby_source_parses(const char* source, size_t length) {
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
pm_arena_t* arena = pm_arena_new();
|
|
60
|
+
pm_parser_t* parser = pm_parser_new(arena, (const uint8_t*) source, length, NULL);
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
bool parses = (parser
|
|
62
|
+
pm_parse(parser);
|
|
63
|
+
bool parses = (pm_parser_errors_size(parser) == 0);
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
pm_parser_free(parser);
|
|
66
|
+
pm_arena_free(arena);
|
|
67
67
|
|
|
68
68
|
return parses;
|
|
69
69
|
}
|
|
@@ -69,17 +69,17 @@ static VALUE rb_<%= node.human %>_from_c_struct(<%= node.struct_type %>* <%= nod
|
|
|
69
69
|
<%- when Herb::Template::PrismNodeField -%>
|
|
70
70
|
VALUE <%= node.human %>_<%= field.name %>;
|
|
71
71
|
if (<%= node.human %>-><%= field.name %>.node != NULL && <%= node.human %>-><%= field.name %>.parser != NULL) {
|
|
72
|
-
pm_buffer_t pm_buffer =
|
|
73
|
-
|
|
72
|
+
pm_buffer_t* pm_buffer = pm_buffer_new();
|
|
73
|
+
herb_prism_node_serialize(<%= node.human %>-><%= field.name %>, pm_buffer);
|
|
74
74
|
|
|
75
|
-
if (pm_buffer
|
|
76
|
-
<%= node.human %>_<%= field.name %> = rb_str_new(pm_buffer
|
|
75
|
+
if (pm_buffer_length(pm_buffer) > 0) {
|
|
76
|
+
<%= node.human %>_<%= field.name %> = rb_str_new(pm_buffer_value(pm_buffer), pm_buffer_length(pm_buffer));
|
|
77
77
|
rb_enc_associate(<%= node.human %>_<%= field.name %>, rb_ascii8bit_encoding());
|
|
78
78
|
OBJ_FREEZE(<%= node.human %>_<%= field.name %>);
|
|
79
79
|
} else {
|
|
80
80
|
<%= node.human %>_<%= field.name %> = Qnil;
|
|
81
81
|
}
|
|
82
|
-
pm_buffer_free(
|
|
82
|
+
pm_buffer_free(pm_buffer);
|
|
83
83
|
} else {
|
|
84
84
|
<%= node.human %>_<%= field.name %> = Qnil;
|
|
85
85
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
#include "parser_options_helpers.h"
|
|
2
2
|
|
|
3
|
+
#include <string.h>
|
|
4
|
+
|
|
3
5
|
void herb_extract_parser_options(VALUE options, parser_options_T* parser_options) {
|
|
4
6
|
if (NIL_P(options)) { return; }
|
|
5
7
|
<%- parser_options.extractable_fields_for(:ruby).each do |field| -%>
|
|
@@ -10,6 +12,31 @@ void herb_extract_parser_options(VALUE options, parser_options_T* parser_options
|
|
|
10
12
|
if (NIL_P(value)) { value = rb_hash_lookup(options, ID2SYM(rb_intern("<%= field.snake_case %>"))); }
|
|
11
13
|
if (!NIL_P(value)) { parser_options-><%= field.c_name %> = RTEST(value); }
|
|
12
14
|
}
|
|
15
|
+
<%- elsif field.string? -%>
|
|
16
|
+
{
|
|
17
|
+
VALUE value = rb_hash_lookup(options, rb_utf8_str_new_cstr("<%= field.snake_case %>"));
|
|
18
|
+
if (NIL_P(value)) { value = rb_hash_lookup(options, ID2SYM(rb_intern("<%= field.snake_case %>"))); }
|
|
19
|
+
|
|
20
|
+
if (!NIL_P(value)) {
|
|
21
|
+
Check_Type(value, T_STRING);
|
|
22
|
+
|
|
23
|
+
const char* data = RSTRING_PTR(value);
|
|
24
|
+
size_t length = (size_t) RSTRING_LEN(value);
|
|
25
|
+
|
|
26
|
+
<%- if field.validator -%>
|
|
27
|
+
if (!<%= field.validator %>(data, length)) {
|
|
28
|
+
rb_raise(rb_eArgError, "<%= field.snake_case %> %+" PRIsVALUE " is not supported", value);
|
|
29
|
+
}
|
|
30
|
+
<%- else -%>
|
|
31
|
+
if (length >= HERB_PARSER_OPTIONS_STRING_CAPACITY) {
|
|
32
|
+
rb_raise(rb_eArgError, "<%= field.snake_case %> must be shorter than %d bytes", HERB_PARSER_OPTIONS_STRING_CAPACITY);
|
|
33
|
+
}
|
|
34
|
+
<%- end -%>
|
|
35
|
+
|
|
36
|
+
memcpy(parser_options-><%= field.c_name %>, data, length);
|
|
37
|
+
parser_options-><%= field.c_name %>[length] = '\0';
|
|
38
|
+
}
|
|
39
|
+
}
|
|
13
40
|
<%- elsif field.ruby_unit == "seconds" -%>
|
|
14
41
|
{
|
|
15
42
|
VALUE value = rb_hash_lookup(options, rb_utf8_str_new_cstr("<%= field.snake_case %>"));
|
|
@@ -52,6 +79,12 @@ VALUE herb_build_parser_options_hash(const parser_options_T* options) {
|
|
|
52
79
|
|
|
53
80
|
rb_hash_aset(kwargs, ID2SYM(rb_intern("<%= field.snake_case %>")), <%= field.snake_case %>);
|
|
54
81
|
}
|
|
82
|
+
<%- elsif field.string? -%>
|
|
83
|
+
rb_hash_aset(
|
|
84
|
+
kwargs,
|
|
85
|
+
ID2SYM(rb_intern("<%= field.snake_case %>")),
|
|
86
|
+
options-><%= field.c_name %>[0] == '\0' ? Qnil : rb_utf8_str_new_cstr(options-><%= field.c_name %>)
|
|
87
|
+
);
|
|
55
88
|
<%- elsif field.ruby_unit == "seconds" -%>
|
|
56
89
|
rb_hash_aset(kwargs, ID2SYM(rb_intern("<%= field.snake_case %>")), DBL2NUM((double) options-><%= field.c_name %> / 1000.0));
|
|
57
90
|
<%- elsif field.nullable? -%>
|
data/templates/java/nodes.c.erb
CHANGED
|
@@ -49,15 +49,15 @@ jobject <%= node.name %>FromCStruct(JNIEnv* env, <%= node.struct_type %>* <%= no
|
|
|
49
49
|
<%- elsif field.is_a?(Herb::Template::PrismNodeField) -%>
|
|
50
50
|
jbyteArray <%= field.name %>;
|
|
51
51
|
if (<%= node.human %>-><%= field.name %>.node != NULL && <%= node.human %>-><%= field.name %>.parser != NULL) {
|
|
52
|
-
pm_buffer_t pm_buffer =
|
|
53
|
-
|
|
54
|
-
if (pm_buffer
|
|
55
|
-
<%= field.name %> = (*env)->NewByteArray(env, (jsize)pm_buffer
|
|
56
|
-
(*env)->SetByteArrayRegion(env, <%= field.name %>, 0, (jsize)pm_buffer
|
|
52
|
+
pm_buffer_t* pm_buffer = pm_buffer_new();
|
|
53
|
+
herb_prism_node_serialize(<%= node.human %>-><%= field.name %>, pm_buffer);
|
|
54
|
+
if (pm_buffer_length(pm_buffer) > 0) {
|
|
55
|
+
<%= field.name %> = (*env)->NewByteArray(env, (jsize)pm_buffer_length(pm_buffer));
|
|
56
|
+
(*env)->SetByteArrayRegion(env, <%= field.name %>, 0, (jsize)pm_buffer_length(pm_buffer), (const jbyte*)pm_buffer_value(pm_buffer));
|
|
57
57
|
} else {
|
|
58
58
|
<%= field.name %> = NULL;
|
|
59
59
|
}
|
|
60
|
-
pm_buffer_free(
|
|
60
|
+
pm_buffer_free(pm_buffer);
|
|
61
61
|
} else {
|
|
62
62
|
<%= field.name %> = NULL;
|
|
63
63
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
#include "parser_options_helpers.h"
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
#include <stdio.h>
|
|
4
|
+
#include <string.h>
|
|
5
|
+
|
|
6
|
+
bool herb_extract_parser_options(JNIEnv* env, jobject options, parser_options_T* parser_options) {
|
|
7
|
+
if (options == NULL) { return true; }
|
|
5
8
|
|
|
6
9
|
jclass optionsClass = (*env)->GetObjectClass(env, options);
|
|
7
10
|
<%- parser_options.extractable_fields_for(:java).each do |field| -%>
|
|
@@ -15,6 +18,40 @@ void herb_extract_parser_options(JNIEnv* env, jobject options, parser_options_T*
|
|
|
15
18
|
parser_options-><%= field.c_name %> = (value == JNI_TRUE);
|
|
16
19
|
}
|
|
17
20
|
}
|
|
21
|
+
<%- elsif field.string? -%>
|
|
22
|
+
{
|
|
23
|
+
jmethodID method = (*env)->GetMethodID(env, optionsClass, "<%= field.java_getter %>", "<%= field.java_jni_signature %>");
|
|
24
|
+
|
|
25
|
+
if (method != NULL) {
|
|
26
|
+
jstring value = (jstring) (*env)->CallObjectMethod(env, options, method);
|
|
27
|
+
|
|
28
|
+
if (value != NULL) {
|
|
29
|
+
const char* string = (*env)->GetStringUTFChars(env, value, NULL);
|
|
30
|
+
size_t length = strlen(string);
|
|
31
|
+
|
|
32
|
+
<%- if field.validator -%>
|
|
33
|
+
if (!<%= field.validator %>(string, length)) {
|
|
34
|
+
char message[96];
|
|
35
|
+
snprintf(message, sizeof(message), "<%= field.snake_case %> \"%.32s\" is not supported", string);
|
|
36
|
+
(*env)->ReleaseStringUTFChars(env, value, string);
|
|
37
|
+
(*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/IllegalArgumentException"), message);
|
|
38
|
+
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
<%- else -%>
|
|
42
|
+
if (length >= HERB_PARSER_OPTIONS_STRING_CAPACITY) {
|
|
43
|
+
(*env)->ReleaseStringUTFChars(env, value, string);
|
|
44
|
+
(*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/IllegalArgumentException"), "<%= field.snake_case %> is too long");
|
|
45
|
+
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
<%- end -%>
|
|
49
|
+
|
|
50
|
+
memcpy(parser_options-><%= field.c_name %>, string, length + 1);
|
|
51
|
+
(*env)->ReleaseStringUTFChars(env, value, string);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
18
55
|
<%- elsif field.nullable? -%>
|
|
19
56
|
{
|
|
20
57
|
jmethodID method = (*env)->GetMethodID(env, optionsClass, "<%= field.java_getter %>", "<%= field.java_jni_signature %>");
|
|
@@ -42,4 +79,6 @@ void herb_extract_parser_options(JNIEnv* env, jobject options, parser_options_T*
|
|
|
42
79
|
}
|
|
43
80
|
<%- end -%>
|
|
44
81
|
<%- end -%>
|
|
82
|
+
|
|
83
|
+
return true;
|
|
45
84
|
}
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
#include "../src/include/parser/parser_options.h"
|
|
5
5
|
|
|
6
6
|
#include <jni.h>
|
|
7
|
+
#include <stdbool.h>
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
bool herb_extract_parser_options(JNIEnv* env, jobject options, parser_options_T* parser_options);
|
|
9
10
|
|
|
10
11
|
#endif
|
|
@@ -13,6 +13,26 @@ import type { LocateResult } from "./locate.js"
|
|
|
13
13
|
|
|
14
14
|
export type SerializedNodeType = string
|
|
15
15
|
|
|
16
|
+
type PrismNodeCacheEntry = {
|
|
17
|
+
bytes: Uint8Array
|
|
18
|
+
source: string
|
|
19
|
+
node: PrismNode | null
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const prismNodeCache = new WeakMap<Node, PrismNodeCacheEntry>()
|
|
23
|
+
|
|
24
|
+
function cachedPrismNode(owner: Node, bytes: Uint8Array, source: string): PrismNode | null {
|
|
25
|
+
const cached = prismNodeCache.get(owner)
|
|
26
|
+
|
|
27
|
+
if (cached && cached.bytes === bytes && cached.source === source) return cached.node
|
|
28
|
+
|
|
29
|
+
const node = deserializePrismNode(bytes, source)
|
|
30
|
+
|
|
31
|
+
prismNodeCache.set(owner, { bytes, source, node })
|
|
32
|
+
|
|
33
|
+
return node
|
|
34
|
+
}
|
|
35
|
+
|
|
16
36
|
export interface SerializedNode {
|
|
17
37
|
type: SerializedNodeType
|
|
18
38
|
location: SerializedLocation
|
|
@@ -388,7 +408,7 @@ export class <%= node.name %> extends Node {
|
|
|
388
408
|
<%- prism_field = node.fields.find { |f| f.is_a?(Herb::Template::PrismSerializedField) || f.is_a?(Herb::Template::PrismNodeField) } -%>
|
|
389
409
|
get prismNode(): PrismNode | null {
|
|
390
410
|
if (!this.<%= prism_field.name %> || !this.source) return null;
|
|
391
|
-
return
|
|
411
|
+
return cachedPrismNode(this, this.<%= prism_field.name %>, this.source);
|
|
392
412
|
}
|
|
393
413
|
<%- end -%>
|
|
394
414
|
|
|
@@ -89,17 +89,17 @@ napi_value <%= node.human %>NodeFromCStruct(napi_env env, <%= node.struct_type %
|
|
|
89
89
|
<%- when Herb::Template::PrismNodeField -%>
|
|
90
90
|
napi_value <%= field.name %>;
|
|
91
91
|
if (<%= node.human %>-><%= field.name %>.node != NULL && <%= node.human %>-><%= field.name %>.parser != NULL) {
|
|
92
|
-
pm_buffer_t pm_buffer =
|
|
93
|
-
|
|
92
|
+
pm_buffer_t* pm_buffer = pm_buffer_new();
|
|
93
|
+
herb_prism_node_serialize(<%= node.human %>-><%= field.name %>, pm_buffer);
|
|
94
94
|
|
|
95
|
-
if (pm_buffer
|
|
95
|
+
if (pm_buffer_length(pm_buffer) > 0) {
|
|
96
96
|
void* buffer_data;
|
|
97
|
-
napi_create_buffer_copy(env, pm_buffer
|
|
97
|
+
napi_create_buffer_copy(env, pm_buffer_length(pm_buffer), pm_buffer_value(pm_buffer), &buffer_data, &<%= field.name %>);
|
|
98
98
|
} else {
|
|
99
99
|
napi_get_null(env, &<%= field.name %>);
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
pm_buffer_free(
|
|
102
|
+
pm_buffer_free(pm_buffer);
|
|
103
103
|
} else {
|
|
104
104
|
napi_get_null(env, &<%= field.name %>);
|
|
105
105
|
}
|