ruby2js 4.0.0 → 4.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Build Status](https://travis-ci.org/rubys/ruby2js.svg)](https://travis-ci.org/rubys/ruby2js)
|
7
6
|
[![Gem Version](https://badge.fury.io/rb/ruby2js.svg)](https://badge.fury.io/rb/ruby2js)
|
8
7
|
[![Gitter](https://badges.gitter.im/ruby2js/community.svg)](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
|