prism 0.17.1 → 0.19.0
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/CHANGELOG.md +60 -1
- data/Makefile +5 -5
- data/README.md +4 -3
- data/config.yml +214 -68
- data/docs/build_system.md +6 -6
- data/docs/building.md +10 -3
- data/docs/configuration.md +11 -9
- data/docs/encoding.md +92 -88
- data/docs/heredocs.md +1 -1
- data/docs/javascript.md +29 -1
- data/docs/local_variable_depth.md +229 -0
- data/docs/ruby_api.md +16 -0
- data/docs/serialization.md +18 -13
- data/ext/prism/api_node.c +411 -240
- data/ext/prism/extconf.rb +97 -127
- data/ext/prism/extension.c +97 -33
- data/ext/prism/extension.h +1 -1
- data/include/prism/ast.h +377 -159
- data/include/prism/defines.h +17 -0
- data/include/prism/diagnostic.h +38 -6
- data/include/prism/{enc/pm_encoding.h → encoding.h} +126 -64
- data/include/prism/options.h +2 -2
- data/include/prism/parser.h +62 -36
- data/include/prism/regexp.h +2 -2
- data/include/prism/util/pm_buffer.h +9 -1
- data/include/prism/util/pm_memchr.h +2 -2
- data/include/prism/util/pm_strpbrk.h +3 -3
- data/include/prism/version.h +3 -3
- data/include/prism.h +13 -15
- data/lib/prism/compiler.rb +15 -3
- data/lib/prism/debug.rb +13 -4
- data/lib/prism/desugar_compiler.rb +4 -3
- data/lib/prism/dispatcher.rb +70 -14
- data/lib/prism/dot_visitor.rb +4612 -0
- data/lib/prism/dsl.rb +77 -57
- data/lib/prism/ffi.rb +19 -6
- data/lib/prism/lex_compat.rb +19 -9
- data/lib/prism/mutation_compiler.rb +26 -6
- data/lib/prism/node.rb +1314 -522
- data/lib/prism/node_ext.rb +102 -19
- data/lib/prism/parse_result.rb +58 -27
- data/lib/prism/ripper_compat.rb +49 -34
- data/lib/prism/serialize.rb +251 -227
- data/lib/prism/visitor.rb +15 -3
- data/lib/prism.rb +21 -4
- data/prism.gemspec +7 -9
- data/rbi/prism.rbi +688 -284
- data/rbi/prism_static.rbi +3 -0
- data/sig/prism.rbs +426 -156
- data/sig/prism_static.rbs +1 -0
- data/src/diagnostic.c +280 -216
- data/src/encoding.c +5137 -0
- data/src/node.c +99 -21
- data/src/options.c +21 -2
- data/src/prettyprint.c +1743 -1241
- data/src/prism.c +1774 -831
- data/src/regexp.c +15 -15
- data/src/serialize.c +261 -164
- data/src/util/pm_buffer.c +10 -1
- data/src/util/pm_memchr.c +1 -1
- data/src/util/pm_strpbrk.c +4 -4
- metadata +8 -10
- data/src/enc/pm_big5.c +0 -53
- data/src/enc/pm_euc_jp.c +0 -59
- data/src/enc/pm_gbk.c +0 -62
- data/src/enc/pm_shift_jis.c +0 -57
- data/src/enc/pm_tables.c +0 -743
- data/src/enc/pm_unicode.c +0 -2369
- data/src/enc/pm_windows_31j.c +0 -57
data/include/prism.h
CHANGED
@@ -61,18 +61,6 @@ PRISM_EXPORTED_FUNCTION void pm_parser_init(pm_parser_t *parser, const uint8_t *
|
|
61
61
|
*/
|
62
62
|
PRISM_EXPORTED_FUNCTION void pm_parser_register_encoding_changed_callback(pm_parser_t *parser, pm_encoding_changed_callback_t callback);
|
63
63
|
|
64
|
-
/**
|
65
|
-
* Register a callback that will be called when prism encounters a magic comment
|
66
|
-
* with an encoding referenced that it doesn't understand. The callback should
|
67
|
-
* return NULL if it also doesn't understand the encoding or it should return a
|
68
|
-
* pointer to a pm_encoding_t struct that contains the functions necessary to
|
69
|
-
* parse identifiers.
|
70
|
-
*
|
71
|
-
* @param parser The parser to register the callback with.
|
72
|
-
* @param callback The callback to register.
|
73
|
-
*/
|
74
|
-
PRISM_EXPORTED_FUNCTION void pm_parser_register_encoding_decode_callback(pm_parser_t *parser, pm_encoding_decode_callback_t callback);
|
75
|
-
|
76
64
|
/**
|
77
65
|
* Free any memory associated with the given parser.
|
78
66
|
*
|
@@ -103,7 +91,7 @@ void pm_serialize_comment_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t
|
|
103
91
|
* @param encoding The encoding to serialize.
|
104
92
|
* @param buffer The buffer to serialize to.
|
105
93
|
*/
|
106
|
-
void pm_serialize_encoding(pm_encoding_t *encoding, pm_buffer_t *buffer);
|
94
|
+
void pm_serialize_encoding(const pm_encoding_t *encoding, pm_buffer_t *buffer);
|
107
95
|
|
108
96
|
/**
|
109
97
|
* Serialize the encoding, metadata, nodes, and constant pool.
|
@@ -164,6 +152,16 @@ PRISM_EXPORTED_FUNCTION void pm_serialize_lex(pm_buffer_t *buffer, const uint8_t
|
|
164
152
|
*/
|
165
153
|
PRISM_EXPORTED_FUNCTION void pm_serialize_parse_lex(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data);
|
166
154
|
|
155
|
+
/**
|
156
|
+
* Parse the source and return true if it parses without errors or warnings.
|
157
|
+
*
|
158
|
+
* @param source The source to parse.
|
159
|
+
* @param size The size of the source.
|
160
|
+
* @param data The optional data to pass to the parser.
|
161
|
+
* @return True if the source parses without errors or warnings.
|
162
|
+
*/
|
163
|
+
PRISM_EXPORTED_FUNCTION bool pm_parse_success_p(const uint8_t *source, size_t size, const char *data);
|
164
|
+
|
167
165
|
/**
|
168
166
|
* Returns a string representation of the given token type.
|
169
167
|
*
|
@@ -213,7 +211,7 @@ PRISM_EXPORTED_FUNCTION const char * pm_token_type_to_str(pm_token_type_t token_
|
|
213
211
|
* pm_node_t *root = pm_parse(&parser);
|
214
212
|
* printf("PARSED!\n");
|
215
213
|
*
|
216
|
-
* pm_node_destroy(root);
|
214
|
+
* pm_node_destroy(&parser, root);
|
217
215
|
* pm_parser_free(&parser);
|
218
216
|
* }
|
219
217
|
* ```
|
@@ -265,7 +263,7 @@ PRISM_EXPORTED_FUNCTION const char * pm_token_type_to_str(pm_token_type_t token_
|
|
265
263
|
* printf("*.s%\n", (int) buffer.length, buffer.value);
|
266
264
|
*
|
267
265
|
* pm_buffer_free(&buffer);
|
268
|
-
* pm_node_destroy(root);
|
266
|
+
* pm_node_destroy(&parser, root);
|
269
267
|
* pm_parser_free(&parser);
|
270
268
|
* }
|
271
269
|
* ```
|
data/lib/prism/compiler.rb
CHANGED
@@ -102,9 +102,15 @@ module Prism
|
|
102
102
|
# Compile a CallOrWriteNode node
|
103
103
|
alias visit_call_or_write_node visit_child_nodes
|
104
104
|
|
105
|
+
# Compile a CallTargetNode node
|
106
|
+
alias visit_call_target_node visit_child_nodes
|
107
|
+
|
105
108
|
# Compile a CapturePatternNode node
|
106
109
|
alias visit_capture_pattern_node visit_child_nodes
|
107
110
|
|
111
|
+
# Compile a CaseMatchNode node
|
112
|
+
alias visit_case_match_node visit_child_nodes
|
113
|
+
|
108
114
|
# Compile a CaseNode node
|
109
115
|
alias visit_case_node visit_child_nodes
|
110
116
|
|
@@ -240,6 +246,9 @@ module Prism
|
|
240
246
|
# Compile a ImplicitNode node
|
241
247
|
alias visit_implicit_node visit_child_nodes
|
242
248
|
|
249
|
+
# Compile a ImplicitRestNode node
|
250
|
+
alias visit_implicit_rest_node visit_child_nodes
|
251
|
+
|
243
252
|
# Compile a InNode node
|
244
253
|
alias visit_in_node visit_child_nodes
|
245
254
|
|
@@ -252,6 +261,9 @@ module Prism
|
|
252
261
|
# Compile a IndexOrWriteNode node
|
253
262
|
alias visit_index_or_write_node visit_child_nodes
|
254
263
|
|
264
|
+
# Compile a IndexTargetNode node
|
265
|
+
alias visit_index_target_node visit_child_nodes
|
266
|
+
|
255
267
|
# Compile a InstanceVariableAndWriteNode node
|
256
268
|
alias visit_instance_variable_and_write_node visit_child_nodes
|
257
269
|
|
@@ -348,6 +360,9 @@ module Prism
|
|
348
360
|
# Compile a NoKeywordsParameterNode node
|
349
361
|
alias visit_no_keywords_parameter_node visit_child_nodes
|
350
362
|
|
363
|
+
# Compile a NumberedParametersNode node
|
364
|
+
alias visit_numbered_parameters_node visit_child_nodes
|
365
|
+
|
351
366
|
# Compile a NumberedReferenceReadNode node
|
352
367
|
alias visit_numbered_reference_read_node visit_child_nodes
|
353
368
|
|
@@ -435,9 +450,6 @@ module Prism
|
|
435
450
|
# Compile a StatementsNode node
|
436
451
|
alias visit_statements_node visit_child_nodes
|
437
452
|
|
438
|
-
# Compile a StringConcatNode node
|
439
|
-
alias visit_string_concat_node visit_child_nodes
|
440
|
-
|
441
453
|
# Compile a StringNode node
|
442
454
|
alias visit_string_node visit_child_nodes
|
443
455
|
|
data/lib/prism/debug.rb
CHANGED
@@ -103,9 +103,14 @@ module Prism
|
|
103
103
|
case node
|
104
104
|
when BlockNode, DefNode, LambdaNode
|
105
105
|
names = node.locals
|
106
|
-
|
107
|
-
|
108
|
-
|
106
|
+
params =
|
107
|
+
if node.is_a?(DefNode)
|
108
|
+
node.parameters
|
109
|
+
elsif node.parameters.is_a?(NumberedParametersNode)
|
110
|
+
nil
|
111
|
+
else
|
112
|
+
node.parameters&.parameters
|
113
|
+
end
|
109
114
|
|
110
115
|
# prism places parameters in the same order that they appear in the
|
111
116
|
# source. CRuby places them in the order that they need to appear
|
@@ -121,7 +126,7 @@ module Prism
|
|
121
126
|
end
|
122
127
|
end,
|
123
128
|
*params.optionals.map(&:name),
|
124
|
-
*((params.rest.name || :*) if params.rest && params.rest.
|
129
|
+
*((params.rest.name || :*) if params.rest && !params.rest.is_a?(ImplicitRestNode)),
|
125
130
|
*params.posts.map do |post|
|
126
131
|
if post.is_a?(RequiredParameterNode)
|
127
132
|
post.name
|
@@ -133,6 +138,10 @@ module Prism
|
|
133
138
|
*params.keywords.grep(OptionalKeywordParameterNode).map(&:name),
|
134
139
|
]
|
135
140
|
|
141
|
+
if params.keyword_rest.is_a?(ForwardingParameterNode)
|
142
|
+
sorted.push(:*, :&, :"...")
|
143
|
+
end
|
144
|
+
|
136
145
|
sorted << AnonymousLocal if params.keywords.any?
|
137
146
|
|
138
147
|
# Recurse down the parameter tree to find any destructured
|
@@ -157,15 +157,15 @@ module Prism
|
|
157
157
|
*arguments,
|
158
158
|
node.name_loc,
|
159
159
|
CallNode.new(
|
160
|
+
0,
|
160
161
|
read_class.new(*arguments, node.name_loc),
|
161
162
|
nil,
|
163
|
+
node.operator_loc.slice.chomp("="),
|
162
164
|
node.operator_loc.copy(length: node.operator_loc.length - 1),
|
163
165
|
nil,
|
164
|
-
ArgumentsNode.new([node.value],
|
166
|
+
ArgumentsNode.new(0, [node.value], node.value.location),
|
165
167
|
nil,
|
166
168
|
nil,
|
167
|
-
0,
|
168
|
-
node.operator_loc.slice.chomp("="),
|
169
169
|
node.location
|
170
170
|
),
|
171
171
|
node.operator_loc.copy(start_offset: node.operator_loc.end_offset - 1, length: 1),
|
@@ -188,6 +188,7 @@ module Prism
|
|
188
188
|
IfNode.new(
|
189
189
|
node.operator_loc,
|
190
190
|
DefinedNode.new(nil, read_class.new(*arguments, node.name_loc), nil, node.operator_loc, node.name_loc),
|
191
|
+
node.operator_loc,
|
191
192
|
StatementsNode.new([read_class.new(*arguments, node.name_loc)], node.location),
|
192
193
|
ElseNode.new(
|
193
194
|
node.operator_loc,
|
data/lib/prism/dispatcher.rb
CHANGED
@@ -233,6 +233,14 @@ module Prism
|
|
233
233
|
listeners[:on_call_or_write_node_leave]&.each { |listener| listener.on_call_or_write_node_leave(node) }
|
234
234
|
end
|
235
235
|
|
236
|
+
# Dispatch enter and leave events for CallTargetNode nodes and continue
|
237
|
+
# walking the tree.
|
238
|
+
def visit_call_target_node(node)
|
239
|
+
listeners[:on_call_target_node_enter]&.each { |listener| listener.on_call_target_node_enter(node) }
|
240
|
+
super
|
241
|
+
listeners[:on_call_target_node_leave]&.each { |listener| listener.on_call_target_node_leave(node) }
|
242
|
+
end
|
243
|
+
|
236
244
|
# Dispatch enter and leave events for CapturePatternNode nodes and continue
|
237
245
|
# walking the tree.
|
238
246
|
def visit_capture_pattern_node(node)
|
@@ -241,6 +249,14 @@ module Prism
|
|
241
249
|
listeners[:on_capture_pattern_node_leave]&.each { |listener| listener.on_capture_pattern_node_leave(node) }
|
242
250
|
end
|
243
251
|
|
252
|
+
# Dispatch enter and leave events for CaseMatchNode nodes and continue
|
253
|
+
# walking the tree.
|
254
|
+
def visit_case_match_node(node)
|
255
|
+
listeners[:on_case_match_node_enter]&.each { |listener| listener.on_case_match_node_enter(node) }
|
256
|
+
super
|
257
|
+
listeners[:on_case_match_node_leave]&.each { |listener| listener.on_case_match_node_leave(node) }
|
258
|
+
end
|
259
|
+
|
244
260
|
# Dispatch enter and leave events for CaseNode nodes and continue
|
245
261
|
# walking the tree.
|
246
262
|
def visit_case_node(node)
|
@@ -601,6 +617,14 @@ module Prism
|
|
601
617
|
listeners[:on_implicit_node_leave]&.each { |listener| listener.on_implicit_node_leave(node) }
|
602
618
|
end
|
603
619
|
|
620
|
+
# Dispatch enter and leave events for ImplicitRestNode nodes and continue
|
621
|
+
# walking the tree.
|
622
|
+
def visit_implicit_rest_node(node)
|
623
|
+
listeners[:on_implicit_rest_node_enter]&.each { |listener| listener.on_implicit_rest_node_enter(node) }
|
624
|
+
super
|
625
|
+
listeners[:on_implicit_rest_node_leave]&.each { |listener| listener.on_implicit_rest_node_leave(node) }
|
626
|
+
end
|
627
|
+
|
604
628
|
# Dispatch enter and leave events for InNode nodes and continue
|
605
629
|
# walking the tree.
|
606
630
|
def visit_in_node(node)
|
@@ -633,6 +657,14 @@ module Prism
|
|
633
657
|
listeners[:on_index_or_write_node_leave]&.each { |listener| listener.on_index_or_write_node_leave(node) }
|
634
658
|
end
|
635
659
|
|
660
|
+
# Dispatch enter and leave events for IndexTargetNode nodes and continue
|
661
|
+
# walking the tree.
|
662
|
+
def visit_index_target_node(node)
|
663
|
+
listeners[:on_index_target_node_enter]&.each { |listener| listener.on_index_target_node_enter(node) }
|
664
|
+
super
|
665
|
+
listeners[:on_index_target_node_leave]&.each { |listener| listener.on_index_target_node_leave(node) }
|
666
|
+
end
|
667
|
+
|
636
668
|
# Dispatch enter and leave events for InstanceVariableAndWriteNode nodes and continue
|
637
669
|
# walking the tree.
|
638
670
|
def visit_instance_variable_and_write_node(node)
|
@@ -889,6 +921,14 @@ module Prism
|
|
889
921
|
listeners[:on_no_keywords_parameter_node_leave]&.each { |listener| listener.on_no_keywords_parameter_node_leave(node) }
|
890
922
|
end
|
891
923
|
|
924
|
+
# Dispatch enter and leave events for NumberedParametersNode nodes and continue
|
925
|
+
# walking the tree.
|
926
|
+
def visit_numbered_parameters_node(node)
|
927
|
+
listeners[:on_numbered_parameters_node_enter]&.each { |listener| listener.on_numbered_parameters_node_enter(node) }
|
928
|
+
super
|
929
|
+
listeners[:on_numbered_parameters_node_leave]&.each { |listener| listener.on_numbered_parameters_node_leave(node) }
|
930
|
+
end
|
931
|
+
|
892
932
|
# Dispatch enter and leave events for NumberedReferenceReadNode nodes and continue
|
893
933
|
# walking the tree.
|
894
934
|
def visit_numbered_reference_read_node(node)
|
@@ -1121,14 +1161,6 @@ module Prism
|
|
1121
1161
|
listeners[:on_statements_node_leave]&.each { |listener| listener.on_statements_node_leave(node) }
|
1122
1162
|
end
|
1123
1163
|
|
1124
|
-
# Dispatch enter and leave events for StringConcatNode nodes and continue
|
1125
|
-
# walking the tree.
|
1126
|
-
def visit_string_concat_node(node)
|
1127
|
-
listeners[:on_string_concat_node_enter]&.each { |listener| listener.on_string_concat_node_enter(node) }
|
1128
|
-
super
|
1129
|
-
listeners[:on_string_concat_node_leave]&.each { |listener| listener.on_string_concat_node_leave(node) }
|
1130
|
-
end
|
1131
|
-
|
1132
1164
|
# Dispatch enter and leave events for StringNode nodes and continue
|
1133
1165
|
# walking the tree.
|
1134
1166
|
def visit_string_node(node)
|
@@ -1350,12 +1382,24 @@ module Prism
|
|
1350
1382
|
listeners[:on_call_or_write_node_leave]&.each { |listener| listener.on_call_or_write_node_leave(node) }
|
1351
1383
|
end
|
1352
1384
|
|
1385
|
+
# Dispatch enter and leave events for CallTargetNode nodes.
|
1386
|
+
def visit_call_target_node(node)
|
1387
|
+
listeners[:on_call_target_node_enter]&.each { |listener| listener.on_call_target_node_enter(node) }
|
1388
|
+
listeners[:on_call_target_node_leave]&.each { |listener| listener.on_call_target_node_leave(node) }
|
1389
|
+
end
|
1390
|
+
|
1353
1391
|
# Dispatch enter and leave events for CapturePatternNode nodes.
|
1354
1392
|
def visit_capture_pattern_node(node)
|
1355
1393
|
listeners[:on_capture_pattern_node_enter]&.each { |listener| listener.on_capture_pattern_node_enter(node) }
|
1356
1394
|
listeners[:on_capture_pattern_node_leave]&.each { |listener| listener.on_capture_pattern_node_leave(node) }
|
1357
1395
|
end
|
1358
1396
|
|
1397
|
+
# Dispatch enter and leave events for CaseMatchNode nodes.
|
1398
|
+
def visit_case_match_node(node)
|
1399
|
+
listeners[:on_case_match_node_enter]&.each { |listener| listener.on_case_match_node_enter(node) }
|
1400
|
+
listeners[:on_case_match_node_leave]&.each { |listener| listener.on_case_match_node_leave(node) }
|
1401
|
+
end
|
1402
|
+
|
1359
1403
|
# Dispatch enter and leave events for CaseNode nodes.
|
1360
1404
|
def visit_case_node(node)
|
1361
1405
|
listeners[:on_case_node_enter]&.each { |listener| listener.on_case_node_enter(node) }
|
@@ -1626,6 +1670,12 @@ module Prism
|
|
1626
1670
|
listeners[:on_implicit_node_leave]&.each { |listener| listener.on_implicit_node_leave(node) }
|
1627
1671
|
end
|
1628
1672
|
|
1673
|
+
# Dispatch enter and leave events for ImplicitRestNode nodes.
|
1674
|
+
def visit_implicit_rest_node(node)
|
1675
|
+
listeners[:on_implicit_rest_node_enter]&.each { |listener| listener.on_implicit_rest_node_enter(node) }
|
1676
|
+
listeners[:on_implicit_rest_node_leave]&.each { |listener| listener.on_implicit_rest_node_leave(node) }
|
1677
|
+
end
|
1678
|
+
|
1629
1679
|
# Dispatch enter and leave events for InNode nodes.
|
1630
1680
|
def visit_in_node(node)
|
1631
1681
|
listeners[:on_in_node_enter]&.each { |listener| listener.on_in_node_enter(node) }
|
@@ -1650,6 +1700,12 @@ module Prism
|
|
1650
1700
|
listeners[:on_index_or_write_node_leave]&.each { |listener| listener.on_index_or_write_node_leave(node) }
|
1651
1701
|
end
|
1652
1702
|
|
1703
|
+
# Dispatch enter and leave events for IndexTargetNode nodes.
|
1704
|
+
def visit_index_target_node(node)
|
1705
|
+
listeners[:on_index_target_node_enter]&.each { |listener| listener.on_index_target_node_enter(node) }
|
1706
|
+
listeners[:on_index_target_node_leave]&.each { |listener| listener.on_index_target_node_leave(node) }
|
1707
|
+
end
|
1708
|
+
|
1653
1709
|
# Dispatch enter and leave events for InstanceVariableAndWriteNode nodes.
|
1654
1710
|
def visit_instance_variable_and_write_node(node)
|
1655
1711
|
listeners[:on_instance_variable_and_write_node_enter]&.each { |listener| listener.on_instance_variable_and_write_node_enter(node) }
|
@@ -1842,6 +1898,12 @@ module Prism
|
|
1842
1898
|
listeners[:on_no_keywords_parameter_node_leave]&.each { |listener| listener.on_no_keywords_parameter_node_leave(node) }
|
1843
1899
|
end
|
1844
1900
|
|
1901
|
+
# Dispatch enter and leave events for NumberedParametersNode nodes.
|
1902
|
+
def visit_numbered_parameters_node(node)
|
1903
|
+
listeners[:on_numbered_parameters_node_enter]&.each { |listener| listener.on_numbered_parameters_node_enter(node) }
|
1904
|
+
listeners[:on_numbered_parameters_node_leave]&.each { |listener| listener.on_numbered_parameters_node_leave(node) }
|
1905
|
+
end
|
1906
|
+
|
1845
1907
|
# Dispatch enter and leave events for NumberedReferenceReadNode nodes.
|
1846
1908
|
def visit_numbered_reference_read_node(node)
|
1847
1909
|
listeners[:on_numbered_reference_read_node_enter]&.each { |listener| listener.on_numbered_reference_read_node_enter(node) }
|
@@ -2016,12 +2078,6 @@ module Prism
|
|
2016
2078
|
listeners[:on_statements_node_leave]&.each { |listener| listener.on_statements_node_leave(node) }
|
2017
2079
|
end
|
2018
2080
|
|
2019
|
-
# Dispatch enter and leave events for StringConcatNode nodes.
|
2020
|
-
def visit_string_concat_node(node)
|
2021
|
-
listeners[:on_string_concat_node_enter]&.each { |listener| listener.on_string_concat_node_enter(node) }
|
2022
|
-
listeners[:on_string_concat_node_leave]&.each { |listener| listener.on_string_concat_node_leave(node) }
|
2023
|
-
end
|
2024
|
-
|
2025
2081
|
# Dispatch enter and leave events for StringNode nodes.
|
2026
2082
|
def visit_string_node(node)
|
2027
2083
|
listeners[:on_string_node_enter]&.each { |listener| listener.on_string_node_enter(node) }
|