prism 0.13.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.
Files changed (95) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +172 -0
  3. data/CODE_OF_CONDUCT.md +76 -0
  4. data/CONTRIBUTING.md +62 -0
  5. data/LICENSE.md +7 -0
  6. data/Makefile +84 -0
  7. data/README.md +89 -0
  8. data/config.yml +2481 -0
  9. data/docs/build_system.md +74 -0
  10. data/docs/building.md +22 -0
  11. data/docs/configuration.md +60 -0
  12. data/docs/design.md +53 -0
  13. data/docs/encoding.md +117 -0
  14. data/docs/fuzzing.md +93 -0
  15. data/docs/heredocs.md +36 -0
  16. data/docs/mapping.md +117 -0
  17. data/docs/ripper.md +36 -0
  18. data/docs/ruby_api.md +25 -0
  19. data/docs/serialization.md +181 -0
  20. data/docs/testing.md +55 -0
  21. data/ext/prism/api_node.c +4725 -0
  22. data/ext/prism/api_pack.c +256 -0
  23. data/ext/prism/extconf.rb +136 -0
  24. data/ext/prism/extension.c +626 -0
  25. data/ext/prism/extension.h +18 -0
  26. data/include/prism/ast.h +1932 -0
  27. data/include/prism/defines.h +45 -0
  28. data/include/prism/diagnostic.h +231 -0
  29. data/include/prism/enc/pm_encoding.h +95 -0
  30. data/include/prism/node.h +41 -0
  31. data/include/prism/pack.h +141 -0
  32. data/include/prism/parser.h +418 -0
  33. data/include/prism/regexp.h +19 -0
  34. data/include/prism/unescape.h +48 -0
  35. data/include/prism/util/pm_buffer.h +51 -0
  36. data/include/prism/util/pm_char.h +91 -0
  37. data/include/prism/util/pm_constant_pool.h +78 -0
  38. data/include/prism/util/pm_list.h +67 -0
  39. data/include/prism/util/pm_memchr.h +14 -0
  40. data/include/prism/util/pm_newline_list.h +61 -0
  41. data/include/prism/util/pm_state_stack.h +24 -0
  42. data/include/prism/util/pm_string.h +61 -0
  43. data/include/prism/util/pm_string_list.h +25 -0
  44. data/include/prism/util/pm_strpbrk.h +29 -0
  45. data/include/prism/version.h +4 -0
  46. data/include/prism.h +82 -0
  47. data/lib/prism/compiler.rb +465 -0
  48. data/lib/prism/debug.rb +157 -0
  49. data/lib/prism/desugar_compiler.rb +206 -0
  50. data/lib/prism/dispatcher.rb +2051 -0
  51. data/lib/prism/dsl.rb +750 -0
  52. data/lib/prism/ffi.rb +251 -0
  53. data/lib/prism/lex_compat.rb +838 -0
  54. data/lib/prism/mutation_compiler.rb +718 -0
  55. data/lib/prism/node.rb +14540 -0
  56. data/lib/prism/node_ext.rb +55 -0
  57. data/lib/prism/node_inspector.rb +68 -0
  58. data/lib/prism/pack.rb +185 -0
  59. data/lib/prism/parse_result/comments.rb +172 -0
  60. data/lib/prism/parse_result/newlines.rb +60 -0
  61. data/lib/prism/parse_result.rb +266 -0
  62. data/lib/prism/pattern.rb +239 -0
  63. data/lib/prism/ripper_compat.rb +174 -0
  64. data/lib/prism/serialize.rb +662 -0
  65. data/lib/prism/visitor.rb +470 -0
  66. data/lib/prism.rb +64 -0
  67. data/prism.gemspec +113 -0
  68. data/src/diagnostic.c +287 -0
  69. data/src/enc/pm_big5.c +52 -0
  70. data/src/enc/pm_euc_jp.c +58 -0
  71. data/src/enc/pm_gbk.c +61 -0
  72. data/src/enc/pm_shift_jis.c +56 -0
  73. data/src/enc/pm_tables.c +507 -0
  74. data/src/enc/pm_unicode.c +2324 -0
  75. data/src/enc/pm_windows_31j.c +56 -0
  76. data/src/node.c +2633 -0
  77. data/src/pack.c +493 -0
  78. data/src/prettyprint.c +2136 -0
  79. data/src/prism.c +14587 -0
  80. data/src/regexp.c +580 -0
  81. data/src/serialize.c +1899 -0
  82. data/src/token_type.c +349 -0
  83. data/src/unescape.c +637 -0
  84. data/src/util/pm_buffer.c +103 -0
  85. data/src/util/pm_char.c +272 -0
  86. data/src/util/pm_constant_pool.c +252 -0
  87. data/src/util/pm_list.c +41 -0
  88. data/src/util/pm_memchr.c +33 -0
  89. data/src/util/pm_newline_list.c +134 -0
  90. data/src/util/pm_state_stack.c +19 -0
  91. data/src/util/pm_string.c +200 -0
  92. data/src/util/pm_string_list.c +29 -0
  93. data/src/util/pm_strncasecmp.c +17 -0
  94. data/src/util/pm_strpbrk.c +66 -0
  95. metadata +138 -0
@@ -0,0 +1,465 @@
1
+ # frozen_string_literal: true
2
+ =begin
3
+ This file is generated by the templates/template.rb script and should not be
4
+ modified manually. See templates/lib/prism/compiler.rb.erb
5
+ if you are looking to modify the template
6
+ =end
7
+
8
+ module Prism
9
+ # A compiler is a visitor that returns the value of each node as it visits.
10
+ # This is as opposed to a visitor which will only walk the tree. This can be
11
+ # useful when you are trying to compile a tree into a different format.
12
+ #
13
+ # For example, to build a representation of the tree as s-expressions, you
14
+ # could write:
15
+ #
16
+ # class SExpressions < Prism::Compiler
17
+ # def visit_arguments_node(node) = [:arguments, super]
18
+ # def visit_call_node(node) = [:call, super]
19
+ # def visit_integer_node(node) = [:integer]
20
+ # def visit_program_node(node) = [:program, super]
21
+ # end
22
+ #
23
+ # Prism.parse("1 + 2").value.accept(SExpressions.new)
24
+ # # => [:program, [[[:call, [[:integer], [:arguments, [[:integer]]]]]]]]
25
+ #
26
+ class Compiler
27
+ # Visit an individual node.
28
+ def visit(node)
29
+ node&.accept(self)
30
+ end
31
+
32
+ # Visit a list of nodes.
33
+ def visit_all(nodes)
34
+ nodes.map { |node| node&.accept(self) }
35
+ end
36
+
37
+ # Visit the child nodes of the given node.
38
+ def visit_child_nodes(node)
39
+ node.compact_child_nodes.map { |node| node.accept(self) }
40
+ end
41
+
42
+ # Compile a AliasGlobalVariableNode node
43
+ alias visit_alias_global_variable_node visit_child_nodes
44
+
45
+ # Compile a AliasMethodNode node
46
+ alias visit_alias_method_node visit_child_nodes
47
+
48
+ # Compile a AlternationPatternNode node
49
+ alias visit_alternation_pattern_node visit_child_nodes
50
+
51
+ # Compile a AndNode node
52
+ alias visit_and_node visit_child_nodes
53
+
54
+ # Compile a ArgumentsNode node
55
+ alias visit_arguments_node visit_child_nodes
56
+
57
+ # Compile a ArrayNode node
58
+ alias visit_array_node visit_child_nodes
59
+
60
+ # Compile a ArrayPatternNode node
61
+ alias visit_array_pattern_node visit_child_nodes
62
+
63
+ # Compile a AssocNode node
64
+ alias visit_assoc_node visit_child_nodes
65
+
66
+ # Compile a AssocSplatNode node
67
+ alias visit_assoc_splat_node visit_child_nodes
68
+
69
+ # Compile a BackReferenceReadNode node
70
+ alias visit_back_reference_read_node visit_child_nodes
71
+
72
+ # Compile a BeginNode node
73
+ alias visit_begin_node visit_child_nodes
74
+
75
+ # Compile a BlockArgumentNode node
76
+ alias visit_block_argument_node visit_child_nodes
77
+
78
+ # Compile a BlockLocalVariableNode node
79
+ alias visit_block_local_variable_node visit_child_nodes
80
+
81
+ # Compile a BlockNode node
82
+ alias visit_block_node visit_child_nodes
83
+
84
+ # Compile a BlockParameterNode node
85
+ alias visit_block_parameter_node visit_child_nodes
86
+
87
+ # Compile a BlockParametersNode node
88
+ alias visit_block_parameters_node visit_child_nodes
89
+
90
+ # Compile a BreakNode node
91
+ alias visit_break_node visit_child_nodes
92
+
93
+ # Compile a CallAndWriteNode node
94
+ alias visit_call_and_write_node visit_child_nodes
95
+
96
+ # Compile a CallNode node
97
+ alias visit_call_node visit_child_nodes
98
+
99
+ # Compile a CallOperatorWriteNode node
100
+ alias visit_call_operator_write_node visit_child_nodes
101
+
102
+ # Compile a CallOrWriteNode node
103
+ alias visit_call_or_write_node visit_child_nodes
104
+
105
+ # Compile a CapturePatternNode node
106
+ alias visit_capture_pattern_node visit_child_nodes
107
+
108
+ # Compile a CaseNode node
109
+ alias visit_case_node visit_child_nodes
110
+
111
+ # Compile a ClassNode node
112
+ alias visit_class_node visit_child_nodes
113
+
114
+ # Compile a ClassVariableAndWriteNode node
115
+ alias visit_class_variable_and_write_node visit_child_nodes
116
+
117
+ # Compile a ClassVariableOperatorWriteNode node
118
+ alias visit_class_variable_operator_write_node visit_child_nodes
119
+
120
+ # Compile a ClassVariableOrWriteNode node
121
+ alias visit_class_variable_or_write_node visit_child_nodes
122
+
123
+ # Compile a ClassVariableReadNode node
124
+ alias visit_class_variable_read_node visit_child_nodes
125
+
126
+ # Compile a ClassVariableTargetNode node
127
+ alias visit_class_variable_target_node visit_child_nodes
128
+
129
+ # Compile a ClassVariableWriteNode node
130
+ alias visit_class_variable_write_node visit_child_nodes
131
+
132
+ # Compile a ConstantAndWriteNode node
133
+ alias visit_constant_and_write_node visit_child_nodes
134
+
135
+ # Compile a ConstantOperatorWriteNode node
136
+ alias visit_constant_operator_write_node visit_child_nodes
137
+
138
+ # Compile a ConstantOrWriteNode node
139
+ alias visit_constant_or_write_node visit_child_nodes
140
+
141
+ # Compile a ConstantPathAndWriteNode node
142
+ alias visit_constant_path_and_write_node visit_child_nodes
143
+
144
+ # Compile a ConstantPathNode node
145
+ alias visit_constant_path_node visit_child_nodes
146
+
147
+ # Compile a ConstantPathOperatorWriteNode node
148
+ alias visit_constant_path_operator_write_node visit_child_nodes
149
+
150
+ # Compile a ConstantPathOrWriteNode node
151
+ alias visit_constant_path_or_write_node visit_child_nodes
152
+
153
+ # Compile a ConstantPathTargetNode node
154
+ alias visit_constant_path_target_node visit_child_nodes
155
+
156
+ # Compile a ConstantPathWriteNode node
157
+ alias visit_constant_path_write_node visit_child_nodes
158
+
159
+ # Compile a ConstantReadNode node
160
+ alias visit_constant_read_node visit_child_nodes
161
+
162
+ # Compile a ConstantTargetNode node
163
+ alias visit_constant_target_node visit_child_nodes
164
+
165
+ # Compile a ConstantWriteNode node
166
+ alias visit_constant_write_node visit_child_nodes
167
+
168
+ # Compile a DefNode node
169
+ alias visit_def_node visit_child_nodes
170
+
171
+ # Compile a DefinedNode node
172
+ alias visit_defined_node visit_child_nodes
173
+
174
+ # Compile a ElseNode node
175
+ alias visit_else_node visit_child_nodes
176
+
177
+ # Compile a EmbeddedStatementsNode node
178
+ alias visit_embedded_statements_node visit_child_nodes
179
+
180
+ # Compile a EmbeddedVariableNode node
181
+ alias visit_embedded_variable_node visit_child_nodes
182
+
183
+ # Compile a EnsureNode node
184
+ alias visit_ensure_node visit_child_nodes
185
+
186
+ # Compile a FalseNode node
187
+ alias visit_false_node visit_child_nodes
188
+
189
+ # Compile a FindPatternNode node
190
+ alias visit_find_pattern_node visit_child_nodes
191
+
192
+ # Compile a FlipFlopNode node
193
+ alias visit_flip_flop_node visit_child_nodes
194
+
195
+ # Compile a FloatNode node
196
+ alias visit_float_node visit_child_nodes
197
+
198
+ # Compile a ForNode node
199
+ alias visit_for_node visit_child_nodes
200
+
201
+ # Compile a ForwardingArgumentsNode node
202
+ alias visit_forwarding_arguments_node visit_child_nodes
203
+
204
+ # Compile a ForwardingParameterNode node
205
+ alias visit_forwarding_parameter_node visit_child_nodes
206
+
207
+ # Compile a ForwardingSuperNode node
208
+ alias visit_forwarding_super_node visit_child_nodes
209
+
210
+ # Compile a GlobalVariableAndWriteNode node
211
+ alias visit_global_variable_and_write_node visit_child_nodes
212
+
213
+ # Compile a GlobalVariableOperatorWriteNode node
214
+ alias visit_global_variable_operator_write_node visit_child_nodes
215
+
216
+ # Compile a GlobalVariableOrWriteNode node
217
+ alias visit_global_variable_or_write_node visit_child_nodes
218
+
219
+ # Compile a GlobalVariableReadNode node
220
+ alias visit_global_variable_read_node visit_child_nodes
221
+
222
+ # Compile a GlobalVariableTargetNode node
223
+ alias visit_global_variable_target_node visit_child_nodes
224
+
225
+ # Compile a GlobalVariableWriteNode node
226
+ alias visit_global_variable_write_node visit_child_nodes
227
+
228
+ # Compile a HashNode node
229
+ alias visit_hash_node visit_child_nodes
230
+
231
+ # Compile a HashPatternNode node
232
+ alias visit_hash_pattern_node visit_child_nodes
233
+
234
+ # Compile a IfNode node
235
+ alias visit_if_node visit_child_nodes
236
+
237
+ # Compile a ImaginaryNode node
238
+ alias visit_imaginary_node visit_child_nodes
239
+
240
+ # Compile a ImplicitNode node
241
+ alias visit_implicit_node visit_child_nodes
242
+
243
+ # Compile a InNode node
244
+ alias visit_in_node visit_child_nodes
245
+
246
+ # Compile a InstanceVariableAndWriteNode node
247
+ alias visit_instance_variable_and_write_node visit_child_nodes
248
+
249
+ # Compile a InstanceVariableOperatorWriteNode node
250
+ alias visit_instance_variable_operator_write_node visit_child_nodes
251
+
252
+ # Compile a InstanceVariableOrWriteNode node
253
+ alias visit_instance_variable_or_write_node visit_child_nodes
254
+
255
+ # Compile a InstanceVariableReadNode node
256
+ alias visit_instance_variable_read_node visit_child_nodes
257
+
258
+ # Compile a InstanceVariableTargetNode node
259
+ alias visit_instance_variable_target_node visit_child_nodes
260
+
261
+ # Compile a InstanceVariableWriteNode node
262
+ alias visit_instance_variable_write_node visit_child_nodes
263
+
264
+ # Compile a IntegerNode node
265
+ alias visit_integer_node visit_child_nodes
266
+
267
+ # Compile a InterpolatedMatchLastLineNode node
268
+ alias visit_interpolated_match_last_line_node visit_child_nodes
269
+
270
+ # Compile a InterpolatedRegularExpressionNode node
271
+ alias visit_interpolated_regular_expression_node visit_child_nodes
272
+
273
+ # Compile a InterpolatedStringNode node
274
+ alias visit_interpolated_string_node visit_child_nodes
275
+
276
+ # Compile a InterpolatedSymbolNode node
277
+ alias visit_interpolated_symbol_node visit_child_nodes
278
+
279
+ # Compile a InterpolatedXStringNode node
280
+ alias visit_interpolated_x_string_node visit_child_nodes
281
+
282
+ # Compile a KeywordHashNode node
283
+ alias visit_keyword_hash_node visit_child_nodes
284
+
285
+ # Compile a KeywordParameterNode node
286
+ alias visit_keyword_parameter_node visit_child_nodes
287
+
288
+ # Compile a KeywordRestParameterNode node
289
+ alias visit_keyword_rest_parameter_node visit_child_nodes
290
+
291
+ # Compile a LambdaNode node
292
+ alias visit_lambda_node visit_child_nodes
293
+
294
+ # Compile a LocalVariableAndWriteNode node
295
+ alias visit_local_variable_and_write_node visit_child_nodes
296
+
297
+ # Compile a LocalVariableOperatorWriteNode node
298
+ alias visit_local_variable_operator_write_node visit_child_nodes
299
+
300
+ # Compile a LocalVariableOrWriteNode node
301
+ alias visit_local_variable_or_write_node visit_child_nodes
302
+
303
+ # Compile a LocalVariableReadNode node
304
+ alias visit_local_variable_read_node visit_child_nodes
305
+
306
+ # Compile a LocalVariableTargetNode node
307
+ alias visit_local_variable_target_node visit_child_nodes
308
+
309
+ # Compile a LocalVariableWriteNode node
310
+ alias visit_local_variable_write_node visit_child_nodes
311
+
312
+ # Compile a MatchLastLineNode node
313
+ alias visit_match_last_line_node visit_child_nodes
314
+
315
+ # Compile a MatchPredicateNode node
316
+ alias visit_match_predicate_node visit_child_nodes
317
+
318
+ # Compile a MatchRequiredNode node
319
+ alias visit_match_required_node visit_child_nodes
320
+
321
+ # Compile a MatchWriteNode node
322
+ alias visit_match_write_node visit_child_nodes
323
+
324
+ # Compile a MissingNode node
325
+ alias visit_missing_node visit_child_nodes
326
+
327
+ # Compile a ModuleNode node
328
+ alias visit_module_node visit_child_nodes
329
+
330
+ # Compile a MultiTargetNode node
331
+ alias visit_multi_target_node visit_child_nodes
332
+
333
+ # Compile a MultiWriteNode node
334
+ alias visit_multi_write_node visit_child_nodes
335
+
336
+ # Compile a NextNode node
337
+ alias visit_next_node visit_child_nodes
338
+
339
+ # Compile a NilNode node
340
+ alias visit_nil_node visit_child_nodes
341
+
342
+ # Compile a NoKeywordsParameterNode node
343
+ alias visit_no_keywords_parameter_node visit_child_nodes
344
+
345
+ # Compile a NumberedReferenceReadNode node
346
+ alias visit_numbered_reference_read_node visit_child_nodes
347
+
348
+ # Compile a OptionalParameterNode node
349
+ alias visit_optional_parameter_node visit_child_nodes
350
+
351
+ # Compile a OrNode node
352
+ alias visit_or_node visit_child_nodes
353
+
354
+ # Compile a ParametersNode node
355
+ alias visit_parameters_node visit_child_nodes
356
+
357
+ # Compile a ParenthesesNode node
358
+ alias visit_parentheses_node visit_child_nodes
359
+
360
+ # Compile a PinnedExpressionNode node
361
+ alias visit_pinned_expression_node visit_child_nodes
362
+
363
+ # Compile a PinnedVariableNode node
364
+ alias visit_pinned_variable_node visit_child_nodes
365
+
366
+ # Compile a PostExecutionNode node
367
+ alias visit_post_execution_node visit_child_nodes
368
+
369
+ # Compile a PreExecutionNode node
370
+ alias visit_pre_execution_node visit_child_nodes
371
+
372
+ # Compile a ProgramNode node
373
+ alias visit_program_node visit_child_nodes
374
+
375
+ # Compile a RangeNode node
376
+ alias visit_range_node visit_child_nodes
377
+
378
+ # Compile a RationalNode node
379
+ alias visit_rational_node visit_child_nodes
380
+
381
+ # Compile a RedoNode node
382
+ alias visit_redo_node visit_child_nodes
383
+
384
+ # Compile a RegularExpressionNode node
385
+ alias visit_regular_expression_node visit_child_nodes
386
+
387
+ # Compile a RequiredDestructuredParameterNode node
388
+ alias visit_required_destructured_parameter_node visit_child_nodes
389
+
390
+ # Compile a RequiredParameterNode node
391
+ alias visit_required_parameter_node visit_child_nodes
392
+
393
+ # Compile a RescueModifierNode node
394
+ alias visit_rescue_modifier_node visit_child_nodes
395
+
396
+ # Compile a RescueNode node
397
+ alias visit_rescue_node visit_child_nodes
398
+
399
+ # Compile a RestParameterNode node
400
+ alias visit_rest_parameter_node visit_child_nodes
401
+
402
+ # Compile a RetryNode node
403
+ alias visit_retry_node visit_child_nodes
404
+
405
+ # Compile a ReturnNode node
406
+ alias visit_return_node visit_child_nodes
407
+
408
+ # Compile a SelfNode node
409
+ alias visit_self_node visit_child_nodes
410
+
411
+ # Compile a SingletonClassNode node
412
+ alias visit_singleton_class_node visit_child_nodes
413
+
414
+ # Compile a SourceEncodingNode node
415
+ alias visit_source_encoding_node visit_child_nodes
416
+
417
+ # Compile a SourceFileNode node
418
+ alias visit_source_file_node visit_child_nodes
419
+
420
+ # Compile a SourceLineNode node
421
+ alias visit_source_line_node visit_child_nodes
422
+
423
+ # Compile a SplatNode node
424
+ alias visit_splat_node visit_child_nodes
425
+
426
+ # Compile a StatementsNode node
427
+ alias visit_statements_node visit_child_nodes
428
+
429
+ # Compile a StringConcatNode node
430
+ alias visit_string_concat_node visit_child_nodes
431
+
432
+ # Compile a StringNode node
433
+ alias visit_string_node visit_child_nodes
434
+
435
+ # Compile a SuperNode node
436
+ alias visit_super_node visit_child_nodes
437
+
438
+ # Compile a SymbolNode node
439
+ alias visit_symbol_node visit_child_nodes
440
+
441
+ # Compile a TrueNode node
442
+ alias visit_true_node visit_child_nodes
443
+
444
+ # Compile a UndefNode node
445
+ alias visit_undef_node visit_child_nodes
446
+
447
+ # Compile a UnlessNode node
448
+ alias visit_unless_node visit_child_nodes
449
+
450
+ # Compile a UntilNode node
451
+ alias visit_until_node visit_child_nodes
452
+
453
+ # Compile a WhenNode node
454
+ alias visit_when_node visit_child_nodes
455
+
456
+ # Compile a WhileNode node
457
+ alias visit_while_node visit_child_nodes
458
+
459
+ # Compile a XStringNode node
460
+ alias visit_x_string_node visit_child_nodes
461
+
462
+ # Compile a YieldNode node
463
+ alias visit_yield_node visit_child_nodes
464
+ end
465
+ end
@@ -0,0 +1,157 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Prism
4
+ # This module is used for testing and debugging and is not meant to be used by
5
+ # consumers of this library.
6
+ module Debug
7
+ class ISeq
8
+ attr_reader :parts
9
+
10
+ def initialize(parts)
11
+ @parts = parts
12
+ end
13
+
14
+ def type
15
+ parts[0]
16
+ end
17
+
18
+ def local_table
19
+ parts[10]
20
+ end
21
+
22
+ def instructions
23
+ parts[13]
24
+ end
25
+
26
+ def each_child
27
+ instructions.each do |instruction|
28
+ # Only look at arrays. Other instructions are line numbers or
29
+ # tracepoint events.
30
+ next unless instruction.is_a?(Array)
31
+
32
+ instruction.each do |opnd|
33
+ # Only look at arrays. Other operands are literals.
34
+ next unless opnd.is_a?(Array)
35
+
36
+ # Only look at instruction sequences. Other operands are literals.
37
+ next unless opnd[0] == "YARVInstructionSequence/SimpleDataFormat"
38
+
39
+ yield ISeq.new(opnd)
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ # For the given source, compiles with CRuby and returns a list of all of the
46
+ # sets of local variables that were encountered.
47
+ def self.cruby_locals(source)
48
+ verbose = $VERBOSE
49
+ $VERBOSE = nil
50
+
51
+ begin
52
+ locals = []
53
+ stack = [ISeq.new(RubyVM::InstructionSequence.compile(source).to_a)]
54
+
55
+ while (iseq = stack.pop)
56
+ if iseq.type != :once
57
+ names = iseq.local_table
58
+
59
+ # CRuby will push on a special local variable when there are keyword
60
+ # arguments. We get rid of that here.
61
+ names = names.grep_v(Integer)
62
+
63
+ # For some reason, CRuby occasionally pushes this special local
64
+ # variable when there are splat arguments. We get rid of that here.
65
+ names = names.grep_v(:"#arg_rest")
66
+
67
+ # Now push them onto the list of locals.
68
+ locals << names
69
+ end
70
+
71
+ iseq.each_child { |child| stack << child }
72
+ end
73
+
74
+ locals
75
+ ensure
76
+ $VERBOSE = verbose
77
+ end
78
+ end
79
+
80
+ # For the given source, parses with prism and returns a list of all of the
81
+ # sets of local variables that were encountered.
82
+ def self.prism_locals(source)
83
+ locals = []
84
+ stack = [Prism.parse(source).value]
85
+
86
+ while (node = stack.pop)
87
+ case node
88
+ when BlockNode, DefNode, LambdaNode
89
+ names = node.locals
90
+
91
+ params = node.parameters
92
+ params = params&.parameters unless node.is_a?(DefNode)
93
+
94
+ # prism places parameters in the same order that they appear in the
95
+ # source. CRuby places them in the order that they need to appear
96
+ # according to their own internal calling convention. We mimic that
97
+ # order here so that we can compare properly.
98
+ if params
99
+ sorted = [
100
+ *params.requireds.grep(RequiredParameterNode).map(&:name),
101
+ *params.optionals.map(&:name),
102
+ *((params.rest.name || :*) if params.rest && params.rest.operator != ","),
103
+ *params.posts.grep(RequiredParameterNode).map(&:name),
104
+ *params.keywords.reject(&:value).map(&:name),
105
+ *params.keywords.select(&:value).map(&:name)
106
+ ]
107
+
108
+ # TODO: When we get a ... parameter, we should be pushing * and &
109
+ # onto the local list. We don't do that yet, so we need to add them
110
+ # in here.
111
+ if params.keyword_rest.is_a?(ForwardingParameterNode)
112
+ sorted.push(:*, :&, :"...")
113
+ end
114
+
115
+ # Recurse down the parameter tree to find any destructured
116
+ # parameters and add them after the other parameters.
117
+ param_stack = params.requireds.concat(params.posts).grep(RequiredDestructuredParameterNode).reverse
118
+ while (param = param_stack.pop)
119
+ case param
120
+ when RequiredDestructuredParameterNode
121
+ param_stack.concat(param.parameters.reverse)
122
+ when RequiredParameterNode
123
+ sorted << param.name
124
+ when SplatNode
125
+ sorted << param.expression.name if param.expression
126
+ end
127
+ end
128
+
129
+ names = sorted.concat(names - sorted)
130
+ end
131
+
132
+ locals << names
133
+ when ClassNode, ModuleNode, ProgramNode, SingletonClassNode
134
+ locals << node.locals
135
+ when ForNode
136
+ locals << []
137
+ when PostExecutionNode
138
+ locals.push([], [])
139
+ when InterpolatedRegularExpressionNode
140
+ locals << [] if node.once?
141
+ end
142
+
143
+ stack.concat(node.compact_child_nodes)
144
+ end
145
+
146
+ locals
147
+ end
148
+
149
+ def self.newlines(source)
150
+ Prism.parse(source).source.offsets
151
+ end
152
+
153
+ def self.parse_serialize_file(filepath)
154
+ parse_serialize_file_metadata(filepath, [filepath.bytesize, filepath.b, 0].pack("LA*L"))
155
+ end
156
+ end
157
+ end