ruby2js 3.0.15 → 3.3.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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +92 -7
  3. data/lib/ruby2js.rb +30 -3
  4. data/lib/ruby2js/converter.rb +23 -3
  5. data/lib/ruby2js/converter/args.rb +31 -1
  6. data/lib/ruby2js/converter/block.rb +2 -2
  7. data/lib/ruby2js/converter/casgn.rb +3 -2
  8. data/lib/ruby2js/converter/class.rb +2 -2
  9. data/lib/ruby2js/converter/class2.rb +117 -13
  10. data/lib/ruby2js/converter/cvar.rb +5 -3
  11. data/lib/ruby2js/converter/cvasgn.rb +5 -3
  12. data/lib/ruby2js/converter/def.rb +2 -2
  13. data/lib/ruby2js/converter/for.rb +8 -1
  14. data/lib/ruby2js/converter/hash.rb +22 -6
  15. data/lib/ruby2js/converter/if.rb +13 -2
  16. data/lib/ruby2js/converter/import.rb +38 -0
  17. data/lib/ruby2js/converter/ivar.rb +2 -0
  18. data/lib/ruby2js/converter/ivasgn.rb +1 -1
  19. data/lib/ruby2js/converter/kwbegin.rb +16 -2
  20. data/lib/ruby2js/converter/logical.rb +46 -1
  21. data/lib/ruby2js/converter/opasgn.rb +5 -2
  22. data/lib/ruby2js/converter/regexp.rb +27 -2
  23. data/lib/ruby2js/converter/return.rb +1 -1
  24. data/lib/ruby2js/converter/send.rb +160 -69
  25. data/lib/ruby2js/converter/super.rb +15 -9
  26. data/lib/ruby2js/converter/xnode.rb +89 -0
  27. data/lib/ruby2js/es2018.rb +5 -0
  28. data/lib/ruby2js/es2018/strict.rb +3 -0
  29. data/lib/ruby2js/es2019.rb +5 -0
  30. data/lib/ruby2js/es2019/strict.rb +3 -0
  31. data/lib/ruby2js/es2020.rb +5 -0
  32. data/lib/ruby2js/es2020/strict.rb +3 -0
  33. data/lib/ruby2js/es2021.rb +5 -0
  34. data/lib/ruby2js/es2021/strict.rb +3 -0
  35. data/lib/ruby2js/filter.rb +1 -0
  36. data/lib/ruby2js/filter/cjs.rb +2 -2
  37. data/lib/ruby2js/filter/esm.rb +72 -0
  38. data/lib/ruby2js/filter/functions.rb +218 -34
  39. data/lib/ruby2js/filter/matchAll.rb +49 -0
  40. data/lib/ruby2js/filter/node.rb +18 -10
  41. data/lib/ruby2js/filter/nokogiri.rb +13 -13
  42. data/lib/ruby2js/filter/react.rb +190 -30
  43. data/lib/ruby2js/filter/require.rb +1 -4
  44. data/lib/ruby2js/filter/rubyjs.rb +4 -4
  45. data/lib/ruby2js/filter/vue.rb +45 -17
  46. data/lib/ruby2js/filter/wunderbar.rb +63 -0
  47. data/lib/ruby2js/serializer.rb +25 -11
  48. data/lib/ruby2js/version.rb +2 -2
  49. metadata +16 -4
@@ -0,0 +1,89 @@
1
+ module Ruby2JS
2
+ class Converter
3
+
4
+ # (xnode str hash)
5
+
6
+ # NOTE: xnode is a synthetic
7
+
8
+ handle :xnode do |nodename, *args|
9
+ attrs = {}
10
+ children = []
11
+
12
+ args.each do |arg|
13
+ if arg.type == :hash
14
+ arg.children.each do |pair|
15
+ name = pair.children[0].children[0]
16
+
17
+ if defined? Ruby2JS::Filter::React
18
+ name = :className if name == :class
19
+ name = :htmlFor if name == :for
20
+ end
21
+
22
+ if [:class, :className].include? name and attrs[name]
23
+ if attrs[name].type == :str and pair.children[1].type == :str
24
+ attrs[name] = s(:str, pair.children[1].children[0] + ' ' +
25
+ attrs[name].children[0])
26
+ else
27
+ attrs[name] = s(:send, s(:send, attrs[name], :+,
28
+ s(:str, ' ')), :+, pair.children[1])
29
+ end
30
+ else
31
+ attrs[name] = pair.children[1]
32
+ end
33
+ end
34
+ elsif arg.type == :begin
35
+ children += arg.children
36
+ else
37
+ children << arg
38
+ end
39
+ end
40
+
41
+ put '<'
42
+ put nodename
43
+
44
+ attrs.each do |name, value|
45
+ put ' '
46
+ put name
47
+ put '='
48
+ if value.type == :str
49
+ parse value
50
+ else
51
+ put '{'
52
+ parse value
53
+ put '}'
54
+ end
55
+ end
56
+
57
+ if children.empty?
58
+ put '/>'
59
+ else
60
+ put '>'
61
+ put @nl unless children.length == 1 and children.first.type != :xnode
62
+
63
+ children.each_with_index do |child, index|
64
+ put @nl unless index == 0
65
+ if child.type == :str
66
+ put child.children.first
67
+ elsif child.type == :xnode
68
+ parse child
69
+ else
70
+ begin
71
+ jsx, @jsx = @jsx, true
72
+ put '{'
73
+ parse child
74
+ put '}'
75
+ ensure
76
+ @jsx = jsx
77
+ end
78
+ end
79
+ end
80
+
81
+ put @nl unless children.length == 1 and children.first.type != :xnode
82
+
83
+ put '</'
84
+ put nodename
85
+ put ">"
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,5 @@
1
+ require 'ruby2js'
2
+
3
+ if Ruby2JS.eslevel_default < 2018
4
+ Ruby2JS.eslevel_default = 2018
5
+ end
@@ -0,0 +1,3 @@
1
+ require 'ruby2js/es2018'
2
+
3
+ Ruby2JS.strict_default = true
@@ -0,0 +1,5 @@
1
+ require 'ruby2js'
2
+
3
+ if Ruby2JS.eslevel_default < 2019
4
+ Ruby2JS.eslevel_default = 2019
5
+ end
@@ -0,0 +1,3 @@
1
+ require 'ruby2js/es2019'
2
+
3
+ Ruby2JS.strict_default = true
@@ -0,0 +1,5 @@
1
+ require 'ruby2js'
2
+
3
+ if Ruby2JS.eslevel_default < 2020
4
+ Ruby2JS.eslevel_default = 2020
5
+ end
@@ -0,0 +1,3 @@
1
+ require 'ruby2js/es2020'
2
+
3
+ Ruby2JS.strict_default = true
@@ -0,0 +1,5 @@
1
+ require 'ruby2js'
2
+
3
+ if Ruby2JS.eslevel_default < 2021
4
+ Ruby2JS.eslevel_default = 2021
5
+ end
@@ -0,0 +1,3 @@
1
+ require 'ruby2js/es2021'
2
+
3
+ Ruby2JS.strict_default = true
@@ -51,6 +51,7 @@ module Ruby2JS
51
51
  if @included
52
52
  not @included.include? method
53
53
  else
54
+ return true if @exclude_methods.flatten.include? method
54
55
  @excluded.include? method
55
56
  end
56
57
  end
@@ -24,7 +24,7 @@ module Ruby2JS
24
24
  *assign.children[1..-1]
25
25
  ])
26
26
 
27
- elsif
27
+ elsif \
28
28
  node.children[2].type == :send and
29
29
  node.children[2].children[0..1] == [nil, :async] and
30
30
  node.children[2].children[2].type == :def
@@ -38,7 +38,7 @@ module Ruby2JS
38
38
  *process_all(fn.children[1..-1])))
39
39
  ])
40
40
 
41
- elsif
41
+ elsif \
42
42
  node.children[2].type == :send and
43
43
  node.children[2].children[0..1] == [nil, :default]
44
44
  then
@@ -0,0 +1,72 @@
1
+ require 'ruby2js'
2
+
3
+ module Ruby2JS
4
+ module Filter
5
+ module ESM
6
+ include SEXP
7
+
8
+ def initialize(*args)
9
+ @esm_include = nil
10
+ super
11
+ end
12
+
13
+ def process(node)
14
+ return super if @esm_include
15
+ @esm_include = Set.new
16
+ @esm_exclude = Set.new
17
+ @esm_export = nil
18
+ result = super
19
+
20
+ esm_walk(result)
21
+
22
+ inventory = (@esm_include - @esm_exclude).to_a.sort
23
+
24
+ if inventory.empty? and not @esm_export
25
+ result
26
+ else
27
+ list = inventory.map do |name|
28
+ if name == "React" and defined? Ruby2JS::Filter::React
29
+ s(:import, "#{name.downcase}", s(:const, nil, name))
30
+ elsif not %w(JSON Object).include? name
31
+ s(:import, "./#{name.downcase}.js", s(:const, nil, name))
32
+ end
33
+ end
34
+
35
+ list.push result
36
+
37
+ if @esm_export
38
+ list.push s(:export, :default, s(:const, nil, @esm_export))
39
+ end
40
+
41
+ s(:begin, *list.compact)
42
+ end
43
+ end
44
+
45
+ # gather constants
46
+ def esm_walk(node)
47
+ # extract ivars and cvars
48
+ if node.type == :const and node.children.first == nil
49
+ @esm_include << node.children.last.to_s
50
+ elsif node.type == :xnode
51
+ name = node.children.first
52
+ @esm_include << name unless name.empty? or name =~ /^[a-z]/
53
+ elsif node.type == :casgn and node.children.first == nil
54
+ @esm_exclude << node.children[1].to_s
55
+ elsif node.type == :class and node.children.first.type == :const
56
+ if node.children.first.children.first == nil
57
+ name = node.children.first.children.last.to_s
58
+ @esm_exclude << name
59
+ @esm_export ||= name
60
+ end
61
+ end
62
+
63
+ # recurse
64
+ node.children.each do |child|
65
+ esm_walk(child) if Parser::AST::Node === child
66
+ end
67
+ end
68
+ end
69
+
70
+ DEFAULTS.push ESM
71
+ end
72
+ end
@@ -1,4 +1,5 @@
1
1
  require 'ruby2js'
2
+ require 'regexp_parser'
2
3
 
3
4
  module Ruby2JS
4
5
  module Filter
@@ -15,6 +16,11 @@ module Ruby2JS
15
16
  gvar: :gvasgn
16
17
  }
17
18
 
19
+ def initialize(*args)
20
+ @jsx = false
21
+ super
22
+ end
23
+
18
24
  def on_send(node)
19
25
  target, method, *args = node.children
20
26
  return super if excluded?(method)
@@ -35,6 +41,105 @@ module Ruby2JS
35
41
  elsif method == :keys and args.length == 0 and node.is_method?
36
42
  process S(:send, s(:const, nil, :Object), :keys, target)
37
43
 
44
+ elsif method == :[]= and args.length == 3 and
45
+ args[0].type == :regexp and args[1].type == :int
46
+ index = args[1].children.first
47
+
48
+ parts = Regexp::Parser.parse(args[0].children.first.children.first)
49
+ split = parts.index do |part|
50
+ part.type == :group and part.number == index
51
+ end
52
+
53
+ return super unless split
54
+
55
+ rewritten = parts[split].to_s
56
+
57
+ dstr = [args.last]
58
+ if rewritten == '()'
59
+ index -= 1
60
+ rewritten = ''
61
+ end
62
+
63
+ parts = parts.to_a
64
+
65
+ pre = ''
66
+ if parts.first.type == :anchor
67
+ pre = parts.shift.to_s
68
+ split -= 1
69
+ end
70
+
71
+ if split > 0
72
+ if split == 1 and parts.first.type == :group
73
+ rewritten = parts.first.to_s + rewritten
74
+ else
75
+ rewritten = '(' + parts[0 .. split - 1].join + ')' + rewritten
76
+ index += 1
77
+ end
78
+ dstr.unshift s(:send, s(:lvar, :match), :[], s(:int, 0))
79
+ end
80
+
81
+
82
+ post = ''
83
+ if parts.last.type == :anchor
84
+ post = parts.pop.to_s
85
+ end
86
+
87
+ if split + 1 < parts.length
88
+ if split + 2 == parts.length and parts.last.type == :group
89
+ rewritten += parts.last.to_s
90
+ else
91
+ rewritten += '(' + parts[split + 1 .. -1].join + ')'
92
+ end
93
+ dstr << s(:send, s(:lvar, :match), :[], s(:int, index))
94
+ end
95
+
96
+ rewritten = pre + rewritten + post
97
+
98
+ regex = process s(:regexp, s(:str, rewritten), args[0].children.last)
99
+ block = s(:block,
100
+ s(:send, target, :replace, regex),
101
+ s(:args, s(:arg, :match)),
102
+ process(s(:dstr, *dstr)))
103
+
104
+ if VAR_TO_ASSIGN.keys.include? target.type
105
+ S(VAR_TO_ASSIGN[target.type], target.children.first, block)
106
+ elsif target.type == :send
107
+ if target.children[0] == nil
108
+ S(:lvasgn, target.children[1], block)
109
+ else
110
+ S(:send, target.children[0], :"#{target.children[1]}=", block)
111
+ end
112
+ else
113
+ super
114
+ end
115
+
116
+ elsif method == :merge
117
+ args.unshift target
118
+
119
+ if es2015
120
+ if es2018
121
+ process S(:hash, *args.map {|arg| s(:kwsplat, arg)})
122
+ else
123
+ process S(:send, s(:const, nil, :Object), :assign, s(:hash),
124
+ *args)
125
+ end
126
+ else
127
+ copy = [s(:gvasgn, :$$, s(:hash))]
128
+
129
+ s(:send, s(:block, s(:send, nil, :lambda), s(:args),
130
+ s(:begin, *copy, *args.map {|modname|
131
+ if modname.type == :hash
132
+ s(:begin, *modname.children.map {|pair|
133
+ s(:send, s(:gvar, :$$), :[]=, *pair.children)
134
+ })
135
+ else
136
+ s(:for, s(:lvasgn, :$_), modname,
137
+ s(:send, s(:gvar, :$$), :[]=,
138
+ s(:lvar, :$_), s(:send, modname, :[], s(:lvar, :$_))))
139
+ end
140
+ }, s(:return, s(:gvar, :$$)))), :[])
141
+ end
142
+
38
143
  elsif method == :merge!
39
144
  if es2015
40
145
  process S(:send, s(:const, nil, :Object), :assign, target, *args)
@@ -51,9 +156,15 @@ module Ruby2JS
51
156
 
52
157
  s(:send, s(:block, s(:send, nil, :lambda), s(:args),
53
158
  s(:begin, *copy, *args.map {|modname|
54
- s(:for, s(:lvasgn, :$_), modname,
55
- s(:send, target, :[]=,
56
- s(:lvar, :$_), s(:send, modname, :[], s(:lvar, :$_))))
159
+ if modname.type == :hash
160
+ s(:begin, *modname.children.map {|pair|
161
+ s(:send, target, :[]=, *pair.children)
162
+ })
163
+ else
164
+ s(:for, s(:lvasgn, :$_), modname,
165
+ s(:send, target, :[]=,
166
+ s(:lvar, :$_), s(:send, modname, :[], s(:lvar, :$_))))
167
+ end
57
168
  }, s(:return, target))), :[])
58
169
  end
59
170
 
@@ -113,23 +224,33 @@ module Ruby2JS
113
224
  [s(:str, Regexp.escape(arg.children.first)), s(:regopt)])
114
225
  end
115
226
 
116
- pattern = arg.children.first.children.first
117
- pattern = pattern.gsub(/\\./, '').gsub(/\[.*\]/, '')
118
-
119
227
  if arg.type == :regexp
228
+ pattern = arg.children.first.children.first
229
+ pattern = pattern.gsub(/\\./, '').gsub(/\[.*\]/, '')
230
+
120
231
  gpattern = arg.updated(:regexp, [*arg.children[0...-1],
121
232
  s(:regopt, :g, *arg.children.last)])
122
233
  else
123
- super
234
+ gpattern = s(:send, s(:const, nil, :RegExp), :new, arg, s(:str, 'g'))
124
235
  end
125
236
 
126
- if pattern.include? '('
127
- s(:block, s(:send,
128
- s(:send, process(target), :match, gpattern), :map),
129
- s(:args, s(:arg, :s)),
130
- s(:return, s(:send, s(:send, s(:lvar, :s), :match, arg),
131
- :slice, s(:int, 1))))
237
+ if arg.type != :regexp or pattern.include? '('
238
+ if es2020
239
+ # Array.from(str.matchAll(/.../g), s => s.slice(1))
240
+ s(:send, s(:const, nil, :Array), :from,
241
+ s(:send, process(target), :matchAll, gpattern),
242
+ s(:block, s(:send, nil, :proc), s(:args, s(:arg, :s)),
243
+ s(:send, s(:lvar, :s), :slice, s(:int, 1))))
244
+ else
245
+ # str.match(/.../g).map(s => s.match(/.../).slice(1))
246
+ s(:block, s(:send,
247
+ s(:send, process(target), :match, gpattern), :map),
248
+ s(:args, s(:arg, :s)),
249
+ s(:return, s(:send, s(:send, s(:lvar, :s), :match, arg),
250
+ :slice, s(:int, 1))))
251
+ end
132
252
  else
253
+ # str.match(/.../g)
133
254
  S(:send, process(target), :match, gpattern)
134
255
  end
135
256
 
@@ -257,6 +378,9 @@ module Ruby2JS
257
378
  end
258
379
 
259
380
 
381
+ elsif method == :[] and target == s(:const, nil, :Hash)
382
+ s(:send, s(:const, nil, :Object), :fromEntries, *process_all(args))
383
+
260
384
  elsif method == :[]
261
385
  # resolve negative literal indexes
262
386
  i = proc do |index|
@@ -274,9 +398,15 @@ module Ruby2JS
274
398
  super
275
399
 
276
400
  elsif index.type == :regexp
277
- process S(:send,
278
- s(:or, S(:send, process(target), :match, index), s(:array)),
279
- :[], args[1] || s(:int, 0))
401
+ if es2020
402
+ process S(:csend,
403
+ S(:send, process(target), :match, index),
404
+ :[], args[1] || s(:int, 0))
405
+ else
406
+ process S(:send,
407
+ s(:or, S(:send, process(target), :match, index), s(:array)),
408
+ :[], args[1] || s(:int, 0))
409
+ end
280
410
 
281
411
  elsif node.children.length != 3
282
412
  super
@@ -286,7 +416,9 @@ module Ruby2JS
286
416
 
287
417
  elsif index.type == :erange
288
418
  start, finish = index.children
289
- if finish.type == :int
419
+ if not finish
420
+ process S(:send, target, :slice, start)
421
+ elsif finish.type == :int
290
422
  process S(:send, target, :slice, i.(start), finish)
291
423
  else
292
424
  process S(:send, target, :slice, i.(start), i.(finish))
@@ -294,7 +426,7 @@ module Ruby2JS
294
426
 
295
427
  elsif index.type == :irange
296
428
  start, finish = index.children
297
- if finish.type == :int
429
+ if finish and finish.type == :int
298
430
  final = S(:int, finish.children.first+1)
299
431
  else
300
432
  final = S(:send, finish, :+, s(:int, 1))
@@ -302,7 +434,7 @@ module Ruby2JS
302
434
 
303
435
  # No need for the last argument if it's -1
304
436
  # This means take all to the end of array
305
- if finish.children.first == -1
437
+ if not finish or finish.children.first == -1
306
438
  process S(:send, target, :slice, start)
307
439
  else
308
440
  process S(:send, target, :slice, start, final)
@@ -367,9 +499,35 @@ module Ruby2JS
367
499
  elsif es2017 and method==:ljust
368
500
  process node.updated(nil, [target, :padEnd, *args])
369
501
 
502
+ elsif es2019 and method==:flatten and args.length == 0
503
+ process node.updated(nil, [target, :flat, s(:lvar, :Infinity)])
504
+
505
+ elsif es2019 and method==:to_h and args.length==0
506
+ process node.updated(nil, [s(:const, nil, :Object), :fromEntries,
507
+ target])
508
+
509
+ elsif method==:rstrip
510
+ if es2019
511
+ process node.updated(nil, [target, :trimEnd, *args])
512
+ else
513
+ node.updated(nil, [process(target), :replace,
514
+ s(:regexp, s(:str, '\s+\z') , s(:regopt)), s(:str, '')])
515
+ end
516
+
517
+ elsif method==:lstrip and args.length == 0
518
+ if es2019
519
+ process s(:send, target, :trimStart)
520
+ else
521
+ node.updated(nil, [process(target), :replace,
522
+ s(:regexp, s(:str, '\A\s+') , s(:regopt)), s(:str, '')])
523
+ end
524
+
370
525
  elsif method == :class and args.length==0 and not node.is_method?
371
526
  process node.updated(:attr, [target, :constructor])
372
527
 
528
+ elsif method == :new and target == s(:const, nil, :Exception)
529
+ process S(:send, s(:const, nil, :Error), :new, *args)
530
+
373
531
  else
374
532
  super
375
533
  end
@@ -464,7 +622,7 @@ module Ruby2JS
464
622
  call = call.updated(nil, [s(:begin, range), :step, s(:int, 1)])
465
623
  process node.updated(nil, [call, *node.children[1..-1]])
466
624
 
467
- elsif
625
+ elsif \
468
626
  method == :each and call.children[0].type == :send and
469
627
  call.children[0].children[1] == :step
470
628
  then
@@ -476,7 +634,7 @@ module Ruby2JS
476
634
  :step, step])
477
635
  process node.updated(nil, [call, *node.children[1..-1]])
478
636
 
479
- elsif
637
+ elsif \
480
638
  # (a..b).each {|v| ...}
481
639
  method == :each and
482
640
  call.children[0].type == :begin and
@@ -484,23 +642,34 @@ module Ruby2JS
484
642
  [:irange, :erange].include? call.children[0].children[0].type and
485
643
  node.children[1].children.length == 1
486
644
  then
487
- s(:for, s(:lvasgn, node.children[1].children[0].children[0]),
645
+ process s(:for, s(:lvasgn, node.children[1].children[0].children[0]),
488
646
  call.children[0].children[0], node.children[2])
489
647
 
490
- elsif
491
- [:each, :each_value].include? method and
492
- node.children[1].children.length == 1
648
+ elsif \
649
+ [:each, :each_value].include? method
493
650
  then
494
- if es2015
495
- process node.updated(:for_of,
496
- [s(:lvasgn, node.children[1].children[0].children[0]),
497
- node.children[0].children[0], node.children[2]])
651
+ if es2015 or @jsx
652
+ if node.children[1].children.length > 1
653
+ process node.updated(:for_of,
654
+ [s(:mlhs, *node.children[1].children.map {|child|
655
+ s(:lvasgn, child.children[0])}),
656
+ node.children[0].children[0], node.children[2]])
657
+ elsif node.children[1].children[0].type == :mlhs
658
+ process node.updated(:for_of,
659
+ [s(:mlhs, *node.children[1].children[0].children.map {|child|
660
+ s(:lvasgn, child.children[0])}),
661
+ node.children[0].children[0], node.children[2]])
662
+ else
663
+ process node.updated(:for_of,
664
+ [s(:lvasgn, node.children[1].children[0].children[0]),
665
+ node.children[0].children[0], node.children[2]])
666
+ end
498
667
  else
499
668
  process node.updated(nil, [s(:send, call.children[0],
500
669
  :forEach), *node.children[1..2]])
501
670
  end
502
671
 
503
- elsif
672
+ elsif \
504
673
  method == :each_key and
505
674
  [:each, :each_key].include? method and
506
675
  node.children[1].children.length == 1
@@ -514,10 +683,25 @@ module Ruby2JS
514
683
  s(:block, s(:send, nil, :lambda), *node.children[1..2]),
515
684
  *call.children[2..-1]])
516
685
 
517
- elsif es2017 and method == :each_pair
518
- process node.updated(nil, [s(:send, s(:send, s(:const, nil, :Object),
519
- :entries, call.children[0]), :forEach), s(:args, s(:mlhs,
520
- *node.children[1].children)), node.children[2]])
686
+ elsif method == :each_pair and node.children[1].children.length == 2
687
+ if es2017
688
+ # Object.entries(a).forEach(([key, value]) => {})
689
+ process node.updated(nil, [s(:send, s(:send,
690
+ s(:const, nil, :Object), :entries, call.children[0]), :each),
691
+ node.children[1], node.children[2]])
692
+ else
693
+ # for (key in a). {var value = a[key]; ...}
694
+ process node.updated(:for, [s(:lvasgn,
695
+ node.children[1].children[0].children[0]), call.children[0],
696
+ s(:begin, s(:lvasgn, node.children[1].children[1].children[0],
697
+ s(:send, call.children[0], :[],
698
+ s(:lvar, node.children[1].children[0].children[0]))),
699
+ node.children[2])])
700
+ end
701
+
702
+ elsif method == :scan and call.children.length == 3
703
+ process call.updated(nil, [*call.children, s(:block,
704
+ s(:send, nil, :proc), *node.children[1..-1])])
521
705
 
522
706
  else
523
707
  super