refract 0.0.1 → 1.0.0.beta1

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 (164) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE.txt +21 -0
  3. data/README.md +7 -0
  4. data/lib/refract/basic_visitor.rb +40 -0
  5. data/lib/refract/converter.rb +1032 -0
  6. data/lib/refract/formatter.rb +1271 -0
  7. data/lib/refract/mutation_visitor.rb +899 -0
  8. data/lib/refract/nodes/alias_global_variable_node.rb +12 -0
  9. data/lib/refract/nodes/alias_method_node.rb +12 -0
  10. data/lib/refract/nodes/alternation_pattern_node.rb +12 -0
  11. data/lib/refract/nodes/and_node.rb +13 -0
  12. data/lib/refract/nodes/arguments_node.rb +11 -0
  13. data/lib/refract/nodes/array_node.rb +11 -0
  14. data/lib/refract/nodes/array_pattern_node.rb +14 -0
  15. data/lib/refract/nodes/assoc_node.rb +12 -0
  16. data/lib/refract/nodes/assoc_splat_node.rb +11 -0
  17. data/lib/refract/nodes/back_reference_read_node.rb +11 -0
  18. data/lib/refract/nodes/begin_node.rb +14 -0
  19. data/lib/refract/nodes/block_argument_node.rb +11 -0
  20. data/lib/refract/nodes/block_local_variable_node.rb +11 -0
  21. data/lib/refract/nodes/block_node.rb +12 -0
  22. data/lib/refract/nodes/block_parameter_node.rb +11 -0
  23. data/lib/refract/nodes/block_parameters_node.rb +12 -0
  24. data/lib/refract/nodes/break_node.rb +11 -0
  25. data/lib/refract/nodes/call_and_write_node.rb +13 -0
  26. data/lib/refract/nodes/call_node.rb +14 -0
  27. data/lib/refract/nodes/call_operator_write_node.rb +14 -0
  28. data/lib/refract/nodes/call_or_write_node.rb +13 -0
  29. data/lib/refract/nodes/call_target_node.rb +12 -0
  30. data/lib/refract/nodes/capture_pattern_node.rb +12 -0
  31. data/lib/refract/nodes/case_match_node.rb +13 -0
  32. data/lib/refract/nodes/case_node.rb +13 -0
  33. data/lib/refract/nodes/class_node.rb +13 -0
  34. data/lib/refract/nodes/class_variable_and_write_node.rb +12 -0
  35. data/lib/refract/nodes/class_variable_operator_write_node.rb +13 -0
  36. data/lib/refract/nodes/class_variable_or_write_node.rb +12 -0
  37. data/lib/refract/nodes/class_variable_read_node.rb +11 -0
  38. data/lib/refract/nodes/class_variable_target_node.rb +11 -0
  39. data/lib/refract/nodes/class_variable_write_node.rb +12 -0
  40. data/lib/refract/nodes/constant_and_write_node.rb +12 -0
  41. data/lib/refract/nodes/constant_operator_write_node.rb +13 -0
  42. data/lib/refract/nodes/constant_or_write_node.rb +12 -0
  43. data/lib/refract/nodes/constant_path.rb +12 -0
  44. data/lib/refract/nodes/constant_path_and_write_node.rb +12 -0
  45. data/lib/refract/nodes/constant_path_operator_write_node.rb +13 -0
  46. data/lib/refract/nodes/constant_path_or_write_node.rb +12 -0
  47. data/lib/refract/nodes/constant_path_target_node.rb +12 -0
  48. data/lib/refract/nodes/constant_path_write_node.rb +12 -0
  49. data/lib/refract/nodes/constant_read_node.rb +11 -0
  50. data/lib/refract/nodes/constant_target_node.rb +11 -0
  51. data/lib/refract/nodes/constant_write_node.rb +12 -0
  52. data/lib/refract/nodes/def_node.rb +14 -0
  53. data/lib/refract/nodes/defined_node.rb +11 -0
  54. data/lib/refract/nodes/else_node.rb +11 -0
  55. data/lib/refract/nodes/embedded_statements_node.rb +11 -0
  56. data/lib/refract/nodes/embedded_variable_node.rb +11 -0
  57. data/lib/refract/nodes/ensure_node.rb +11 -0
  58. data/lib/refract/nodes/false_node.rb +6 -0
  59. data/lib/refract/nodes/find_pattern_node.rb +14 -0
  60. data/lib/refract/nodes/flip_flop_node.rb +13 -0
  61. data/lib/refract/nodes/float_node.rb +11 -0
  62. data/lib/refract/nodes/for_node.rb +13 -0
  63. data/lib/refract/nodes/forwarding_arguments_node.rb +6 -0
  64. data/lib/refract/nodes/forwarding_parameter_node.rb +6 -0
  65. data/lib/refract/nodes/forwarding_super_node.rb +11 -0
  66. data/lib/refract/nodes/global_variable_and_write_node.rb +12 -0
  67. data/lib/refract/nodes/global_variable_operator_write_node.rb +13 -0
  68. data/lib/refract/nodes/global_variable_or_write_node.rb +12 -0
  69. data/lib/refract/nodes/global_variable_read_node.rb +11 -0
  70. data/lib/refract/nodes/global_variable_target_node.rb +11 -0
  71. data/lib/refract/nodes/global_variable_write_node.rb +12 -0
  72. data/lib/refract/nodes/hash_node.rb +11 -0
  73. data/lib/refract/nodes/hash_pattern_node.rb +12 -0
  74. data/lib/refract/nodes/if_node.rb +13 -0
  75. data/lib/refract/nodes/imaginary_node.rb +11 -0
  76. data/lib/refract/nodes/implicit_node.rb +11 -0
  77. data/lib/refract/nodes/implicit_rest_node.rb +6 -0
  78. data/lib/refract/nodes/in_node.rb +12 -0
  79. data/lib/refract/nodes/index_and_write_node.rb +14 -0
  80. data/lib/refract/nodes/index_operator_write_node.rb +15 -0
  81. data/lib/refract/nodes/index_or_write_node.rb +14 -0
  82. data/lib/refract/nodes/index_target_node.rb +13 -0
  83. data/lib/refract/nodes/instance_variable_and_write_node.rb +12 -0
  84. data/lib/refract/nodes/instance_variable_operator_write_node.rb +13 -0
  85. data/lib/refract/nodes/instance_variable_or_write_node.rb +12 -0
  86. data/lib/refract/nodes/instance_variable_read_node.rb +11 -0
  87. data/lib/refract/nodes/instance_variable_target_node.rb +11 -0
  88. data/lib/refract/nodes/instance_variable_write_node.rb +12 -0
  89. data/lib/refract/nodes/integer_node.rb +11 -0
  90. data/lib/refract/nodes/interpolated_match_last_line_node.rb +15 -0
  91. data/lib/refract/nodes/interpolated_regular_expression_node.rb +15 -0
  92. data/lib/refract/nodes/interpolated_string_node.rb +11 -0
  93. data/lib/refract/nodes/interpolated_symbol_node.rb +11 -0
  94. data/lib/refract/nodes/interpolated_x_string_node.rb +11 -0
  95. data/lib/refract/nodes/it_local_variable_read_node.rb +6 -0
  96. data/lib/refract/nodes/it_parameters_node.rb +6 -0
  97. data/lib/refract/nodes/keyword_hash_node.rb +11 -0
  98. data/lib/refract/nodes/keyword_rest_parameter_node.rb +11 -0
  99. data/lib/refract/nodes/lambda_node.rb +12 -0
  100. data/lib/refract/nodes/local_variable_and_write_node.rb +13 -0
  101. data/lib/refract/nodes/local_variable_operator_write_node.rb +14 -0
  102. data/lib/refract/nodes/local_variable_or_write_node.rb +13 -0
  103. data/lib/refract/nodes/local_variable_read_node.rb +11 -0
  104. data/lib/refract/nodes/local_variable_target_node.rb +11 -0
  105. data/lib/refract/nodes/local_variable_write_node.rb +12 -0
  106. data/lib/refract/nodes/match_last_line_node.rb +15 -0
  107. data/lib/refract/nodes/match_predicate_node.rb +12 -0
  108. data/lib/refract/nodes/match_required_node.rb +12 -0
  109. data/lib/refract/nodes/match_write_node.rb +12 -0
  110. data/lib/refract/nodes/missing_node.rb +6 -0
  111. data/lib/refract/nodes/module_node.rb +12 -0
  112. data/lib/refract/nodes/multi_target_node.rb +13 -0
  113. data/lib/refract/nodes/multi_write_node.rb +14 -0
  114. data/lib/refract/nodes/next_node.rb +11 -0
  115. data/lib/refract/nodes/nil_node.rb +6 -0
  116. data/lib/refract/nodes/no_keywords_parameter_node.rb +6 -0
  117. data/lib/refract/nodes/numbered_parameters_node.rb +6 -0
  118. data/lib/refract/nodes/numbered_reference_read_node.rb +11 -0
  119. data/lib/refract/nodes/optional_keyword_parameter_node.rb +12 -0
  120. data/lib/refract/nodes/optional_parameter_node.rb +12 -0
  121. data/lib/refract/nodes/or_node.rb +13 -0
  122. data/lib/refract/nodes/parameters_node.rb +17 -0
  123. data/lib/refract/nodes/parentheses_node.rb +11 -0
  124. data/lib/refract/nodes/pinned_expression_node.rb +11 -0
  125. data/lib/refract/nodes/pinned_variable_node.rb +11 -0
  126. data/lib/refract/nodes/post_execution_node.rb +11 -0
  127. data/lib/refract/nodes/pre_execution_node.rb +11 -0
  128. data/lib/refract/nodes/program_node.rb +11 -0
  129. data/lib/refract/nodes/range_node.rb +13 -0
  130. data/lib/refract/nodes/rational_node.rb +12 -0
  131. data/lib/refract/nodes/redo_node.rb +6 -0
  132. data/lib/refract/nodes/regular_expression_node.rb +15 -0
  133. data/lib/refract/nodes/required_keyword_parameter_node.rb +11 -0
  134. data/lib/refract/nodes/required_parameter_node.rb +11 -0
  135. data/lib/refract/nodes/rescue_modifier_node.rb +12 -0
  136. data/lib/refract/nodes/rescue_node.rb +14 -0
  137. data/lib/refract/nodes/rest_parameter_node.rb +11 -0
  138. data/lib/refract/nodes/retry_node.rb +6 -0
  139. data/lib/refract/nodes/return_node.rb +11 -0
  140. data/lib/refract/nodes/self_node.rb +6 -0
  141. data/lib/refract/nodes/shareable_constant_node.rb +11 -0
  142. data/lib/refract/nodes/singleton_class_node.rb +12 -0
  143. data/lib/refract/nodes/source_encoding_node.rb +6 -0
  144. data/lib/refract/nodes/source_file_node.rb +6 -0
  145. data/lib/refract/nodes/source_line_node.rb +6 -0
  146. data/lib/refract/nodes/splat_node.rb +11 -0
  147. data/lib/refract/nodes/statements_node.rb +11 -0
  148. data/lib/refract/nodes/string_node.rb +11 -0
  149. data/lib/refract/nodes/super_node.rb +12 -0
  150. data/lib/refract/nodes/symbol_node.rb +11 -0
  151. data/lib/refract/nodes/true_node.rb +6 -0
  152. data/lib/refract/nodes/undef_node.rb +11 -0
  153. data/lib/refract/nodes/unless_node.rb +13 -0
  154. data/lib/refract/nodes/until_node.rb +12 -0
  155. data/lib/refract/nodes/when_node.rb +12 -0
  156. data/lib/refract/nodes/while_node.rb +12 -0
  157. data/lib/refract/nodes/x_string_node.rb +11 -0
  158. data/lib/refract/nodes/yield_node.rb +11 -0
  159. data/lib/refract/version.rb +5 -0
  160. data/lib/refract/visitor.rb +689 -0
  161. data/lib/refract.rb +35 -45
  162. data/lib/rubocop/cop/refract/ordered_visit_methods.rb +107 -0
  163. data/lib/rubocop/cop/refract_cops.rb +3 -0
  164. metadata +189 -26
@@ -0,0 +1,1271 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Refract
4
+ class Formatter < BasicVisitor
5
+ def initialize
6
+ super
7
+ @buffer = []
8
+ @source_map = []
9
+ @current_line = 1
10
+ @indent = 0
11
+ end
12
+
13
+ def format_node(node)
14
+ visit(node)
15
+ @buffer.join
16
+ end
17
+
18
+ visit AliasGlobalVariableNode do |node|
19
+ push "alias"
20
+ space
21
+ visit node.new_name
22
+ space
23
+ visit node.old_name
24
+ end
25
+
26
+ visit AliasMethodNode do |node|
27
+ push "alias"
28
+ space
29
+ visit node.new_name
30
+ space
31
+ visit node.old_name
32
+ end
33
+
34
+ visit AlternationPatternNode do |node|
35
+ visit node.left
36
+ push " | "
37
+ visit node.right
38
+ end
39
+
40
+ visit AndNode do |node|
41
+ visit node.left
42
+ space
43
+ push node.operator
44
+ space
45
+ visit node.right
46
+ end
47
+
48
+ visit ArgumentsNode do |node|
49
+ visit_each(node.arguments) { push ", " }
50
+ end
51
+
52
+ visit ArrayNode do |node|
53
+ brackets do
54
+ indent do
55
+ visit_each(node.elements) { push ","; new_line }
56
+ end
57
+ new_line
58
+ end
59
+ end
60
+
61
+ visit ArrayPatternNode do |node|
62
+ visit node.constant
63
+ brackets do
64
+ visit_each(node.requireds) { push ", " }
65
+ visit(node.rest)
66
+ end
67
+ end
68
+
69
+ visit AssocNode do |node|
70
+ case node.key
71
+ when SymbolNode
72
+ push node.key.unescaped
73
+ push ":"
74
+ space unless ImplicitNode === node.value
75
+ visit node.value
76
+ else
77
+ visit node.key
78
+ push " => "
79
+ visit node.value
80
+ end
81
+ end
82
+
83
+ visit AssocSplatNode do |node|
84
+ push "**"
85
+ visit node.value
86
+ end
87
+
88
+ visit BackReferenceReadNode do |node|
89
+ push node.name
90
+ end
91
+
92
+ visit BeginNode do |node|
93
+ outdent do
94
+ push "begin"
95
+
96
+ indent do
97
+ visit node.statements
98
+ end
99
+
100
+ new_line
101
+
102
+ if node.rescue_clause
103
+ visit node.rescue_clause
104
+ new_line
105
+ end
106
+
107
+ if node.else_clause
108
+ visit node.else_clause
109
+ new_line
110
+ end
111
+
112
+ if node.ensure_clause
113
+ visit node.ensure_clause
114
+ new_line
115
+ end
116
+
117
+ push "end"
118
+ end
119
+ end
120
+
121
+ visit BlockArgumentNode do |node|
122
+ push "&"
123
+ visit node.expression
124
+ end
125
+
126
+ visit BlockLocalVariableNode do |node|
127
+ push node.name
128
+ end
129
+
130
+ visit BlockNode do |node|
131
+ braces do
132
+ case node.parameters
133
+ when nil
134
+ nil
135
+ when ItParametersNode, NumberedParametersNode
136
+ visit node.parameters
137
+ else
138
+ space
139
+ pipes do
140
+ visit node.parameters
141
+ end
142
+ end
143
+
144
+ indent do
145
+ visit node.body
146
+ end
147
+
148
+ new_line
149
+ end
150
+ end
151
+
152
+ visit BlockParameterNode do |node|
153
+ push "&"
154
+ push node.name
155
+ end
156
+
157
+ visit BlockParametersNode do |node|
158
+ visit node.parameters
159
+
160
+ if node.locals&.any?
161
+ push "; "
162
+ visit_each(node.locals) { push ", " }
163
+ end
164
+ end
165
+
166
+ visit BreakNode do |node|
167
+ push "break"
168
+ if node.arguments
169
+ space
170
+ visit node.arguments
171
+ end
172
+ end
173
+
174
+ visit CallAndWriteNode do |node|
175
+ if node.receiver
176
+ visit node.receiver
177
+ push "."
178
+ end
179
+
180
+ push node.read_name
181
+ space
182
+ push "&&="
183
+ space
184
+ visit node.value
185
+ end
186
+
187
+ visit CallNode do |node|
188
+ if node.receiver
189
+ visit node.receiver
190
+ push "."
191
+ end
192
+
193
+ push node.message
194
+
195
+ case node.block
196
+ when BlockNode
197
+ if node.arguments
198
+ parens { visit node.arguments }
199
+ end
200
+
201
+ space
202
+ visit node.block
203
+ when BlockArgumentNode
204
+ parens do
205
+ if node.arguments
206
+ visit node.arguments
207
+ push ", "
208
+ end
209
+
210
+ visit node.block
211
+ end
212
+ else
213
+ if node.arguments
214
+ parens { visit node.arguments }
215
+ end
216
+ end
217
+ end
218
+
219
+ visit CallOperatorWriteNode do |node|
220
+ if node.receiver
221
+ visit node.receiver
222
+ push "."
223
+ end
224
+
225
+ push node.read_name
226
+ space
227
+ push node.binary_operator
228
+ push "="
229
+ space
230
+ visit node.value
231
+ end
232
+
233
+ visit CallOrWriteNode do |node|
234
+ if node.receiver
235
+ visit node.receiver
236
+ push "."
237
+ end
238
+
239
+ push node.read_name
240
+ push " ||= "
241
+ visit node.value
242
+ end
243
+
244
+ visit CallTargetNode do |node|
245
+ if node.receiver
246
+ visit node.receiver
247
+ push "."
248
+ end
249
+
250
+ push node.name[0..-2]
251
+ end
252
+
253
+ visit CapturePatternNode do |node|
254
+ visit node.value
255
+ push " => "
256
+ visit node.target
257
+ end
258
+
259
+ visit CaseMatchNode do |node|
260
+ push "case "
261
+ visit node.predicate
262
+ new_line
263
+ visit_each(node.conditions) { new_line }
264
+ new_line
265
+ if node.else_clause
266
+ visit node.else_clause
267
+ new_line
268
+ end
269
+ push "end"
270
+ end
271
+
272
+ visit CaseNode do |node|
273
+ push "case "
274
+ visit node.predicate
275
+ new_line
276
+ visit_each(node.conditions) { new_line }
277
+ new_line
278
+ if node.else_clause
279
+ visit node.else_clause
280
+ new_line
281
+ end
282
+ push "end"
283
+ end
284
+
285
+ visit ClassNode do |node|
286
+ push "class"
287
+ space
288
+ visit node.constant_path
289
+ if node.superclass
290
+ push " < "
291
+ visit node.superclass
292
+ end
293
+ if node.body
294
+ indent do
295
+ visit node.body
296
+ end
297
+ end
298
+ new_line
299
+ push "end"
300
+ end
301
+
302
+ visit ClassVariableAndWriteNode do |node|
303
+ push node.name
304
+ push " &&= "
305
+ visit node.value
306
+ end
307
+
308
+ visit ClassVariableOperatorWriteNode do |node|
309
+ push node.name
310
+ push " #{node.binary_operator}= "
311
+ visit node.value
312
+ end
313
+
314
+ visit ClassVariableOrWriteNode do |node|
315
+ push node.name
316
+ push " ||= "
317
+ visit node.value
318
+ end
319
+
320
+ visit ClassVariableReadNode do |node|
321
+ push node.name
322
+ end
323
+
324
+ visit ClassVariableTargetNode do |node|
325
+ push node.name
326
+ end
327
+
328
+ visit ClassVariableWriteNode do |node|
329
+ push node.name
330
+ push " = "
331
+ visit node.value
332
+ end
333
+
334
+ visit ConstantAndWriteNode do |node|
335
+ push node.name
336
+ push " &&= "
337
+ visit node.value
338
+ end
339
+
340
+ visit ConstantOperatorWriteNode do |node|
341
+ push node.name
342
+ push " #{node.binary_operator}= "
343
+ visit node.value
344
+ end
345
+
346
+ visit ConstantOrWriteNode do |node|
347
+ push node.name
348
+ push " ||= "
349
+ visit node.value
350
+ end
351
+
352
+ visit ConstantPath do |node|
353
+ visit node.parent
354
+ push "::"
355
+ push node.name
356
+ end
357
+
358
+ visit ConstantPathAndWriteNode do |node|
359
+ visit node.target
360
+ push " &&= "
361
+ visit node.value
362
+ end
363
+
364
+ visit ConstantPathOperatorWriteNode do |node|
365
+ visit node.target
366
+ space
367
+ push node.binary_operator
368
+ push "= "
369
+ visit node.value
370
+ end
371
+
372
+ visit ConstantPathOrWriteNode do |node|
373
+ visit node.target
374
+ push " ||= "
375
+ visit node.value
376
+ end
377
+
378
+ visit ConstantPathTargetNode do |node|
379
+ visit node.parent if node.parent
380
+ push "::" if node.parent
381
+ push node.name
382
+ end
383
+
384
+ visit ConstantPathWriteNode do |node|
385
+ visit node.target
386
+ push " = "
387
+ visit node.value
388
+ end
389
+
390
+ visit ConstantReadNode do |node|
391
+ push node.name
392
+ end
393
+
394
+ visit ConstantTargetNode do |node|
395
+ push node.name
396
+ end
397
+
398
+ visit ConstantWriteNode do |node|
399
+ push node.name
400
+ push " = "
401
+ visit node.value
402
+ end
403
+
404
+ visit DefNode do |node|
405
+ push "def"
406
+ space
407
+
408
+ if node.receiver
409
+ visit node.receiver
410
+ push "."
411
+ end
412
+
413
+ push node.name
414
+
415
+ if node.parameters
416
+ parens do
417
+ visit node.parameters
418
+ end
419
+ end
420
+
421
+ if node.body
422
+ indent do
423
+ visit node.body
424
+ end
425
+ end
426
+
427
+ new_line
428
+
429
+ push "end"
430
+ end
431
+
432
+ visit DefinedNode do |node|
433
+ push "defined?"
434
+ parens do
435
+ visit node.value
436
+ end
437
+ end
438
+
439
+ visit ElseNode do |node|
440
+ push "else"
441
+
442
+ indent do
443
+ visit node.statements
444
+ end
445
+ end
446
+
447
+ visit EmbeddedStatementsNode do |node|
448
+ push "\#{"
449
+ visit node.statements
450
+ push "}"
451
+ end
452
+
453
+ visit EmbeddedVariableNode do |node|
454
+ push "#"
455
+ visit node.variable
456
+ end
457
+
458
+ visit EnsureNode do |node|
459
+ push "ensure"
460
+
461
+ indent do
462
+ visit node.statements
463
+ end
464
+ end
465
+
466
+ visit FalseNode do |node|
467
+ push "false"
468
+ end
469
+
470
+ visit FindPatternNode do |node|
471
+ visit node.constant
472
+ brackets do
473
+ visit_each([node.left, *node.requireds, node.right]) { push ", " }
474
+ end
475
+ end
476
+
477
+ visit FlipFlopNode do |node|
478
+ visit node.left
479
+ push node.exclude_end ? "..." : ".."
480
+ visit node.right
481
+ end
482
+
483
+ visit FloatNode do |node|
484
+ push node.value.to_s
485
+ end
486
+
487
+ visit ForNode do |node|
488
+ push "for"
489
+ space
490
+ visit node.index
491
+ push " in "
492
+ visit node.collection
493
+ indent do
494
+ visit node.statements
495
+ end
496
+ new_line
497
+ push "end"
498
+ end
499
+
500
+ visit ForwardingArgumentsNode do |node|
501
+ push "..."
502
+ end
503
+
504
+ visit ForwardingParameterNode do |node|
505
+ push "..."
506
+ end
507
+
508
+ visit ForwardingSuperNode do |node|
509
+ push "super"
510
+ visit node.block if node.block
511
+ end
512
+
513
+ visit GlobalVariableAndWriteNode do |node|
514
+ push node.name
515
+ push " &&= "
516
+ visit node.value
517
+ end
518
+
519
+ visit GlobalVariableOperatorWriteNode do |node|
520
+ push node.name
521
+ space
522
+ push node.binary_operator
523
+ push "= "
524
+ visit node.value
525
+ end
526
+
527
+ visit GlobalVariableOrWriteNode do |node|
528
+ push node.name
529
+ push " ||= "
530
+ visit node.value
531
+ end
532
+
533
+ visit GlobalVariableReadNode do |node|
534
+ push node.name
535
+ end
536
+
537
+ visit GlobalVariableTargetNode do |node|
538
+ push node.name
539
+ end
540
+
541
+ visit GlobalVariableWriteNode do |node|
542
+ push node.name
543
+ push " = "
544
+ visit node.value
545
+ end
546
+
547
+ visit HashNode do |node|
548
+ braces do
549
+ indent do
550
+ visit_each(node.elements) { push ","; new_line }
551
+ end
552
+
553
+ new_line
554
+ end
555
+ end
556
+
557
+ visit HashPatternNode do |node|
558
+ braces do
559
+ space
560
+ visit_each([*node.elements, node.rest]) { push ", " }
561
+ space
562
+ end
563
+ end
564
+
565
+ visit IfNode do |node|
566
+ # Check if this is an elsif by looking at the parent
567
+ if IfNode === @stack[-2]
568
+ push "elsif "
569
+ else
570
+ push "if "
571
+ end
572
+ visit node.predicate
573
+ if node.statements
574
+ indent do
575
+ visit node.statements
576
+ end
577
+ end
578
+ if node.subsequent
579
+ new_line
580
+ visit node.subsequent
581
+ end
582
+ unless IfNode === @stack[-2]
583
+ new_line
584
+ push "end"
585
+ end
586
+ end
587
+
588
+ visit ImaginaryNode do |node|
589
+ visit node.numeric
590
+ push "i"
591
+ end
592
+
593
+ visit ImplicitNode do |node|
594
+ nil
595
+ end
596
+
597
+ visit ImplicitRestNode do |node|
598
+ nil
599
+ end
600
+
601
+ visit InNode do |node|
602
+ push "in "
603
+ visit node.pattern
604
+ if node.statements
605
+ indent do
606
+ visit node.statements
607
+ end
608
+ end
609
+ end
610
+
611
+ visit IndexAndWriteNode do |node|
612
+ visit node.receiver
613
+ push "["
614
+ visit_each([node.arguments, node.block]) { push ", " }
615
+ push "] &&= "
616
+ visit node.value
617
+ end
618
+
619
+ visit IndexOperatorWriteNode do |node|
620
+ visit node.receiver
621
+ push "["
622
+ visit_each([node.arguments, node.block]) { push ", " }
623
+ push "] "
624
+ push node.binary_operator
625
+ push "= "
626
+ visit node.value
627
+ end
628
+
629
+ visit IndexOrWriteNode do |node|
630
+ visit node.receiver
631
+ push "["
632
+ visit_each([node.arguments, node.block]) { push ", " }
633
+ push "] ||= "
634
+ visit node.value
635
+ end
636
+
637
+ visit IndexTargetNode do |node|
638
+ visit node.receiver
639
+ push "["
640
+ visit_each([node.arguments, node.block]) { push ", " }
641
+ push "]"
642
+ end
643
+
644
+ visit InstanceVariableAndWriteNode do |node|
645
+ push node.name
646
+ push " &&= "
647
+ visit node.value
648
+ end
649
+
650
+ visit InstanceVariableOperatorWriteNode do |node|
651
+ push node.name
652
+ space
653
+ push node.binary_operator
654
+ push "= "
655
+ visit node.value
656
+ end
657
+
658
+ visit InstanceVariableOrWriteNode do |node|
659
+ push node.name
660
+ push " ||= "
661
+ visit node.value
662
+ end
663
+
664
+ visit InstanceVariableReadNode do |node|
665
+ push node.name
666
+ end
667
+
668
+ visit InstanceVariableTargetNode do |node|
669
+ push node.name
670
+ end
671
+
672
+ visit InstanceVariableWriteNode do |node|
673
+ push node.name
674
+ push " = "
675
+ visit node.value
676
+ end
677
+
678
+ visit IntegerNode do |node|
679
+ push node.value.to_s
680
+ end
681
+
682
+ visit InterpolatedMatchLastLineNode do |node|
683
+ push "/"
684
+ node.parts.each do |part|
685
+ case part
686
+ when StringNode
687
+ push part.unescaped.gsub("/", "\\/")
688
+ else
689
+ visit part
690
+ end
691
+ end
692
+ push "/"
693
+ end
694
+
695
+ visit InterpolatedRegularExpressionNode do |node|
696
+ push "/"
697
+ node.parts.each do |part|
698
+ case part
699
+ when StringNode
700
+ push part.unescaped.gsub("/", "\\/")
701
+ else
702
+ visit part
703
+ end
704
+ end
705
+ push "/"
706
+ push "i" if node.ignore_case
707
+ push "m" if node.multi_line
708
+ push "x" if node.extended
709
+ push "o" if node.once
710
+ end
711
+
712
+ visit InterpolatedStringNode do |node|
713
+ doubles do
714
+ node.parts.each do |part|
715
+ case part
716
+ when StringNode
717
+ push part.unescaped.gsub('"', '\"')
718
+ else
719
+ visit part
720
+ end
721
+ end
722
+ end
723
+ end
724
+
725
+ visit InterpolatedSymbolNode do |node|
726
+ push ':"'
727
+ node.parts.each do |part|
728
+ case part
729
+ when StringNode
730
+ push part.unescaped.gsub('"', '\"')
731
+ else
732
+ visit part
733
+ end
734
+ end
735
+ push '"'
736
+ end
737
+
738
+ visit InterpolatedXStringNode do |node|
739
+ push "`"
740
+ node.parts.each do |part|
741
+ case part
742
+ when StringNode
743
+ push part.unescaped.gsub("`", "\\`")
744
+ else
745
+ visit part
746
+ end
747
+ end
748
+ push "`"
749
+ end
750
+
751
+ visit ItLocalVariableReadNode do |node|
752
+ push "it"
753
+ end
754
+
755
+ visit ItParametersNode do |node|
756
+ nil
757
+ end
758
+
759
+ visit KeywordHashNode do |node|
760
+ visit_each(node.elements) { push ", " }
761
+ end
762
+
763
+ visit KeywordRestParameterNode do |node|
764
+ push "**"
765
+ push node.name
766
+ end
767
+
768
+ visit LambdaNode do |node|
769
+ push "->"
770
+
771
+ case node.parameters
772
+ when nil
773
+ nil
774
+ when ItParametersNode, NumberedParametersNode
775
+ visit node.parameters
776
+ else
777
+ space
778
+
779
+ parens do
780
+ visit node.parameters
781
+ end
782
+ end
783
+
784
+ space
785
+
786
+ braces do
787
+ indent do
788
+ visit node.body
789
+ end
790
+
791
+ new_line
792
+ end
793
+ end
794
+
795
+ visit LocalVariableAndWriteNode do |node|
796
+ push node.name
797
+ push " &&= "
798
+ visit node.value
799
+ end
800
+
801
+ visit LocalVariableOperatorWriteNode do |node|
802
+ push node.name
803
+ space
804
+ push node.binary_operator
805
+ push "= "
806
+ visit node.value
807
+ end
808
+
809
+ visit LocalVariableOrWriteNode do |node|
810
+ push node.name
811
+ push " ||= "
812
+ visit node.value
813
+ end
814
+
815
+ visit LocalVariableReadNode do |node|
816
+ push node.name
817
+ end
818
+
819
+ visit LocalVariableTargetNode do |node|
820
+ push node.name
821
+ end
822
+
823
+ visit LocalVariableWriteNode do |node|
824
+ push node.name
825
+ push " = "
826
+ visit node.value
827
+ end
828
+
829
+ visit MatchLastLineNode do |node|
830
+ push "/"
831
+ push node.unescaped.gsub("/", '\\/')
832
+ push "/"
833
+ push "i" if node.ignore_case
834
+ push "m" if node.multi_line
835
+ push "x" if node.extended
836
+ push "o" if node.once
837
+ end
838
+
839
+ visit MatchPredicateNode do |node|
840
+ visit node.value
841
+ push " in "
842
+ visit node.pattern
843
+ end
844
+
845
+ visit MatchRequiredNode do |node|
846
+ visit node.value
847
+ push " => "
848
+ visit node.pattern
849
+ end
850
+
851
+ visit MatchWriteNode do |node|
852
+ visit node.call
853
+ # Targets are written to by the match
854
+ end
855
+
856
+ visit MissingNode do |node|
857
+ # Missing nodes represent syntax errors - output nothing
858
+ end
859
+
860
+ visit ModuleNode do |node|
861
+ push "module"
862
+ space
863
+ visit node.constant_path
864
+ if node.body
865
+ indent do
866
+ visit node.body
867
+ end
868
+ end
869
+ new_line
870
+ push "end"
871
+ end
872
+
873
+ visit MultiTargetNode do |node|
874
+ visit_each([*node.lefts, node.rest, *node.rights]) { push ", " }
875
+ end
876
+
877
+ visit MultiWriteNode do |node|
878
+ visit_each([*node.lefts, node.rest, *node.rights]) { push ", " }
879
+ space unless ImplicitRestNode === node.rest
880
+ push "= "
881
+ visit node.value
882
+ end
883
+
884
+ visit NextNode do |node|
885
+ push "next"
886
+ if node.arguments
887
+ space
888
+ visit node.arguments
889
+ end
890
+ end
891
+
892
+ visit NilNode do |node|
893
+ push "nil"
894
+ end
895
+
896
+ visit NoKeywordsParameterNode do |node|
897
+ push "**nil"
898
+ end
899
+
900
+ visit NumberedParametersNode do |node|
901
+ nil
902
+ end
903
+
904
+ visit NumberedReferenceReadNode do |node|
905
+ push "$#{node.number}"
906
+ end
907
+
908
+ visit OptionalKeywordParameterNode do |node|
909
+ push node.name
910
+ push ": "
911
+ visit node.value
912
+ end
913
+
914
+ visit OptionalParameterNode do |node|
915
+ push node.name
916
+ push " = "
917
+ visit node.value
918
+ end
919
+
920
+ visit OrNode do |node|
921
+ visit node.left
922
+ space
923
+ push node.operator
924
+ space
925
+ visit node.right
926
+ end
927
+
928
+ visit ParametersNode do |node|
929
+ visit_each([
930
+ *node.requireds,
931
+ *node.optionals,
932
+ node.rest,
933
+ *node.posts,
934
+ *node.keywords,
935
+ node.keyword_rest,
936
+ node.block,
937
+ ]) { push ", " }
938
+ end
939
+
940
+ visit ParenthesesNode do |node|
941
+ parens do
942
+ visit node.body
943
+ end
944
+ end
945
+
946
+ visit PinnedExpressionNode do |node|
947
+ push "^("
948
+ visit node.expression
949
+ push ")"
950
+ end
951
+
952
+ visit PinnedVariableNode do |node|
953
+ push "^"
954
+ visit node.variable
955
+ end
956
+
957
+ visit PostExecutionNode do |node|
958
+ push "END {"
959
+ indent do
960
+ visit node.statements
961
+ end
962
+ new_line
963
+ push "}"
964
+ end
965
+
966
+ visit PreExecutionNode do |node|
967
+ push "BEGIN {"
968
+ indent do
969
+ visit node.statements
970
+ end
971
+ new_line
972
+ push "}"
973
+ end
974
+
975
+ visit ProgramNode do |node|
976
+ visit node.statements
977
+ end
978
+
979
+ visit RangeNode do |node|
980
+ visit node.left
981
+ push node.exclude_end ? "..." : ".."
982
+ visit node.right
983
+ end
984
+
985
+ visit RationalNode do |node|
986
+ if node.denominator == 1
987
+ push node.numerator.to_s
988
+ push "r"
989
+ else
990
+ push "#{(node.numerator.to_f / node.denominator)}r"
991
+ end
992
+ end
993
+
994
+ visit RedoNode do |node|
995
+ push "redo"
996
+ end
997
+
998
+ visit RegularExpressionNode do |node|
999
+ push "/"
1000
+ push node.unescaped.gsub("/", '\\/')
1001
+ push "/"
1002
+ push "i" if node.ignore_case
1003
+ push "m" if node.multi_line
1004
+ push "x" if node.extended
1005
+ push "o" if node.once
1006
+ end
1007
+
1008
+ visit RequiredKeywordParameterNode do |node|
1009
+ push node.name
1010
+ push ":"
1011
+ end
1012
+
1013
+ visit RequiredParameterNode do |node|
1014
+ push node.name
1015
+ end
1016
+
1017
+ visit RescueModifierNode do |node|
1018
+ visit node.expression
1019
+ push " rescue "
1020
+ visit node.rescue_expression
1021
+ end
1022
+
1023
+ visit RescueNode do |node|
1024
+ push "rescue"
1025
+ if node.exceptions&.any?
1026
+ space
1027
+ visit_each(node.exceptions) { push ", " }
1028
+ end
1029
+
1030
+ if node.reference
1031
+ push " => "
1032
+ visit node.reference
1033
+ end
1034
+
1035
+ if node.statements
1036
+ indent do
1037
+ visit node.statements
1038
+ end
1039
+ end
1040
+
1041
+ if node.subsequent
1042
+ new_line
1043
+ visit node.subsequent
1044
+ end
1045
+ end
1046
+
1047
+ visit RestParameterNode do |node|
1048
+ push "*"
1049
+ push node.name
1050
+ end
1051
+
1052
+ visit RetryNode do |node|
1053
+ push "retry"
1054
+ end
1055
+
1056
+ visit ReturnNode do |node|
1057
+ push "return"
1058
+ if node.arguments
1059
+ space
1060
+ visit node.arguments
1061
+ end
1062
+ end
1063
+
1064
+ visit SelfNode do |node|
1065
+ push "self"
1066
+ end
1067
+
1068
+ visit ShareableConstantNode do |node|
1069
+ visit node.write
1070
+ end
1071
+
1072
+ visit SingletonClassNode do |node|
1073
+ push "class << "
1074
+ visit node.expression
1075
+
1076
+ if node.body
1077
+ indent do
1078
+ visit node.body
1079
+ end
1080
+ end
1081
+
1082
+ new_line
1083
+ push "end"
1084
+ end
1085
+
1086
+ visit SourceEncodingNode do |node|
1087
+ push "__ENCODING__"
1088
+ end
1089
+
1090
+ visit SourceFileNode do |node|
1091
+ push "__FILE__"
1092
+ end
1093
+
1094
+ visit SourceLineNode do |node|
1095
+ push "__LINE__"
1096
+ end
1097
+
1098
+ visit SplatNode do |node|
1099
+ push "*"
1100
+ visit node.expression
1101
+ end
1102
+
1103
+ visit StatementsNode do |node|
1104
+ visit_each(node.body) { new_line }
1105
+ end
1106
+
1107
+ visit StringNode do |node|
1108
+ doubles do
1109
+ push node.unescaped.gsub('"', '\"')
1110
+ end
1111
+ end
1112
+
1113
+ visit SuperNode do |node|
1114
+ push "super"
1115
+ if node.arguments
1116
+ parens do
1117
+ visit node.arguments
1118
+ end
1119
+ end
1120
+ visit node.block if node.block
1121
+ end
1122
+
1123
+ visit SymbolNode do |node|
1124
+ push ":"
1125
+ push node.unescaped
1126
+ end
1127
+
1128
+ visit TrueNode do |node|
1129
+ push "true"
1130
+ end
1131
+
1132
+ visit UndefNode do |node|
1133
+ push "undef"
1134
+ space
1135
+ visit_each(node.names) { push ", " }
1136
+ end
1137
+
1138
+ visit UnlessNode do |node|
1139
+ push "unless "
1140
+ visit node.predicate
1141
+
1142
+ if node.statements
1143
+ indent do
1144
+ visit node.statements
1145
+ end
1146
+ end
1147
+
1148
+ if node.else_clause
1149
+ new_line
1150
+ visit node.else_clause
1151
+ end
1152
+
1153
+ new_line
1154
+ push "end"
1155
+ end
1156
+
1157
+ visit UntilNode do |node|
1158
+ push "until "
1159
+ visit node.predicate
1160
+ if node.statements
1161
+ indent do
1162
+ visit node.statements
1163
+ end
1164
+ end
1165
+ new_line
1166
+ push "end"
1167
+ end
1168
+
1169
+ visit WhenNode do |node|
1170
+ push "when"
1171
+ space
1172
+ visit_each(node.conditions) { push ", " }
1173
+ indent do
1174
+ visit node.statements
1175
+ end
1176
+ end
1177
+
1178
+ visit WhileNode do |node|
1179
+ push "while "
1180
+ visit node.predicate
1181
+ if node.statements
1182
+ indent do
1183
+ visit node.statements
1184
+ end
1185
+ end
1186
+ new_line
1187
+ push "end"
1188
+ end
1189
+
1190
+ visit XStringNode do |node|
1191
+ push "`"
1192
+ push node.unescaped
1193
+ push "`"
1194
+ end
1195
+
1196
+ visit YieldNode do |node|
1197
+ push "yield"
1198
+ if node.arguments
1199
+ parens do
1200
+ visit node.arguments
1201
+ end
1202
+ end
1203
+ end
1204
+
1205
+ private def push(value)
1206
+ string = case value
1207
+ when String
1208
+ value
1209
+ when Symbol
1210
+ value.name
1211
+ end
1212
+
1213
+ @buffer << string
1214
+ end
1215
+
1216
+ private def space
1217
+ push " "
1218
+ end
1219
+
1220
+ private def new_line
1221
+ push "\n#{"\t" * @indent}"
1222
+ end
1223
+
1224
+ private def indent
1225
+ @indent += 1
1226
+ new_line
1227
+ yield
1228
+ @indent -= 1
1229
+ nil
1230
+ end
1231
+
1232
+ private def outdent
1233
+ return yield if @indent == 0
1234
+ @indent -= 1
1235
+ new_line
1236
+ yield
1237
+ @indent += 1
1238
+ nil
1239
+ end
1240
+
1241
+ private def parens
1242
+ push "("
1243
+ yield
1244
+ push ")"
1245
+ end
1246
+
1247
+ private def braces
1248
+ push "{"
1249
+ yield
1250
+ push "}"
1251
+ end
1252
+
1253
+ private def brackets
1254
+ push "["
1255
+ yield
1256
+ push "]"
1257
+ end
1258
+
1259
+ private def pipes
1260
+ push "|"
1261
+ yield
1262
+ push "|"
1263
+ end
1264
+
1265
+ private def doubles
1266
+ push '"'
1267
+ yield
1268
+ push '"'
1269
+ end
1270
+ end
1271
+ end