ruby2js 4.0.0 → 4.0.5
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 +0 -1
- data/lib/ruby2js.rb +16 -3
- data/lib/ruby2js/converter.rb +31 -0
- data/lib/ruby2js/converter/args.rb +6 -1
- data/lib/ruby2js/converter/class.rb +3 -0
- data/lib/ruby2js/converter/class2.rb +8 -5
- data/lib/ruby2js/converter/def.rb +8 -2
- data/lib/ruby2js/converter/dstr.rb +3 -1
- data/lib/ruby2js/converter/for.rb +1 -1
- data/lib/ruby2js/converter/hash.rb +19 -1
- data/lib/ruby2js/converter/logical.rb +1 -1
- data/lib/ruby2js/converter/next.rb +10 -2
- data/lib/ruby2js/converter/redo.rb +14 -0
- data/lib/ruby2js/converter/return.rb +2 -1
- data/lib/ruby2js/converter/send.rb +30 -4
- data/lib/ruby2js/converter/taglit.rb +9 -2
- data/lib/ruby2js/converter/while.rb +1 -1
- data/lib/ruby2js/converter/whilepost.rb +1 -1
- data/lib/ruby2js/converter/xstr.rb +1 -2
- data/lib/ruby2js/filter/camelCase.rb +2 -0
- data/lib/ruby2js/filter/functions.rb +39 -11
- data/lib/ruby2js/filter/lit-element.rb +202 -0
- data/lib/ruby2js/filter/react.rb +6 -16
- data/lib/ruby2js/filter/require.rb +2 -6
- data/lib/ruby2js/filter/stimulus.rb +4 -2
- data/lib/ruby2js/filter/tagged_templates.rb +4 -2
- data/lib/ruby2js/jsx.rb +19 -1
- data/lib/ruby2js/rails.rb +6 -59
- data/lib/ruby2js/serializer.rb +16 -11
- data/lib/ruby2js/sprockets.rb +40 -0
- data/lib/ruby2js/version.rb +1 -1
- data/lib/tasks/README.md +4 -0
- data/lib/tasks/install/app/javascript/elements/index.js +2 -0
- data/lib/tasks/install/litelement.rb +9 -0
- data/lib/tasks/install/react.rb +2 -0
- data/lib/tasks/install/stimulus-sprockets.rb +32 -0
- data/lib/tasks/install/stimulus-webpacker.rb +5 -0
- data/lib/tasks/install/webpacker.rb +97 -0
- data/lib/tasks/nodetest.js +47 -0
- data/lib/tasks/ruby2js_tasks.rake +42 -0
- data/ruby2js.gemspec +1 -1
- metadata +18 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6728e4201e77b477a9203551b57de3f23b36077f6012061233d4b072d92886b9
|
4
|
+
data.tar.gz: 7d5e6ef7aa5b9add1477b3cc642cc55714a657f7f962dbb6dd7af6688d45cfb0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 321dc88308946ff626914ceb87fa93f93bec4f5cde0b660cab75d7df46b52f9ca63da830e7fab4f070b989586ef468b3cdf9d8f682f64b44ee06fef9df5230f7
|
7
|
+
data.tar.gz: 22f5161f0bc03c294fbfd3f32be407030fea293985e1eff4c7d0fc464bd57aaa6a3cfc70e1bf9ed13e9bbb0dbbac9f394b860e76df52ae236b494accd86c840b
|
data/README.md
CHANGED
@@ -3,7 +3,6 @@ Ruby2JS
|
|
3
3
|
|
4
4
|
Minimal yet extensible Ruby to JavaScript conversion.
|
5
5
|
|
6
|
-
[](https://travis-ci.org/rubys/ruby2js)
|
7
6
|
[](https://badge.fury.io/rb/ruby2js)
|
8
7
|
[](https://gitter.im/ruby2js/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
9
8
|
|
data/lib/ruby2js.rb
CHANGED
@@ -92,6 +92,17 @@ module Ruby2JS
|
|
92
92
|
include_only(options[:include_only]) if options[:include_only]
|
93
93
|
include(options[:include]) if options[:include]
|
94
94
|
exclude(options[:exclude]) if options[:exclude]
|
95
|
+
|
96
|
+
filters = options[:filters] || DEFAULTS
|
97
|
+
@modules_enabled =
|
98
|
+
(defined? Ruby2JS::Filter::ESM and
|
99
|
+
filters.include? Ruby2JS::Filter::ESM) or
|
100
|
+
(defined? Ruby2JS::Filter::CJS and
|
101
|
+
filters.include? Ruby2JS::Filter::CJS)
|
102
|
+
end
|
103
|
+
|
104
|
+
def modules_enabled?
|
105
|
+
@modules_enabled
|
95
106
|
end
|
96
107
|
|
97
108
|
def es2015
|
@@ -169,7 +180,7 @@ module Ruby2JS
|
|
169
180
|
def on_xnode(node); end
|
170
181
|
def on_export(node); end
|
171
182
|
def on_import(node); end
|
172
|
-
def on_taglit(node); end
|
183
|
+
def on_taglit(node); on_pair(node); end
|
173
184
|
|
174
185
|
# provide a method so filters can call 'super'
|
175
186
|
def on_sym(node); node; end
|
@@ -182,10 +193,12 @@ module Ruby2JS
|
|
182
193
|
return on_block s(:block, s(:send, *node.children[0..-2]),
|
183
194
|
s(:args, s(:arg, :a), s(:arg, :b)), s(:return,
|
184
195
|
process(s(:send, s(:lvar, :a), method, s(:lvar, :b)))))
|
185
|
-
|
196
|
+
elsif node.children.last.children.first.type == :sym
|
186
197
|
return on_block s(:block, s(:send, *node.children[0..-2]),
|
187
198
|
s(:args, s(:arg, :item)), s(:return,
|
188
199
|
process(s(:attr, s(:lvar, :item), method))))
|
200
|
+
else
|
201
|
+
super
|
189
202
|
end
|
190
203
|
end
|
191
204
|
super
|
@@ -277,7 +290,7 @@ module Ruby2JS
|
|
277
290
|
|
278
291
|
def self.parse(source, file=nil, line=1)
|
279
292
|
buffer = Parser::Source::Buffer.new(file, line)
|
280
|
-
buffer.source = source.encode('
|
293
|
+
buffer.source = source.encode('UTF-8')
|
281
294
|
parser = Parser::CurrentRuby.new
|
282
295
|
parser.diagnostics.all_errors_are_fatal = true
|
283
296
|
parser.diagnostics.consumer = lambda {|diagnostic| nil}
|
data/lib/ruby2js/converter.rb
CHANGED
@@ -60,12 +60,14 @@ module Ruby2JS
|
|
60
60
|
@class_parent = nil
|
61
61
|
@class_name = nil
|
62
62
|
@jsx = false
|
63
|
+
@autobind = true
|
63
64
|
|
64
65
|
@eslevel = :es5
|
65
66
|
@strict = false
|
66
67
|
@comparison = :equality
|
67
68
|
@or = :logical
|
68
69
|
@underscored_private = true
|
70
|
+
@redoable = false
|
69
71
|
end
|
70
72
|
|
71
73
|
def width=(width)
|
@@ -243,6 +245,34 @@ module Ruby2JS
|
|
243
245
|
end
|
244
246
|
end
|
245
247
|
|
248
|
+
def redoable(block)
|
249
|
+
save_redoable = @redoable
|
250
|
+
|
251
|
+
has_redo = proc do |node|
|
252
|
+
node.children.any? do |child|
|
253
|
+
next false unless child.is_a? Parser::AST::Node
|
254
|
+
next true if child.type == :redo
|
255
|
+
next false if %i[for while while_post until until_post].include? child.type
|
256
|
+
has_redo[child]
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
@redoable = has_redo[@ast]
|
261
|
+
|
262
|
+
if @redoable
|
263
|
+
put es2015 ? 'let ' : 'var '
|
264
|
+
put "redo$#@sep"
|
265
|
+
puts 'do {'
|
266
|
+
put "redo$ = false#@sep"
|
267
|
+
scope block
|
268
|
+
put "#@nl} while(redo$)"
|
269
|
+
else
|
270
|
+
scope block
|
271
|
+
end
|
272
|
+
ensure
|
273
|
+
@redoable = save_redoable
|
274
|
+
end
|
275
|
+
|
246
276
|
def timestamp(file)
|
247
277
|
super
|
248
278
|
|
@@ -335,6 +365,7 @@ require 'ruby2js/converter/nil'
|
|
335
365
|
require 'ruby2js/converter/nthref'
|
336
366
|
require 'ruby2js/converter/opasgn'
|
337
367
|
require 'ruby2js/converter/prototype'
|
368
|
+
require 'ruby2js/converter/redo'
|
338
369
|
require 'ruby2js/converter/regexp'
|
339
370
|
require 'ruby2js/converter/return'
|
340
371
|
require 'ruby2js/converter/self'
|
@@ -30,13 +30,18 @@ module Ruby2JS
|
|
30
30
|
if kw.type == :kwarg
|
31
31
|
put kw.children.first
|
32
32
|
elsif kw.type == :kwoptarg
|
33
|
-
put kw.children.first
|
33
|
+
put kw.children.first
|
34
|
+
unless kw.children.last == s(:send, nil, :undefined)
|
35
|
+
put '='; parse kw.children.last
|
36
|
+
end
|
34
37
|
elsif kw.type == :kwrestarg
|
35
38
|
raise 'Rest arg requires ES2018' unless es2018
|
36
39
|
put '...'; put kw.children.first
|
37
40
|
end
|
38
41
|
end
|
39
42
|
put ' }'
|
43
|
+
|
44
|
+
put ' = {}' unless kwargs.any? {|kw| kw.type == :kwarg}
|
40
45
|
end
|
41
46
|
end
|
42
47
|
|
@@ -114,6 +114,7 @@ module Ruby2JS
|
|
114
114
|
if m.children[1] == :attr_accessor
|
115
115
|
m.children[2..-1].map do |child_sym|
|
116
116
|
var = child_sym.children.first
|
117
|
+
visible[var] = s(:self)
|
117
118
|
s(:prop, s(:attr, name, :prototype), var =>
|
118
119
|
{enumerable: s(:true), configurable: s(:true),
|
119
120
|
get: s(:block, s(:send, nil, :proc), s(:args),
|
@@ -124,6 +125,7 @@ module Ruby2JS
|
|
124
125
|
elsif m.children[1] == :attr_reader
|
125
126
|
m.children[2..-1].map do |child_sym|
|
126
127
|
var = child_sym.children.first
|
128
|
+
visible[var] = s(:self)
|
127
129
|
s(:prop, s(:attr, name, :prototype), var =>
|
128
130
|
{get: s(:block, s(:send, nil, :proc), s(:args),
|
129
131
|
s(:return, s(:ivar, :"@#{var}"))),
|
@@ -133,6 +135,7 @@ module Ruby2JS
|
|
133
135
|
elsif m.children[1] == :attr_writer
|
134
136
|
m.children[2..-1].map do |child_sym|
|
135
137
|
var = child_sym.children.first
|
138
|
+
visible[var] = s(:self)
|
136
139
|
s(:prop, s(:attr, name, :prototype), var =>
|
137
140
|
{set: s(:block, s(:send, nil, :proc), s(:args, s(:arg, var)),
|
138
141
|
s(:ivasgn, :"@#{var}", s(:lvar, var))),
|
@@ -156,7 +156,7 @@ module Ruby2JS
|
|
156
156
|
end
|
157
157
|
end
|
158
158
|
|
159
|
-
if
|
159
|
+
if %i[def defm deff async].include? m.type
|
160
160
|
@prop = m.children.first
|
161
161
|
|
162
162
|
if @prop == :initialize and !@rbstack.last[:initialize]
|
@@ -190,11 +190,11 @@ module Ruby2JS
|
|
190
190
|
end
|
191
191
|
|
192
192
|
elsif \
|
193
|
-
[:defs, :asyncs].include? m.type and m.children.first.type == :self
|
193
|
+
[:defs, :defp, :asyncs].include? m.type and m.children.first.type == :self
|
194
194
|
then
|
195
195
|
|
196
196
|
@prop = "static #{m.children[1]}"
|
197
|
-
if not m.is_method?
|
197
|
+
if m.type == :defp or not m.is_method?
|
198
198
|
@prop = "static get #{m.children[1]}"
|
199
199
|
m = m.updated(m.type, [*m.children[0..2],
|
200
200
|
s(:autoreturn, m.children[3])])
|
@@ -206,7 +206,7 @@ module Ruby2JS
|
|
206
206
|
@prop = "static #{m.children[1]}"
|
207
207
|
end
|
208
208
|
|
209
|
-
@prop.sub
|
209
|
+
@prop = @prop.sub('static', 'static async') if m.type == :asyncs
|
210
210
|
|
211
211
|
m = m.updated(:def, m.children[1..3])
|
212
212
|
begin
|
@@ -224,6 +224,7 @@ module Ruby2JS
|
|
224
224
|
m.children[2..-1].each_with_index do |child_sym, index2|
|
225
225
|
put @sep unless index2 == 0
|
226
226
|
var = child_sym.children.first
|
227
|
+
@rbstack.last[var] = s(:self)
|
227
228
|
put "get #{var}() {#{@nl}return this.#{p}#{var}#@nl}#@sep"
|
228
229
|
put "set #{var}(#{var}) {#{@nl}this.#{p}#{var} = #{var}#@nl}"
|
229
230
|
end
|
@@ -231,12 +232,14 @@ module Ruby2JS
|
|
231
232
|
m.children[2..-1].each_with_index do |child_sym, index2|
|
232
233
|
put @sep unless index2 == 0
|
233
234
|
var = child_sym.children.first
|
235
|
+
@rbstack.last[var] = s(:self)
|
234
236
|
put "get #{var}() {#{@nl}return this.#{p}#{var}#@nl}"
|
235
237
|
end
|
236
238
|
elsif m.children[1] == :attr_writer
|
237
239
|
m.children[2..-1].each_with_index do |child_sym, index2|
|
238
240
|
put @sep unless index2 == 0
|
239
241
|
var = child_sym.children.first
|
242
|
+
@rbstack.last[var] = s(:self)
|
240
243
|
put "set #{var}(#{var}) {#{@nl}this.#{p}#{var} = #{var}#@nl}"
|
241
244
|
end
|
242
245
|
elsif [:private, :protected, :public].include? m.children[1]
|
@@ -276,7 +279,7 @@ module Ruby2JS
|
|
276
279
|
if m.type == :casgn and m.children[0] == nil
|
277
280
|
@rbstack.last[m.children[1]] = name
|
278
281
|
|
279
|
-
if
|
282
|
+
if es2022
|
280
283
|
put 'static '; put m.children[1].to_s; put ' = '
|
281
284
|
parse m.children[2]
|
282
285
|
skipped = false
|
@@ -135,14 +135,20 @@ module Ruby2JS
|
|
135
135
|
style = :statement
|
136
136
|
end
|
137
137
|
|
138
|
-
if args.children.length == 1 and args.children.first.type
|
138
|
+
if args.children.length == 1 and args.children.first.type == :arg and style == :expression
|
139
139
|
parse args; put ' => '
|
140
140
|
else
|
141
141
|
put '('; parse args; put ') => '
|
142
142
|
end
|
143
143
|
|
144
144
|
if style == :expression
|
145
|
-
expr.type == :
|
145
|
+
if expr.type == :taglit
|
146
|
+
parse expr
|
147
|
+
elsif expr.type == :hash
|
148
|
+
group(expr)
|
149
|
+
else
|
150
|
+
wrap('(', ')') { parse(expr) }
|
151
|
+
end
|
146
152
|
elsif body.type == :begin and body.children.length == 0
|
147
153
|
put "{}"
|
148
154
|
else
|
@@ -25,7 +25,9 @@ module Ruby2JS
|
|
25
25
|
put '`'
|
26
26
|
children.each do |child|
|
27
27
|
if child.type == :str
|
28
|
-
str = child.children.first.inspect[1..-2].
|
28
|
+
str = child.children.first.inspect[1..-2].
|
29
|
+
gsub('${', '$\{').gsub('`', '\\\`')
|
30
|
+
str = str.gsub(/\\"/, '"') unless str.include? '\\\\'
|
29
31
|
if heredoc
|
30
32
|
put! str.gsub("\\n", "\n")
|
31
33
|
else
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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, :taglit, :gvar ]
|
18
19
|
|
19
20
|
handle :autoreturn do |*statements|
|
20
21
|
return if statements == [nil]
|
@@ -60,7 +60,7 @@ module Ruby2JS
|
|
60
60
|
return parse args.first, @state
|
61
61
|
|
62
62
|
elsif not receiver and [:lambda, :proc].include? method
|
63
|
-
if method == :lambda
|
63
|
+
if method == :lambda and @state != :statement
|
64
64
|
return parse s(args.first.type, *args.first.children[0..-2],
|
65
65
|
s(:autoreturn, args.first.children[-1])), @state
|
66
66
|
else
|
@@ -75,10 +75,17 @@ module Ruby2JS
|
|
75
75
|
(es2015 || @state == :statement ? group(receiver) : parse(receiver))
|
76
76
|
put '('; parse_all(*args, join: ', '); put ')'
|
77
77
|
return
|
78
|
+
elsif not t2 and m2 == :async and args2.length == 0
|
79
|
+
put '('; parse receiver; put ')()'
|
80
|
+
return
|
78
81
|
end
|
79
82
|
end
|
80
83
|
|
81
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
|
82
89
|
if es2017 and receiver == nil and args.length == 1
|
83
90
|
if method == :async
|
84
91
|
if args.first.type == :def
|
@@ -89,6 +96,15 @@ module Ruby2JS
|
|
89
96
|
# async def o.m(x) {...}
|
90
97
|
return parse args.first.updated :asyncs
|
91
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
|
+
|
92
108
|
elsif args.first.type == :block
|
93
109
|
block = args.first
|
94
110
|
|
@@ -137,6 +153,7 @@ module Ruby2JS
|
|
137
153
|
if receiver
|
138
154
|
if receiver.type == :autobind
|
139
155
|
autobind = receiver = receiver.children.first
|
156
|
+
autobind = nil unless @autobind
|
140
157
|
end
|
141
158
|
|
142
159
|
group_receiver = receiver.type == :send &&
|
@@ -157,6 +174,8 @@ module Ruby2JS
|
|
157
174
|
group_target ||= GROUP_OPERATORS.include? target.type
|
158
175
|
end
|
159
176
|
|
177
|
+
put 'await ' if @ast.type == :await
|
178
|
+
|
160
179
|
if method == :!
|
161
180
|
parse s(:not, receiver)
|
162
181
|
|
@@ -172,7 +191,7 @@ module Ruby2JS
|
|
172
191
|
end
|
173
192
|
|
174
193
|
elsif method == :[]=
|
175
|
-
|
194
|
+
(group_receiver ? group(receiver) : parse(receiver))
|
176
195
|
if \
|
177
196
|
args.length == 2 and [:str, :sym].include? args.first.type and
|
178
197
|
args.first.children.first.to_s =~ /^[a-zA-Z]\w*$/
|
@@ -303,9 +322,16 @@ module Ruby2JS
|
|
303
322
|
elsif method == :typeof and receiver == nil
|
304
323
|
put 'typeof '; parse args.first
|
305
324
|
|
306
|
-
|
307
|
-
put '
|
325
|
+
elsif ast.children[1] == :is_a? and receiver and args.length == 1
|
326
|
+
parse receiver; put ' instanceof '; parse args.first
|
327
|
+
|
328
|
+
elsif ast.children[1] == :kind_of? and receiver and args.length == 1
|
329
|
+
parse receiver; put ' instanceof '; parse args.first
|
308
330
|
|
331
|
+
elsif ast.children[1] == :instance_of? and receiver and args.length == 1
|
332
|
+
parse s(:send, s(:attr, receiver, :constructor), :==, args.first)
|
333
|
+
|
334
|
+
else
|
309
335
|
if method == :bind and receiver&.type == :send
|
310
336
|
if receiver.children.length == 2 and receiver.children.first == nil
|
311
337
|
receiver = receiver.updated(:attr) # prevent autobind
|