sirop 0.3 → 0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a44761c6907c2bd7358e0b7d6c4079b8582949121ff32161b508a0950d0032c
4
- data.tar.gz: 99cf621e80d420ec1a4245e8fd9efdbb06633614982d804d45f545f0a1966a0b
3
+ metadata.gz: b6ffcc66301949fc52bae4b2eef554243263b06a9bdf699d6be61d9d38f1ade1
4
+ data.tar.gz: 6aeba8547c161f56a20e64d7cf219489bfd0f2195063ca8b651c821134944232
5
5
  SHA512:
6
- metadata.gz: de992959d865f0ace64d1be7b9c0149a10d193f54e2bfa0e9b20dcd2fe70f7bf4fe3ec5984c29a75cf89bc70dc385d29747ba372174bfe4286654b3543e0f946
7
- data.tar.gz: '00393520ab9df84615c35a104411d4aad118c07ac4d4212debbf21df536f90883dd924e31e4d9064d4ce7344fa425716c292d4f9fbe3e1fb3b675ccea054fe95'
6
+ metadata.gz: 8dde7126119287b24f05352b5c62922a5023c80ff9ffb3f258ddf8824b6ce947b7f2551bc1818202036ac152815458e3126a838b3e91d147ed413cb6fb181818
7
+ data.tar.gz: 83856a27062116324228881ff61172c62234ca3ce6992ba5ef8355db3f5a823e018695eb6e9e61b61b852cfa1b497039c1ad3fcbf6e7451bb0a9b14b64801da0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ # 2024-04-29 0.4
2
+
3
+ - Improve sourcifier to support all Ruby syntax, based on Prism test fixtures
4
+ - Update Prism
5
+
1
6
  # 2024-04-19 0.3
2
7
 
3
8
  - Add support for injecting (prefixed) parameters to a lambda node
@@ -5,6 +5,90 @@ require 'prism'
5
5
  module Sirop
6
6
  #
7
7
  class Sourcifier < Prism::BasicVisitor
8
+ VISIT_PLANS = {
9
+ alias_global_variable: [:keyword_loc, :new_name, :old_name],
10
+ alias_method: [:keyword_loc, :new_name, :old_name],
11
+ and: [:left, :operator_loc, :right],
12
+ assoc: [:key, :operator_loc, :value],
13
+ assoc_splat: [:operator_loc, :value],
14
+ back_reference_read: :emit_verbatim,
15
+ block: [:opening_loc, :parameters, :body, :closing_loc],
16
+ block_argument: [:operator_loc, :expression],
17
+ block_local_variable: :emit_verbatim,
18
+ block_parameter: [:operator_loc, :name_loc],
19
+ break: [:keyword_loc, :arguments],
20
+ capture_pattern: [:value, :operator_loc, :target],
21
+ class_variable_read: :emit_verbatim,
22
+ class_variable_target: :emit_verbatim,
23
+ class_variable_write: [:name_loc, :operator_loc, :value],
24
+ constant_path: [:parent, :delimiter_loc, :child],
25
+ constant_path_write: [:target, :operator_loc, :value],
26
+ constant_read: :emit_verbatim,
27
+ constant_write: [:name_loc, :operator_loc, :value],
28
+ defined: [:keyword_loc, :lparen_loc, :value, :rparen_loc],
29
+ embedded_statements: [:opening_loc, :statements, :closing_loc],
30
+ embedded_variable: [:operator_loc, :variable],
31
+ false: :emit_verbatim,
32
+ flip_flop: [:left, :operator_loc, :right],
33
+ float: :emit_verbatim,
34
+ forwarding_arguments: :emit_verbatim,
35
+ forwarding_parameter: :emit_verbatim,
36
+ forwarding_super: :emit_verbatim,
37
+ global_variable_read: :emit_verbatim,
38
+ global_variable_target: :emit_verbatim,
39
+ global_variable_write: [:name_loc, :operator_loc, :value],
40
+ imaginary: :emit_verbatim,
41
+ implicit: :emit_nothing,
42
+ implicit_rest: :emit_nothing,
43
+ in: [:in_loc, :pattern, :then_loc],
44
+ index_target: [:receiver, :opening_loc, :arguments, :closing_loc],
45
+ instance_variable_read: :emit_verbatim,
46
+ instance_variable_target: :emit_verbatim,
47
+ instance_variable_write: [:name_loc, :operator_loc, :value],
48
+ integer: :emit_verbatim,
49
+ keyword_rest_parameter: [:operator_loc, :name_loc],
50
+ keyword_parameter: :emit_verbatim,
51
+ local_variable_and_write: [:name_loc, :operator_loc, :value],
52
+ local_variable_operator_write: [:name_loc, :operator_loc, :value],
53
+ local_variable_or_write: [:name_loc, :operator_loc, :value],
54
+ local_variable_read: :emit_verbatim,
55
+ local_variable_target: :emit_verbatim,
56
+ local_variable_write: [:name_loc, :operator_loc, :value],
57
+ match_predicate: [:value, :operator_loc, :pattern],
58
+ match_required: [:value, :operator_loc, :pattern],
59
+ match_write: [:call],
60
+ next: [:keyword_loc, :arguments],
61
+ nil: :emit_verbatim,
62
+ no_keywords_parameter: :emit_verbatim,
63
+ numbered_parameters: :emit_nothing,
64
+ optional_parameter: [:name_loc, :operator_loc, :value],
65
+ optional_keyword_parameter: [:name_loc, :value],
66
+ or: [:left, :operator_loc, :right],
67
+ parentheses: [:opening_loc, :body, :closing_loc],
68
+ pinned_expression: [:operator_loc, :lparen_loc, :expression, :rparen_loc],
69
+ pinned_variable: [:operator_loc, :variable],
70
+ range: [:left, :operator_loc, :right],
71
+ rational: :emit_verbatim,
72
+ redo: :emit_verbatim,
73
+ regular_expression: :emit_verbatim,
74
+ required_parameter: :emit_verbatim,
75
+ required_keyword_parameter: :emit_verbatim,
76
+ rescue_modifier: [:expression, :keyword_loc, :rescue_expression],
77
+ rest_parameter: [:operator_loc, :name_loc],
78
+ retry: :emit_verbatim,
79
+ return: [:keyword_loc, :arguments],
80
+ self: :emit_verbatim,
81
+ source_encoding: :emit_verbatim,
82
+ source_file: :emit_verbatim,
83
+ source_line: :emit_verbatim,
84
+ splat: [:operator_loc, :expression],
85
+ string: [:opening_loc, :content_loc, :closing_loc],
86
+ symbol: :emit_verbatim,
87
+ true: :emit_verbatim,
88
+ x_string: :emit_verbatim,
89
+ yield: [:keyword_loc, :lparen_loc, :arguments, :rparen_loc]
90
+ }
91
+
8
92
  attr_reader :buffer
9
93
 
10
94
  def initialize
@@ -52,20 +136,34 @@ module Sirop
52
136
  @last_loc_end = loc_end(loc)
53
137
  end
54
138
 
55
- def emit_code(loc, semicolon: false)
139
+ def emit_code(loc, semicolon: false, chomp: false)
56
140
  return if !loc
57
141
 
142
+ if @last_loc
143
+ loc_loc = loc.is_a?(Prism::Node) ? loc.location : loc
144
+ return if loc_loc.slice == @last_loc.slice && loc_loc.start_line == @last_loc.start_line &&
145
+ loc_loc.start_column == @last_loc.start_column
146
+ end
147
+
148
+ semicolon ||= @semicolon
149
+ @semicolon = false
58
150
  emit_semicolon(loc) if semicolon
59
151
  return visit(loc) if loc.is_a?(Prism::Node)
60
152
 
61
153
  adjust_whitespace(loc)
62
- emit(loc.slice)
154
+ str = loc.slice
155
+ str = str.chomp if chomp
156
+ emit(str)
63
157
  end
64
158
 
65
159
  def emit_verbatim(node)
66
160
  emit_code(node.location)
67
161
  end
68
162
 
163
+ def emit_nothing(node)
164
+ # emit nothing
165
+ end
166
+
69
167
  def emit_str(str)
70
168
  emit(str)
71
169
  @last_loc_end[1] += str.size
@@ -77,7 +175,11 @@ module Sirop
77
175
 
78
176
  def emit_semicolon(loc)
79
177
  loc = loc.location if loc.is_a?(Prism::Node)
80
- emit_str(';') if loc.start_line == @last_loc.end_line
178
+ if @last_loc && loc.start_line == @last_loc.end_line
179
+ if @buffer[-1] != ';' && loc.start_column > @last_loc_end[1]
180
+ emit_str(';')
181
+ end
182
+ end
81
183
  end
82
184
 
83
185
  def method_missing(sym, node, *args)
@@ -87,44 +189,6 @@ module Sirop
87
189
  visit_child_nodes(node)
88
190
  end
89
191
 
90
- VISIT_PLANS = {
91
- and: [:left, :operator_loc, :right],
92
- assoc: :visit_child_nodes,
93
- assoc_splat: [:operator_loc, :value],
94
- block: [:opening_loc, :parameters, :body, :closing_loc],
95
- block_argument: [:operator_loc, :expression],
96
- block_parameter: [:operator_loc, :name_loc],
97
- block_parameters: [:opening_loc, :injected_parameters, :parameters, :closing_loc],
98
- break: [:keyword_loc, :arguments],
99
- constant_path: [:parent, :delimiter_loc, :child],
100
- constant_read: :emit_verbatim,
101
- else: [:else_keyword_loc, :statements],
102
- embedded_statements: [:opening_loc, :statements, :closing_loc],
103
- false: :emit_verbatim,
104
- integer: :emit_verbatim,
105
- keyword_rest_parameter: [:operator_loc, :name_loc],
106
- keyword_parameter: :emit_verbatim,
107
- lambda: [:operator_loc, :parameters, :opening_loc, :body,
108
- :closing_loc],
109
- local_variable_read: :emit_verbatim,
110
- local_variable_write: [:name_loc, :operator_loc, :value],
111
- next: [:keyword_loc, :arguments],
112
- nil: :emit_verbatim,
113
- optional_parameter: [:name_loc, :operator_loc, :value],
114
- optional_keyword_parameter: [:name_loc, :value],
115
- or: [:left, :operator_loc, :right],
116
- parentheses: [:opening_loc, :body, :closing_loc],
117
- required_parameter: :emit_verbatim,
118
- required_keyword_parameter: :emit_verbatim,
119
- rest_parameter: [:operator_loc, :name_loc],
120
- splat: [:operator_loc, :expression],
121
- statements: :visit_child_nodes,
122
- string: :emit_verbatim,
123
- symbol: :emit_verbatim,
124
- true: :emit_verbatim,
125
- yield: [:keyword_loc, :lparen_loc, :arguments, :rparen_loc],
126
- }
127
-
128
192
  VISIT_PLANS.each do |key, plan|
129
193
  sym = :"visit_#{key}_node"
130
194
  define_method(sym) { |n| visit_plan(plan, n) }
@@ -148,7 +212,7 @@ module Sirop
148
212
 
149
213
  def visit_comma_separated_nodes(list, comma = false)
150
214
  if list
151
- list.each_with_index do |child, idx|
215
+ list.each do |child|
152
216
  emit_comma if comma
153
217
  emit_code(child)
154
218
  comma = true
@@ -157,6 +221,14 @@ module Sirop
157
221
  comma
158
222
  end
159
223
 
224
+ def visit_space_separated_nodes(list)
225
+ if list
226
+ list.each do |child|
227
+ emit_code(child)
228
+ end
229
+ end
230
+ end
231
+
160
232
  def visit_parameters_node(node)
161
233
  comma = false
162
234
  # injected_prefix is a custom attribute added by Sirop to the
@@ -171,13 +243,18 @@ module Sirop
171
243
  end
172
244
  comma = visit_comma_separated_nodes(node.requireds, comma)
173
245
  comma = visit_comma_separated_nodes(node.optionals, comma)
174
- comma = visit_comma_separated_nodes(node.posts, comma)
175
- comma = visit_comma_separated_nodes(node.keywords, comma)
176
246
  if node.rest
177
247
  emit_comma if comma
178
- comma = true
179
248
  emit_code(node.rest)
249
+ comma = true
180
250
  end
251
+ comma = visit_comma_separated_nodes(node.posts, comma)
252
+ comma = visit_comma_separated_nodes(node.keywords, comma)
253
+ # if node.rest
254
+ # emit_comma if comma
255
+ # comma = true
256
+ # emit_code(node.rest)
257
+ # end
181
258
  if node.keyword_rest
182
259
  emit_comma if comma
183
260
  comma = true
@@ -190,8 +267,8 @@ module Sirop
190
267
  end
191
268
  end
192
269
 
193
- def visit_arguments_node(node)
194
- visit_comma_separated_nodes(node.arguments)
270
+ def visit_arguments_node(node, subscript = 0..-1)
271
+ visit_comma_separated_nodes(node.arguments[subscript])
195
272
  end
196
273
 
197
274
  def visit_keyword_hash_node(node)
@@ -208,9 +285,9 @@ module Sirop
208
285
  emit_code(node.if_keyword_loc)
209
286
  emit_code(node.predicate)
210
287
  emit_code(node.then_keyword_loc)
211
- emit_code(node.statements)
288
+ emit_code(node.statements, semicolon: true)
212
289
  emit_code(node.consequent) if node.consequent
213
- emit_code(node.end_keyword_loc) if node.if_keyword_loc.slice == 'if'
290
+ emit_code(node.end_keyword_loc, semicolon: true) if node.if_keyword_loc.slice == 'if'
214
291
  end
215
292
 
216
293
  def visit_if_node_ternary(node)
@@ -226,18 +303,38 @@ module Sirop
226
303
  emit_code(node.predicate)
227
304
  end
228
305
 
306
+ def visit_unless_node(node)
307
+ if !node.end_keyword_loc
308
+ return visit_unless_node_guard(node)
309
+ end
310
+
311
+ emit_code(node.keyword_loc)
312
+ emit_code(node.predicate)
313
+ emit_code(node.then_keyword_loc)
314
+ @semicolon = true
315
+ emit_code(node.statements)
316
+ emit_code(node.consequent) if node.consequent
317
+ emit_code(node.end_keyword_loc, semicolon: true) if node.keyword_loc.slice == 'unless'
318
+ end
319
+
320
+ def visit_unless_node_guard(node)
321
+ emit_code(node.statements)
322
+ emit_code(node.keyword_loc)
323
+ emit_code(node.predicate)
324
+ end
325
+
229
326
  def visit_case_node(node)
230
327
  emit_code(node.case_keyword_loc)
231
328
  emit_code(node.predicate)
232
- node.conditions.each { |c| emit_code(c) }
233
- emit_code(node.consequent)
234
- emit_code(node.end_keyword_loc)
329
+ node.conditions.each { |c| emit_code(c, semicolon: true) }
330
+ emit_code(node.consequent, semicolon: true)
331
+ emit_code(node.end_keyword_loc, semicolon: true)
235
332
  end
236
333
 
237
334
  def visit_when_node(node)
238
335
  emit_code(node.keyword_loc)
239
336
  visit_comma_separated_nodes(node.conditions)
240
- emit_code(node.statements)
337
+ emit_code(node.statements, semicolon: true)
241
338
  end
242
339
 
243
340
  def visit_interpolated_symbol_node(node)
@@ -248,36 +345,49 @@ module Sirop
248
345
  alias_method :visit_interpolated_string_node, :visit_interpolated_symbol_node
249
346
 
250
347
  def visit_def_node(node)
251
- emit_code(node.def_keyword_loc)
348
+ emit_code(node.def_keyword_loc, semicolon: true)
349
+ emit_code(node.receiver)
350
+ emit_code(node.operator_loc)
252
351
  emit_code(node.name_loc)
253
- last_loc = node.name_loc
254
352
 
353
+ emit_code(node.lparen_loc)
255
354
  if node.parameters
256
- emit_str('(')
257
355
  emit_code(node.parameters)
258
- emit_str(')')
259
- last_loc = node.parameters.location
260
356
  end
261
-
262
- emit_code(node.body, semicolon: true)
357
+ emit_code(node.rparen_loc)
358
+ emit_code(node.equal_loc)
359
+ emit_code(node.body, semicolon: !node.equal_loc)
263
360
  emit_code(node.end_keyword_loc, semicolon: true)
361
+ @semicolon = true
264
362
  end
265
363
 
266
364
  def visit_call_node(node)
267
- if node.receiver && !node.call_operator_loc && !node.arguments
365
+ if node.receiver && !node.call_operator_loc && !node.arguments && node.name != :[]
268
366
  return visit_call_node_unary_op(node)
269
367
  end
270
368
 
369
+ if node.receiver && !node.call_operator_loc && node.name == :!
370
+ return visit_call_node_unary_op(node)
371
+ end
372
+
373
+ if node.attribute_write?
374
+ return visit_call_node_attribute_write(node)
375
+ end
376
+
271
377
  block = node.block
272
378
 
273
379
  emit_code(node.receiver)
274
380
  emit_code(node.call_operator_loc)
275
- emit_code(node.message_loc)
381
+ if (ml = node.message_loc)
382
+ ol = node.opening_loc
383
+ emit_message_loc = !ol || (ol.start_line != ml.start_line) || (ol.start_column != ml.start_column)
384
+ emit_code(node.message_loc) if emit_message_loc
385
+ end
276
386
  emit_code(node.opening_loc)
277
387
  emit_code(node.arguments)
278
388
 
279
389
  if block.is_a?(Prism::BlockArgumentNode)
280
- emit_comma if node.arguments&.arguments.size > 0
390
+ emit_comma if node.arguments && node.arguments.arguments.size > 0
281
391
  emit_code(block)
282
392
  block = nil
283
393
  end
@@ -287,7 +397,33 @@ module Sirop
287
397
 
288
398
  def visit_call_node_unary_op(node)
289
399
  emit_code(node.message_loc)
400
+ emit_code(node.opening_loc)
401
+ emit_code(node.receiver)
402
+ emit_code(node.closing_loc)
403
+ end
404
+
405
+ def visit_call_node_attribute_write(node)
290
406
  emit_code(node.receiver)
407
+ if node.call_operator_loc
408
+ emit_code(node.call_operator_loc)
409
+ emit_code(node.message_loc)
410
+ end
411
+ emit_code(node.opening_loc)
412
+ comma = visit_arguments_node(node.arguments, 0..-2)
413
+ if node.block
414
+ emit_comma if comma
415
+ emit_code(node.block)
416
+ end
417
+ emit_code(node.closing_loc)
418
+ emit_str(" = ")
419
+ emit_code(node.arguments.arguments[-1])
420
+ return
421
+ end
422
+
423
+ def visit_call_target_node(node)
424
+ emit_code(node.receiver)
425
+ emit_code(node.call_operator_loc)
426
+ emit_code(node.message_loc)
291
427
  end
292
428
 
293
429
  def visit_while_node(node)
@@ -304,5 +440,241 @@ module Sirop
304
440
  emit_code(node.keyword_loc)
305
441
  emit_code(node.predicate)
306
442
  end
443
+
444
+ def visit_until_node(node)
445
+ return visit_until_node_guard(node) if !node.closing_loc
446
+
447
+ emit_code(node.keyword_loc)
448
+ emit_code(node.predicate)
449
+ emit_code(node.statements, semicolon: true)
450
+ emit_code(node.closing_loc, semicolon: true)
451
+ end
452
+
453
+ def visit_until_node_guard(node)
454
+ emit_code(node.statements)
455
+ emit_code(node.keyword_loc)
456
+ emit_code(node.predicate)
457
+ end
458
+
459
+ def visit_hash_node(node)
460
+ emit_code(node.opening_loc)
461
+ visit_comma_separated_nodes(node.elements)
462
+ emit_code(node.closing_loc)
463
+ end
464
+
465
+ def visit_array_node(node)
466
+ emit_code(node.opening_loc)
467
+ if node.opening_loc && node.opening_loc.slice =~ /^%/
468
+ visit_space_separated_nodes(node.elements)
469
+ else
470
+ visit_comma_separated_nodes(node.elements)
471
+ end
472
+ emit_code(node.closing_loc)
473
+ end
474
+
475
+ def visit_multi_write_node(node)
476
+ emit_code(node.lparen_loc)
477
+ comma = visit_comma_separated_nodes(node.lefts)
478
+ if node.rest
479
+ emit_comma if comma
480
+ emit_code(node.rest)
481
+ comma = true
482
+ end
483
+ visit_comma_separated_nodes(node.rights, comma)
484
+ emit_code(node.rparen_loc)
485
+ emit_code(node.operator_loc)
486
+ emit_code(node.value)
487
+ end
488
+
489
+ def visit_rescue_node(node)
490
+ emit_code(node.keyword_loc, semicolon: true)
491
+ visit_comma_separated_nodes(node.exceptions)
492
+ emit_code(node.operator_loc)
493
+ emit_code(node.reference)
494
+ emit_code(node.statements, semicolon: true)
495
+ emit_code(node.consequent)
496
+ end
497
+
498
+ def visit_begin_node(node)
499
+ emit_code(node.begin_keyword_loc) #, semicolon: true)
500
+ emit_code(node.statements, semicolon: true)
501
+ emit_code(node.rescue_clause)
502
+ emit_code(node.else_clause)
503
+ emit_code(node.ensure_clause)
504
+ emit_code(node.end_keyword_loc, semicolon: true) if node.begin_keyword_loc
505
+ end
506
+
507
+ def visit_index_operator_write_node(node)
508
+ emit_code(node.receiver)
509
+ emit_code(node.opening_loc)
510
+ emit_code(node.arguments)
511
+ if node.block
512
+ if !node.arguments.arguments.empty?
513
+ emit_comma
514
+ end
515
+ emit_code(node.block)
516
+ end
517
+ emit_code(node.closing_loc)
518
+ emit_code(node.operator_loc)
519
+ emit_code(node.value)
520
+ end
521
+ alias_method :visit_index_and_write_node, :visit_index_operator_write_node
522
+ alias_method :visit_index_or_write_node, :visit_index_operator_write_node
523
+
524
+ def visit_ensure_node(node)
525
+ emit_code(node.ensure_keyword_loc, semicolon: true)
526
+ emit_code(node.statements, semicolon: true)
527
+ emit_code(node.end_keyword_loc, semicolon: true)
528
+ end
529
+
530
+ def visit_else_node(node)
531
+ emit_code(node.else_keyword_loc, semicolon: node.else_keyword_loc.slice == 'else')
532
+ emit_code(node.statements, semicolon: node.else_keyword_loc.slice == 'else')
533
+ end
534
+
535
+ def visit_case_match_node(node)
536
+ emit_code(node.case_keyword_loc)
537
+ emit_code(node.predicate)
538
+ @semicolon = true
539
+ visit_comma_separated_nodes(node.conditions)
540
+ emit_code(node.end_keyword_loc)
541
+ end
542
+
543
+ def visit_class_node(node)
544
+ emit_code(node.class_keyword_loc)
545
+ emit_code(node.constant_path)
546
+ emit_code(node.inheritance_operator_loc)
547
+ emit_code(node.superclass)
548
+ emit_code(node.body, semicolon: true)
549
+ emit_code(node.end_keyword_loc, semicolon: true)
550
+ end
551
+
552
+ def visit_module_node(node)
553
+ emit_code(node.module_keyword_loc)
554
+ emit_code(node.constant_path)
555
+ emit_code(node.body, semicolon: true)
556
+ emit_code(node.end_keyword_loc, semicolon: true)
557
+ end
558
+
559
+ def visit_singleton_class_node(node)
560
+ emit_code(node.class_keyword_loc)
561
+ emit_code(node.operator_loc)
562
+ emit_code(node.expression)
563
+ emit_code(node.body, semicolon: true)
564
+ emit_code(node.end_keyword_loc, semicolon: true)
565
+ end
566
+
567
+ def visit_interpolated_x_string_node(node)
568
+ emit_code(node.opening_loc)
569
+ node.parts.each { |p| emit_code(p) }
570
+ emit_code(node.closing_loc, chomp: true)
571
+ end
572
+
573
+ def visit_for_node(node)
574
+ emit_code(node.for_keyword_loc)
575
+ emit_code(node.index)
576
+ emit_code(node.in_keyword_loc)
577
+ emit_code(node.collection)
578
+ emit_code(node.do_keyword_loc)
579
+ emit_code(node.statements, semicolon: true)
580
+ emit_code(node.end_keyword_loc, semicolon: true)
581
+ end
582
+
583
+ def visit_multi_target_node(node)
584
+ emit_code(node.lparen_loc)
585
+ comma = visit_comma_separated_nodes(node.lefts)
586
+ if node.rest
587
+ emit_comma if comma
588
+ emit_code(node.rest)
589
+ comma = true
590
+ end
591
+ visit_comma_separated_nodes(node.rights, comma)
592
+ emit_code(node.rparen_loc)
593
+ end
594
+
595
+ def visit_find_pattern_node(node)
596
+ emit_code(node.constant)
597
+ emit_code(node.opening_loc)
598
+ emit_code(node.left)
599
+ comma = node.left
600
+ comma = visit_comma_separated_nodes(node.requireds, comma)
601
+ if node.right
602
+ emit_comma if comma
603
+ emit_code(node.right)
604
+ end
605
+ emit_code(node.closing_loc)
606
+ end
607
+
608
+ def visit_array_pattern_node(node)
609
+ emit_code(node.constant)
610
+ emit_code(node.opening_loc)
611
+ comma = visit_comma_separated_nodes(node.requireds, comma)
612
+ if node.rest
613
+ emit_comma if comma
614
+ emit_code(node.rest)
615
+ comma = true
616
+ end
617
+ visit_comma_separated_nodes(node.posts, comma)
618
+ emit_code(node.closing_loc)
619
+ end
620
+
621
+ def visit_hash_pattern_node(node)
622
+ emit_code(node.constant)
623
+ emit_code(node.opening_loc)
624
+ visit_comma_separated_nodes(node.elements)
625
+ emit_code(node.closing_loc)
626
+ end
627
+
628
+ def visit_statements_node(node)
629
+ first = true
630
+ node.body&.each do |n|
631
+ @semicolon = !first
632
+ visit(n)
633
+ first = false
634
+ end
635
+ end
636
+
637
+ def visit_block_parameters_node(node)
638
+ emit_code(node.opening_loc)
639
+ emit_code(node.injected_parameters)
640
+ emit_code(node.parameters)
641
+ @semicolon = true if node.parameters
642
+ visit_comma_separated_nodes(node.locals)
643
+ emit_code(node.closing_loc)
644
+ @semicolon = false
645
+ end
646
+
647
+ def visit_lambda_node(node)
648
+ emit_code(node.operator_loc)
649
+ emit_code(node.parameters)
650
+ emit_code(node.opening_loc)
651
+ emit_code(node.body, semicolon: node.opening_loc.slice == 'do')
652
+ emit_code(node.closing_loc, semicolon: node.closing_loc.slice == 'end')
653
+ end
654
+
655
+ def visit_interpolated_regular_expression_node(node)
656
+ emit_code(node.opening_loc)
657
+ node.parts.each { |p| emit_code(p) }
658
+ emit_code(node.closing_loc)
659
+ end
660
+
661
+ def visit_super_node(node)
662
+ emit_code(node.keyword_loc)
663
+ emit_code(node.lparen_loc)
664
+ emit_code(node.arguments)
665
+ emit_block_pre_rparen = node.block.is_a?(Prism::BlockArgumentNode)
666
+ if emit_block_pre_rparen
667
+ emit_comma if node.arguments
668
+ emit_code(node.block)
669
+ end
670
+ emit_code(node.rparen_loc)
671
+ emit_code(node.block) if !emit_block_pre_rparen
672
+ end
673
+
674
+ def visit_undef_node(node)
675
+ emit_code(node.keyword_loc)
676
+ visit_comma_separated_nodes(node.names)
677
+ end
678
+
307
679
  end
308
680
  end
data/lib/sirop/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Sirop
2
2
  # Sirop version
3
- VERSION = '0.3'
3
+ VERSION = '0.4'
4
4
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sirop
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.3'
4
+ version: '0.4'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-04-19 00:00:00.000000000 Z
10
+ date: 2024-04-29 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: prism
@@ -16,14 +15,14 @@ dependencies:
16
15
  requirements:
17
16
  - - "~>"
18
17
  - !ruby/object:Gem::Version
19
- version: 0.19.0
18
+ version: 0.27.0
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - "~>"
25
24
  - !ruby/object:Gem::Version
26
- version: 0.19.0
25
+ version: 0.27.0
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: minitest
29
28
  requirement: !ruby/object:Gem::Requirement
@@ -38,7 +37,6 @@ dependencies:
38
37
  - - "~>"
39
38
  - !ruby/object:Gem::Version
40
39
  version: 5.22.0
41
- description:
42
40
  email: sharon@noteflakes.com
43
41
  executables: []
44
42
  extensions: []
@@ -60,7 +58,6 @@ metadata:
60
58
  homepage_uri: https://github.com/digital-fabric/sirop
61
59
  documentation_uri: https://www.rubydoc.info/gems/sirop
62
60
  changelog_uri: https://github.com/digital-fabric/sirop/blob/main/CHANGELOG.md
63
- post_install_message:
64
61
  rdoc_options:
65
62
  - "--title"
66
63
  - Sirop
@@ -79,8 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
79
76
  - !ruby/object:Gem::Version
80
77
  version: '0'
81
78
  requirements: []
82
- rubygems_version: 3.5.3
83
- signing_key:
79
+ rubygems_version: 3.6.0.dev
84
80
  specification_version: 4
85
81
  summary: 'Sirop: Ruby code rewriter'
86
82
  test_files: []