ruby2js 1.15.1 → 2.0.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 (53) hide show
  1. data/lib/ruby2js.rb +36 -36
  2. data/lib/ruby2js/converter.rb +59 -20
  3. data/lib/ruby2js/converter/arg.rb +1 -1
  4. data/lib/ruby2js/converter/args.rb +1 -1
  5. data/lib/ruby2js/converter/array.rb +3 -4
  6. data/lib/ruby2js/converter/begin.rb +15 -1
  7. data/lib/ruby2js/converter/block.rb +6 -5
  8. data/lib/ruby2js/converter/boolean.rb +1 -1
  9. data/lib/ruby2js/converter/break.rb +1 -1
  10. data/lib/ruby2js/converter/case.rb +27 -7
  11. data/lib/ruby2js/converter/casgn.rb +5 -2
  12. data/lib/ruby2js/converter/class.rb +41 -11
  13. data/lib/ruby2js/converter/const.rb +1 -1
  14. data/lib/ruby2js/converter/cvar.rb +4 -3
  15. data/lib/ruby2js/converter/cvasgn.rb +5 -6
  16. data/lib/ruby2js/converter/def.rb +15 -3
  17. data/lib/ruby2js/converter/defined.rb +1 -1
  18. data/lib/ruby2js/converter/defs.rb +7 -3
  19. data/lib/ruby2js/converter/dstr.rb +3 -3
  20. data/lib/ruby2js/converter/for.rb +7 -10
  21. data/lib/ruby2js/converter/hash.rb +70 -34
  22. data/lib/ruby2js/converter/if.rb +35 -13
  23. data/lib/ruby2js/converter/in.rb +1 -1
  24. data/lib/ruby2js/converter/ivasgn.rb +1 -1
  25. data/lib/ruby2js/converter/kwbegin.rb +20 -20
  26. data/lib/ruby2js/converter/literal.rb +1 -1
  27. data/lib/ruby2js/converter/logical.rb +4 -8
  28. data/lib/ruby2js/converter/next.rb +1 -1
  29. data/lib/ruby2js/converter/nil.rb +1 -1
  30. data/lib/ruby2js/converter/nthref.rb +1 -1
  31. data/lib/ruby2js/converter/opasgn.rb +3 -3
  32. data/lib/ruby2js/converter/regexp.rb +12 -9
  33. data/lib/ruby2js/converter/return.rb +3 -3
  34. data/lib/ruby2js/converter/self.rb +2 -2
  35. data/lib/ruby2js/converter/send.rb +31 -30
  36. data/lib/ruby2js/converter/super.rb +8 -11
  37. data/lib/ruby2js/converter/sym.rb +1 -1
  38. data/lib/ruby2js/converter/undef.rb +9 -2
  39. data/lib/ruby2js/converter/var.rb +1 -1
  40. data/lib/ruby2js/converter/vasgn.rb +13 -5
  41. data/lib/ruby2js/converter/while.rb +2 -1
  42. data/lib/ruby2js/converter/whilepost.rb +2 -1
  43. data/lib/ruby2js/converter/xstr.rb +4 -3
  44. data/lib/ruby2js/execjs.rb +3 -3
  45. data/lib/ruby2js/filter/camelCase.rb +8 -8
  46. data/lib/ruby2js/filter/functions.rb +64 -65
  47. data/lib/ruby2js/filter/react.rb +44 -16
  48. data/lib/ruby2js/filter/require.rb +4 -1
  49. data/lib/ruby2js/filter/underscore.rb +21 -21
  50. data/lib/ruby2js/serializer.rb +347 -0
  51. data/lib/ruby2js/version.rb +3 -3
  52. data/ruby2js.gemspec +3 -3
  53. metadata +3 -2
@@ -17,7 +17,7 @@ module Ruby2JS
17
17
  if node.children[0] == nil and WHITELIST.include? node.children[1].to_s
18
18
  super
19
19
  elsif node.children[1] =~ /_.*\w$/
20
- super s((node.is_method? ? :send : :attr) , node.children[0],
20
+ super S((node.is_method? ? :call : :attr) , node.children[0],
21
21
  camelCase(node.children[1]), *node.children[2..-1])
22
22
  else
23
23
  super
@@ -26,7 +26,7 @@ module Ruby2JS
26
26
 
27
27
  def on_def(node)
28
28
  if node.children[0] =~ /_.*\w$/
29
- super s(:def , camelCase(node.children[0]), *node.children[1..-1])
29
+ super S(:def , camelCase(node.children[0]), *node.children[1..-1])
30
30
  else
31
31
  super
32
32
  end
@@ -34,7 +34,7 @@ module Ruby2JS
34
34
 
35
35
  def on_optarg(node)
36
36
  if node.children[0] =~ /_.*\w$/
37
- super s(:optarg , camelCase(node.children[0]), *node.children[1..-1])
37
+ super S(:optarg , camelCase(node.children[0]), *node.children[1..-1])
38
38
  else
39
39
  super
40
40
  end
@@ -42,7 +42,7 @@ module Ruby2JS
42
42
 
43
43
  def on_lvar(node)
44
44
  if node.children[0] =~ /_.*\w$/
45
- super s(:lvar , camelCase(node.children[0]), *node.children[1..-1])
45
+ super S(:lvar , camelCase(node.children[0]), *node.children[1..-1])
46
46
  else
47
47
  super
48
48
  end
@@ -50,7 +50,7 @@ module Ruby2JS
50
50
 
51
51
  def on_arg(node)
52
52
  if node.children[0] =~ /_.*\w$/
53
- super s(:arg , camelCase(node.children[0]), *node.children[1..-1])
53
+ super S(:arg , camelCase(node.children[0]), *node.children[1..-1])
54
54
  else
55
55
  super
56
56
  end
@@ -58,7 +58,7 @@ module Ruby2JS
58
58
 
59
59
  def on_lvasgn(node)
60
60
  if node.children[0] =~ /_.*\w$/
61
- super s(:lvasgn , camelCase(node.children[0]), *node.children[1..-1])
61
+ super S(:lvasgn , camelCase(node.children[0]), *node.children[1..-1])
62
62
  else
63
63
  super
64
64
  end
@@ -66,7 +66,7 @@ module Ruby2JS
66
66
 
67
67
  def on_sym(node)
68
68
  if node.children[0] =~ /_.*\w$/
69
- super s(:sym , camelCase(node.children[0]), *node.children[1..-1])
69
+ super S(:sym , camelCase(node.children[0]), *node.children[1..-1])
70
70
  else
71
71
  super
72
72
  end
@@ -74,7 +74,7 @@ module Ruby2JS
74
74
 
75
75
  def on_defs(node)
76
76
  if node.children[1] =~ /_.*\w$/
77
- super s(:defs , node.children[0],
77
+ super S(:defs , node.children[0],
78
78
  camelCase(node.children[1]), *node.children[2..-1])
79
79
  else
80
80
  super
@@ -15,22 +15,22 @@ module Ruby2JS
15
15
  def on_send(node)
16
16
  target, method, *args = node.children
17
17
 
18
- if [:max, :min].include? node.children[1] and args.length == 0
18
+ if [:max, :min].include? method and args.length == 0
19
19
  return super unless node.is_method?
20
- process s(:send, s(:attr, s(:const, nil, :Math), node.children[1]),
20
+ process S(:send, s(:attr, s(:const, nil, :Math), node.children[1]),
21
21
  :apply, s(:const, nil, :Math), target)
22
22
 
23
23
  elsif method == :keys and args.length == 0 and node.is_method?
24
- process s(:send, s(:const, nil, :Object), :keys, target)
24
+ process S(:send, s(:const, nil, :Object), :keys, target)
25
25
 
26
26
  elsif method == :delete and args.length == 1
27
- process s(:undef, s(:send, target, :[], args.first))
27
+ process S(:undef, S(:send, target, :[], args.first))
28
28
 
29
29
  elsif method == :to_s
30
- process s(:send, target, :toString, *args)
30
+ process S(:call, target, :toString, *args)
31
31
 
32
32
  elsif method == :to_a
33
- process s(:send, target, :toArray, *args)
33
+ process S(:call, target, :toArray, *args)
34
34
 
35
35
  elsif method == :to_i
36
36
  process node.updated :send, [nil, :parseInt, target, *args]
@@ -44,15 +44,15 @@ module Ruby2JS
44
44
  elsif [:sub!, :gsub!].include? method
45
45
  method = :"#{method.to_s[0..-2]}"
46
46
  if VAR_TO_ASSIGN.keys.include? target.type
47
- process s(VAR_TO_ASSIGN[target.type], target.children[0],
48
- s(:send, target, method, *node.children[2..-1]))
47
+ process S(VAR_TO_ASSIGN[target.type], target.children[0],
48
+ S(:send, target, method, *node.children[2..-1]))
49
49
  elsif target.type == :send
50
50
  if target.children[0] == nil
51
- process s(:lvasgn, target.children[1], s(:send,
52
- s(:lvar, target.children[1]), method, *node.children[2..-1]))
51
+ process S(:lvasgn, target.children[1], S(:send,
52
+ S(:lvar, target.children[1]), method, *node.children[2..-1]))
53
53
  else
54
- process s(:send, target.children[0], :"#{target.children[1]}=",
55
- s(:send, target, method, *node.children[2..-1]))
54
+ process S(:send, target.children[0], :"#{target.children[1]}=",
55
+ S(:send, target, method, *node.children[2..-1]))
56
56
  end
57
57
  else
58
58
  super
@@ -61,93 +61,92 @@ module Ruby2JS
61
61
  elsif method == :gsub and args.length == 2
62
62
  before, after = args
63
63
  if before.type == :regexp
64
- before = s(:regexp, *before.children[0...-1],
65
- s(:regopt, :g, *before.children.last))
64
+ before = before.updated(:regexp, [*before.children[0...-1],
65
+ s(:regopt, :g, *before.children.last)])
66
66
  elsif before.type == :str
67
- before = s(:regexp, s(:str, Regexp.escape(before.children.first)),
68
- s(:regopt, :g))
67
+ before = before.updated(:regexp,
68
+ [s(:str, Regexp.escape(before.children.first)), s(:regopt, :g)])
69
69
  end
70
70
  process node.updated nil, [target, :replace, before, after]
71
71
 
72
72
  elsif method == :ord and args.length == 0
73
73
  if target.type == :str
74
- process s(:int, target.children.last.ord)
74
+ process S(:int, target.children.last.ord)
75
75
  else
76
- process node.updated nil, [target, :charCodeAt, s(:int, 0)]
76
+ process S(:send, target, :charCodeAt, s(:int, 0))
77
77
  end
78
78
 
79
79
  elsif method == :chr and args.length == 0
80
80
  if target.type == :int
81
- process s(:str, target.children.last.chr)
81
+ process S(:str, target.children.last.chr)
82
82
  else
83
- process node.updated nil, [s(:const, nil, :String), :fromCharCode,
84
- target]
83
+ process S(:send, s(:const, nil, :String), :fromCharCode, target)
85
84
  end
86
85
 
87
86
  elsif method == :empty? and args.length == 0
88
- process s(:send, s(:attr, target, :length), :==, s(:int, 0))
87
+ process S(:send, S(:attr, target, :length), :==, s(:int, 0))
89
88
 
90
89
  elsif method == :nil? and args.length == 0
91
- process s(:send, target, :==, s(:nil))
90
+ process S(:send, target, :==, s(:nil))
92
91
 
93
92
  elsif [:start_with?, :end_with?].include? method and args.length == 1
94
93
  if args.first.type == :str
95
- length = s(:int, args.first.children.first.length)
94
+ length = S(:int, args.first.children.first.length)
96
95
  else
97
- length = s(:attr, *args, :length)
96
+ length = S(:attr, *args, :length)
98
97
  end
99
98
 
100
99
  if method == :start_with?
101
- process s(:send, s(:send, target, :substring, s(:int, 0),
100
+ process S(:send, S(:send, target, :substring, s(:int, 0),
102
101
  length), :==, *args)
103
102
  else
104
- process s(:send, s(:send, target, :slice,
105
- s(:send, length, :-@)), :==, *args)
103
+ process S(:send, S(:send, target, :slice,
104
+ S(:send, length, :-@)), :==, *args)
106
105
  end
107
106
 
108
107
  elsif method == :clear and args.length == 0 and node.is_method?
109
- process s(:send, target, :length=, s(:int, 0))
108
+ process S(:send, target, :length=, s(:int, 0))
110
109
 
111
110
  elsif method == :replace and args.length == 1
112
- process s(:begin, s(:send, target, :length=, s(:int, 0)),
113
- s(:send, target, :push, s(:splat, node.children[2])))
111
+ process S(:begin, S(:send, target, :length=, s(:int, 0)),
112
+ S(:send, target, :push, s(:splat, node.children[2])))
114
113
 
115
114
  elsif method == :include? and args.length == 1
116
- process s(:send, s(:send, target, :indexOf, args.first), :!=,
115
+ process S(:send, S(:send, target, :indexOf, args.first), :!=,
117
116
  s(:int, -1))
118
117
 
119
118
  elsif method == :respond_to? and args.length == 1
120
- process s(:in?, args.first, target)
119
+ process S(:in?, args.first, target)
121
120
 
122
121
  elsif method == :each
123
- process node.updated nil, [target, :forEach, *args]
122
+ process S(:send, target, :forEach, *args)
124
123
 
125
124
  elsif method == :downcase and args.length == 0
126
- process node.updated nil, [target, :toLowerCase]
125
+ process S(:send, target, :toLowerCase)
127
126
 
128
127
  elsif method == :upcase and args.length == 0
129
- process node.updated nil, [target, :toUpperCase]
128
+ process S(:send, target, :toUpperCase)
130
129
 
131
130
  elsif node.children[0..1] == [nil, :puts]
132
- process s(:send, s(:attr, nil, :console), :log, *args)
131
+ process S(:send, s(:attr, nil, :console), :log, *args)
133
132
 
134
133
  elsif method == :first
135
134
  if node.children.length == 2
136
- process node.updated nil, [target, :[], s(:int, 0)]
135
+ process S(:send, target, :[], s(:int, 0))
137
136
  elsif node.children.length == 3
138
- process on_send node.updated nil, [target, :[], s(:erange,
139
- s(:int, 0), node.children[2])]
137
+ process on_send S(:send, target, :[], s(:erange,
138
+ s(:int, 0), node.children[2]))
140
139
  else
141
140
  super
142
141
  end
143
142
 
144
143
  elsif method == :last
145
144
  if node.children.length == 2
146
- process on_send node.updated nil, [target, :[], s(:int, -1)]
145
+ process on_send S(:send, target, :[], s(:int, -1))
147
146
  elsif node.children.length == 3
148
- process node.updated nil, [target, :slice,
147
+ process S(:send, target, :slice,
149
148
  s(:send, s(:attr, target, :length), :-, node.children[2]),
150
- s(:attr, target, :length)]
149
+ s(:attr, target, :length))
151
150
  else
152
151
  super
153
152
  end
@@ -159,7 +158,7 @@ module Ruby2JS
159
158
  # resolve negative literal indexes
160
159
  i = proc do |index|
161
160
  if index.type == :int and index.children.first < 0
162
- process s(:send, s(:attr, target, :length), :-,
161
+ process S(:send, S(:attr, target, :length), :-,
163
162
  s(:int, -index.children.first))
164
163
  else
165
164
  index
@@ -167,32 +166,32 @@ module Ruby2JS
167
166
  end
168
167
 
169
168
  if index.type == :regexp
170
- process s(:send, s(:send, target, :match, index), :[],
169
+ process S(:send, S(:send, target, :match, index), :[],
171
170
  args[1] || s(:int, 0))
172
171
 
173
172
  elsif node.children.length != 3
174
173
  super
175
174
 
176
175
  elsif index.type == :int and index.children.first < 0
177
- process node.updated nil, [target, :[], i.(index)]
176
+ process S(:send, target, :[], i.(index))
178
177
 
179
178
  elsif index.type == :erange
180
179
  start, finish = index.children
181
- process node.updated nil, [target, :slice, i.(start), i.(finish)]
180
+ process S(:send, target, :slice, i.(start), i.(finish))
182
181
 
183
182
  elsif index.type == :irange
184
183
  start, finish = index.children
185
184
  start = i.(start)
186
185
  if finish.type == :int
187
186
  if finish.children.first == -1
188
- finish = s(:attr, target, :length)
187
+ finish = S(:attr, target, :length)
189
188
  else
190
- finish = i.(s(:int, finish.children.first+1))
189
+ finish = i.(S(:int, finish.children.first+1))
191
190
  end
192
191
  else
193
- finish = s(:send, finish, :+, s(:int, 1))
192
+ finish = S(:send, finish, :+, s(:int, 1))
194
193
  end
195
- process node.updated nil, [target, :slice, start, finish]
194
+ process S(:send, target, :slice, start, finish)
196
195
 
197
196
  else
198
197
  super
@@ -201,15 +200,15 @@ module Ruby2JS
201
200
  elsif method == :reverse! and node.is_method?
202
201
  # input: a.reverse!
203
202
  # output: a.splice(0, a.length, *a.reverse)
204
- process s(:send, target, :splice, s(:int, 0),
205
- s(:attr, target, :length), s(:splat, s(:send, target,
206
- :"#{node.children[1].to_s[0..-2]}", *node.children[2..-1])))
203
+ process S(:send, target, :splice, s(:int, 0),
204
+ s(:attr, target, :length), s(:splat, S(:send, target,
205
+ :reverse, *node.children[2..-1])))
207
206
 
208
207
  elsif method == :each_with_index
209
- process node.updated nil, [target, :forEach, *args]
208
+ process S(:send, target, :forEach, *args)
210
209
 
211
210
  elsif method == :inspect and args.length == 0
212
- s(:send, s(:const, nil, :JSON), :stringify, process(target))
211
+ S(:send, s(:const, nil, :JSON), :stringify, process(target))
213
212
 
214
213
  else
215
214
  super
@@ -254,15 +253,15 @@ module Ruby2JS
254
253
  # output: a.splice(0, a.length, *a.map {expression})
255
254
  method = (call.children[1] == :map! ? :map : :select)
256
255
  target = call.children.first
257
- process s(:send, target, :splice, s(:splat, s(:send, s(:array,
258
- s(:int, 0), s(:attr, target, :length)), :concat,
256
+ process call.updated(:send, [target, :splice, s(:splat, s(:send,
257
+ s(:array, s(:int, 0), s(:attr, target, :length)), :concat,
259
258
  s(:block, s(:send, target, method, *call.children[2..-1]),
260
- *node.children[1..-1]))))
259
+ *node.children[1..-1])))])
261
260
 
262
261
  elsif node.children[0..1] == [s(:send, nil, :loop), s(:args)]
263
262
  # input: loop {statements}
264
263
  # output: while(true) {statements}
265
- s(:while, s(:true), node.children[2])
264
+ S(:while, s(:true), node.children[2])
266
265
 
267
266
  else
268
267
  super
@@ -278,15 +277,15 @@ module Ruby2JS
278
277
  body.any? {|statement| statement.type == :def and
279
278
  statement.children.first == :initialize}
280
279
  then
281
- body.unshift s(:def, :initialize, s(:args, s(:arg, :message)),
282
- s(:begin, s(:send, s(:self), :message=, s(:lvar, :message)),
283
- s(:send, s(:self), :name=, s(:sym, name.children[1])),
284
- s(:send, s(:self), :stack=, s(:send, s(:send, nil, :Error,
280
+ body.unshift S(:def, :initialize, s(:args, s(:arg, :message)),
281
+ s(:begin, S(:send, s(:self), :message=, s(:lvar, :message)),
282
+ S(:send, s(:self), :name=, s(:sym, name.children[1])),
283
+ S(:send, s(:self), :stack=, s(:send, s(:send, nil, :Error,
285
284
  s(:lvar, :message)), :stack))))
286
285
  end
287
286
 
288
287
  body = [s(:begin, *body)] if body.length > 1
289
- s(:class, name, s(:const, nil, :Error), *body)
288
+ S(:class, name, s(:const, nil, :Error), *body)
290
289
  else
291
290
  super
292
291
  end
@@ -66,16 +66,16 @@ module Ruby2JS
66
66
  body.select {|child| child.type == :defs}.each do |child|
67
67
  parent, mname, args, *block = child.children
68
68
  if child.is_method?
69
- statics << s(:pair, s(:sym, mname),
70
- s(:block, s(:send, nil, :proc), args, s(:autoreturn, *block)))
69
+ statics << s(:pair, s(:sym, mname), child.updated(:block,
70
+ [s(:send, nil, :proc), args, s(:autoreturn, *block)]))
71
71
  elsif
72
72
  block.length == 1 and
73
73
  Converter::EXPRESSIONS.include? block.first.type
74
74
  then
75
75
  statics << s(:pair, s(:sym, mname), *block)
76
76
  else
77
- statics << s(:pair, s(:prop, mname), {get:
78
- s(:block, s(:send, nil, :proc), args, s(:autoreturn, *block))})
77
+ statics << s(:pair, s(:prop, mname), {get: child.updated(
78
+ :block, [s(:send, nil, :proc), args, s(:autoreturn, *block)])})
79
79
  end
80
80
  end
81
81
 
@@ -84,11 +84,27 @@ module Ruby2JS
84
84
  pairs << s(:pair, s(:sym, :statics), s(:hash, *statics))
85
85
  end
86
86
 
87
+ # create a default getInitialState method if there is no such method
88
+ # and there are references to instance variables.
89
+ if
90
+ not body.any? do |child|
91
+ child.type == :def and
92
+ [:getInitialState, :initialize].include? child.children.first
93
+ end
94
+ then
95
+ @reactIvars = {pre: [], post: [], asgn: [], ref: []}
96
+ react_walk(node)
97
+ unless @reactIvars.values.flatten.empty?
98
+ body = [s(:def, :getInitialState, s(:args),
99
+ s(:return, s(:hash))), *body]
100
+ end
101
+ end
102
+
87
103
  # add a proc/function for each method
88
104
  body.select {|child| child.type == :def}.each do |child|
89
105
  mname, args, *block = child.children
90
106
  @reactMethod = mname
91
- @reactProps = s(:attr, s(:self), :props)
107
+ @reactProps = child.updated(:attr, [s(:self), :props])
92
108
 
93
109
  # analyze ivar usage
94
110
  @reactIvars = {pre: [], post: [], asgn: [], ref: []}
@@ -145,7 +161,7 @@ module Ruby2JS
145
161
  elsif mname == :componentWillReceiveProps
146
162
  if args.children.length == 0
147
163
  args = s(:args, s(:arg, :"$$props"))
148
- child = s(:def, mname, args, *block)
164
+ child = child.updated(:def, [mname, args, *block])
149
165
  @reactProps = s(:lvar, :"$$props")
150
166
  else
151
167
  @reactProps = s(:lvar, args.children.first.children.last)
@@ -179,9 +195,18 @@ module Ruby2JS
179
195
  end
180
196
 
181
197
  # add method to class
182
- pairs << s(:pair, s(:sym, mname), s(:block, s(:send, nil, :proc),
183
- args, process(s((child.is_method? ? :begin : :autoreturn),
184
- *block))))
198
+ type = (child.is_method? ? :begin : :autoreturn)
199
+ if block.length == 1 and Parser::AST::Node === block.first
200
+ type = :begin if block.first.type == :return
201
+ end
202
+
203
+ pairs << s(:pair, s(:sym, mname), child.updated(:block,
204
+ [s(:send, nil, :proc), args, process(s(type, *block))]))
205
+
206
+ # retain comment
207
+ unless @comments[child].empty?
208
+ @comments[pairs.last] = @comments[child]
209
+ end
185
210
  end
186
211
  ensure
187
212
  @react = react
@@ -190,8 +215,8 @@ module Ruby2JS
190
215
  end
191
216
 
192
217
  # emit a createClass statement
193
- s(:casgn, nil, cname.children.last,
194
- s(:send, inheritance, :createClass, s(:hash, *pairs)))
218
+ node.updated(:casgn, [nil, cname.children.last,
219
+ s(:send, inheritance, :createClass, s(:hash, *pairs))])
195
220
  end
196
221
 
197
222
  def on_send(node)
@@ -379,7 +404,8 @@ module Ruby2JS
379
404
  params.pop if params.last == s(:nil)
380
405
 
381
406
  # construct element using params
382
- element = s(:send, s(:const, nil, :React), :createElement, *params)
407
+ element = node.updated(:send, [s(:const, nil, :React),
408
+ :createElement, *params])
383
409
 
384
410
  if @reactApply
385
411
  # if apply is set, emit code that pushes result
@@ -528,7 +554,7 @@ module Ruby2JS
528
554
  end
529
555
 
530
556
  # collapse series of method calls into a single call
531
- return process(s(:send, *node.children[0..1], *children))
557
+ return process(node.updated(nil, [*node.children[0..1], *children]))
532
558
  else
533
559
  super
534
560
  end
@@ -588,7 +614,8 @@ module Ruby2JS
588
614
  if child.children[0] == nil and child.children[1] =~ /^_\w/
589
615
  block = s(:block, s(:send, nil, :proc), s(:args),
590
616
  *node.children[2..-1])
591
- return on_send s(:send, *node.children.first.children, block)
617
+ return on_send node.children.first.updated(:send,
618
+ [*node.children.first.children, block])
592
619
  end
593
620
 
594
621
  super
@@ -604,9 +631,10 @@ module Ruby2JS
604
631
  def on_ivar(node)
605
632
  return super unless @reactClass
606
633
  if @reactMethod and @reactIvars[:capture].include? node.children.first
607
- s(:lvar, "$#{node.children.first[1..-1]}")
634
+ node.updated(:lvar, ["$#{node.children.first[1..-1]}"])
608
635
  else
609
- s(:attr, s(:attr, s(:self), :state), node.children.first.to_s[1..-1])
636
+ node.updated(:attr, [s(:attr, s(:self), :state),
637
+ node.children.first.to_s[1..-1]])
610
638
  end
611
639
  end
612
640