herb 0.8.10-arm-linux-gnu → 0.9.0-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/Makefile +11 -3
- data/README.md +64 -34
- data/Rakefile +48 -40
- data/config.yml +317 -34
- data/ext/herb/error_helpers.c +367 -140
- data/ext/herb/error_helpers.h +1 -0
- data/ext/herb/extconf.rb +67 -28
- data/ext/herb/extension.c +317 -51
- data/ext/herb/extension.h +1 -0
- data/ext/herb/extension_helpers.c +23 -14
- data/ext/herb/extension_helpers.h +2 -2
- data/ext/herb/nodes.c +537 -270
- data/ext/herb/nodes.h +1 -0
- data/herb.gemspec +3 -2
- 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/helpers.rb +3 -3
- data/lib/herb/ast/node.rb +15 -2
- data/lib/herb/ast/nodes.rb +1132 -157
- data/lib/herb/bootstrap.rb +87 -0
- data/lib/herb/cli.rb +341 -31
- data/lib/herb/configuration.rb +248 -0
- data/lib/herb/defaults.yml +32 -0
- data/lib/herb/engine/compiler.rb +78 -11
- data/lib/herb/engine/debug_visitor.rb +13 -3
- data/lib/herb/engine/error_formatter.rb +13 -9
- data/lib/herb/engine/parser_error_overlay.rb +10 -6
- data/lib/herb/engine/validator.rb +8 -3
- data/lib/herb/engine/validators/nesting_validator.rb +2 -2
- data/lib/herb/engine.rb +82 -35
- data/lib/herb/errors.rb +563 -88
- data/lib/herb/lex_result.rb +1 -0
- data/lib/herb/location.rb +7 -3
- data/lib/herb/parse_result.rb +12 -2
- data/lib/herb/parser_options.rb +57 -0
- data/lib/herb/position.rb +1 -0
- data/lib/herb/prism_inspect.rb +116 -0
- data/lib/herb/project.rb +923 -331
- data/lib/herb/range.rb +1 -0
- data/lib/herb/token.rb +7 -1
- data/lib/herb/version.rb +1 -1
- data/lib/herb/visitor.rb +37 -2
- data/lib/herb/warnings.rb +6 -1
- data/lib/herb.rb +35 -3
- data/sig/herb/ast/helpers.rbs +2 -2
- data/sig/herb/ast/node.rbs +12 -2
- data/sig/herb/ast/nodes.rbs +641 -128
- data/sig/herb/bootstrap.rbs +31 -0
- data/sig/herb/configuration.rbs +89 -0
- data/sig/herb/engine/compiler.rbs +9 -1
- data/sig/herb/engine/debug_visitor.rbs +2 -0
- data/sig/herb/engine/validator.rbs +5 -1
- data/sig/herb/engine.rbs +17 -3
- data/sig/herb/errors.rbs +258 -63
- data/sig/herb/location.rbs +4 -0
- data/sig/herb/parse_result.rbs +4 -2
- data/sig/herb/parser_options.rbs +42 -0
- data/sig/herb/position.rbs +1 -0
- data/sig/herb/prism_inspect.rbs +28 -0
- data/sig/herb/range.rbs +1 -0
- data/sig/herb/token.rbs +6 -0
- data/sig/herb/visitor.rbs +25 -4
- data/sig/herb/warnings.rbs +6 -1
- data/sig/herb.rbs +14 -0
- data/sig/herb_c_extension.rbs +5 -2
- data/sig/serialized_ast_errors.rbs +54 -6
- data/sig/serialized_ast_nodes.rbs +60 -6
- data/src/analyze/action_view/attribute_extraction_helpers.c +290 -0
- data/src/analyze/action_view/content_tag.c +70 -0
- data/src/analyze/action_view/link_to.c +143 -0
- data/src/analyze/action_view/registry.c +60 -0
- data/src/analyze/action_view/tag.c +64 -0
- data/src/analyze/action_view/tag_helper_node_builders.c +305 -0
- data/src/analyze/action_view/tag_helpers.c +748 -0
- data/src/analyze/action_view/turbo_frame_tag.c +88 -0
- data/src/analyze/analyze.c +882 -0
- data/src/{analyzed_ruby.c → analyze/analyzed_ruby.c} +13 -11
- data/src/analyze/builders.c +343 -0
- data/src/analyze/conditional_elements.c +594 -0
- data/src/analyze/conditional_open_tags.c +640 -0
- data/src/analyze/control_type.c +250 -0
- data/src/{analyze_helpers.c → analyze/helpers.c} +48 -23
- data/src/analyze/invalid_structures.c +193 -0
- data/src/{analyze_missing_end.c → analyze/missing_end.c} +33 -22
- data/src/analyze/parse_errors.c +84 -0
- data/src/analyze/prism_annotate.c +397 -0
- data/src/{analyze_transform.c → analyze/transform.c} +17 -3
- data/src/ast_node.c +17 -7
- data/src/ast_nodes.c +662 -387
- data/src/ast_pretty_print.c +190 -6
- data/src/errors.c +1076 -520
- data/src/extract.c +145 -49
- data/src/herb.c +52 -34
- data/src/html_util.c +241 -12
- data/src/include/analyze/action_view/attribute_extraction_helpers.h +36 -0
- data/src/include/analyze/action_view/tag_helper_handler.h +41 -0
- data/src/include/analyze/action_view/tag_helper_node_builders.h +70 -0
- data/src/include/analyze/action_view/tag_helpers.h +38 -0
- data/src/include/{analyze.h → analyze/analyze.h} +14 -4
- data/src/include/{analyzed_ruby.h → analyze/analyzed_ruby.h} +3 -3
- data/src/include/analyze/builders.h +27 -0
- data/src/include/analyze/conditional_elements.h +9 -0
- data/src/include/analyze/conditional_open_tags.h +9 -0
- data/src/include/analyze/control_type.h +14 -0
- data/src/include/{analyze_helpers.h → analyze/helpers.h} +4 -2
- data/src/include/analyze/invalid_structures.h +11 -0
- data/src/include/analyze/prism_annotate.h +16 -0
- data/src/include/ast_node.h +11 -5
- data/src/include/ast_nodes.h +117 -38
- data/src/include/ast_pretty_print.h +5 -0
- data/src/include/element_source.h +3 -8
- data/src/include/errors.h +148 -55
- data/src/include/extract.h +21 -5
- data/src/include/herb.h +18 -6
- data/src/include/herb_prism_node.h +13 -0
- data/src/include/html_util.h +7 -2
- data/src/include/io.h +3 -1
- data/src/include/lex_helpers.h +29 -0
- data/src/include/lexer.h +1 -1
- data/src/include/lexer_peek_helpers.h +87 -13
- data/src/include/lexer_struct.h +2 -0
- data/src/include/location.h +2 -1
- data/src/include/parser.h +27 -2
- data/src/include/parser_helpers.h +19 -3
- data/src/include/pretty_print.h +10 -5
- data/src/include/prism_context.h +45 -0
- data/src/include/prism_helpers.h +10 -7
- data/src/include/prism_serialized.h +12 -0
- data/src/include/token.h +16 -4
- data/src/include/token_struct.h +10 -3
- data/src/include/utf8.h +2 -1
- data/src/include/util/hb_allocator.h +78 -0
- data/src/include/util/hb_arena.h +6 -1
- data/src/include/util/hb_arena_debug.h +12 -1
- data/src/include/util/hb_array.h +7 -3
- data/src/include/util/hb_buffer.h +6 -4
- data/src/include/util/hb_foreach.h +79 -0
- data/src/include/util/hb_narray.h +8 -4
- data/src/include/util/hb_string.h +56 -9
- data/src/include/util.h +6 -3
- data/src/include/version.h +1 -1
- data/src/io.c +3 -2
- data/src/lexer.c +42 -30
- data/src/lexer_peek_helpers.c +12 -74
- data/src/location.c +2 -2
- data/src/main.c +53 -28
- data/src/parser.c +783 -247
- data/src/parser_helpers.c +110 -23
- data/src/parser_match_tags.c +109 -48
- data/src/pretty_print.c +29 -24
- data/src/prism_helpers.c +30 -27
- data/src/ruby_parser.c +2 -0
- data/src/token.c +151 -66
- data/src/token_matchers.c +0 -1
- data/src/utf8.c +7 -6
- data/src/util/hb_allocator.c +341 -0
- data/src/util/hb_arena.c +81 -56
- data/src/util/hb_arena_debug.c +32 -17
- data/src/util/hb_array.c +30 -15
- data/src/util/hb_buffer.c +17 -21
- data/src/util/hb_narray.c +22 -7
- data/src/util/hb_string.c +49 -35
- data/src/util.c +21 -11
- data/src/visitor.c +47 -0
- data/templates/ext/herb/error_helpers.c.erb +24 -11
- data/templates/ext/herb/error_helpers.h.erb +1 -0
- data/templates/ext/herb/nodes.c.erb +50 -16
- data/templates/ext/herb/nodes.h.erb +1 -0
- data/templates/java/error_helpers.c.erb +1 -1
- data/templates/java/nodes.c.erb +30 -8
- data/templates/java/org/herb/ast/Errors.java.erb +24 -1
- data/templates/java/org/herb/ast/Nodes.java.erb +80 -21
- data/templates/javascript/packages/core/src/errors.ts.erb +16 -3
- data/templates/javascript/packages/core/src/node-type-guards.ts.erb +3 -1
- data/templates/javascript/packages/core/src/nodes.ts.erb +109 -32
- data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +13 -4
- data/templates/javascript/packages/node/extension/nodes.cpp.erb +43 -4
- data/templates/lib/herb/ast/nodes.rb.erb +88 -31
- data/templates/lib/herb/errors.rb.erb +15 -3
- data/templates/lib/herb/visitor.rb.erb +2 -2
- data/templates/rust/src/ast/nodes.rs.erb +97 -44
- data/templates/rust/src/errors.rs.erb +2 -1
- data/templates/rust/src/nodes.rs.erb +167 -15
- data/templates/rust/src/union_types.rs.erb +60 -0
- data/templates/rust/src/visitor.rs.erb +81 -0
- data/templates/src/{analyze_missing_end.c.erb → analyze/missing_end.c.erb} +9 -6
- data/templates/src/{analyze_transform.c.erb → analyze/transform.c.erb} +2 -2
- data/templates/src/ast_nodes.c.erb +34 -26
- data/templates/src/ast_pretty_print.c.erb +24 -5
- data/templates/src/errors.c.erb +60 -54
- data/templates/src/include/ast_nodes.h.erb +6 -2
- data/templates/src/include/ast_pretty_print.h.erb +5 -0
- data/templates/src/include/errors.h.erb +15 -11
- data/templates/src/include/util/hb_foreach.h.erb +20 -0
- data/templates/src/parser_match_tags.c.erb +10 -4
- data/templates/src/visitor.c.erb +2 -2
- data/templates/template.rb +204 -29
- data/templates/wasm/error_helpers.cpp.erb +9 -5
- data/templates/wasm/nodes.cpp.erb +41 -4
- metadata +57 -16
- data/src/analyze.c +0 -1608
- data/src/element_source.c +0 -12
- data/src/include/util/hb_system.h +0 -9
- data/src/util/hb_system.c +0 -30
data/ext/herb/error_helpers.h
CHANGED
data/ext/herb/extconf.rb
CHANGED
|
@@ -1,9 +1,42 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "mkmf"
|
|
4
|
+
require_relative "../../lib/herb/bootstrap"
|
|
4
5
|
|
|
5
6
|
extension_name = "herb"
|
|
6
7
|
|
|
8
|
+
if Herb::Bootstrap.git_source? && !Herb::Bootstrap.templates_generated?
|
|
9
|
+
puts "Building from source — running bootstrap..."
|
|
10
|
+
Herb::Bootstrap.generate_templates
|
|
11
|
+
|
|
12
|
+
unless Herb::Bootstrap.prism_vendored?
|
|
13
|
+
prism_path = Herb::Bootstrap.find_prism_gem_path
|
|
14
|
+
|
|
15
|
+
abort <<~MSG unless prism_path
|
|
16
|
+
ERROR: Could not find Prism C source files.
|
|
17
|
+
|
|
18
|
+
When installing Herb from a git source, a git-sourced Prism is required
|
|
19
|
+
(the released gem does not include C source files).
|
|
20
|
+
|
|
21
|
+
Add it to your Gemfile before the herb git reference:
|
|
22
|
+
|
|
23
|
+
gem "prism", github: "ruby/prism", tag: "v1.9.0"
|
|
24
|
+
gem "herb", github: "...", branch: "..."
|
|
25
|
+
|
|
26
|
+
Then run `bundle install` again.
|
|
27
|
+
MSG
|
|
28
|
+
|
|
29
|
+
puts "Vendoring Prism from #{prism_path}..."
|
|
30
|
+
Herb::Bootstrap.vendor_prism(prism_gem_path: prism_path)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
root_path = Herb::Bootstrap::ROOT_PATH
|
|
34
|
+
sha = `git -C #{root_path} rev-parse --short HEAD 2>/dev/null`.strip
|
|
35
|
+
|
|
36
|
+
$CFLAGS << " -DHERB_GIT_BUILD"
|
|
37
|
+
$CFLAGS << " -DHERB_GIT_SHA=\\\"#{sha}\\\"" unless sha.empty?
|
|
38
|
+
end
|
|
39
|
+
|
|
7
40
|
include_path = File.expand_path("../../src/include", __dir__)
|
|
8
41
|
prism_path = File.expand_path("../../vendor/prism", __dir__)
|
|
9
42
|
|
|
@@ -11,6 +44,8 @@ prism_src_path = "#{prism_path}/src"
|
|
|
11
44
|
prism_include_path = "#{prism_path}/include"
|
|
12
45
|
|
|
13
46
|
$VPATH << "$(srcdir)/../../src"
|
|
47
|
+
$VPATH << "$(srcdir)/../../src/analyze"
|
|
48
|
+
$VPATH << "$(srcdir)/../../src/analyze/action_view"
|
|
14
49
|
$VPATH << "$(srcdir)/../../src/util"
|
|
15
50
|
$VPATH << prism_src_path
|
|
16
51
|
$VPATH << "#{prism_src_path}/util"
|
|
@@ -21,41 +56,45 @@ $INCFLAGS << " -I#{prism_src_path}"
|
|
|
21
56
|
$INCFLAGS << " -I#{prism_src_path}/util"
|
|
22
57
|
|
|
23
58
|
$CFLAGS << " -fvisibility=hidden"
|
|
59
|
+
$CFLAGS << " -DHERB_EXCLUDE_PRETTYPRINT"
|
|
60
|
+
$CFLAGS << " -DPRISM_EXCLUDE_PRETTYPRINT"
|
|
61
|
+
$CFLAGS << " -DPRISM_EXCLUDE_JSON"
|
|
62
|
+
$CFLAGS << " -DPRISM_EXCLUDE_PACK"
|
|
24
63
|
|
|
25
64
|
herb_src_files = Dir.glob("#{$srcdir}/../../src/**/*.c").map { |file| file.delete_prefix("../../../../ext/herb/") }.sort
|
|
26
65
|
|
|
27
|
-
prism_main_files =
|
|
28
|
-
diagnostic.c
|
|
29
|
-
encoding.c
|
|
30
|
-
node.c
|
|
31
|
-
options.c
|
|
32
|
-
pack.c
|
|
33
|
-
prettyprint.c
|
|
34
|
-
prism.c
|
|
35
|
-
regexp.c
|
|
36
|
-
serialize.c
|
|
37
|
-
static_literals.c
|
|
38
|
-
token_type.c
|
|
66
|
+
prism_main_files = [
|
|
67
|
+
"diagnostic.c",
|
|
68
|
+
"encoding.c",
|
|
69
|
+
"node.c",
|
|
70
|
+
"options.c",
|
|
71
|
+
"pack.c",
|
|
72
|
+
"prettyprint.c",
|
|
73
|
+
"prism.c",
|
|
74
|
+
"regexp.c",
|
|
75
|
+
"serialize.c",
|
|
76
|
+
"static_literals.c",
|
|
77
|
+
"token_type.c"
|
|
39
78
|
]
|
|
40
79
|
|
|
41
|
-
prism_util_files =
|
|
42
|
-
pm_buffer.c
|
|
43
|
-
pm_char.c
|
|
44
|
-
pm_constant_pool.c
|
|
45
|
-
pm_integer.c
|
|
46
|
-
pm_list.c
|
|
47
|
-
pm_memchr.c
|
|
48
|
-
pm_newline_list.c
|
|
49
|
-
pm_string.c
|
|
50
|
-
pm_strncasecmp.c
|
|
51
|
-
pm_strpbrk.c
|
|
80
|
+
prism_util_files = [
|
|
81
|
+
"pm_buffer.c",
|
|
82
|
+
"pm_char.c",
|
|
83
|
+
"pm_constant_pool.c",
|
|
84
|
+
"pm_integer.c",
|
|
85
|
+
"pm_list.c",
|
|
86
|
+
"pm_memchr.c",
|
|
87
|
+
"pm_newline_list.c",
|
|
88
|
+
"pm_string.c",
|
|
89
|
+
"pm_strncasecmp.c",
|
|
90
|
+
"pm_strpbrk.c"
|
|
52
91
|
]
|
|
53
92
|
|
|
54
|
-
core_src_files =
|
|
55
|
-
extension.c
|
|
56
|
-
nodes.c
|
|
57
|
-
error_helpers.c
|
|
58
|
-
extension_helpers.c
|
|
93
|
+
core_src_files = [
|
|
94
|
+
"extension.c",
|
|
95
|
+
"nodes.c",
|
|
96
|
+
"error_helpers.c",
|
|
97
|
+
"extension_helpers.c"
|
|
59
98
|
]
|
|
60
99
|
|
|
61
100
|
$srcs = core_src_files + herb_src_files + prism_main_files + prism_util_files
|
data/ext/herb/extension.c
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#include <ruby.h>
|
|
2
2
|
|
|
3
|
+
#include "../../src/include/util/hb_allocator.h"
|
|
4
|
+
#include "../../src/include/util/hb_arena_debug.h"
|
|
5
|
+
|
|
3
6
|
#include "error_helpers.h"
|
|
4
7
|
#include "extension.h"
|
|
5
8
|
#include "extension_helpers.h"
|
|
6
9
|
#include "nodes.h"
|
|
7
10
|
|
|
8
|
-
#include "../../src/include/analyze.h"
|
|
9
|
-
|
|
10
11
|
VALUE mHerb;
|
|
11
12
|
VALUE cPosition;
|
|
12
13
|
VALUE cLocation;
|
|
@@ -15,29 +16,96 @@ VALUE cToken;
|
|
|
15
16
|
VALUE cResult;
|
|
16
17
|
VALUE cLexResult;
|
|
17
18
|
VALUE cParseResult;
|
|
19
|
+
VALUE cParserOptions;
|
|
20
|
+
|
|
21
|
+
typedef struct {
|
|
22
|
+
AST_DOCUMENT_NODE_T* root;
|
|
23
|
+
VALUE source;
|
|
24
|
+
const parser_options_T* parser_options;
|
|
25
|
+
hb_allocator_T allocator;
|
|
26
|
+
} parse_args_T;
|
|
27
|
+
|
|
28
|
+
typedef struct {
|
|
29
|
+
hb_array_T* tokens;
|
|
30
|
+
VALUE source;
|
|
31
|
+
hb_allocator_T allocator;
|
|
32
|
+
} lex_args_T;
|
|
33
|
+
|
|
34
|
+
typedef struct {
|
|
35
|
+
char* buffer_value;
|
|
36
|
+
hb_allocator_T allocator;
|
|
37
|
+
} buffer_args_T;
|
|
38
|
+
|
|
39
|
+
static VALUE parse_convert_body(VALUE arg) {
|
|
40
|
+
parse_args_T* args = (parse_args_T*) arg;
|
|
41
|
+
|
|
42
|
+
return create_parse_result(args->root, args->source, args->parser_options);
|
|
43
|
+
}
|
|
18
44
|
|
|
19
|
-
static VALUE
|
|
20
|
-
|
|
45
|
+
static VALUE parse_cleanup(VALUE arg) {
|
|
46
|
+
parse_args_T* args = (parse_args_T*) arg;
|
|
21
47
|
|
|
22
|
-
|
|
48
|
+
if (args->root != NULL) { ast_node_free((AST_NODE_T*) args->root, &args->allocator); }
|
|
23
49
|
|
|
24
|
-
|
|
50
|
+
hb_allocator_destroy(&args->allocator);
|
|
25
51
|
|
|
26
|
-
|
|
52
|
+
return Qnil;
|
|
53
|
+
}
|
|
27
54
|
|
|
28
|
-
|
|
55
|
+
static VALUE lex_convert_body(VALUE arg) {
|
|
56
|
+
lex_args_T* args = (lex_args_T*) arg;
|
|
57
|
+
|
|
58
|
+
return create_lex_result(args->tokens, args->source);
|
|
29
59
|
}
|
|
30
60
|
|
|
31
|
-
static VALUE
|
|
32
|
-
|
|
33
|
-
hb_array_T* tokens = herb_lex_file(file_path);
|
|
61
|
+
static VALUE lex_cleanup(VALUE arg) {
|
|
62
|
+
lex_args_T* args = (lex_args_T*) arg;
|
|
34
63
|
|
|
35
|
-
|
|
36
|
-
VALUE result = create_lex_result(tokens, source_value);
|
|
64
|
+
if (args->tokens != NULL) { herb_free_tokens(&args->tokens, &args->allocator); }
|
|
37
65
|
|
|
38
|
-
|
|
66
|
+
hb_allocator_destroy(&args->allocator);
|
|
39
67
|
|
|
40
|
-
return
|
|
68
|
+
return Qnil;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static VALUE buffer_to_string_body(VALUE arg) {
|
|
72
|
+
buffer_args_T* args = (buffer_args_T*) arg;
|
|
73
|
+
|
|
74
|
+
return rb_utf8_str_new_cstr(args->buffer_value);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
static VALUE buffer_cleanup(VALUE arg) {
|
|
78
|
+
buffer_args_T* args = (buffer_args_T*) arg;
|
|
79
|
+
|
|
80
|
+
hb_allocator_dealloc(&args->allocator, args->buffer_value);
|
|
81
|
+
hb_allocator_destroy(&args->allocator);
|
|
82
|
+
|
|
83
|
+
return Qnil;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
static VALUE Herb_lex(int argc, VALUE* argv, VALUE self) {
|
|
87
|
+
VALUE source, options;
|
|
88
|
+
rb_scan_args(argc, argv, "1:", &source, &options);
|
|
89
|
+
|
|
90
|
+
char* string = (char*) check_string(source);
|
|
91
|
+
bool print_arena_stats = false;
|
|
92
|
+
|
|
93
|
+
if (!NIL_P(options)) {
|
|
94
|
+
VALUE arena_stats = rb_hash_lookup(options, rb_utf8_str_new_cstr("arena_stats"));
|
|
95
|
+
if (NIL_P(arena_stats)) { arena_stats = rb_hash_lookup(options, ID2SYM(rb_intern("arena_stats"))); }
|
|
96
|
+
if (!NIL_P(arena_stats) && RTEST(arena_stats)) { print_arena_stats = true; }
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
lex_args_T args = { 0 };
|
|
100
|
+
args.source = source;
|
|
101
|
+
|
|
102
|
+
if (!hb_allocator_init(&args.allocator, HB_ALLOCATOR_ARENA)) { return Qnil; }
|
|
103
|
+
|
|
104
|
+
args.tokens = herb_lex(string, &args.allocator);
|
|
105
|
+
|
|
106
|
+
if (print_arena_stats) { hb_arena_print_stats((hb_arena_T*) args.allocator.context); }
|
|
107
|
+
|
|
108
|
+
return rb_ensure(lex_convert_body, (VALUE) &args, lex_cleanup, (VALUE) &args);
|
|
41
109
|
}
|
|
42
110
|
|
|
43
111
|
static VALUE Herb_parse(int argc, VALUE* argv, VALUE self) {
|
|
@@ -45,72 +113,244 @@ static VALUE Herb_parse(int argc, VALUE* argv, VALUE self) {
|
|
|
45
113
|
rb_scan_args(argc, argv, "1:", &source, &options);
|
|
46
114
|
|
|
47
115
|
char* string = (char*) check_string(source);
|
|
116
|
+
bool print_arena_stats = false;
|
|
48
117
|
|
|
49
|
-
parser_options_T
|
|
50
|
-
parser_options_T opts = { 0 };
|
|
118
|
+
parser_options_T parser_options = HERB_DEFAULT_PARSER_OPTIONS;
|
|
51
119
|
|
|
52
120
|
if (!NIL_P(options)) {
|
|
53
121
|
VALUE track_whitespace = rb_hash_lookup(options, rb_utf8_str_new_cstr("track_whitespace"));
|
|
54
122
|
if (NIL_P(track_whitespace)) { track_whitespace = rb_hash_lookup(options, ID2SYM(rb_intern("track_whitespace"))); }
|
|
123
|
+
if (!NIL_P(track_whitespace) && RTEST(track_whitespace)) { parser_options.track_whitespace = true; }
|
|
124
|
+
|
|
125
|
+
VALUE analyze = rb_hash_lookup(options, rb_utf8_str_new_cstr("analyze"));
|
|
126
|
+
if (NIL_P(analyze)) { analyze = rb_hash_lookup(options, ID2SYM(rb_intern("analyze"))); }
|
|
127
|
+
if (!NIL_P(analyze) && !RTEST(analyze)) { parser_options.analyze = false; }
|
|
55
128
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
129
|
+
VALUE strict = rb_hash_lookup(options, rb_utf8_str_new_cstr("strict"));
|
|
130
|
+
if (NIL_P(strict)) { strict = rb_hash_lookup(options, ID2SYM(rb_intern("strict"))); }
|
|
131
|
+
if (!NIL_P(strict)) { parser_options.strict = RTEST(strict); }
|
|
132
|
+
|
|
133
|
+
VALUE action_view_helpers = rb_hash_lookup(options, rb_utf8_str_new_cstr("action_view_helpers"));
|
|
134
|
+
if (NIL_P(action_view_helpers)) {
|
|
135
|
+
action_view_helpers = rb_hash_lookup(options, ID2SYM(rb_intern("action_view_helpers")));
|
|
59
136
|
}
|
|
137
|
+
if (!NIL_P(action_view_helpers) && RTEST(action_view_helpers)) { parser_options.action_view_helpers = true; }
|
|
138
|
+
|
|
139
|
+
VALUE prism_nodes = rb_hash_lookup(options, rb_utf8_str_new_cstr("prism_nodes"));
|
|
140
|
+
if (NIL_P(prism_nodes)) { prism_nodes = rb_hash_lookup(options, ID2SYM(rb_intern("prism_nodes"))); }
|
|
141
|
+
if (!NIL_P(prism_nodes) && RTEST(prism_nodes)) { parser_options.prism_nodes = true; }
|
|
142
|
+
|
|
143
|
+
VALUE prism_nodes_deep = rb_hash_lookup(options, rb_utf8_str_new_cstr("prism_nodes_deep"));
|
|
144
|
+
if (NIL_P(prism_nodes_deep)) { prism_nodes_deep = rb_hash_lookup(options, ID2SYM(rb_intern("prism_nodes_deep"))); }
|
|
145
|
+
if (!NIL_P(prism_nodes_deep) && RTEST(prism_nodes_deep)) { parser_options.prism_nodes_deep = true; }
|
|
146
|
+
|
|
147
|
+
VALUE prism_program = rb_hash_lookup(options, rb_utf8_str_new_cstr("prism_program"));
|
|
148
|
+
if (NIL_P(prism_program)) { prism_program = rb_hash_lookup(options, ID2SYM(rb_intern("prism_program"))); }
|
|
149
|
+
if (!NIL_P(prism_program) && RTEST(prism_program)) { parser_options.prism_program = true; }
|
|
150
|
+
|
|
151
|
+
VALUE arena_stats = rb_hash_lookup(options, rb_utf8_str_new_cstr("arena_stats"));
|
|
152
|
+
if (NIL_P(arena_stats)) { arena_stats = rb_hash_lookup(options, ID2SYM(rb_intern("arena_stats"))); }
|
|
153
|
+
if (!NIL_P(arena_stats) && RTEST(arena_stats)) { print_arena_stats = true; }
|
|
60
154
|
}
|
|
61
155
|
|
|
62
|
-
|
|
156
|
+
parse_args_T args = { 0 };
|
|
157
|
+
args.source = source;
|
|
158
|
+
args.parser_options = &parser_options;
|
|
63
159
|
|
|
64
|
-
|
|
160
|
+
if (!hb_allocator_init(&args.allocator, HB_ALLOCATOR_ARENA)) { return Qnil; }
|
|
65
161
|
|
|
66
|
-
|
|
162
|
+
args.root = herb_parse(string, &parser_options, &args.allocator);
|
|
67
163
|
|
|
68
|
-
|
|
164
|
+
if (print_arena_stats) { hb_arena_print_stats((hb_arena_T*) args.allocator.context); }
|
|
69
165
|
|
|
70
|
-
return
|
|
166
|
+
return rb_ensure(parse_convert_body, (VALUE) &args, parse_cleanup, (VALUE) &args);
|
|
71
167
|
}
|
|
72
168
|
|
|
73
|
-
static VALUE
|
|
74
|
-
|
|
169
|
+
static VALUE Herb_extract_ruby(int argc, VALUE* argv, VALUE self) {
|
|
170
|
+
VALUE source, options;
|
|
171
|
+
rb_scan_args(argc, argv, "1:", &source, &options);
|
|
75
172
|
|
|
76
|
-
|
|
77
|
-
char* string = (char*) check_string(source_value);
|
|
173
|
+
char* string = (char*) check_string(source);
|
|
78
174
|
|
|
79
|
-
|
|
175
|
+
hb_allocator_T allocator;
|
|
176
|
+
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) { return Qnil; }
|
|
80
177
|
|
|
81
|
-
|
|
178
|
+
hb_buffer_T output;
|
|
179
|
+
if (!hb_buffer_init(&output, strlen(string), &allocator)) { return Qnil; }
|
|
82
180
|
|
|
83
|
-
|
|
181
|
+
herb_extract_ruby_options_T extract_options = HERB_EXTRACT_RUBY_DEFAULT_OPTIONS;
|
|
84
182
|
|
|
85
|
-
|
|
183
|
+
if (!NIL_P(options)) {
|
|
184
|
+
VALUE semicolons_value = rb_hash_lookup(options, rb_utf8_str_new_cstr("semicolons"));
|
|
185
|
+
if (NIL_P(semicolons_value)) { semicolons_value = rb_hash_lookup(options, ID2SYM(rb_intern("semicolons"))); }
|
|
186
|
+
if (!NIL_P(semicolons_value)) { extract_options.semicolons = RTEST(semicolons_value); }
|
|
86
187
|
|
|
87
|
-
|
|
188
|
+
VALUE comments_value = rb_hash_lookup(options, rb_utf8_str_new_cstr("comments"));
|
|
189
|
+
if (NIL_P(comments_value)) { comments_value = rb_hash_lookup(options, ID2SYM(rb_intern("comments"))); }
|
|
190
|
+
if (!NIL_P(comments_value)) { extract_options.comments = RTEST(comments_value); }
|
|
191
|
+
|
|
192
|
+
VALUE preserve_positions_value = rb_hash_lookup(options, rb_utf8_str_new_cstr("preserve_positions"));
|
|
193
|
+
if (NIL_P(preserve_positions_value)) {
|
|
194
|
+
preserve_positions_value = rb_hash_lookup(options, ID2SYM(rb_intern("preserve_positions")));
|
|
195
|
+
}
|
|
196
|
+
if (!NIL_P(preserve_positions_value)) { extract_options.preserve_positions = RTEST(preserve_positions_value); }
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
herb_extract_ruby_to_buffer_with_options(string, &output, &extract_options, &allocator);
|
|
200
|
+
|
|
201
|
+
buffer_args_T args = { .buffer_value = output.value, .allocator = allocator };
|
|
202
|
+
|
|
203
|
+
return rb_ensure(buffer_to_string_body, (VALUE) &args, buffer_cleanup, (VALUE) &args);
|
|
88
204
|
}
|
|
89
205
|
|
|
90
|
-
static VALUE
|
|
206
|
+
static VALUE Herb_extract_html(VALUE self, VALUE source) {
|
|
91
207
|
char* string = (char*) check_string(source);
|
|
208
|
+
|
|
209
|
+
hb_allocator_T allocator;
|
|
210
|
+
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) { return Qnil; }
|
|
211
|
+
|
|
92
212
|
hb_buffer_T output;
|
|
213
|
+
if (!hb_buffer_init(&output, strlen(string), &allocator)) { return Qnil; }
|
|
93
214
|
|
|
94
|
-
|
|
215
|
+
herb_extract_html_to_buffer(string, &output, &allocator);
|
|
95
216
|
|
|
96
|
-
|
|
217
|
+
buffer_args_T args = { .buffer_value = output.value, .allocator = allocator };
|
|
97
218
|
|
|
98
|
-
VALUE
|
|
99
|
-
|
|
219
|
+
return rb_ensure(buffer_to_string_body, (VALUE) &args, buffer_cleanup, (VALUE) &args);
|
|
220
|
+
}
|
|
100
221
|
|
|
101
|
-
|
|
222
|
+
static VALUE Herb_arena_stats(int argc, VALUE* argv, VALUE self) {
|
|
223
|
+
VALUE source, options;
|
|
224
|
+
rb_scan_args(argc, argv, "1:", &source, &options);
|
|
225
|
+
|
|
226
|
+
char* string = (char*) check_string(source);
|
|
227
|
+
|
|
228
|
+
parser_options_T parser_options = HERB_DEFAULT_PARSER_OPTIONS;
|
|
229
|
+
|
|
230
|
+
if (!NIL_P(options)) {
|
|
231
|
+
VALUE track_whitespace = rb_hash_lookup(options, rb_utf8_str_new_cstr("track_whitespace"));
|
|
232
|
+
if (NIL_P(track_whitespace)) { track_whitespace = rb_hash_lookup(options, ID2SYM(rb_intern("track_whitespace"))); }
|
|
233
|
+
if (!NIL_P(track_whitespace) && RTEST(track_whitespace)) { parser_options.track_whitespace = true; }
|
|
234
|
+
|
|
235
|
+
VALUE analyze = rb_hash_lookup(options, rb_utf8_str_new_cstr("analyze"));
|
|
236
|
+
if (NIL_P(analyze)) { analyze = rb_hash_lookup(options, ID2SYM(rb_intern("analyze"))); }
|
|
237
|
+
if (!NIL_P(analyze) && !RTEST(analyze)) { parser_options.analyze = false; }
|
|
238
|
+
|
|
239
|
+
VALUE strict = rb_hash_lookup(options, rb_utf8_str_new_cstr("strict"));
|
|
240
|
+
if (NIL_P(strict)) { strict = rb_hash_lookup(options, ID2SYM(rb_intern("strict"))); }
|
|
241
|
+
if (!NIL_P(strict)) { parser_options.strict = RTEST(strict); }
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
hb_allocator_T allocator;
|
|
245
|
+
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) { return Qnil; }
|
|
246
|
+
|
|
247
|
+
AST_DOCUMENT_NODE_T* root = herb_parse(string, &parser_options, &allocator);
|
|
248
|
+
|
|
249
|
+
hb_arena_stats_T stats = hb_arena_get_stats((hb_arena_T*) allocator.context);
|
|
250
|
+
|
|
251
|
+
if (root != NULL) { ast_node_free((AST_NODE_T*) root, &allocator); }
|
|
252
|
+
hb_allocator_destroy(&allocator);
|
|
253
|
+
|
|
254
|
+
VALUE hash = rb_hash_new();
|
|
255
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("pages")), SIZET2NUM(stats.pages));
|
|
256
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("total_capacity")), SIZET2NUM(stats.total_capacity));
|
|
257
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("total_used")), SIZET2NUM(stats.total_used));
|
|
258
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("total_available")), SIZET2NUM(stats.total_available));
|
|
259
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("allocations")), SIZET2NUM(stats.allocations));
|
|
260
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("fragmentation")), SIZET2NUM(stats.fragmentation));
|
|
261
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("default_page_size")), SIZET2NUM(stats.default_page_size));
|
|
262
|
+
|
|
263
|
+
return hash;
|
|
102
264
|
}
|
|
103
265
|
|
|
104
|
-
static VALUE
|
|
266
|
+
static VALUE make_tracking_hash(hb_allocator_tracking_stats_T* stats) {
|
|
267
|
+
VALUE hash = rb_hash_new();
|
|
268
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("allocations")), SIZET2NUM(stats->allocation_count));
|
|
269
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("deallocations")), SIZET2NUM(stats->deallocation_count));
|
|
270
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("bytes_allocated")), SIZET2NUM(stats->bytes_allocated));
|
|
271
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("bytes_deallocated")), SIZET2NUM(stats->bytes_deallocated));
|
|
272
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("untracked_deallocations")), SIZET2NUM(stats->untracked_deallocation_count));
|
|
273
|
+
|
|
274
|
+
VALUE leaks = rb_ary_new();
|
|
275
|
+
for (size_t i = 0; i < stats->buckets_capacity; i++) {
|
|
276
|
+
if (stats->buckets[i].pointer != NULL && stats->buckets[i].pointer != (void*) 1) {
|
|
277
|
+
rb_ary_push(leaks, SIZET2NUM(stats->buckets[i].size));
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("leaks")), leaks);
|
|
281
|
+
|
|
282
|
+
VALUE untracked = rb_ary_new_capa((long) stats->untracked_pointers_size);
|
|
283
|
+
for (size_t i = 0; i < stats->untracked_pointers_size; i++) {
|
|
284
|
+
rb_ary_push(untracked, rb_sprintf("%p", stats->untracked_pointers[i]));
|
|
285
|
+
}
|
|
286
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("untracked_pointers")), untracked);
|
|
287
|
+
|
|
288
|
+
return hash;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
static VALUE Herb_leak_check(VALUE self, VALUE source) {
|
|
105
292
|
char* string = (char*) check_string(source);
|
|
106
|
-
|
|
293
|
+
VALUE result = rb_hash_new();
|
|
294
|
+
|
|
295
|
+
{
|
|
296
|
+
hb_allocator_T allocator;
|
|
297
|
+
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_TRACKING)) { return Qnil; }
|
|
298
|
+
|
|
299
|
+
hb_array_T* tokens = herb_lex(string, &allocator);
|
|
300
|
+
if (tokens != NULL) { herb_free_tokens(&tokens, &allocator); }
|
|
301
|
+
|
|
302
|
+
hb_allocator_tracking_stats_T* stats = hb_allocator_tracking_stats(&allocator);
|
|
303
|
+
rb_hash_aset(result, ID2SYM(rb_intern("lex")), make_tracking_hash(stats));
|
|
304
|
+
|
|
305
|
+
hb_allocator_destroy(&allocator);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
{
|
|
309
|
+
hb_allocator_T allocator;
|
|
310
|
+
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_TRACKING)) { return Qnil; }
|
|
311
|
+
|
|
312
|
+
parser_options_T parser_options = HERB_DEFAULT_PARSER_OPTIONS;
|
|
313
|
+
AST_DOCUMENT_NODE_T* root = herb_parse(string, &parser_options, &allocator);
|
|
314
|
+
if (root != NULL) { ast_node_free((AST_NODE_T*) root, &allocator); }
|
|
315
|
+
|
|
316
|
+
hb_allocator_tracking_stats_T* stats = hb_allocator_tracking_stats(&allocator);
|
|
317
|
+
rb_hash_aset(result, ID2SYM(rb_intern("parse")), make_tracking_hash(stats));
|
|
318
|
+
|
|
319
|
+
hb_allocator_destroy(&allocator);
|
|
320
|
+
}
|
|
107
321
|
|
|
108
|
-
|
|
322
|
+
{
|
|
323
|
+
hb_allocator_T allocator;
|
|
324
|
+
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_TRACKING)) { return Qnil; }
|
|
109
325
|
|
|
110
|
-
|
|
326
|
+
hb_buffer_T output;
|
|
327
|
+
if (!hb_buffer_init(&output, strlen(string), &allocator)) { return Qnil; }
|
|
111
328
|
|
|
112
|
-
|
|
113
|
-
|
|
329
|
+
herb_extract_ruby_options_T extract_options = HERB_EXTRACT_RUBY_DEFAULT_OPTIONS;
|
|
330
|
+
herb_extract_ruby_to_buffer_with_options(string, &output, &extract_options, &allocator);
|
|
331
|
+
|
|
332
|
+
hb_allocator_tracking_stats_T* stats = hb_allocator_tracking_stats(&allocator);
|
|
333
|
+
rb_hash_aset(result, ID2SYM(rb_intern("extract_ruby")), make_tracking_hash(stats));
|
|
334
|
+
|
|
335
|
+
hb_buffer_free(&output);
|
|
336
|
+
hb_allocator_destroy(&allocator);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
{
|
|
340
|
+
hb_allocator_T allocator;
|
|
341
|
+
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_TRACKING)) { return Qnil; }
|
|
342
|
+
|
|
343
|
+
hb_buffer_T output;
|
|
344
|
+
if (!hb_buffer_init(&output, strlen(string), &allocator)) { return Qnil; }
|
|
345
|
+
|
|
346
|
+
herb_extract_html_to_buffer(string, &output, &allocator);
|
|
347
|
+
|
|
348
|
+
hb_allocator_tracking_stats_T* stats = hb_allocator_tracking_stats(&allocator);
|
|
349
|
+
rb_hash_aset(result, ID2SYM(rb_intern("extract_html")), make_tracking_hash(stats));
|
|
350
|
+
|
|
351
|
+
hb_buffer_free(&output);
|
|
352
|
+
hb_allocator_destroy(&allocator);
|
|
353
|
+
}
|
|
114
354
|
|
|
115
355
|
return result;
|
|
116
356
|
}
|
|
@@ -119,9 +359,31 @@ static VALUE Herb_version(VALUE self) {
|
|
|
119
359
|
VALUE gem_version = rb_const_get(self, rb_intern("VERSION"));
|
|
120
360
|
VALUE libherb_version = rb_utf8_str_new_cstr(herb_version());
|
|
121
361
|
VALUE libprism_version = rb_utf8_str_new_cstr(herb_prism_version());
|
|
122
|
-
|
|
362
|
+
|
|
363
|
+
#ifdef HERB_GIT_BUILD
|
|
364
|
+
# ifdef HERB_GIT_SHA
|
|
365
|
+
VALUE format_string = rb_utf8_str_new_cstr(
|
|
366
|
+
"herb gem " HERB_GIT_SHA ", libprism v%s, libherb " HERB_GIT_SHA " (Ruby C native extension, built from source)"
|
|
367
|
+
);
|
|
368
|
+
|
|
369
|
+
return rb_funcall(rb_mKernel, rb_intern("sprintf"), 2, format_string, libprism_version);
|
|
370
|
+
# else
|
|
371
|
+
VALUE format_string =
|
|
372
|
+
rb_utf8_str_new_cstr("herb gem v%s, libprism v%s, libherb v%s (Ruby C native extension, built from source)");
|
|
123
373
|
|
|
124
374
|
return rb_funcall(rb_mKernel, rb_intern("sprintf"), 4, format_string, gem_version, libprism_version, libherb_version);
|
|
375
|
+
# endif
|
|
376
|
+
#else
|
|
377
|
+
return rb_funcall(
|
|
378
|
+
rb_mKernel,
|
|
379
|
+
rb_intern("sprintf"),
|
|
380
|
+
4,
|
|
381
|
+
rb_utf8_str_new_cstr("herb gem v%s, libprism v%s, libherb v%s (Ruby C native extension)"),
|
|
382
|
+
gem_version,
|
|
383
|
+
libprism_version,
|
|
384
|
+
libherb_version
|
|
385
|
+
);
|
|
386
|
+
#endif
|
|
125
387
|
}
|
|
126
388
|
|
|
127
389
|
__attribute__((__visibility__("default"))) void Init_herb(void) {
|
|
@@ -133,12 +395,16 @@ __attribute__((__visibility__("default"))) void Init_herb(void) {
|
|
|
133
395
|
cResult = rb_define_class_under(mHerb, "Result", rb_cObject);
|
|
134
396
|
cLexResult = rb_define_class_under(mHerb, "LexResult", cResult);
|
|
135
397
|
cParseResult = rb_define_class_under(mHerb, "ParseResult", cResult);
|
|
398
|
+
cParserOptions = rb_define_class_under(mHerb, "ParserOptions", rb_cObject);
|
|
399
|
+
|
|
400
|
+
rb_init_node_classes();
|
|
401
|
+
rb_init_error_classes();
|
|
136
402
|
|
|
137
403
|
rb_define_singleton_method(mHerb, "parse", Herb_parse, -1);
|
|
138
|
-
rb_define_singleton_method(mHerb, "lex", Herb_lex, 1);
|
|
139
|
-
rb_define_singleton_method(mHerb, "
|
|
140
|
-
rb_define_singleton_method(mHerb, "lex_file", Herb_lex_file, 1);
|
|
141
|
-
rb_define_singleton_method(mHerb, "extract_ruby", Herb_extract_ruby, 1);
|
|
404
|
+
rb_define_singleton_method(mHerb, "lex", Herb_lex, -1);
|
|
405
|
+
rb_define_singleton_method(mHerb, "extract_ruby", Herb_extract_ruby, -1);
|
|
142
406
|
rb_define_singleton_method(mHerb, "extract_html", Herb_extract_html, 1);
|
|
407
|
+
rb_define_singleton_method(mHerb, "arena_stats", Herb_arena_stats, -1);
|
|
408
|
+
rb_define_singleton_method(mHerb, "leak_check", Herb_leak_check, 1);
|
|
143
409
|
rb_define_singleton_method(mHerb, "version", Herb_version, 0);
|
|
144
410
|
}
|
data/ext/herb/extension.h
CHANGED
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
#include "nodes.h"
|
|
6
6
|
|
|
7
7
|
#include "../../src/include/herb.h"
|
|
8
|
-
#include "../../src/include/io.h"
|
|
9
8
|
#include "../../src/include/location.h"
|
|
10
9
|
#include "../../src/include/position.h"
|
|
11
10
|
#include "../../src/include/token.h"
|
|
11
|
+
#include "../../src/include/util/hb_allocator.h"
|
|
12
|
+
#include "../../src/include/util/hb_string.h"
|
|
12
13
|
|
|
13
14
|
const char* check_string(VALUE value) {
|
|
14
15
|
if (NIL_P(value)) { return NULL; }
|
|
@@ -44,14 +45,19 @@ VALUE rb_range_from_c_struct(range_T range) {
|
|
|
44
45
|
return rb_class_new_instance(2, args, cRange);
|
|
45
46
|
}
|
|
46
47
|
|
|
48
|
+
VALUE rb_string_from_hb_string(hb_string_T string) {
|
|
49
|
+
if (hb_string_is_null(string)) { return Qnil; }
|
|
50
|
+
|
|
51
|
+
return rb_utf8_str_new(string.data, string.length);
|
|
52
|
+
}
|
|
53
|
+
|
|
47
54
|
VALUE rb_token_from_c_struct(token_T* token) {
|
|
48
55
|
if (!token) { return Qnil; }
|
|
49
56
|
|
|
50
|
-
VALUE value =
|
|
51
|
-
|
|
57
|
+
VALUE value = rb_string_from_hb_string(token->value);
|
|
52
58
|
VALUE range = rb_range_from_c_struct(token->range);
|
|
53
59
|
VALUE location = rb_location_from_c_struct(token->location);
|
|
54
|
-
VALUE type =
|
|
60
|
+
VALUE type = rb_string_from_hb_string(token_type_to_string(token->type));
|
|
55
61
|
|
|
56
62
|
VALUE args[4] = { value, range, location, type };
|
|
57
63
|
|
|
@@ -73,21 +79,24 @@ VALUE create_lex_result(hb_array_T* tokens, VALUE source) {
|
|
|
73
79
|
return rb_class_new_instance(4, args, cLexResult);
|
|
74
80
|
}
|
|
75
81
|
|
|
76
|
-
VALUE create_parse_result(AST_DOCUMENT_NODE_T* root, VALUE source) {
|
|
82
|
+
VALUE create_parse_result(AST_DOCUMENT_NODE_T* root, VALUE source, const parser_options_T* options) {
|
|
77
83
|
VALUE value = rb_node_from_c_struct((AST_NODE_T*) root);
|
|
78
84
|
VALUE warnings = rb_ary_new();
|
|
79
85
|
VALUE errors = rb_ary_new();
|
|
80
86
|
|
|
81
|
-
VALUE
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
87
|
+
VALUE kwargs = rb_hash_new();
|
|
88
|
+
rb_hash_aset(kwargs, ID2SYM(rb_intern("strict")), options->strict ? Qtrue : Qfalse);
|
|
89
|
+
rb_hash_aset(kwargs, ID2SYM(rb_intern("track_whitespace")), options->track_whitespace ? Qtrue : Qfalse);
|
|
90
|
+
rb_hash_aset(kwargs, ID2SYM(rb_intern("analyze")), options->analyze ? Qtrue : Qfalse);
|
|
91
|
+
rb_hash_aset(kwargs, ID2SYM(rb_intern("action_view_helpers")), options->action_view_helpers ? Qtrue : Qfalse);
|
|
92
|
+
rb_hash_aset(kwargs, ID2SYM(rb_intern("prism_nodes")), options->prism_nodes ? Qtrue : Qfalse);
|
|
93
|
+
rb_hash_aset(kwargs, ID2SYM(rb_intern("prism_nodes_deep")), options->prism_nodes_deep ? Qtrue : Qfalse);
|
|
94
|
+
rb_hash_aset(kwargs, ID2SYM(rb_intern("prism_program")), options->prism_program ? Qtrue : Qfalse);
|
|
85
95
|
|
|
86
|
-
VALUE
|
|
87
|
-
|
|
88
|
-
VALUE source_value = rb_utf8_str_new_cstr(source);
|
|
96
|
+
VALUE parser_options_args[1] = { kwargs };
|
|
97
|
+
VALUE parser_options = rb_class_new_instance_kw(1, parser_options_args, cParserOptions, RB_PASS_KEYWORDS);
|
|
89
98
|
|
|
90
|
-
|
|
99
|
+
VALUE args[5] = { value, source, warnings, errors, parser_options };
|
|
91
100
|
|
|
92
|
-
return
|
|
101
|
+
return rb_class_new_instance(5, args, cParseResult);
|
|
93
102
|
}
|