ruby2js 3.5.3 → 4.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -665
- data/lib/ruby2js.rb +60 -15
- data/lib/ruby2js/converter.rb +39 -3
- data/lib/ruby2js/converter/args.rb +6 -1
- 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 +80 -21
- data/lib/ruby2js/converter/class2.rb +107 -33
- data/lib/ruby2js/converter/def.rb +7 -3
- data/lib/ruby2js/converter/dstr.rb +8 -3
- data/lib/ruby2js/converter/for.rb +1 -1
- data/lib/ruby2js/converter/hash.rb +28 -6
- data/lib/ruby2js/converter/hide.rb +13 -0
- data/lib/ruby2js/converter/if.rb +10 -2
- data/lib/ruby2js/converter/import.rb +19 -4
- data/lib/ruby2js/converter/kwbegin.rb +9 -2
- data/lib/ruby2js/converter/literal.rb +14 -2
- data/lib/ruby2js/converter/logical.rb +1 -1
- data/lib/ruby2js/converter/module.rb +41 -4
- data/lib/ruby2js/converter/next.rb +10 -2
- data/lib/ruby2js/converter/opasgn.rb +8 -0
- data/lib/ruby2js/converter/redo.rb +14 -0
- data/lib/ruby2js/converter/return.rb +2 -1
- data/lib/ruby2js/converter/send.rb +73 -8
- data/lib/ruby2js/converter/vasgn.rb +5 -0
- data/lib/ruby2js/converter/while.rb +1 -1
- data/lib/ruby2js/converter/whilepost.rb +1 -1
- data/lib/ruby2js/converter/xstr.rb +2 -3
- 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 +6 -3
- data/lib/ruby2js/filter/cjs.rb +2 -0
- data/lib/ruby2js/filter/esm.rb +118 -26
- data/lib/ruby2js/filter/functions.rb +137 -109
- data/lib/ruby2js/filter/{wunderbar.rb → jsx.rb} +29 -7
- data/lib/ruby2js/filter/node.rb +58 -14
- data/lib/ruby2js/filter/nokogiri.rb +12 -12
- data/lib/ruby2js/filter/react.rb +182 -57
- data/lib/ruby2js/filter/require.rb +102 -11
- data/lib/ruby2js/filter/return.rb +13 -1
- data/lib/ruby2js/filter/stimulus.rb +187 -0
- data/lib/ruby2js/jsx.rb +309 -0
- data/lib/ruby2js/namespace.rb +75 -0
- data/lib/ruby2js/serializer.rb +19 -12
- data/lib/ruby2js/sprockets.rb +40 -0
- data/lib/ruby2js/version.rb +3 -3
- data/ruby2js.gemspec +2 -2
- metadata +23 -13
- data/lib/ruby2js/filter/esm_migration.rb +0 -72
- data/lib/ruby2js/rails.rb +0 -63
@@ -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 == :arg and style == :expression
|
135
139
|
parse args; put ' => '
|
136
140
|
else
|
137
141
|
put '('; parse args; put ') => '
|
@@ -10,6 +10,11 @@ module Ruby2JS
|
|
10
10
|
# (...))
|
11
11
|
|
12
12
|
handle :dstr, :dsym do |*children|
|
13
|
+
if @state == :expression and children.empty?
|
14
|
+
puts '""'
|
15
|
+
return
|
16
|
+
end
|
17
|
+
|
13
18
|
if es2015
|
14
19
|
# gather length of string parts; if long enough, newlines will
|
15
20
|
# not be escaped (poor man's HEREDOC)
|
@@ -26,7 +31,7 @@ module Ruby2JS
|
|
26
31
|
else
|
27
32
|
put str
|
28
33
|
end
|
29
|
-
|
34
|
+
elsif child != s(:begin)
|
30
35
|
put '${'
|
31
36
|
parse child
|
32
37
|
put '}'
|
@@ -40,8 +45,8 @@ module Ruby2JS
|
|
40
45
|
children.each_with_index do |child, index|
|
41
46
|
put ' + ' unless index == 0
|
42
47
|
|
43
|
-
if child.type == :begin and child.children.length
|
44
|
-
child = child.children.first
|
48
|
+
if child.type == :begin and child.children.length <= 1
|
49
|
+
child = child.children.first || s(:str, '')
|
45
50
|
end
|
46
51
|
|
47
52
|
if child.type == :send
|
@@ -7,6 +7,24 @@ module Ruby2JS
|
|
7
7
|
# (str "value")))
|
8
8
|
|
9
9
|
handle :hash do |*pairs|
|
10
|
+
if not es2018 and pairs.any? {|pair| pair.type == :kwsplat}
|
11
|
+
groups = []
|
12
|
+
pending = []
|
13
|
+
while not pairs.empty?
|
14
|
+
pair = pairs.shift
|
15
|
+
if pair.type != :kwsplat
|
16
|
+
pending << pair
|
17
|
+
else
|
18
|
+
groups << s(:hash, *pending) unless pending.empty?
|
19
|
+
groups << pair.children.first
|
20
|
+
pending = []
|
21
|
+
end
|
22
|
+
end
|
23
|
+
groups << s(:hash, *pending) unless pending.empty?
|
24
|
+
parse s(:assign, s(:hash), *groups)
|
25
|
+
return
|
26
|
+
end
|
27
|
+
|
10
28
|
compact do
|
11
29
|
singleton = pairs.length <= 1
|
12
30
|
|
@@ -24,7 +42,7 @@ module Ruby2JS
|
|
24
42
|
pairs.unshift(*node.children.first.children)
|
25
43
|
index = 0
|
26
44
|
else
|
27
|
-
|
45
|
+
put '...'; parse node.children.first
|
28
46
|
end
|
29
47
|
|
30
48
|
next
|
@@ -73,7 +91,7 @@ module Ruby2JS
|
|
73
91
|
if right.type == :hash
|
74
92
|
right.children.each do |pair|
|
75
93
|
next unless Parser::AST::Node === pair.children.last
|
76
|
-
if [
|
94
|
+
if %i[block def defm async].include? pair.children.last.type
|
77
95
|
if @comments[pair.children.last]
|
78
96
|
(puts ''; singleton = false) if singleton
|
79
97
|
comments(pair.children.last).each do |comment|
|
@@ -120,22 +138,26 @@ module Ruby2JS
|
|
120
138
|
|
121
139
|
if \
|
122
140
|
anonfn and
|
123
|
-
left.children.first.to_s =~ /\A[a-zA-Z_$][a-zA-Z_$0-9]*\
|
141
|
+
left.children.first.to_s =~ /\A[a-zA-Z_$][a-zA-Z_$0-9]*\z/
|
124
142
|
then
|
125
143
|
@prop = left.children.first
|
126
144
|
parse right, :method
|
127
145
|
elsif \
|
128
|
-
es2015 and left.type == :sym and right.type == :lvar
|
129
|
-
|
146
|
+
es2015 and left.type == :sym and (right.type == :lvar or
|
147
|
+
(right.type == :send and right.children.first == nil)) and
|
148
|
+
left.children.last == right.children.last
|
130
149
|
then
|
131
150
|
parse right
|
151
|
+
elsif right.type == :defm and %i[sym str].include? left.type and es2015
|
152
|
+
@prop = left.children.first.to_s
|
153
|
+
parse right
|
132
154
|
else
|
133
155
|
if not [:str, :sym].include? left.type and es2015
|
134
156
|
put '['
|
135
157
|
parse left
|
136
158
|
put ']'
|
137
159
|
elsif \
|
138
|
-
left.children.first.to_s =~ /\A[a-zA-Z_$][a-zA-Z_$0-9]*\
|
160
|
+
left.children.first.to_s =~ /\A[a-zA-Z_$][a-zA-Z_$0-9]*\z/
|
139
161
|
then
|
140
162
|
put left.children.first
|
141
163
|
else
|
data/lib/ruby2js/converter/if.rb
CHANGED
@@ -64,10 +64,18 @@ module Ruby2JS
|
|
64
64
|
if else_block.type == :begin
|
65
65
|
else_block = s(:xnode, '', *else_block.children)
|
66
66
|
end
|
67
|
+
else
|
68
|
+
if then_block.type == :begin
|
69
|
+
then_block = s(:kwbegin, then_block)
|
70
|
+
end
|
71
|
+
|
72
|
+
if else_block.type == :begin
|
73
|
+
else_block = s(:kwbegin, else_block)
|
74
|
+
end
|
67
75
|
end
|
68
76
|
|
69
|
-
parse condition; put ' ? '; parse then_block
|
70
|
-
put ' : '; parse else_block
|
77
|
+
parse condition; put ' ? '; parse then_block, @state
|
78
|
+
put ' : '; parse else_block, @state
|
71
79
|
end
|
72
80
|
end
|
73
81
|
end
|
@@ -28,14 +28,29 @@ module Ruby2JS
|
|
28
28
|
put path.inspect
|
29
29
|
else
|
30
30
|
# import (x) from "file.js"
|
31
|
-
default_import = !args.first.is_a?(Array) && [
|
31
|
+
default_import = !args.first.is_a?(Array) && %i[const send attr str].include?(args.first.type)
|
32
|
+
|
33
|
+
if default_import and args.length > 1
|
34
|
+
parse args.shift
|
35
|
+
put ', '
|
36
|
+
default_import = false
|
37
|
+
end
|
38
|
+
|
32
39
|
args = args.first if args.first.is_a?(Array)
|
33
40
|
|
41
|
+
if args.first.type == :array
|
42
|
+
args = args.first.children
|
43
|
+
end
|
44
|
+
|
34
45
|
# handle the default name or { ConstA, Const B } portion
|
35
46
|
put "{ " unless default_import
|
36
47
|
args.each_with_index do |arg, index|
|
37
48
|
put ', ' unless index == 0
|
38
|
-
|
49
|
+
if arg.type == :str
|
50
|
+
put arg.children.first # useful for '*'
|
51
|
+
else
|
52
|
+
parse arg
|
53
|
+
end
|
39
54
|
end
|
40
55
|
put " }" unless default_import
|
41
56
|
|
@@ -43,7 +58,7 @@ module Ruby2JS
|
|
43
58
|
|
44
59
|
# should there be an as clause? e.g., import React as *
|
45
60
|
if path.is_a?(Array) && !path[0].is_a?(String) && path[0].type == :pair && path[0].children[0].children[0] == :as
|
46
|
-
put " as #{path[0].children[1].children
|
61
|
+
put " as #{path[0].children[1].children.last}"
|
47
62
|
|
48
63
|
# advance to the next kwarg, aka from
|
49
64
|
from_kwarg_position = 1
|
@@ -82,7 +97,7 @@ module Ruby2JS
|
|
82
97
|
elsif node.respond_to?(:type) && node.children[1] == :default
|
83
98
|
put 'default '
|
84
99
|
args[0] = node.children[2]
|
85
|
-
elsif node.respond_to?(:type) && node.type
|
100
|
+
elsif node.respond_to?(:type) && [:lvasgn, :casgn].include?(node.type)
|
86
101
|
if node.children[0] == :default
|
87
102
|
put 'default '
|
88
103
|
args[0] = node.children[1]
|
@@ -6,7 +6,7 @@ module Ruby2JS
|
|
6
6
|
# (resbody nil nil
|
7
7
|
# (send nil :b)) nil)
|
8
8
|
handle :rescue do |*statements|
|
9
|
-
|
9
|
+
parse s(:kwbegin, s(:rescue, *statements)), @state
|
10
10
|
end
|
11
11
|
|
12
12
|
# (kwbegin
|
@@ -19,7 +19,14 @@ module Ruby2JS
|
|
19
19
|
|
20
20
|
handle :kwbegin do |*children|
|
21
21
|
block = children.first
|
22
|
-
|
22
|
+
|
23
|
+
if @state == :expression
|
24
|
+
parse s(:send, s(:block, s(:send, nil, :proc), s(:args),
|
25
|
+
s(:begin, s(:autoreturn, *children))), :[])
|
26
|
+
return
|
27
|
+
end
|
28
|
+
|
29
|
+
if block&.type == :ensure
|
23
30
|
block, finally = block.children
|
24
31
|
else
|
25
32
|
finally = nil
|
@@ -5,12 +5,24 @@ module Ruby2JS
|
|
5
5
|
# (float 1.1)
|
6
6
|
# (str "1"))
|
7
7
|
|
8
|
-
handle :
|
8
|
+
handle :str do |value|
|
9
9
|
put value.inspect
|
10
10
|
end
|
11
11
|
|
12
|
+
handle :int, :float do |value|
|
13
|
+
put number_format(value)
|
14
|
+
end
|
15
|
+
|
12
16
|
handle :octal do |value|
|
13
|
-
put '0' + value.to_s(8)
|
17
|
+
put '0' + number_format(value.to_s(8))
|
18
|
+
end
|
19
|
+
|
20
|
+
def number_format(number)
|
21
|
+
return number.to_s unless es2021
|
22
|
+
parts = number.to_s.split('.')
|
23
|
+
parts[0] = parts[0].gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1_")
|
24
|
+
parts[1] = parts[1].gsub(/(\d\d\d)(?=\d)/, "\\1_") if parts[1]
|
25
|
+
parts.join('.')
|
14
26
|
end
|
15
27
|
end
|
16
28
|
end
|
@@ -57,7 +57,7 @@ module Ruby2JS
|
|
57
57
|
else
|
58
58
|
group = LOGICAL.include?( expr.type ) &&
|
59
59
|
operator_index( :not ) < operator_index( expr.type )
|
60
|
-
group = true if expr and expr.type
|
60
|
+
group = true if expr and %i[begin in?].include? expr.type
|
61
61
|
|
62
62
|
put '!'; put '(' if group; parse expr; put ')' if group
|
63
63
|
end
|
@@ -4,14 +4,43 @@ module Ruby2JS
|
|
4
4
|
# (module
|
5
5
|
# (const nil :A)
|
6
6
|
# (...)
|
7
|
+
#
|
8
|
+
# Note: modules_hash is an anonymous modules as a value in a hash; the
|
9
|
+
# name has already been output so should be ignored other than
|
10
|
+
# in determining the namespace.
|
11
|
+
|
12
|
+
handle :module, :module_hash do |name, *body|
|
13
|
+
extend = @namespace.enter(name)
|
14
|
+
|
15
|
+
if body == [nil]
|
16
|
+
if @ast.type == :module and not extend
|
17
|
+
parse @ast.updated(:casgn, [*name.children, s(:hash)])
|
18
|
+
else
|
19
|
+
parse @ast.updated(:hash, [])
|
20
|
+
end
|
21
|
+
|
22
|
+
@namespace.leave
|
23
|
+
return
|
24
|
+
end
|
7
25
|
|
8
|
-
handle :module do |name, *body|
|
9
26
|
while body.length == 1 and body.first.type == :begin
|
10
27
|
body = body.first.children
|
11
28
|
end
|
12
29
|
|
13
|
-
if body.length > 0 and body.all? {|child|
|
14
|
-
|
30
|
+
if body.length > 0 and body.all? {|child|
|
31
|
+
%i[def module].include? child.type or
|
32
|
+
(es2015 and child.type == :class and child.children[1] == nil)}
|
33
|
+
|
34
|
+
if extend
|
35
|
+
parse s(:assign, name, @ast.updated(:class_module,
|
36
|
+
[nil, nil, *body])), :statement
|
37
|
+
elsif @ast.type == :module_hash
|
38
|
+
parse @ast.updated(:class_module, [nil, nil, *body])
|
39
|
+
else
|
40
|
+
parse @ast.updated(:class_module, [name, nil, *body])
|
41
|
+
end
|
42
|
+
|
43
|
+
@namespace.leave
|
15
44
|
return
|
16
45
|
end
|
17
46
|
|
@@ -42,6 +71,8 @@ module Ruby2JS
|
|
42
71
|
symbols << node.children.first
|
43
72
|
elsif node.type == :class and node.children.first.children.first == nil
|
44
73
|
symbols << node.children.first.children.last
|
74
|
+
elsif node.type == :module
|
75
|
+
symbols << node.children.first.children.last
|
45
76
|
end
|
46
77
|
end
|
47
78
|
|
@@ -50,11 +81,17 @@ module Ruby2JS
|
|
50
81
|
|
51
82
|
body = s(:send, s(:block, s(:send, nil, :proc), s(:args),
|
52
83
|
s(:begin, *body)), :[])
|
53
|
-
if name
|
84
|
+
if not name
|
85
|
+
parse body
|
86
|
+
elsif extend
|
87
|
+
parse s(:assign, name, body)
|
88
|
+
elsif name.children.first == nil
|
54
89
|
parse s(:lvasgn, name.children.last, body)
|
55
90
|
else
|
56
91
|
parse s(:send, name.children.first, "#{name.children.last}=", body)
|
57
92
|
end
|
93
|
+
|
94
|
+
@namespace.leave
|
58
95
|
end
|
59
96
|
end
|
60
97
|
end
|
@@ -5,8 +5,16 @@ module Ruby2JS
|
|
5
5
|
# (int 1))
|
6
6
|
|
7
7
|
handle :next do |n=nil|
|
8
|
-
|
9
|
-
|
8
|
+
if @next_token == :return
|
9
|
+
put 'return'
|
10
|
+
if n
|
11
|
+
put ' '
|
12
|
+
parse n
|
13
|
+
end
|
14
|
+
else
|
15
|
+
raise Error.new("next argument #{ n.inspect }", @ast) if n
|
16
|
+
put @next_token.to_s
|
17
|
+
end
|
10
18
|
end
|
11
19
|
end
|
12
20
|
end
|
@@ -12,6 +12,14 @@ module Ruby2JS
|
|
12
12
|
var = s(:lvar, var.children.first) if var.type == :lvasgn
|
13
13
|
var = s(:cvar, var.children.first) if var.type == :cvasgn
|
14
14
|
|
15
|
+
if var.type == :lvar
|
16
|
+
name = var.children.first
|
17
|
+
receiver = @rbstack.map {|rb| rb[name]}.compact.last
|
18
|
+
if receiver
|
19
|
+
var = s(:attr, nil, name)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
15
23
|
if \
|
16
24
|
[:+, :-].include?(op) and value.type==:int and
|
17
25
|
(value.children==[1] or value.children==[-1])
|
@@ -14,7 +14,8 @@ module Ruby2JS
|
|
14
14
|
|
15
15
|
EXPRESSIONS = [ :array, :float, :hash, :int, :lvar, :nil, :send, :attr,
|
16
16
|
:str, :sym, :dstr, :dsym, :cvar, :ivar, :zsuper, :super, :or, :and,
|
17
|
-
:block, :const, :true, :false, :xnode, :taglit, :self
|
17
|
+
:block, :const, :true, :false, :xnode, :taglit, :self,
|
18
|
+
:op_asgn, :and_asgn, :or_asgn ]
|
18
19
|
|
19
20
|
handle :autoreturn do |*statements|
|
20
21
|
return if statements == [nil]
|
@@ -9,11 +9,12 @@ module Ruby2JS
|
|
9
9
|
# (sendw nil :puts
|
10
10
|
# (int 1))
|
11
11
|
|
12
|
-
# Note: attr, sendw, and await are only generated by filters. Attr forces
|
12
|
+
# Note: attr, sendw, send!, and await are only generated by filters. Attr forces
|
13
13
|
# interpretation as an attribute vs a function call with zero parameters.
|
14
|
+
# send! forces interpretation as a method call even with zero parameters.
|
14
15
|
# Sendw forces parameters to be placed on separate lines.
|
15
16
|
|
16
|
-
handle :send, :sendw, :await, :attr, :call do |receiver, method, *args|
|
17
|
+
handle :send, :sendw, :send!, :await, :attr, :call do |receiver, method, *args|
|
17
18
|
ast = @ast
|
18
19
|
|
19
20
|
if \
|
@@ -40,12 +41,26 @@ module Ruby2JS
|
|
40
41
|
# strip '!' and '?' decorations
|
41
42
|
method = method.to_s[0..-2] if method =~ /\w[!?]$/
|
42
43
|
|
44
|
+
# anonymous class
|
45
|
+
if method == :new and receiver and receiver.children == [nil, :Class] and
|
46
|
+
args.last.type == :def and args.last.children.first == nil
|
47
|
+
|
48
|
+
parent = (args.length > 1) ? args.first : nil
|
49
|
+
|
50
|
+
if es2015
|
51
|
+
return parse s(:class2, nil, parent, *args.last.children[2..-1])
|
52
|
+
else
|
53
|
+
return parse s(:kwbegin, s(:class, s(:const, nil, :$$), parent,
|
54
|
+
*args.last.children[2..-1]), s(:const, nil, :$$))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
43
58
|
# three ways to define anonymous functions
|
44
59
|
if method == :new and receiver and receiver.children == [nil, :Proc]
|
45
60
|
return parse args.first, @state
|
46
61
|
|
47
62
|
elsif not receiver and [:lambda, :proc].include? method
|
48
|
-
if method == :lambda
|
63
|
+
if method == :lambda and @state != :statement
|
49
64
|
return parse s(args.first.type, *args.first.children[0..-2],
|
50
65
|
s(:autoreturn, args.first.children[-1])), @state
|
51
66
|
else
|
@@ -60,10 +75,17 @@ module Ruby2JS
|
|
60
75
|
(es2015 || @state == :statement ? group(receiver) : parse(receiver))
|
61
76
|
put '('; parse_all(*args, join: ', '); put ')'
|
62
77
|
return
|
78
|
+
elsif not t2 and m2 == :async and args2.length == 0
|
79
|
+
put '('; parse receiver; put ')()'
|
80
|
+
return
|
63
81
|
end
|
64
82
|
end
|
65
83
|
|
66
84
|
# async/await support
|
85
|
+
# map "await x do...end" to "await x {...}" due to precedence rules
|
86
|
+
if method == :await and es2017 and receiver == nil and args.length == 2 and args[1].type == :def
|
87
|
+
args = [s(:block, args.first, *args.last.children[1..-1])]
|
88
|
+
end
|
67
89
|
if es2017 and receiver == nil and args.length == 1
|
68
90
|
if method == :async
|
69
91
|
if args.first.type == :def
|
@@ -74,6 +96,15 @@ module Ruby2JS
|
|
74
96
|
# async def o.m(x) {...}
|
75
97
|
return parse args.first.updated :asyncs
|
76
98
|
|
99
|
+
elsif args.first.type == :send and
|
100
|
+
args.first.children.first.type == :block and
|
101
|
+
args.first.children.last == :[]
|
102
|
+
|
103
|
+
put '(async '
|
104
|
+
parse args.first.children.first, :statement
|
105
|
+
put ')()'
|
106
|
+
return
|
107
|
+
|
77
108
|
elsif args.first.type == :block
|
78
109
|
block = args.first
|
79
110
|
|
@@ -117,8 +148,13 @@ module Ruby2JS
|
|
117
148
|
|
118
149
|
# resolve anonymous receivers against rbstack
|
119
150
|
receiver ||= @rbstack.map {|rb| rb[method]}.compact.last
|
151
|
+
autobind = nil
|
120
152
|
|
121
153
|
if receiver
|
154
|
+
if receiver.type == :autobind
|
155
|
+
autobind = receiver = receiver.children.first
|
156
|
+
end
|
157
|
+
|
122
158
|
group_receiver = receiver.type == :send &&
|
123
159
|
op_index < operator_index( receiver.children[1] ) if receiver
|
124
160
|
group_receiver ||= GROUP_OPERATORS.include? receiver.type
|
@@ -137,6 +173,8 @@ module Ruby2JS
|
|
137
173
|
group_target ||= GROUP_OPERATORS.include? target.type
|
138
174
|
end
|
139
175
|
|
176
|
+
put 'await ' if @ast.type == :await
|
177
|
+
|
140
178
|
if method == :!
|
141
179
|
parse s(:not, receiver)
|
142
180
|
|
@@ -152,7 +190,7 @@ module Ruby2JS
|
|
152
190
|
end
|
153
191
|
|
154
192
|
elsif method == :[]=
|
155
|
-
|
193
|
+
(group_receiver ? group(receiver) : parse(receiver))
|
156
194
|
if \
|
157
195
|
args.length == 2 and [:str, :sym].include? args.first.type and
|
158
196
|
args.first.children.first.to_s =~ /^[a-zA-Z]\w*$/
|
@@ -175,9 +213,15 @@ module Ruby2JS
|
|
175
213
|
receiver.type == :send and
|
176
214
|
receiver.children[1] == :+@ and
|
177
215
|
Parser::AST::Node === receiver.children[0] and
|
178
|
-
receiver.children[0].type
|
216
|
+
%i(class module).include? receiver.children[0].type
|
179
217
|
then
|
180
|
-
|
218
|
+
if receiver.children[0].type == :class
|
219
|
+
parse receiver.children[0].updated(:class_extend)
|
220
|
+
else
|
221
|
+
mod = receiver.children[0]
|
222
|
+
parse s(:assign, mod.children[0],
|
223
|
+
mod.updated(nil, [nil, *mod.children[1..-1]]))
|
224
|
+
end
|
181
225
|
else
|
182
226
|
put method.to_s[0]; parse receiver
|
183
227
|
end
|
@@ -277,10 +321,23 @@ module Ruby2JS
|
|
277
321
|
elsif method == :typeof and receiver == nil
|
278
322
|
put 'typeof '; parse args.first
|
279
323
|
|
324
|
+
elsif ast.children[1] == :is_a? and receiver and args.length == 1
|
325
|
+
parse receiver; put ' instanceof '; parse args.first
|
326
|
+
|
327
|
+
elsif ast.children[1] == :kind_of? and receiver and args.length == 1
|
328
|
+
parse receiver; put ' instanceof '; parse args.first
|
329
|
+
|
330
|
+
elsif ast.children[1] == :instance_of? and receiver and args.length == 1
|
331
|
+
parse s(:send, s(:attr, receiver, :constructor), :==, args.first)
|
332
|
+
|
280
333
|
else
|
281
|
-
|
334
|
+
if method == :bind and receiver&.type == :send
|
335
|
+
if receiver.children.length == 2 and receiver.children.first == nil
|
336
|
+
receiver = receiver.updated(:attr) # prevent autobind
|
337
|
+
end
|
338
|
+
end
|
282
339
|
|
283
|
-
if not ast.is_method?
|
340
|
+
if not ast.is_method? and ast.type != :send!
|
284
341
|
if receiver
|
285
342
|
(group_receiver ? group(receiver) : parse(receiver))
|
286
343
|
put ".#{ method }"
|
@@ -302,6 +359,14 @@ module Ruby2JS
|
|
302
359
|
compact { puts "("; parse_all(*args, join: ",#@ws"); sput ')' }
|
303
360
|
end
|
304
361
|
end
|
362
|
+
|
363
|
+
if autobind and not ast.is_method? and ast.type != :attr
|
364
|
+
if @state == :statement
|
365
|
+
put '()'
|
366
|
+
else
|
367
|
+
put '.bind('; parse(autobind); put ')'
|
368
|
+
end
|
369
|
+
end
|
305
370
|
end
|
306
371
|
end
|
307
372
|
|