ruby2js 3.5.1 → 4.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.
- checksums.yaml +4 -4
- data/README.md +5 -662
- data/lib/ruby2js.rb +61 -10
- data/lib/ruby2js/converter.rb +10 -4
- data/lib/ruby2js/converter/assign.rb +159 -0
- data/lib/ruby2js/converter/begin.rb +7 -2
- data/lib/ruby2js/converter/case.rb +7 -2
- data/lib/ruby2js/converter/class.rb +77 -21
- data/lib/ruby2js/converter/class2.rb +102 -31
- data/lib/ruby2js/converter/def.rb +7 -3
- data/lib/ruby2js/converter/dstr.rb +8 -3
- data/lib/ruby2js/converter/hash.rb +9 -5
- data/lib/ruby2js/converter/hide.rb +13 -0
- data/lib/ruby2js/converter/if.rb +10 -2
- data/lib/ruby2js/converter/import.rb +35 -4
- data/lib/ruby2js/converter/kwbegin.rb +9 -2
- data/lib/ruby2js/converter/literal.rb +14 -2
- data/lib/ruby2js/converter/module.rb +41 -4
- data/lib/ruby2js/converter/opasgn.rb +8 -0
- data/lib/ruby2js/converter/send.rb +45 -5
- data/lib/ruby2js/converter/vasgn.rb +5 -0
- data/lib/ruby2js/converter/xstr.rb +1 -1
- data/lib/ruby2js/demo.rb +53 -0
- data/lib/ruby2js/es2022.rb +5 -0
- data/lib/ruby2js/es2022/strict.rb +3 -0
- data/lib/ruby2js/filter.rb +9 -1
- data/lib/ruby2js/filter/active_functions.rb +44 -0
- data/lib/ruby2js/filter/camelCase.rb +4 -3
- data/lib/ruby2js/filter/cjs.rb +2 -0
- data/lib/ruby2js/filter/esm.rb +133 -7
- data/lib/ruby2js/filter/functions.rb +107 -98
- data/lib/ruby2js/filter/{wunderbar.rb → jsx.rb} +29 -7
- data/lib/ruby2js/filter/node.rb +95 -74
- data/lib/ruby2js/filter/nokogiri.rb +15 -41
- data/lib/ruby2js/filter/react.rb +191 -56
- data/lib/ruby2js/filter/require.rb +100 -5
- data/lib/ruby2js/filter/return.rb +15 -1
- data/lib/ruby2js/filter/securerandom.rb +33 -0
- data/lib/ruby2js/filter/stimulus.rb +185 -0
- data/lib/ruby2js/filter/vue.rb +9 -0
- data/lib/ruby2js/jsx.rb +291 -0
- data/lib/ruby2js/namespace.rb +75 -0
- data/lib/ruby2js/rails.rb +15 -9
- data/lib/ruby2js/serializer.rb +3 -1
- data/lib/ruby2js/version.rb +3 -3
- data/ruby2js.gemspec +1 -1
- metadata +14 -5
- data/lib/ruby2js/filter/esm_migration.rb +0 -72
- data/lib/ruby2js/filter/fast-deep-equal.rb +0 -23
@@ -11,13 +11,27 @@ module Ruby2JS
|
|
11
11
|
# NOTE: class_extend is not generated by the parser, but instead produced
|
12
12
|
# when ++class is encountered; it signals that this construct is
|
13
13
|
# meant to extend an already existing JavaScrpt class.
|
14
|
+
#
|
15
|
+
# class_hash is an anonymous class as a value in a hash; the
|
16
|
+
# name has already been output so should be ignored other than
|
17
|
+
# in determining the namespace.
|
18
|
+
#
|
19
|
+
# class_module is a module that to be re-processed by this handler
|
20
|
+
# given the similarity between the two structures.
|
14
21
|
|
15
|
-
handle :class, :class_extend, :class_module do |name, inheritance, *body|
|
16
|
-
|
22
|
+
handle :class, :class_hash, :class_extend, :class_module do |name, inheritance, *body|
|
23
|
+
extend = @namespace.enter(name) unless @ast.type == :class_module
|
24
|
+
|
25
|
+
if !%i(class class_hash).include?(@ast.type) or extend
|
17
26
|
init = nil
|
18
27
|
else
|
19
|
-
if es2015
|
20
|
-
|
28
|
+
if es2015 and not extend
|
29
|
+
if @ast.type == :class_hash
|
30
|
+
parse @ast.updated(:class2, [nil, *@ast.children[1..-1]])
|
31
|
+
else
|
32
|
+
parse @ast.updated(:class2)
|
33
|
+
end
|
34
|
+
@namespace.leave unless @ast.type == :class_module
|
21
35
|
return
|
22
36
|
end
|
23
37
|
|
@@ -35,7 +49,7 @@ module Ruby2JS
|
|
35
49
|
end
|
36
50
|
|
37
51
|
body.compact!
|
38
|
-
visible =
|
52
|
+
visible = @namespace.getOwnProps
|
39
53
|
body.map! do |m|
|
40
54
|
if \
|
41
55
|
@ast.type == :class_module and m.type == :defs and
|
@@ -45,7 +59,7 @@ module Ruby2JS
|
|
45
59
|
end
|
46
60
|
|
47
61
|
node = if m.type == :def
|
48
|
-
if m.children.first == :initialize
|
62
|
+
if m.children.first == :initialize and !visible[:initialize]
|
49
63
|
# constructor: remove from body and overwrite init function
|
50
64
|
init = m
|
51
65
|
nil
|
@@ -54,17 +68,20 @@ module Ruby2JS
|
|
54
68
|
sym = :"#{m.children.first.to_s[0..-2]}"
|
55
69
|
s(:prop, s(:attr, name, :prototype), sym =>
|
56
70
|
{enumerable: s(:true), configurable: s(:true),
|
57
|
-
set: s(:
|
71
|
+
set: s(:defm, nil, *m.children[1..-1])})
|
58
72
|
else
|
59
|
-
visible[m.children[0]] = s(:self)
|
60
73
|
|
61
74
|
if not m.is_method?
|
75
|
+
visible[m.children[0]] = s(:self)
|
76
|
+
|
62
77
|
# property getter
|
63
78
|
s(:prop, s(:attr, name, :prototype), m.children.first =>
|
64
79
|
{enumerable: s(:true), configurable: s(:true),
|
65
|
-
get: s(:
|
80
|
+
get: s(:defm, nil, m.children[1],
|
66
81
|
m.updated(:autoreturn, m.children[2..-1]))})
|
67
82
|
else
|
83
|
+
visible[m.children[0]] = s(:autobind, s(:self))
|
84
|
+
|
68
85
|
# method: add to prototype
|
69
86
|
s(:method, s(:attr, name, :prototype),
|
70
87
|
:"#{m.children[0].to_s.chomp('!')}=",
|
@@ -90,7 +107,7 @@ module Ruby2JS
|
|
90
107
|
else
|
91
108
|
# class method definition: add to prototype
|
92
109
|
s(:prototype, s(:send, name, "#{m.children[1]}=",
|
93
|
-
s(:
|
110
|
+
s(:defm, nil, *m.children[2..-1])))
|
94
111
|
end
|
95
112
|
|
96
113
|
elsif m.type == :send and m.children.first == nil
|
@@ -125,9 +142,10 @@ module Ruby2JS
|
|
125
142
|
elsif m.children[1] == :include
|
126
143
|
s(:send, s(:block, s(:send, nil, :lambda), s(:args),
|
127
144
|
s(:begin, *m.children[2..-1].map {|modname|
|
128
|
-
|
129
|
-
|
130
|
-
|
145
|
+
@namespace.defineProps @namespace.find(modname)
|
146
|
+
s(:for, s(:lvasgn, :$_), modname,
|
147
|
+
s(:send, s(:attr, name, :prototype), :[]=,
|
148
|
+
s(:lvar, :$_), s(:send, modname, :[], s(:lvar, :$_))))
|
131
149
|
})), :[])
|
132
150
|
elsif [:private, :protected, :public].include? m.children[1]
|
133
151
|
raise Error.new("class #{m.children[1]} is not supported", @ast)
|
@@ -160,17 +178,23 @@ module Ruby2JS
|
|
160
178
|
s(:send, s(:attr, name, :prototype),
|
161
179
|
"#{m.children[0].children.first}=",
|
162
180
|
s(:attr, s(:attr, name, :prototype), m.children[1].children.first))
|
163
|
-
elsif m.type == :class
|
181
|
+
elsif m.type == :class or m.type == :module
|
164
182
|
innerclass_name = m.children.first
|
165
183
|
if innerclass_name.children.first
|
166
184
|
innerclass_name = innerclass_name.updated(nil,
|
167
|
-
[s(:attr, innerclass_name.children[0]
|
185
|
+
[s(:attr, name, innerclass_name.children[0].children.last),
|
168
186
|
innerclass_name.children[1]])
|
169
187
|
else
|
170
188
|
innerclass_name = innerclass_name.updated(nil,
|
171
189
|
[name, innerclass_name.children[1]])
|
172
190
|
end
|
173
191
|
m.updated(nil, [innerclass_name, *m.children[1..-1]])
|
192
|
+
elsif @ast.type == :class_module
|
193
|
+
m
|
194
|
+
elsif m.type == :defineProps
|
195
|
+
@namespace.defineProps m.children.first
|
196
|
+
visible.merge! m.children.first
|
197
|
+
nil
|
174
198
|
else
|
175
199
|
raise Error.new("class #{ m.type } not supported", @ast)
|
176
200
|
end
|
@@ -194,7 +218,7 @@ module Ruby2JS
|
|
194
218
|
# merge property definitions
|
195
219
|
combine_properties(body)
|
196
220
|
|
197
|
-
if inheritance
|
221
|
+
if inheritance and (@ast.type != :class_extend and !extend)
|
198
222
|
body.unshift s(:send, name, :prototype=,
|
199
223
|
s(:send, s(:const, nil, :Object), :create,
|
200
224
|
s(:attr, inheritance, :prototype))),
|
@@ -206,10 +230,14 @@ module Ruby2JS
|
|
206
230
|
methods = 0
|
207
231
|
start = 0
|
208
232
|
body.each do |node|
|
209
|
-
if
|
233
|
+
if (node.type == :method or (node.type == :prop and es2015)) and
|
210
234
|
node.children[0].type == :attr and
|
211
235
|
node.children[0].children[1] == :prototype
|
212
236
|
methods += 1
|
237
|
+
elsif node.type == :class and @ast.type == :class_module and es2015
|
238
|
+
methods += 1 if node.children.first.children.first == name
|
239
|
+
elsif node.type == :module and @ast.type == :class_module
|
240
|
+
methods += 1 if node.children.first.children.first == name
|
213
241
|
elsif methods == 0
|
214
242
|
start += 1
|
215
243
|
else
|
@@ -219,14 +247,22 @@ module Ruby2JS
|
|
219
247
|
|
220
248
|
# collapse sequence to a single assignment
|
221
249
|
if \
|
222
|
-
@ast.type
|
223
|
-
|
250
|
+
@ast.type == :class_module or methods > 1 or
|
251
|
+
body[start]&.type == :prop
|
224
252
|
then
|
225
253
|
pairs = body[start...start+methods].map do |node|
|
226
254
|
if node.type == :method
|
227
255
|
replacement = node.updated(:pair, [
|
228
256
|
s(:str, node.children[1].to_s.chomp('=')),
|
229
257
|
node.children[2]])
|
258
|
+
elsif node.type == :class and node.children.first.children.first == name
|
259
|
+
sym = node.children.first.children.last
|
260
|
+
replacement = s(:pair, s(:sym, sym),
|
261
|
+
s(:class_hash, s(:const, nil, sym), nil, node.children.last))
|
262
|
+
elsif node.type == :module and node.children.first.children.first == name
|
263
|
+
sym = node.children.first.children.last
|
264
|
+
replacement = s(:pair, s(:sym, sym),
|
265
|
+
s(:module_hash, s(:const, nil, sym), node.children.last))
|
230
266
|
else
|
231
267
|
replacement = node.children[1].map do |prop, descriptor|
|
232
268
|
node.updated(:pair, [s(:prop, prop), descriptor])
|
@@ -244,12 +280,30 @@ module Ruby2JS
|
|
244
280
|
end
|
245
281
|
|
246
282
|
if @ast.type == :class_module
|
283
|
+
start = 0 if methods == 0
|
284
|
+
if name
|
285
|
+
body[start...start+methods] =
|
286
|
+
s(:casgn, *name.children, s(:hash, *pairs.flatten))
|
287
|
+
else
|
288
|
+
body[start...start+methods] = s(:hash, *pairs.flatten)
|
289
|
+
end
|
290
|
+
elsif @ast.type == :class_extend or extend
|
247
291
|
body[start...start+methods] =
|
248
|
-
s(:
|
292
|
+
s(:assign, body[start].children.first, s(:hash, *pairs.flatten))
|
249
293
|
else
|
250
294
|
body[start...start+methods] =
|
251
295
|
s(:send, name, :prototype=, s(:hash, *pairs.flatten))
|
252
296
|
end
|
297
|
+
|
298
|
+
elsif (@ast.type == :class_extend or extend) and methods > 1
|
299
|
+
|
300
|
+
pairs = body[start...start+methods].map do |node|
|
301
|
+
node.updated(:pair, [
|
302
|
+
s(:sym, node.children[1].to_s[0..-2]), node.children[2]])
|
303
|
+
end
|
304
|
+
|
305
|
+
body[start...start+methods] =
|
306
|
+
s(:assign, body[start].children.first, s(:hash, *pairs))
|
253
307
|
end
|
254
308
|
end
|
255
309
|
|
@@ -258,7 +312,7 @@ module Ruby2JS
|
|
258
312
|
constructor = init.updated(:constructor, [name, *init.children[1..-1]])
|
259
313
|
@comments[constructor] = @comments[init] unless @comments[init].empty?
|
260
314
|
|
261
|
-
if @ast.type == :class_extend
|
315
|
+
if @ast.type == :class_extend or extend
|
262
316
|
if es2015
|
263
317
|
constructor = s(:masgn, s(:mlhs,
|
264
318
|
s(:attr, s(:casgn, *name.children, constructor), :prototype)),
|
@@ -285,6 +339,7 @@ module Ruby2JS
|
|
285
339
|
|
286
340
|
# add locally visible interfaces to rbstack. See send.rb, const.rb
|
287
341
|
@rbstack.push visible
|
342
|
+
@rbstack.last.merge!(@namespace.find(inheritance)) if inheritance
|
288
343
|
|
289
344
|
parse s(:begin, *body.compact), :statement
|
290
345
|
ensure
|
@@ -292,6 +347,7 @@ module Ruby2JS
|
|
292
347
|
@class_name = class_name
|
293
348
|
@class_parent = class_parent
|
294
349
|
@rbstack.pop
|
350
|
+
@namespace.leave unless @ast.type == :class_module
|
295
351
|
end
|
296
352
|
end
|
297
353
|
|
@@ -9,11 +9,24 @@ module Ruby2JS
|
|
9
9
|
# NOTE: this is the es2015 version of class
|
10
10
|
|
11
11
|
handle :class2 do |name, inheritance, *body|
|
12
|
-
|
12
|
+
body.compact!
|
13
|
+
while body.length == 1 and body.first.type == :begin
|
14
|
+
body = body.first.children
|
15
|
+
end
|
16
|
+
|
17
|
+
proxied = body.find do |node|
|
18
|
+
node.type == :def and node.children.first == :method_missing
|
19
|
+
end
|
20
|
+
|
21
|
+
if not name
|
22
|
+
put 'class'
|
23
|
+
elsif name.type == :const and name.children.first == nil
|
13
24
|
put 'class '
|
14
25
|
parse name
|
26
|
+
put '$' if proxied
|
15
27
|
else
|
16
28
|
parse name
|
29
|
+
put '$' if proxied
|
17
30
|
put ' = class'
|
18
31
|
end
|
19
32
|
|
@@ -24,15 +37,11 @@ module Ruby2JS
|
|
24
37
|
|
25
38
|
put " {"
|
26
39
|
|
27
|
-
body.compact!
|
28
|
-
while body.length == 1 and body.first.type == :begin
|
29
|
-
body = body.first.children
|
30
|
-
end
|
31
|
-
|
32
40
|
begin
|
33
41
|
class_name, @class_name = @class_name, name
|
34
42
|
class_parent, @class_parent = @class_parent, inheritance
|
35
|
-
@rbstack.push(
|
43
|
+
@rbstack.push(@namespace.getOwnProps)
|
44
|
+
@rbstack.last.merge!(@namespace.find(inheritance)) if inheritance
|
36
45
|
constructor = []
|
37
46
|
index = 0
|
38
47
|
|
@@ -40,10 +49,17 @@ module Ruby2JS
|
|
40
49
|
body.each do |m|
|
41
50
|
if m.type == :def
|
42
51
|
prop = m.children.first
|
43
|
-
if prop == :initialize
|
52
|
+
if prop == :initialize and !@rbstack.last[:initialize]
|
44
53
|
constructor = m.children[2..-1]
|
45
|
-
elsif
|
46
|
-
@rbstack.last[prop] = s(:self)
|
54
|
+
elsif prop.to_s.end_with? '='
|
55
|
+
@rbstack.last[prop.to_s[0..-2].to_sym] = s(:autobind, s(:self))
|
56
|
+
else
|
57
|
+
@rbstack.last[prop] = m.is_method? ? s(:autobind, s(:self)) : s(:self)
|
58
|
+
end
|
59
|
+
elsif m.type == :send and m.children[0..1] == [nil, :async]
|
60
|
+
if m.children[2].type == :def
|
61
|
+
prop = m.children[2].children.first
|
62
|
+
@rbstack.last[prop] = s(:autobind, s(:self))
|
47
63
|
end
|
48
64
|
end
|
49
65
|
end
|
@@ -64,21 +80,21 @@ module Ruby2JS
|
|
64
80
|
walk[child] if child.is_a? Parser::AST::Node
|
65
81
|
end
|
66
82
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
83
|
+
if ast.type == :send and ast.children.first == nil
|
84
|
+
if ast.children[1] == :attr_accessor
|
85
|
+
ast.children[2..-1].each_with_index do |child_sym, index2|
|
86
|
+
ivars << :"@#{child_sym.children.first}"
|
87
|
+
end
|
88
|
+
elsif ast.children[1] == :attr_reader
|
89
|
+
ast.children[2..-1].each_with_index do |child_sym, index2|
|
90
|
+
ivars << :"@#{child_sym.children.first}"
|
91
|
+
end
|
92
|
+
elsif ast.children[1] == :attr_writer
|
93
|
+
ast.children[2..-1].each_with_index do |child_sym, index2|
|
94
|
+
ivars << :"@#{child_sym.children.first}"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
82
98
|
|
83
99
|
end
|
84
100
|
walk[@ast]
|
@@ -140,10 +156,10 @@ module Ruby2JS
|
|
140
156
|
end
|
141
157
|
end
|
142
158
|
|
143
|
-
if m.type == :def || m.type == :async
|
159
|
+
if m.type == :def || m.type == :defm || m.type == :async
|
144
160
|
@prop = m.children.first
|
145
161
|
|
146
|
-
if @prop == :initialize
|
162
|
+
if @prop == :initialize and !@rbstack.last[:initialize]
|
147
163
|
@prop = :constructor
|
148
164
|
|
149
165
|
if constructor == [] or constructor == [(:super)]
|
@@ -228,13 +244,27 @@ module Ruby2JS
|
|
228
244
|
else
|
229
245
|
if m.children[1] == :include
|
230
246
|
m = m.updated(:begin, m.children[2..-1].map {|mname|
|
231
|
-
|
232
|
-
s(:attr, name, :prototype), mname)
|
247
|
+
@namespace.defineProps @namespace.find(mname)
|
248
|
+
s(:assign, s(:attr, name, :prototype), mname)
|
249
|
+
})
|
233
250
|
end
|
234
251
|
|
235
252
|
skipped = true
|
236
253
|
end
|
237
254
|
|
255
|
+
elsif es2022 and \
|
256
|
+
m.type == :send and m.children.first.type == :self and \
|
257
|
+
m.children[1].to_s.end_with? '='
|
258
|
+
|
259
|
+
put 'static '
|
260
|
+
parse m.updated(:lvasgn, [m.children[1].to_s.sub('=', ''),
|
261
|
+
m.children[2]])
|
262
|
+
|
263
|
+
elsif m.type == :defineProps
|
264
|
+
skipped = true
|
265
|
+
@namespace.defineProps m.children.first
|
266
|
+
@rbstack.last.merge! m.children.first
|
267
|
+
|
238
268
|
else
|
239
269
|
if m.type == :cvasgn and !underscored_private
|
240
270
|
put 'static #$'; put m.children[0].to_s[2..-1]; put ' = '
|
@@ -257,7 +287,7 @@ module Ruby2JS
|
|
257
287
|
end
|
258
288
|
|
259
289
|
if skipped
|
260
|
-
post << [m, comments]
|
290
|
+
post << [m, comments] unless m.type == :defineProps
|
261
291
|
else
|
262
292
|
comments.reverse.each {|comment| insert location, comment}
|
263
293
|
end
|
@@ -294,15 +324,56 @@ module Ruby2JS
|
|
294
324
|
else
|
295
325
|
parse m.updated(:send, [@class_name, *m.children[1..-1]])
|
296
326
|
end
|
327
|
+
elsif m.type == :block and m.children.first.children.first == nil
|
328
|
+
# class method calls passing a block
|
329
|
+
parse s(:block, s(:send, name, *m.children.first.children[1..-1]),
|
330
|
+
*m.children[1..-1])
|
297
331
|
else
|
298
332
|
parse m, :statement
|
299
333
|
end
|
300
334
|
end
|
301
335
|
|
336
|
+
if proxied
|
337
|
+
put @sep
|
338
|
+
|
339
|
+
rename = name.updated(nil, [name.children.first, name.children.last.to_s + '$'])
|
340
|
+
|
341
|
+
if proxied.children[1].children.length == 1
|
342
|
+
# special case: if method_missing only has on argument, call it
|
343
|
+
# directly (i.e., don't pass arguments). This enables
|
344
|
+
# method_missing to return instance attributes (getters) as well
|
345
|
+
# as bound functions (methods).
|
346
|
+
forward = s(:send, s(:lvar, :obj), :method_missing, s(:lvar, :prop))
|
347
|
+
else
|
348
|
+
# normal case: return a function which, when called, will call
|
349
|
+
# method_missing with method name and arguments.
|
350
|
+
forward = s(:block, s(:send, nil, :proc), s(:args, s(:restarg, :args)),
|
351
|
+
s(:send, s(:lvar, :obj), :method_missing, s(:lvar, :prop),
|
352
|
+
s(:splat, s(:lvar, :args))))
|
353
|
+
end
|
354
|
+
|
355
|
+
proxy = s(:return, s(:send, s(:const, nil, :Proxy), :new,
|
356
|
+
s(:send, rename, :new, s(:splat, s(:lvar, :args))),
|
357
|
+
s(:hash, s(:pair, s(:sym, :get), s(:block, s(:send, nil, :proc),
|
358
|
+
s(:args, s(:arg, :obj), s(:arg, :prop)),
|
359
|
+
s(:if, s(:in?, s(:lvar, :prop), s(:lvar, :obj)),
|
360
|
+
s(:return, s(:send, s(:lvar, :obj), :[], s(:lvar, :prop))),
|
361
|
+
s(:return, forward))))))
|
362
|
+
)
|
363
|
+
|
364
|
+
if name.children.first == nil
|
365
|
+
proxy = s(:def, name.children.last, s(:args, s(:restarg, :args)), proxy)
|
366
|
+
else
|
367
|
+
proxy = s(:defs, *name.children, s(:args, s(:restarg, :args)), proxy)
|
368
|
+
end
|
369
|
+
|
370
|
+
parse proxy
|
371
|
+
end
|
372
|
+
|
302
373
|
ensure
|
303
374
|
@class_name = class_name
|
304
375
|
@class_parent = class_parent
|
305
|
-
@rbstack.pop
|
376
|
+
@namespace.defineProps @rbstack.pop
|
306
377
|
end
|
307
378
|
end
|
308
379
|
end
|
@@ -6,7 +6,7 @@ module Ruby2JS
|
|
6
6
|
# (arg :x)
|
7
7
|
# (...)
|
8
8
|
|
9
|
-
handle :def, :defm, :async do |name, args, body=nil|
|
9
|
+
handle :def, :defm, :async, :deff do |name, args, body=nil|
|
10
10
|
body ||= s(:begin)
|
11
11
|
|
12
12
|
add_implicit_block = false
|
@@ -106,7 +106,7 @@ module Ruby2JS
|
|
106
106
|
# es2015 fat arrow support
|
107
107
|
if \
|
108
108
|
not name and es2015 and @state != :method and @ast.type != :defm and
|
109
|
-
not @prop
|
109
|
+
@ast.type != :deff and not @prop
|
110
110
|
then
|
111
111
|
expr = body
|
112
112
|
expr = expr.children.first while expr.type == :autoreturn
|
@@ -118,6 +118,10 @@ module Ruby2JS
|
|
118
118
|
if EXPRESSIONS.include? expr.type
|
119
119
|
if expr.type == :send and expr.children[0..1] == [nil, :raise]
|
120
120
|
style = :statement
|
121
|
+
elsif expr.type == :send and expr.children.length == 2 and
|
122
|
+
expr.children.first == nil and @rbstack.last and
|
123
|
+
@rbstack.last[expr.children[1]]&.type == :autobind
|
124
|
+
style = :statement
|
121
125
|
else
|
122
126
|
style = :expression
|
123
127
|
end
|
@@ -131,7 +135,7 @@ module Ruby2JS
|
|
131
135
|
style = :statement
|
132
136
|
end
|
133
137
|
|
134
|
-
if args.children.length == 1 and style == :expression
|
138
|
+
if args.children.length == 1 and args.children.first.type != :restarg and style == :expression
|
135
139
|
parse args; put ' => '
|
136
140
|
else
|
137
141
|
put '('; parse args; put ') => '
|