herb 0.11.1 → 0.11.2
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 +6 -0
- data/ext/herb/extconf.rb +8 -31
- data/ext/herb/nodes.c +75 -75
- data/ext/herb/parser_options_helpers.c +26 -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/configuration.rb +11 -1
- data/lib/herb/dev/classifier.rb +1 -1
- data/lib/herb/engine/compiler.rb +5 -8
- data/lib/herb/engine/slots/dynamics_compiler.rb +53 -14
- data/lib/herb/engine/slots/subtree_compiler.rb +1 -1
- data/lib/herb/engine/slots/visitor.rb +32 -4
- data/lib/herb/engine/visitors/instrumentation_visitor.rb +18 -6
- 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/configuration.rbs +3 -0
- data/sig/herb/engine/slots/dynamics_compiler.rbs +24 -7
- data/sig/herb/engine/slots/visitor.rbs +14 -0
- 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/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 +6 -13
- data/src/analyze/action_view/tag_helpers.c +139 -90
- data/src/analyze/action_view/turbo_frame_tag.c +5 -4
- data/src/analyze/analyze.c +35 -19
- data/src/analyze/analyze_helpers.c +161 -188
- data/src/analyze/analyzed_ruby.c +8 -7
- data/src/analyze/control_type.c +29 -22
- 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 +29 -28
- 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/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 -2
- data/src/include/analyze/analyzed_ruby.h +4 -2
- data/src/include/analyze/helpers.h +6 -6
- data/src/include/herb.h +3 -2
- data/src/include/parser/parser_options.h +5 -0
- 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/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 +84 -50
- 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/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/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 +5 -5
- 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
|
@@ -1,153 +1,93 @@
|
|
|
1
1
|
#line <%= __LINE__ + 1 %> "prism/templates/src/<%= File.basename(__FILE__) %>"
|
|
2
|
-
#include "prism/node.h"
|
|
2
|
+
#include "prism/internal/node.h"
|
|
3
|
+
|
|
4
|
+
#include "prism/internal/arena.h"
|
|
5
|
+
|
|
6
|
+
#include <stdlib.h>
|
|
3
7
|
|
|
4
8
|
/**
|
|
5
9
|
* Attempts to grow the node list to the next size. If there is already
|
|
6
|
-
* capacity in the list, this function does nothing. Otherwise it
|
|
7
|
-
*
|
|
8
|
-
*
|
|
10
|
+
* capacity in the list, this function does nothing. Otherwise it allocates a
|
|
11
|
+
* new array from the arena (abandon-and-copy strategy) and copies the existing
|
|
12
|
+
* data into it.
|
|
9
13
|
*/
|
|
10
|
-
static
|
|
11
|
-
pm_node_list_grow(pm_node_list_t *list, size_t size) {
|
|
14
|
+
static void
|
|
15
|
+
pm_node_list_grow(pm_arena_t *arena, pm_node_list_t *list, size_t size) {
|
|
12
16
|
size_t requested_size = list->size + size;
|
|
13
17
|
|
|
14
|
-
//
|
|
15
|
-
if (requested_size < list->size)
|
|
18
|
+
// Guard against overflow on the addition.
|
|
19
|
+
if (requested_size < list->size) abort();
|
|
16
20
|
|
|
17
|
-
// If the requested size is within the existing capacity, return
|
|
18
|
-
if (requested_size
|
|
21
|
+
// If the requested size is within the existing capacity, return.
|
|
22
|
+
if (requested_size <= list->capacity) return;
|
|
19
23
|
|
|
20
|
-
// Otherwise,
|
|
24
|
+
// Otherwise, compute the next capacity by doubling.
|
|
21
25
|
size_t next_capacity = list->capacity == 0 ? 4 : list->capacity * 2;
|
|
22
26
|
|
|
23
|
-
//
|
|
24
|
-
if (next_capacity < list->capacity) return false;
|
|
25
|
-
|
|
26
|
-
// If we didn't get enough by doubling, keep doubling until we do.
|
|
27
|
+
// Guard against overflow on the doubling.
|
|
27
28
|
while (requested_size > next_capacity) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
// Ensure we didn't overflow by multiplying by 2.
|
|
31
|
-
if (double_capacity < next_capacity) return false;
|
|
32
|
-
next_capacity = double_capacity;
|
|
29
|
+
if (next_capacity == 0) abort();
|
|
30
|
+
next_capacity *= 2;
|
|
33
31
|
}
|
|
34
32
|
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
// Allocate a new array from the arena (old array is abandoned).
|
|
34
|
+
pm_node_t **nodes = (pm_node_t **) pm_arena_alloc(arena, sizeof(pm_node_t *) * next_capacity, PRISM_ALIGNOF(pm_node_t *));
|
|
35
|
+
|
|
36
|
+
// Copy old data into the new array.
|
|
37
|
+
if (list->size > 0) {
|
|
38
|
+
memcpy(nodes, list->nodes, list->size * sizeof(pm_node_t *));
|
|
39
|
+
}
|
|
37
40
|
|
|
38
41
|
list->nodes = nodes;
|
|
39
42
|
list->capacity = next_capacity;
|
|
40
|
-
return true;
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
/**
|
|
44
|
-
*
|
|
46
|
+
* Slow path for pm_node_list_append_inline: grow the list and append the node.
|
|
47
|
+
* Do not call directly - use pm_node_list_append_inline instead.
|
|
45
48
|
*/
|
|
46
49
|
void
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
50
|
+
pm_node_list_append_slow(pm_arena_t *arena, pm_node_list_t *list, pm_node_t *node) {
|
|
51
|
+
pm_node_list_grow(arena, list, 1);
|
|
52
|
+
list->nodes[list->size++] = node;
|
|
51
53
|
}
|
|
52
54
|
|
|
53
55
|
/**
|
|
54
|
-
*
|
|
56
|
+
* Append a new node onto the end of the node list.
|
|
55
57
|
*/
|
|
56
58
|
void
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
memmove(list->nodes + 1, list->nodes, list->size * sizeof(pm_node_t *));
|
|
60
|
-
list->nodes[0] = node;
|
|
61
|
-
list->size++;
|
|
62
|
-
}
|
|
59
|
+
pm_node_list_append(pm_arena_t *arena, pm_node_list_t *list, pm_node_t *node) {
|
|
60
|
+
pm_node_list_append_inline(arena, list, node);
|
|
63
61
|
}
|
|
64
62
|
|
|
65
63
|
/**
|
|
66
|
-
*
|
|
64
|
+
* Prepend a new node onto the beginning of the node list.
|
|
67
65
|
*/
|
|
68
66
|
void
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
67
|
+
pm_node_list_prepend(pm_arena_t *arena, pm_node_list_t *list, pm_node_t *node) {
|
|
68
|
+
pm_node_list_grow(arena, list, 1);
|
|
69
|
+
memmove(list->nodes + 1, list->nodes, list->size * sizeof(pm_node_t *));
|
|
70
|
+
list->nodes[0] = node;
|
|
71
|
+
list->size++;
|
|
74
72
|
}
|
|
75
73
|
|
|
76
74
|
/**
|
|
77
|
-
*
|
|
75
|
+
* Concatenate the given node list onto the end of the other node list.
|
|
78
76
|
*/
|
|
79
77
|
void
|
|
80
|
-
|
|
81
|
-
if (
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
PRISM_EXPORTED_FUNCTION void
|
|
88
|
-
pm_node_destroy(pm_parser_t *parser, pm_node_t *node);
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Destroy the nodes that are contained within the given node list.
|
|
92
|
-
*/
|
|
93
|
-
static void
|
|
94
|
-
pm_node_list_destroy(pm_parser_t *parser, pm_node_list_t *list) {
|
|
95
|
-
pm_node_t *node;
|
|
96
|
-
PM_NODE_LIST_FOREACH(list, index, node) pm_node_destroy(parser, node);
|
|
97
|
-
pm_node_list_free(list);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Deallocate the space for a pm_node_t. Similarly to pm_node_alloc, we're not
|
|
102
|
-
* using the parser argument, but it's there to allow for the future possibility
|
|
103
|
-
* of pre-allocating larger memory pools.
|
|
104
|
-
*/
|
|
105
|
-
PRISM_EXPORTED_FUNCTION void
|
|
106
|
-
pm_node_destroy(pm_parser_t *parser, pm_node_t *node) {
|
|
107
|
-
switch (PM_NODE_TYPE(node)) {
|
|
108
|
-
<%- nodes.each do |node| -%>
|
|
109
|
-
#line <%= __LINE__ + 1 %> "prism/templates/src/<%= File.basename(__FILE__) %>"
|
|
110
|
-
case <%= node.type %>: {
|
|
111
|
-
<%- if node.fields.any? { |field| ![Prism::Template::LocationField, Prism::Template::OptionalLocationField, Prism::Template::UInt8Field, Prism::Template::UInt32Field, Prism::Template::ConstantField, Prism::Template::OptionalConstantField, Prism::Template::DoubleField].include?(field.class) } -%>
|
|
112
|
-
pm_<%= node.human %>_t *cast = (pm_<%= node.human %>_t *) node;
|
|
113
|
-
<%- end -%>
|
|
114
|
-
<%- node.fields.each do |field| -%>
|
|
115
|
-
<%- case field -%>
|
|
116
|
-
<%- when Prism::Template::LocationField, Prism::Template::OptionalLocationField, Prism::Template::UInt8Field, Prism::Template::UInt32Field, Prism::Template::ConstantField, Prism::Template::OptionalConstantField, Prism::Template::DoubleField -%>
|
|
117
|
-
<%- when Prism::Template::NodeField -%>
|
|
118
|
-
pm_node_destroy(parser, (pm_node_t *)cast-><%= field.name %>);
|
|
119
|
-
<%- when Prism::Template::OptionalNodeField -%>
|
|
120
|
-
if (cast-><%= field.name %> != NULL) {
|
|
121
|
-
pm_node_destroy(parser, (pm_node_t *)cast-><%= field.name %>);
|
|
122
|
-
}
|
|
123
|
-
<%- when Prism::Template::StringField -%>
|
|
124
|
-
pm_string_free(&cast-><%= field.name %>);
|
|
125
|
-
<%- when Prism::Template::NodeListField -%>
|
|
126
|
-
pm_node_list_destroy(parser, &cast-><%= field.name %>);
|
|
127
|
-
<%- when Prism::Template::ConstantListField -%>
|
|
128
|
-
pm_constant_id_list_free(&cast-><%= field.name %>);
|
|
129
|
-
<%- when Prism::Template::IntegerField -%>
|
|
130
|
-
pm_integer_free(&cast-><%= field.name %>);
|
|
131
|
-
<%- else -%>
|
|
132
|
-
<%- raise -%>
|
|
133
|
-
<%- end -%>
|
|
134
|
-
<%- end -%>
|
|
135
|
-
break;
|
|
136
|
-
}
|
|
137
|
-
<%- end -%>
|
|
138
|
-
#line <%= __LINE__ + 1 %> "prism/templates/src/<%= File.basename(__FILE__) %>"
|
|
139
|
-
default:
|
|
140
|
-
assert(false && "unreachable");
|
|
141
|
-
break;
|
|
78
|
+
pm_node_list_concat(pm_arena_t *arena, pm_node_list_t *list, pm_node_list_t *other) {
|
|
79
|
+
if (other->size > 0) {
|
|
80
|
+
pm_node_list_grow(arena, list, other->size);
|
|
81
|
+
memcpy(list->nodes + list->size, other->nodes, other->size * sizeof(pm_node_t *));
|
|
82
|
+
list->size += other->size;
|
|
142
83
|
}
|
|
143
|
-
xfree(node);
|
|
144
84
|
}
|
|
145
85
|
|
|
146
86
|
/**
|
|
147
87
|
* Returns a string representation of the given node type.
|
|
148
88
|
*/
|
|
149
|
-
|
|
150
|
-
|
|
89
|
+
const char *
|
|
90
|
+
pm_node_type(pm_node_type_t node_type)
|
|
151
91
|
{
|
|
152
92
|
switch (node_type) {
|
|
153
93
|
<%- nodes.each do |node| -%>
|
|
@@ -160,24 +100,26 @@ pm_node_type_to_str(pm_node_type_t node_type)
|
|
|
160
100
|
|
|
161
101
|
/**
|
|
162
102
|
* Visit each of the nodes in this subtree using the given visitor callback. The
|
|
163
|
-
* callback function will be called for each node in the subtree
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
* see fit.
|
|
103
|
+
* callback function will be called for each node in the subtree, and its
|
|
104
|
+
* return value determines whether the walk visits that node's children, skips
|
|
105
|
+
* them, or stops entirely. The data parameter is treated as an opaque pointer
|
|
106
|
+
* and is passed to the visitor callback for consumers to use as they see fit.
|
|
168
107
|
*/
|
|
169
|
-
|
|
170
|
-
pm_visit_node(const pm_node_t *node,
|
|
171
|
-
|
|
108
|
+
bool
|
|
109
|
+
pm_visit_node(const pm_node_t *node, pm_visit_callback_t visitor, void *data) {
|
|
110
|
+
pm_visit_result_t result = visitor(node, data);
|
|
111
|
+
if (result == PM_VISIT_DESCEND) return pm_visit_child_nodes(node, visitor, data);
|
|
112
|
+
return result != PM_VISIT_STOP;
|
|
172
113
|
}
|
|
173
114
|
|
|
174
115
|
/**
|
|
175
116
|
* Visit the children of the given node with the given callback. This is the
|
|
176
117
|
* default behavior for walking the tree that is called from pm_visit_node if
|
|
177
|
-
* the callback returns
|
|
118
|
+
* the callback returns PM_VISIT_DESCEND. A stop from any child returns false
|
|
119
|
+
* immediately, so that it propagates up through every enclosing call.
|
|
178
120
|
*/
|
|
179
|
-
|
|
180
|
-
pm_visit_child_nodes(const pm_node_t *node,
|
|
121
|
+
bool
|
|
122
|
+
pm_visit_child_nodes(const pm_node_t *node, pm_visit_callback_t visitor, void *data) {
|
|
181
123
|
switch (PM_NODE_TYPE(node)) {
|
|
182
124
|
<%- nodes.each do |node| -%>
|
|
183
125
|
<%- if (fields = node.fields.select { |field| field.is_a?(Prism::Template::NodeField) || field.is_a?(Prism::Template::OptionalNodeField) || field.is_a?(Prism::Template::NodeListField) }).any? -%>
|
|
@@ -188,15 +130,13 @@ pm_visit_child_nodes(const pm_node_t *node, bool (*visitor)(const pm_node_t *nod
|
|
|
188
130
|
// Visit the <%= field.name %> field
|
|
189
131
|
<%- case field -%>
|
|
190
132
|
<%- when Prism::Template::NodeField -%>
|
|
191
|
-
pm_visit_node((const pm_node_t *) cast-><%= field.name %>, visitor, data);
|
|
133
|
+
if (!pm_visit_node((const pm_node_t *) cast-><%= field.name %>, visitor, data)) return false;
|
|
192
134
|
<%- when Prism::Template::OptionalNodeField -%>
|
|
193
|
-
if (cast-><%= field.name %> != NULL)
|
|
194
|
-
pm_visit_node((const pm_node_t *) cast-><%= field.name %>, visitor, data);
|
|
195
|
-
}
|
|
135
|
+
if (cast-><%= field.name %> != NULL && !pm_visit_node((const pm_node_t *) cast-><%= field.name %>, visitor, data)) return false;
|
|
196
136
|
<%- when Prism::Template::NodeListField -%>
|
|
197
137
|
const pm_node_list_t *<%= field.name %> = &cast-><%= field.name %>;
|
|
198
138
|
for (size_t index = 0; index < <%= field.name %>->size; index++) {
|
|
199
|
-
pm_visit_node(<%= field.name %>->nodes[index], visitor, data);
|
|
139
|
+
if (!pm_visit_node(<%= field.name %>->nodes[index], visitor, data)) return false;
|
|
200
140
|
}
|
|
201
141
|
<%- end -%>
|
|
202
142
|
<%- end -%>
|
|
@@ -211,123 +151,26 @@ pm_visit_child_nodes(const pm_node_t *node, bool (*visitor)(const pm_node_t *nod
|
|
|
211
151
|
case PM_SCOPE_NODE:
|
|
212
152
|
break;
|
|
213
153
|
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// We optionally support dumping to JSON. For systems that don't want or need
|
|
217
|
-
// this functionality, it can be turned off with the PRISM_EXCLUDE_JSON define.
|
|
218
|
-
#ifndef PRISM_EXCLUDE_JSON
|
|
219
154
|
|
|
220
|
-
|
|
221
|
-
pm_dump_json_constant(pm_buffer_t *buffer, const pm_parser_t *parser, pm_constant_id_t constant_id) {
|
|
222
|
-
const pm_constant_t *constant = pm_constant_pool_id_to_constant(&parser->constant_pool, constant_id);
|
|
223
|
-
pm_buffer_append_byte(buffer, '"');
|
|
224
|
-
pm_buffer_append_source(buffer, constant->start, constant->length, PM_BUFFER_ESCAPING_JSON);
|
|
225
|
-
pm_buffer_append_byte(buffer, '"');
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
static void
|
|
229
|
-
pm_dump_json_location(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_location_t *location) {
|
|
230
|
-
uint32_t start = (uint32_t) (location->start - parser->start);
|
|
231
|
-
uint32_t end = (uint32_t) (location->end - parser->start);
|
|
232
|
-
pm_buffer_append_format(buffer, "{\"start\":%" PRIu32 ",\"end\":%" PRIu32 "}", start, end);
|
|
155
|
+
return true;
|
|
233
156
|
}
|
|
157
|
+
<%- nodes.each do |node| -%>
|
|
234
158
|
|
|
159
|
+
<%- params = node.fields.map(&:c_param) -%>
|
|
235
160
|
/**
|
|
236
|
-
*
|
|
161
|
+
* Allocate and initialize a new <%= node.name %> node.
|
|
237
162
|
*/
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
// Dump the <%= field.name %> field
|
|
250
|
-
pm_buffer_append_byte(buffer, ',');
|
|
251
|
-
pm_buffer_append_string(buffer, "\"<%= field.name %>\":", <%= field.name.bytesize + 3 %>);
|
|
252
|
-
<%- case field -%>
|
|
253
|
-
<%- when Prism::Template::NodeField -%>
|
|
254
|
-
pm_dump_json(buffer, parser, (const pm_node_t *) cast-><%= field.name %>);
|
|
255
|
-
<%- when Prism::Template::OptionalNodeField -%>
|
|
256
|
-
if (cast-><%= field.name %> != NULL) {
|
|
257
|
-
pm_dump_json(buffer, parser, (const pm_node_t *) cast-><%= field.name %>);
|
|
258
|
-
} else {
|
|
259
|
-
pm_buffer_append_string(buffer, "null", 4);
|
|
260
|
-
}
|
|
261
|
-
<%- when Prism::Template::NodeListField -%>
|
|
262
|
-
const pm_node_list_t *<%= field.name %> = &cast-><%= field.name %>;
|
|
263
|
-
pm_buffer_append_byte(buffer, '[');
|
|
264
|
-
|
|
265
|
-
for (size_t index = 0; index < <%= field.name %>->size; index++) {
|
|
266
|
-
if (index != 0) pm_buffer_append_byte(buffer, ',');
|
|
267
|
-
pm_dump_json(buffer, parser, <%= field.name %>->nodes[index]);
|
|
268
|
-
}
|
|
269
|
-
pm_buffer_append_byte(buffer, ']');
|
|
270
|
-
<%- when Prism::Template::StringField -%>
|
|
271
|
-
const pm_string_t *<%= field.name %> = &cast-><%= field.name %>;
|
|
272
|
-
pm_buffer_append_byte(buffer, '"');
|
|
273
|
-
pm_buffer_append_source(buffer, pm_string_source(<%= field.name %>), pm_string_length(<%= field.name %>), PM_BUFFER_ESCAPING_JSON);
|
|
274
|
-
pm_buffer_append_byte(buffer, '"');
|
|
275
|
-
<%- when Prism::Template::ConstantField -%>
|
|
276
|
-
pm_dump_json_constant(buffer, parser, cast-><%= field.name %>);
|
|
277
|
-
<%- when Prism::Template::OptionalConstantField -%>
|
|
278
|
-
if (cast-><%= field.name %> != PM_CONSTANT_ID_UNSET) {
|
|
279
|
-
pm_dump_json_constant(buffer, parser, cast-><%= field.name %>);
|
|
280
|
-
} else {
|
|
281
|
-
pm_buffer_append_string(buffer, "null", 4);
|
|
282
|
-
}
|
|
283
|
-
<%- when Prism::Template::ConstantListField -%>
|
|
284
|
-
const pm_constant_id_list_t *<%= field.name %> = &cast-><%= field.name %>;
|
|
285
|
-
pm_buffer_append_byte(buffer, '[');
|
|
286
|
-
|
|
287
|
-
for (size_t index = 0; index < <%= field.name %>->size; index++) {
|
|
288
|
-
if (index != 0) pm_buffer_append_byte(buffer, ',');
|
|
289
|
-
pm_dump_json_constant(buffer, parser, <%= field.name %>->ids[index]);
|
|
290
|
-
}
|
|
291
|
-
pm_buffer_append_byte(buffer, ']');
|
|
292
|
-
<%- when Prism::Template::LocationField -%>
|
|
293
|
-
pm_dump_json_location(buffer, parser, &cast-><%= field.name %>);
|
|
294
|
-
<%- when Prism::Template::OptionalLocationField -%>
|
|
295
|
-
if (cast-><%= field.name %>.start != NULL) {
|
|
296
|
-
pm_dump_json_location(buffer, parser, &cast-><%= field.name %>);
|
|
297
|
-
} else {
|
|
298
|
-
pm_buffer_append_string(buffer, "null", 4);
|
|
299
|
-
}
|
|
300
|
-
<%- when Prism::Template::UInt8Field -%>
|
|
301
|
-
pm_buffer_append_format(buffer, "%" PRIu8, cast-><%= field.name %>);
|
|
302
|
-
<%- when Prism::Template::UInt32Field -%>
|
|
303
|
-
pm_buffer_append_format(buffer, "%" PRIu32, cast-><%= field.name %>);
|
|
304
|
-
<%- when Prism::Template::Flags -%>
|
|
305
|
-
size_t flags = 0;
|
|
306
|
-
pm_buffer_append_byte(buffer, '[');
|
|
307
|
-
<%- node.flags.values.each_with_index do |value, index| -%>
|
|
308
|
-
if (PM_NODE_FLAG_P(cast, PM_<%= node.flags.human.upcase %>_<%= value.name %>)) {
|
|
309
|
-
if (flags != 0) pm_buffer_append_byte(buffer, ',');
|
|
310
|
-
pm_buffer_append_string(buffer, "\"<%= value.name %>\"", <%= value.name.bytesize + 2 %>);
|
|
311
|
-
flags++;
|
|
312
|
-
}
|
|
313
|
-
<%- end -%>
|
|
314
|
-
pm_buffer_append_byte(buffer, ']');
|
|
315
|
-
<%- when Prism::Template::IntegerField -%>
|
|
316
|
-
pm_integer_string(buffer, &cast-><%= field.name %>);
|
|
317
|
-
<%- when Prism::Template::DoubleField -%>
|
|
318
|
-
pm_buffer_append_format(buffer, "%f", cast-><%= field.name %>);
|
|
319
|
-
<%- else -%>
|
|
320
|
-
<%- raise %>
|
|
321
|
-
<%- end -%>
|
|
322
|
-
<%- end -%>
|
|
163
|
+
pm_<%= node.human %>_t *
|
|
164
|
+
pm_<%= node.human %>_new(pm_arena_t *arena, uint32_t node_id, pm_node_flags_t flags, pm_location_t location<%= params.empty? ? "" : ", #{params.join(", ")}" %>) {
|
|
165
|
+
pm_<%= node.human %>_t *node = (pm_<%= node.human %>_t *) pm_arena_alloc(arena, sizeof(pm_<%= node.human %>_t), PRISM_ALIGNOF(pm_<%= node.human %>_t));
|
|
166
|
+
|
|
167
|
+
*node = (pm_<%= node.human %>_t) {
|
|
168
|
+
.base = { .type = <%= node.type %>, .flags = flags, .node_id = node_id, .location = location }<%= node.fields.empty? ? "" : "," %>
|
|
169
|
+
<%- node.fields.each_with_index do |field, index| -%>
|
|
170
|
+
.<%= field.name %> = <%= field.name %><%= index < node.fields.size - 1 ? "," : "" %>
|
|
171
|
+
<%- end -%>
|
|
172
|
+
};
|
|
323
173
|
|
|
324
|
-
|
|
325
|
-
break;
|
|
326
|
-
}
|
|
327
|
-
<%- end -%>
|
|
328
|
-
case PM_SCOPE_NODE:
|
|
329
|
-
break;
|
|
330
|
-
}
|
|
174
|
+
return node;
|
|
331
175
|
}
|
|
332
|
-
|
|
333
|
-
#endif
|
|
176
|
+
<%- end -%>
|
|
@@ -1,23 +1,34 @@
|
|
|
1
1
|
<%# encoding: ASCII -%>
|
|
2
2
|
#include "prism/prettyprint.h"
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
/* We optionally support pretty printing nodes. For systems that don't want or
|
|
5
|
+
* need this functionality, it can be turned off with the
|
|
6
|
+
* PRISM_EXCLUDE_PRETTYPRINT define. */
|
|
7
7
|
#ifdef PRISM_EXCLUDE_PRETTYPRINT
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
/* Ensure this translation unit is never empty, even when prettyprint is
|
|
10
|
+
* excluded. */
|
|
11
|
+
typedef int pm_prettyprint_unused_t;
|
|
10
12
|
|
|
11
13
|
#else
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
#include "prism/compiler/inline.h"
|
|
16
|
+
#include "prism/internal/buffer.h"
|
|
17
|
+
#include "prism/internal/constant_pool.h"
|
|
18
|
+
#include "prism/internal/integer.h"
|
|
19
|
+
#include "prism/internal/parser.h"
|
|
20
|
+
#include "prism/line_offset_list.h"
|
|
21
|
+
|
|
22
|
+
#include <inttypes.h>
|
|
23
|
+
|
|
24
|
+
static PRISM_INLINE void
|
|
14
25
|
prettyprint_location(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_location_t *location) {
|
|
15
|
-
pm_line_column_t start =
|
|
16
|
-
pm_line_column_t end =
|
|
26
|
+
pm_line_column_t start = pm_line_offset_list_line_column(&parser->line_offsets, location->start, parser->start_line);
|
|
27
|
+
pm_line_column_t end = pm_line_offset_list_line_column(&parser->line_offsets, location->start + location->length, parser->start_line);
|
|
17
28
|
pm_buffer_append_format(output_buffer, "(%" PRIi32 ",%" PRIu32 ")-(%" PRIi32 ",%" PRIu32 ")", start.line, start.column, end.line, end.column);
|
|
18
29
|
}
|
|
19
30
|
|
|
20
|
-
static
|
|
31
|
+
static PRISM_INLINE void
|
|
21
32
|
prettyprint_constant(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_constant_id_t constant_id) {
|
|
22
33
|
pm_constant_t *constant = pm_constant_pool_id_to_constant(&parser->constant_pool, constant_id);
|
|
23
34
|
pm_buffer_append_format(output_buffer, ":%.*s", (int) constant->length, constant->start);
|
|
@@ -106,17 +117,17 @@ prettyprint_node(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm
|
|
|
106
117
|
pm_buffer_append_byte(output_buffer, ' ');
|
|
107
118
|
prettyprint_location(output_buffer, parser, location);
|
|
108
119
|
pm_buffer_append_string(output_buffer, " = \"", 4);
|
|
109
|
-
pm_buffer_append_source(output_buffer, location->start, (size_t)
|
|
120
|
+
pm_buffer_append_source(output_buffer, parser->start + location->start, (size_t) location->length, PM_BUFFER_ESCAPING_RUBY);
|
|
110
121
|
pm_buffer_append_string(output_buffer, "\"\n", 2);
|
|
111
122
|
<%- when Prism::Template::OptionalLocationField -%>
|
|
112
123
|
pm_location_t *location = &cast-><%= field.name %>;
|
|
113
|
-
if (location->
|
|
124
|
+
if (location->length == 0) {
|
|
114
125
|
pm_buffer_append_string(output_buffer, " nil\n", 5);
|
|
115
126
|
} else {
|
|
116
127
|
pm_buffer_append_byte(output_buffer, ' ');
|
|
117
128
|
prettyprint_location(output_buffer, parser, location);
|
|
118
129
|
pm_buffer_append_string(output_buffer, " = \"", 4);
|
|
119
|
-
pm_buffer_append_source(output_buffer, location->start, (size_t)
|
|
130
|
+
pm_buffer_append_source(output_buffer, parser->start + location->start, (size_t) location->length, PM_BUFFER_ESCAPING_RUBY);
|
|
120
131
|
pm_buffer_append_string(output_buffer, "\"\n", 2);
|
|
121
132
|
}
|
|
122
133
|
<%- when Prism::Template::UInt8Field -%>
|
|
@@ -156,11 +167,11 @@ prettyprint_node(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm
|
|
|
156
167
|
/**
|
|
157
168
|
* Pretty-prints the AST represented by the given node to the given buffer.
|
|
158
169
|
*/
|
|
159
|
-
|
|
170
|
+
void
|
|
160
171
|
pm_prettyprint(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_node_t *node) {
|
|
161
172
|
pm_buffer_t prefix_buffer = { 0 };
|
|
162
173
|
prettyprint_node(output_buffer, parser, node, &prefix_buffer);
|
|
163
|
-
|
|
174
|
+
pm_buffer_cleanup(&prefix_buffer);
|
|
164
175
|
}
|
|
165
176
|
|
|
166
177
|
#endif
|