ruby2js 3.1.1 → 3.3.2
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 +52 -11
- data/lib/ruby2js.rb +14 -2
- data/lib/ruby2js/converter.rb +11 -3
- data/lib/ruby2js/converter/args.rb +1 -1
- data/lib/ruby2js/converter/block.rb +2 -2
- data/lib/ruby2js/converter/class.rb +4 -3
- data/lib/ruby2js/converter/class2.rb +38 -9
- data/lib/ruby2js/converter/cvar.rb +1 -1
- data/lib/ruby2js/converter/cvasgn.rb +1 -1
- data/lib/ruby2js/converter/def.rb +2 -2
- data/lib/ruby2js/converter/for.rb +7 -0
- data/lib/ruby2js/converter/hash.rb +3 -3
- data/lib/ruby2js/converter/if.rb +13 -2
- data/lib/ruby2js/converter/import.rb +38 -0
- data/lib/ruby2js/converter/logical.rb +46 -1
- data/lib/ruby2js/converter/opasgn.rb +5 -2
- data/lib/ruby2js/converter/regexp.rb +27 -2
- data/lib/ruby2js/converter/return.rb +1 -1
- data/lib/ruby2js/converter/send.rb +53 -27
- data/lib/ruby2js/converter/super.rb +15 -9
- data/lib/ruby2js/converter/xnode.rb +89 -0
- data/lib/ruby2js/es2021.rb +5 -0
- data/lib/ruby2js/es2021/strict.rb +3 -0
- data/lib/ruby2js/filter/cjs.rb +2 -2
- data/lib/ruby2js/filter/esm.rb +72 -0
- data/lib/ruby2js/filter/functions.rb +191 -41
- data/lib/ruby2js/filter/matchAll.rb +49 -0
- data/lib/ruby2js/filter/node.rb +18 -10
- data/lib/ruby2js/filter/nokogiri.rb +13 -13
- data/lib/ruby2js/filter/react.rb +190 -30
- data/lib/ruby2js/filter/require.rb +1 -4
- data/lib/ruby2js/filter/rubyjs.rb +4 -4
- data/lib/ruby2js/filter/vue.rb +40 -15
- data/lib/ruby2js/filter/wunderbar.rb +63 -0
- data/lib/ruby2js/serializer.rb +25 -11
- data/lib/ruby2js/version.rb +2 -2
- data/ruby2js.gemspec +2 -11
- metadata +24 -4
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'ruby2js'
|
2
|
+
|
3
|
+
module Ruby2JS
|
4
|
+
module Filter
|
5
|
+
module MatchAll
|
6
|
+
include SEXP
|
7
|
+
|
8
|
+
# ensure matchAll is before Functions in the filter list
|
9
|
+
def self.reorder(filters)
|
10
|
+
if \
|
11
|
+
defined? Ruby2JS::Filter::Functions and
|
12
|
+
filters.include? Ruby2JS::Filter::Functions
|
13
|
+
then
|
14
|
+
filters = filters.dup
|
15
|
+
matchAll = filters.delete(Ruby2JS::Filter::MatchAll)
|
16
|
+
filters.insert filters.index(Ruby2JS::Filter::Functions), matchAll
|
17
|
+
else
|
18
|
+
filters
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def on_block(node)
|
23
|
+
return super if es2020
|
24
|
+
|
25
|
+
# only process each/forEach blocks
|
26
|
+
call = node.children.first
|
27
|
+
return super unless
|
28
|
+
[:each, :forEach].include? call.children[1] and
|
29
|
+
call.children.first.type == :send and
|
30
|
+
node.children[1].children.length == 1
|
31
|
+
|
32
|
+
# only process matchAll requests with simple expressions
|
33
|
+
call = call.children.first
|
34
|
+
return super unless
|
35
|
+
call.children[1] == :matchAll and
|
36
|
+
call.children[2].type == :send and
|
37
|
+
call.children[2].children.first == nil and
|
38
|
+
call.children[2].children.length == 2
|
39
|
+
|
40
|
+
process s(:while,
|
41
|
+
s(:lvasgn, node.children[1].children[0].children[0],
|
42
|
+
s(:send, call.children[2], :exec, call.children.first)),
|
43
|
+
node.children[2])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
DEFAULTS.push MatchAll
|
48
|
+
end
|
49
|
+
end
|
data/lib/ruby2js/filter/node.rb
CHANGED
@@ -56,7 +56,7 @@ module Ruby2JS
|
|
56
56
|
s(:hash, s(:pair, s(:sym, :stdio), s(:str, 'inherit'))))
|
57
57
|
end
|
58
58
|
|
59
|
-
elsif
|
59
|
+
elsif \
|
60
60
|
method == :require and args.length == 1 and
|
61
61
|
args.first.type == :str and
|
62
62
|
%w(fileutils tmpdir).include? args.first.children.first
|
@@ -67,7 +67,7 @@ module Ruby2JS
|
|
67
67
|
super
|
68
68
|
end
|
69
69
|
|
70
|
-
elsif
|
70
|
+
elsif \
|
71
71
|
[:File, :IO].include? target.children.last and
|
72
72
|
target.type == :const and target.children.first == nil
|
73
73
|
then
|
@@ -99,7 +99,7 @@ module Ruby2JS
|
|
99
99
|
@node_setup << :fs
|
100
100
|
S(:send, s(:attr, nil, :fs), :renameSync, *process_all(args))
|
101
101
|
|
102
|
-
elsif
|
102
|
+
elsif \
|
103
103
|
[:chmod, :lchmod].include? method and
|
104
104
|
args.length > 1 and args.first.type == :int
|
105
105
|
then
|
@@ -110,7 +110,7 @@ module Ruby2JS
|
|
110
110
|
s(:octal, *args.first.children))
|
111
111
|
})
|
112
112
|
|
113
|
-
elsif
|
113
|
+
elsif \
|
114
114
|
[:chown, :lchown].include? method and args.length > 2 and
|
115
115
|
args[0].type == :int and args[1].type == :int
|
116
116
|
then
|
@@ -148,7 +148,7 @@ module Ruby2JS
|
|
148
148
|
super
|
149
149
|
end
|
150
150
|
|
151
|
-
elsif
|
151
|
+
elsif \
|
152
152
|
target.children.last == :FileUtils and
|
153
153
|
target.type == :const and target.children.first == nil
|
154
154
|
then
|
@@ -201,7 +201,7 @@ module Ruby2JS
|
|
201
201
|
s(:send, s(:attr, nil, :fs), :unlinkSync, process(file))
|
202
202
|
})
|
203
203
|
|
204
|
-
elsif
|
204
|
+
elsif \
|
205
205
|
method == :chmod and args.length == 2 and args.first.type == :int
|
206
206
|
then
|
207
207
|
@node_setup << :fs
|
@@ -211,7 +211,7 @@ module Ruby2JS
|
|
211
211
|
s(:octal, *args.first.children))
|
212
212
|
})
|
213
213
|
|
214
|
-
elsif
|
214
|
+
elsif \
|
215
215
|
method == :chown and args.length == 3 and
|
216
216
|
args[0].type == :int and args[1].type == :int
|
217
217
|
then
|
@@ -233,7 +233,7 @@ module Ruby2JS
|
|
233
233
|
super
|
234
234
|
end
|
235
235
|
|
236
|
-
elsif
|
236
|
+
elsif \
|
237
237
|
target.type == :const and target.children.first == nil and
|
238
238
|
target.children.last == :Dir
|
239
239
|
then
|
@@ -274,7 +274,7 @@ module Ruby2JS
|
|
274
274
|
call = node.children.first
|
275
275
|
target, method, *args = call.children
|
276
276
|
|
277
|
-
if
|
277
|
+
if \
|
278
278
|
method == :chdir and args.length == 1 and
|
279
279
|
target.children.last == :Dir and
|
280
280
|
target.type == :const and target.children.first == nil
|
@@ -324,7 +324,15 @@ module Ruby2JS
|
|
324
324
|
children = node.children.dup
|
325
325
|
command = children.shift
|
326
326
|
while children.length > 0
|
327
|
-
|
327
|
+
child = children.shift
|
328
|
+
if \
|
329
|
+
child.type == :begin and child.children.length == 1 and
|
330
|
+
child.children.first.type == :send and
|
331
|
+
child.children.first.children.first == nil
|
332
|
+
then
|
333
|
+
child = child.children.first
|
334
|
+
end
|
335
|
+
command = s(:send, command, :+, child)
|
328
336
|
end
|
329
337
|
|
330
338
|
s(:send, s(:attr, nil, :child_process), :execSync, command,
|
@@ -36,7 +36,7 @@ module Ruby2JS
|
|
36
36
|
return super if excluded?(method)
|
37
37
|
|
38
38
|
if target == nil
|
39
|
-
if
|
39
|
+
if \
|
40
40
|
method == :require and args.length == 1 and
|
41
41
|
args.first.type == :str and
|
42
42
|
%w(nokogiri nokogumbo).include? args.first.children.first
|
@@ -47,7 +47,7 @@ module Ruby2JS
|
|
47
47
|
super
|
48
48
|
end
|
49
49
|
|
50
|
-
elsif
|
50
|
+
elsif \
|
51
51
|
[:HTML, :HTML5].include? method and
|
52
52
|
target == s(:const, nil, :Nokogiri)
|
53
53
|
then
|
@@ -55,7 +55,7 @@ module Ruby2JS
|
|
55
55
|
S(:attr, s(:attr, s(:send, s(:const, nil, :JSDOM), :new,
|
56
56
|
*process_all(args)), :window), :document)
|
57
57
|
|
58
|
-
elsif
|
58
|
+
elsif \
|
59
59
|
method == :parse and
|
60
60
|
target.type == :const and
|
61
61
|
target.children.first == s(:const, nil, :Nokogiri) and
|
@@ -65,13 +65,13 @@ module Ruby2JS
|
|
65
65
|
S(:attr, s(:attr, s(:send, s(:const, nil, :JSDOM), :new,
|
66
66
|
*process_all(args)), :window), :document)
|
67
67
|
|
68
|
-
elsif
|
68
|
+
elsif \
|
69
69
|
method == :at and
|
70
70
|
args.length == 1 and args.first.type == :str
|
71
71
|
then
|
72
72
|
S(:send, target, :querySelector, process(args.first))
|
73
73
|
|
74
|
-
elsif
|
74
|
+
elsif \
|
75
75
|
method == :search and
|
76
76
|
args.length == 1 and args.first.type == :str
|
77
77
|
then
|
@@ -98,25 +98,25 @@ module Ruby2JS
|
|
98
98
|
elsif method === :to_html and args.length == 0
|
99
99
|
S(:attr, target, :outerHTML)
|
100
100
|
|
101
|
-
elsif
|
101
|
+
elsif \
|
102
102
|
[:attr, :get_attribute].include? method and
|
103
103
|
args.length == 1 and args.first.type == :str
|
104
104
|
then
|
105
105
|
S(:send, target, :getAttribute, process(args.first))
|
106
106
|
|
107
|
-
elsif
|
107
|
+
elsif \
|
108
108
|
[:key?, :has_attribute].include? method and
|
109
109
|
args.length == 1 and args.first.type == :str
|
110
110
|
then
|
111
111
|
S(:send, target, :hasAttribute, process(args.first))
|
112
112
|
|
113
|
-
elsif
|
113
|
+
elsif \
|
114
114
|
method == :set_attribute and
|
115
115
|
args.length == 2 and args.first.type == :str
|
116
116
|
then
|
117
117
|
S(:send, target, :setAttribute, *process_all(args))
|
118
118
|
|
119
|
-
elsif
|
119
|
+
elsif \
|
120
120
|
method == :attribute and
|
121
121
|
args.length == 1 and args.first.type == :str
|
122
122
|
then
|
@@ -128,7 +128,7 @@ module Ruby2JS
|
|
128
128
|
elsif method == :attribute_nodes and args.length == 0
|
129
129
|
S(:attr, target, :attributes)
|
130
130
|
|
131
|
-
elsif
|
131
|
+
elsif \
|
132
132
|
method == :new and args.length == 2 and
|
133
133
|
target == s(:const, s(:const, s(:const, nil, :Nokogiri), :XML), :Node)
|
134
134
|
then
|
@@ -172,14 +172,14 @@ module Ruby2JS
|
|
172
172
|
elsif method == :add_child and args.length == 1
|
173
173
|
S(:send, target, :appendChild, process(args.first))
|
174
174
|
|
175
|
-
elsif
|
175
|
+
elsif \
|
176
176
|
[:add_next_sibling, :next=, :after].include? method and
|
177
177
|
args.length == 1
|
178
178
|
then
|
179
179
|
S(:send, s(:attr, target, :parentNode), :insertBefore,
|
180
180
|
process(args.first), s(:attr, target, :nextSibling))
|
181
181
|
|
182
|
-
elsif
|
182
|
+
elsif \
|
183
183
|
[:add_previous_sibling, :previous=, :before].include? method and
|
184
184
|
args.length == 1
|
185
185
|
then
|
@@ -199,7 +199,7 @@ module Ruby2JS
|
|
199
199
|
elsif method == :previous_element and args.length == 0
|
200
200
|
S(:attr, target, :previousElement)
|
201
201
|
|
202
|
-
elsif
|
202
|
+
elsif \
|
203
203
|
[:previous, :previous_sibling].include? method and args.length == 0
|
204
204
|
then
|
205
205
|
S(:attr, target, :previousSibling)
|
data/lib/ruby2js/filter/react.rb
CHANGED
@@ -68,12 +68,31 @@ module Ruby2JS
|
|
68
68
|
@reactApply = nil
|
69
69
|
@reactBlock = nil
|
70
70
|
@reactClass = nil
|
71
|
+
@react_props = []
|
72
|
+
@react_methods = []
|
73
|
+
@react_filter_functions = false
|
74
|
+
@jsx = false
|
71
75
|
super
|
72
76
|
end
|
73
77
|
|
74
78
|
def options=(options)
|
75
79
|
super
|
76
80
|
@react = true if options[:react]
|
81
|
+
filters = options[:filters] || Filter::DEFAULTS
|
82
|
+
|
83
|
+
if \
|
84
|
+
defined? Ruby2JS::Filter::Functions and
|
85
|
+
filters.include? Ruby2JS::Filter::Functions
|
86
|
+
then
|
87
|
+
@react_filter_functions = true
|
88
|
+
end
|
89
|
+
|
90
|
+
if \
|
91
|
+
defined? Ruby2JS::Filter::Wunderbar and
|
92
|
+
filters.include? Ruby2JS::Filter::Wunderbar
|
93
|
+
then
|
94
|
+
@jsx = true
|
95
|
+
end
|
77
96
|
end
|
78
97
|
|
79
98
|
# Example conversion
|
@@ -85,7 +104,9 @@ module Ruby2JS
|
|
85
104
|
def on_class(node)
|
86
105
|
cname, inheritance, *body = node.children
|
87
106
|
return super unless cname.children.first == nil
|
88
|
-
return super unless inheritance == s(:const, nil, :React)
|
107
|
+
return super unless inheritance == s(:const, nil, :React) or
|
108
|
+
inheritance == s(:const, nil, :Vue) or
|
109
|
+
inheritance == s(:send, s(:const, nil, :React), :Component)
|
89
110
|
|
90
111
|
# traverse down to actual list of class statements
|
91
112
|
if body.length == 1
|
@@ -106,18 +127,25 @@ module Ruby2JS
|
|
106
127
|
react, @react = @react, true
|
107
128
|
reactClass, @reactClass = @reactClass, true
|
108
129
|
|
109
|
-
|
110
|
-
|
111
|
-
|
130
|
+
pairs = []
|
131
|
+
|
132
|
+
unless es2015
|
133
|
+
# automatically capture the displayName for the class
|
134
|
+
pairs << s(:pair, s(:sym, :displayName),
|
135
|
+
s(:str, cname.children.last.to_s))
|
136
|
+
end
|
112
137
|
|
113
138
|
# collect static properties/functions
|
114
139
|
statics = []
|
115
140
|
body.select {|child| child.type == :defs}.each do |child|
|
116
141
|
_parent, mname, args, *block = child.children
|
117
|
-
if
|
142
|
+
if es2015
|
143
|
+
block = [s(:autoreturn, *block)] unless child.is_method?
|
144
|
+
pairs << s(:defs, s(:self), mname, args, *block)
|
145
|
+
elsif child.is_method?
|
118
146
|
statics << s(:pair, s(:sym, mname), process(child.updated(:block,
|
119
147
|
[s(:send, nil, :proc), args, s(:autoreturn, *block)])))
|
120
|
-
elsif
|
148
|
+
elsif \
|
121
149
|
block.length == 1 and
|
122
150
|
Converter::EXPRESSIONS.include? block.first.type
|
123
151
|
then
|
@@ -128,6 +156,25 @@ module Ruby2JS
|
|
128
156
|
end
|
129
157
|
end
|
130
158
|
|
159
|
+
# collect instance methods (including getters and setters)
|
160
|
+
@react_props = []
|
161
|
+
@react_methods = []
|
162
|
+
body.each do |statement|
|
163
|
+
if statement.type == :def
|
164
|
+
method = statement.children.first
|
165
|
+
unless method == :initialize
|
166
|
+
if method.to_s.end_with? '='
|
167
|
+
method = method.to_s[0..-2].to_sym
|
168
|
+
@react_props << method unless @react_props.include? method
|
169
|
+
elsif statement.is_method?
|
170
|
+
@react_methods << method unless @react_methods.include? method
|
171
|
+
else
|
172
|
+
@react_props << method unless @react_props.include? method
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
131
178
|
# append statics (if any)
|
132
179
|
unless statics.empty?
|
133
180
|
pairs << s(:pair, s(:sym, :statics), s(:hash, *statics))
|
@@ -135,7 +182,8 @@ module Ruby2JS
|
|
135
182
|
|
136
183
|
# create a default getInitialState method if there is no such method
|
137
184
|
# and there are references to instance variables.
|
138
|
-
if
|
185
|
+
if \
|
186
|
+
not es2015 and
|
139
187
|
not body.any? do |child|
|
140
188
|
child.type == :def and
|
141
189
|
[:getInitialState, :initialize].include? child.children.first
|
@@ -162,7 +210,7 @@ module Ruby2JS
|
|
162
210
|
(@reactIvars[:pre] + @reactIvars[:post]).uniq
|
163
211
|
|
164
212
|
if mname == :initialize
|
165
|
-
mname = :getInitialState
|
213
|
+
mname = es2015 ? :initialize : :getInitialState
|
166
214
|
|
167
215
|
# extract real list of statements
|
168
216
|
if block.length == 1
|
@@ -193,7 +241,9 @@ module Ruby2JS
|
|
193
241
|
anode.children.first.to_s[1..-1]), anode.children.last)})
|
194
242
|
|
195
243
|
# modify block to build and/or return state
|
196
|
-
if
|
244
|
+
if mname == :initialize
|
245
|
+
block.unshift(s(:send, s(:self), :state=, state))
|
246
|
+
elsif block.empty?
|
197
247
|
block = [s(:return, state)]
|
198
248
|
else
|
199
249
|
block.unshift(s(:send, s(:self), :state=, state))
|
@@ -201,13 +251,30 @@ module Ruby2JS
|
|
201
251
|
end
|
202
252
|
|
203
253
|
elsif mname == :render
|
204
|
-
if
|
205
|
-
|
254
|
+
if \
|
255
|
+
block.length != 1 or not block.last or
|
206
256
|
not [:send, :block].include? block.last.type
|
207
257
|
then
|
208
|
-
|
209
|
-
|
210
|
-
|
258
|
+
if @jsx
|
259
|
+
while block.length == 1 and block.first.type == :begin
|
260
|
+
block = block.first.children.dup
|
261
|
+
end
|
262
|
+
|
263
|
+
# gather non-element emitting statements in the front
|
264
|
+
prolog = []
|
265
|
+
while not block.empty? and
|
266
|
+
react_wunderbar_free([block.first]) do
|
267
|
+
prolog << process(block.shift)
|
268
|
+
end
|
269
|
+
|
270
|
+
# wrap multi-line blocks with an empty element
|
271
|
+
block = [*prolog, s(:return,
|
272
|
+
s(:xnode, '', *process_all(block)))]
|
273
|
+
else
|
274
|
+
# wrap multi-line blocks with a 'span' element
|
275
|
+
block = [s(:return,
|
276
|
+
s(:block, s(:send, nil, :_span), s(:args), *block))]
|
277
|
+
end
|
211
278
|
end
|
212
279
|
|
213
280
|
elsif mname == :componentWillReceiveProps
|
@@ -227,12 +294,17 @@ module Ruby2JS
|
|
227
294
|
|
228
295
|
# add method to class
|
229
296
|
type = (child.is_method? ? :begin : :autoreturn)
|
297
|
+
type = :begin if mname == :initialize
|
230
298
|
if block.length == 1 and Parser::AST::Node === block.first
|
231
299
|
type = :begin if block.first.type == :return
|
232
300
|
end
|
233
301
|
|
234
|
-
|
235
|
-
|
302
|
+
if es2015
|
303
|
+
pairs << s(:def, mname, args, process(s(type, *block)))
|
304
|
+
else
|
305
|
+
pairs << s(:pair, s(:sym, mname), child.updated(:block,
|
306
|
+
[s(:send, nil, :proc), args, process(s(type, *block))]))
|
307
|
+
end
|
236
308
|
|
237
309
|
# retain comment
|
238
310
|
unless @comments[child].empty?
|
@@ -245,18 +317,61 @@ module Ruby2JS
|
|
245
317
|
@reactMethod = nil
|
246
318
|
end
|
247
319
|
|
248
|
-
|
249
|
-
|
250
|
-
|
320
|
+
if es2015
|
321
|
+
# emit a class that extends React.Component
|
322
|
+
node.updated(:class, [s(:const, nil, cname.children.last),
|
323
|
+
s(:attr, s(:const, nil, :React), :Component), *pairs])
|
324
|
+
else
|
325
|
+
# emit a createClass statement
|
326
|
+
node.updated(:casgn, [nil, cname.children.last,
|
327
|
+
s(:send, s(:const, nil, :React), :createClass, s(:hash, *pairs))])
|
328
|
+
end
|
251
329
|
end
|
252
330
|
|
253
331
|
def on_send(node)
|
332
|
+
# convert Vue.utile.defineReactive to class fields or assignments
|
333
|
+
if node.children.first == s(:send, s(:const, nil, :Vue), :util)
|
334
|
+
if node.children[1] == :defineReactive
|
335
|
+
if node.children[2].type == :cvar
|
336
|
+
return process s(:cvasgn, node.children[2].children.first,
|
337
|
+
node.children[3])
|
338
|
+
elsif node.children[2].type == :send
|
339
|
+
assign = node.children[2]
|
340
|
+
return assign.updated(nil, [assign.children[0],
|
341
|
+
assign.children[1].to_s + '=', node.children[3]])
|
342
|
+
end
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
# calls to methods (including getters) defined in this class
|
347
|
+
if node.children[0]==nil and Symbol === node.children[1]
|
348
|
+
if node.is_method?
|
349
|
+
if @react_methods.include? node.children[1]
|
350
|
+
# calls to methods defined in this class
|
351
|
+
return node.updated nil, [s(:self), node.children[1],
|
352
|
+
*process_all(node.children[2..-1])]
|
353
|
+
end
|
354
|
+
else
|
355
|
+
if @react_props.include? node.children[1]
|
356
|
+
# access to properties defined in this class
|
357
|
+
return node.updated nil, [s(:self), node.children[1],
|
358
|
+
*process_all(node.children[2..-1])]
|
359
|
+
end
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
if node.children.first == s(:const, nil, :Vue)
|
364
|
+
node = node.updated(nil, [s(:const, nil, :React),
|
365
|
+
*node.children[1..-1]])
|
366
|
+
end
|
367
|
+
|
254
368
|
if not @react
|
255
369
|
# enable React filtering within React class method calls or
|
256
370
|
# React component calls
|
257
|
-
if
|
371
|
+
if \
|
258
372
|
node.children.first == s(:const, nil, :React)
|
259
373
|
then
|
374
|
+
|
260
375
|
begin
|
261
376
|
react, @react = @react, true
|
262
377
|
return on_send(node)
|
@@ -278,7 +393,7 @@ module Ruby2JS
|
|
278
393
|
process(node.children[2])
|
279
394
|
end
|
280
395
|
|
281
|
-
elsif
|
396
|
+
elsif \
|
282
397
|
@reactApply and node.children[1] == :createElement and
|
283
398
|
node.children[0] == s(:const, nil, :React)
|
284
399
|
then
|
@@ -286,7 +401,7 @@ module Ruby2JS
|
|
286
401
|
s(:send, s(:gvar, :$_), :push, s(:send, *node.children[0..1],
|
287
402
|
*process_all(node.children[2..-1])))
|
288
403
|
|
289
|
-
elsif node.children[0] == nil and node.children[1] =~ /^_\w/
|
404
|
+
elsif !@jsx and node.children[0] == nil and node.children[1] =~ /^_\w/
|
290
405
|
# map method calls starting with an underscore to React calls
|
291
406
|
# to create an element.
|
292
407
|
#
|
@@ -344,7 +459,7 @@ module Ruby2JS
|
|
344
459
|
expr = expr.children.first
|
345
460
|
end
|
346
461
|
|
347
|
-
if
|
462
|
+
if \
|
348
463
|
expr.type == :if and expr.children[1] and
|
349
464
|
expr.children[1].type == :str
|
350
465
|
then
|
@@ -468,6 +583,8 @@ module Ruby2JS
|
|
468
583
|
# explicit call to React.createElement
|
469
584
|
next true if arg.children[1] == :createElement and
|
470
585
|
arg.children[0] == s(:const, nil, :React)
|
586
|
+
next true if arg.children[1] == :createElement and
|
587
|
+
arg.children[0] == s(:const, nil, :Vue)
|
471
588
|
|
472
589
|
# wunderbar style call
|
473
590
|
arg = arg.children.first if arg.type == :block
|
@@ -669,7 +786,7 @@ module Ruby2JS
|
|
669
786
|
super
|
670
787
|
end
|
671
788
|
|
672
|
-
elsif
|
789
|
+
elsif \
|
673
790
|
node.children[0] and node.children[0].type == :self and
|
674
791
|
node.children.length == 2 and
|
675
792
|
node.children[1] == :componentWillReceiveProps
|
@@ -686,7 +803,7 @@ module Ruby2JS
|
|
686
803
|
if not @react
|
687
804
|
# enable React filtering within React class method calls or
|
688
805
|
# React component calls
|
689
|
-
if
|
806
|
+
if \
|
690
807
|
node.children.first == s(:const, nil, :React)
|
691
808
|
then
|
692
809
|
begin
|
@@ -713,7 +830,7 @@ module Ruby2JS
|
|
713
830
|
#
|
714
831
|
# Base Ruby2JS processing will convert the 'splat' to 'apply'
|
715
832
|
child = node.children.first
|
716
|
-
if
|
833
|
+
if \
|
717
834
|
child.children[1] == :createElement and
|
718
835
|
child.children[0] == s(:const, nil, :React)
|
719
836
|
then
|
@@ -743,7 +860,7 @@ module Ruby2JS
|
|
743
860
|
end
|
744
861
|
|
745
862
|
# wunderbar style calls
|
746
|
-
if child.children[0] == nil and child.children[1] =~ /^_\w/
|
863
|
+
if !@jsx and child.children[0] == nil and child.children[1] =~ /^_\w/
|
747
864
|
if node.children[1].children.empty?
|
748
865
|
# append block as a standalone proc
|
749
866
|
block = s(:block, s(:send, nil, :proc), s(:args),
|
@@ -875,6 +992,49 @@ module Ruby2JS
|
|
875
992
|
s(:attr, @reactProps, node.children.first.to_s[2..-1])
|
876
993
|
end
|
877
994
|
|
995
|
+
# is this a "wunderbar" style call or createElement?
|
996
|
+
def react_element?(node)
|
997
|
+
return false unless node
|
998
|
+
|
999
|
+
forEach = [:forEach]
|
1000
|
+
forEach << :each if @react_filter_functions
|
1001
|
+
|
1002
|
+
return true if node.type == :block and
|
1003
|
+
forEach.include? node.children.first.children.last and
|
1004
|
+
react_element?(node.children.last)
|
1005
|
+
|
1006
|
+
# explicit call to React.createElement
|
1007
|
+
return true if node.children[1] == :createElement and
|
1008
|
+
node.children[0] == s(:const, nil, :React)
|
1009
|
+
|
1010
|
+
# explicit call to Vue.createElement
|
1011
|
+
return true if node.children[1] == :createElement and
|
1012
|
+
node.children[0] == s(:const, nil, :Vue)
|
1013
|
+
|
1014
|
+
# wunderbar style call
|
1015
|
+
node = node.children.first if node.type == :block
|
1016
|
+
while node.type == :send and node.children.first != nil
|
1017
|
+
node = node.children.first
|
1018
|
+
end
|
1019
|
+
node.type == :send and node.children[1].to_s.start_with? '_'
|
1020
|
+
end
|
1021
|
+
|
1022
|
+
# ensure that there are no "wunderbar" or "createElement" calls in
|
1023
|
+
# a set of statements.
|
1024
|
+
def react_wunderbar_free(nodes)
|
1025
|
+
nodes.each do |node|
|
1026
|
+
if Parser::AST::Node === node
|
1027
|
+
return false if react_element?(node)
|
1028
|
+
|
1029
|
+
# recurse
|
1030
|
+
return false unless react_wunderbar_free(node.children)
|
1031
|
+
end
|
1032
|
+
end
|
1033
|
+
|
1034
|
+
# no problems found
|
1035
|
+
return true
|
1036
|
+
end
|
1037
|
+
|
878
1038
|
# analyze ivar usage
|
879
1039
|
def react_walk(node)
|
880
1040
|
# ignore hash values which are blocks (most typically, event handlers)
|
@@ -920,7 +1080,7 @@ module Ruby2JS
|
|
920
1080
|
end
|
921
1081
|
|
922
1082
|
when :send
|
923
|
-
if
|
1083
|
+
if \
|
924
1084
|
child and child.type == :self and node.children.length == 2 and
|
925
1085
|
node.children[1] == :componentWillReceiveProps
|
926
1086
|
then
|
@@ -933,7 +1093,7 @@ module Ruby2JS
|
|
933
1093
|
# Ruby 'desugars' -> to lambda, and Ruby2JS presumes that lambdas
|
934
1094
|
# return a value.
|
935
1095
|
def on_pair(node)
|
936
|
-
if
|
1096
|
+
if \
|
937
1097
|
node.children[1].type == :block and
|
938
1098
|
node.children[1].children[0] == s(:send, nil, :lambda)
|
939
1099
|
then
|
@@ -949,7 +1109,7 @@ module Ruby2JS
|
|
949
1109
|
def on_begin(node)
|
950
1110
|
node = super
|
951
1111
|
(node.children.length-2).downto(0) do |i|
|
952
|
-
if
|
1112
|
+
if \
|
953
1113
|
node.children[i].type == :send and
|
954
1114
|
node.children[i].children[0] and
|
955
1115
|
node.children[i].children[0].type == :self and
|