ruby2js 4.0.5 → 4.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ruby2js/converter.rb +1 -0
- data/lib/ruby2js/converter/class.rb +7 -5
- data/lib/ruby2js/converter/class2.rb +1 -1
- data/lib/ruby2js/converter/match.rb +7 -0
- data/lib/ruby2js/converter/send.rb +3 -3
- data/lib/ruby2js/converter/taglit.rb +6 -2
- data/lib/ruby2js/filter/camelCase.rb +17 -0
- data/lib/ruby2js/filter/cjs.rb +100 -2
- data/lib/ruby2js/filter/functions.rb +11 -6
- data/lib/ruby2js/filter/lit-element.rb +29 -13
- data/lib/ruby2js/filter/react.rb +275 -87
- data/lib/ruby2js/serializer.rb +41 -10
- data/lib/ruby2js/version.rb +2 -2
- data/lib/tasks/install/config/webpack/loaders/ruby2js.js +20 -0
- data/lib/tasks/install/preact.rb +3 -0
- data/lib/tasks/install/webpacker.rb +14 -31
- data/lib/tasks/ruby2js_tasks.rake +5 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ff40ad496d47d0ec4fa430f6d04b47b1c0d7ae6f152c479da8de49a9f506a00
|
4
|
+
data.tar.gz: 84de6a0f644de7716d9e094f2944d896c49cafaca082523d4947a5d8f567eddc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f34521a4ef3677997f541721dfc5a0eb8e870a567ec2198b9b98e1f0d15270160bc076a070e0e5728b77a6622ba4ed0c133f20c9086dbec1cbb1d736bbe28a2
|
7
|
+
data.tar.gz: 9196de55781c332df1183361bcf1428f51ccebb1e38eab2b2ab9f7e3b30b6502b4176eefac0539eb3079906b955e138ee95971822ea59a775a36af5ca27a8aa5
|
data/lib/ruby2js/converter.rb
CHANGED
@@ -359,6 +359,7 @@ require 'ruby2js/converter/kwbegin'
|
|
359
359
|
require 'ruby2js/converter/literal'
|
360
360
|
require 'ruby2js/converter/logical'
|
361
361
|
require 'ruby2js/converter/masgn'
|
362
|
+
require 'ruby2js/converter/match'
|
362
363
|
require 'ruby2js/converter/module'
|
363
364
|
require 'ruby2js/converter/next'
|
364
365
|
require 'ruby2js/converter/nil'
|
@@ -36,7 +36,8 @@ module Ruby2JS
|
|
36
36
|
end
|
37
37
|
|
38
38
|
if inheritance
|
39
|
-
|
39
|
+
parent = @namespace.find(inheritance)&.[](:constructor)
|
40
|
+
init = s(:def, :initialize, parent || s(:args), s(:zsuper))
|
40
41
|
else
|
41
42
|
init = s(:def, :initialize, s(:args), nil)
|
42
43
|
end
|
@@ -58,7 +59,7 @@ module Ruby2JS
|
|
58
59
|
m = m.updated(:def, m.children[1..-1])
|
59
60
|
end
|
60
61
|
|
61
|
-
node = if m.type
|
62
|
+
node = if %i(def defm deff).include? m.type
|
62
63
|
if m.children.first == :initialize and !visible[:initialize]
|
63
64
|
# constructor: remove from body and overwrite init function
|
64
65
|
init = m
|
@@ -89,7 +90,7 @@ module Ruby2JS
|
|
89
90
|
end
|
90
91
|
end
|
91
92
|
|
92
|
-
elsif m.type
|
93
|
+
elsif %i(defs defp).include? m.type and m.children.first == s(:self)
|
93
94
|
if m.children[1] =~ /=$/
|
94
95
|
# class property setter
|
95
96
|
s(:prop, name, m.children[1].to_s[0..-2] =>
|
@@ -313,7 +314,7 @@ module Ruby2JS
|
|
313
314
|
# prepend constructor
|
314
315
|
if init
|
315
316
|
constructor = init.updated(:constructor, [name, *init.children[1..-1]])
|
316
|
-
|
317
|
+
visible[:constructor] = init.children[1]
|
317
318
|
|
318
319
|
if @ast.type == :class_extend or extend
|
319
320
|
if es2015
|
@@ -329,6 +330,7 @@ module Ruby2JS
|
|
329
330
|
end
|
330
331
|
end
|
331
332
|
|
333
|
+
@comments[constructor] = @comments[init] unless @comments[init].empty?
|
332
334
|
body.unshift constructor
|
333
335
|
end
|
334
336
|
|
@@ -349,7 +351,7 @@ module Ruby2JS
|
|
349
351
|
self.ivars = ivars
|
350
352
|
@class_name = class_name
|
351
353
|
@class_parent = class_parent
|
352
|
-
@rbstack.pop
|
354
|
+
@namespace.defineProps @rbstack.pop
|
353
355
|
@namespace.leave unless @ast.type == :class_module
|
354
356
|
end
|
355
357
|
end
|
@@ -99,7 +99,6 @@ module Ruby2JS
|
|
99
99
|
end
|
100
100
|
walk[@ast]
|
101
101
|
|
102
|
-
# process leading initializers in constructor
|
103
102
|
while constructor.length == 1 and constructor.first.type == :begin
|
104
103
|
constructor = constructor.first.children.dup
|
105
104
|
end
|
@@ -116,6 +115,7 @@ module Ruby2JS
|
|
116
115
|
put 'static #$' + cvar.to_s[2..-1]
|
117
116
|
end
|
118
117
|
|
118
|
+
# process leading initializers in constructor
|
119
119
|
while constructor.length > 0 and constructor.first.type == :ivasgn
|
120
120
|
put(index == 0 ? @nl : @sep)
|
121
121
|
index += 1
|
@@ -323,13 +323,13 @@ module Ruby2JS
|
|
323
323
|
put 'typeof '; parse args.first
|
324
324
|
|
325
325
|
elsif ast.children[1] == :is_a? and receiver and args.length == 1
|
326
|
-
parse receiver; put ' instanceof '; parse args.first
|
326
|
+
put '('; parse receiver; put ' instanceof '; parse args.first; put ')'
|
327
327
|
|
328
328
|
elsif ast.children[1] == :kind_of? and receiver and args.length == 1
|
329
|
-
parse receiver; put ' instanceof '; parse args.first
|
329
|
+
put '('; parse receiver; put ' instanceof '; parse args.first; put ')'
|
330
330
|
|
331
331
|
elsif ast.children[1] == :instance_of? and receiver and args.length == 1
|
332
|
-
parse s(:send, s(:attr, receiver, :constructor), :==, args.first)
|
332
|
+
put '('; parse s(:send, s(:attr, receiver, :constructor), :==, args.first); put ')'
|
333
333
|
|
334
334
|
else
|
335
335
|
if method == :bind and receiver&.type == :send
|
@@ -10,8 +10,12 @@ module Ruby2JS
|
|
10
10
|
# disable autobinding in tag literals
|
11
11
|
save_autobind, @autobind = @autobind, false
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
if es2015
|
14
|
+
put tag.children.first
|
15
|
+
parse_all(*children, join: '')
|
16
|
+
else
|
17
|
+
parse @ast.updated(:send, [nil, tag.children.last, *children])
|
18
|
+
end
|
15
19
|
ensure
|
16
20
|
@autobind = save_autobind
|
17
21
|
end
|
@@ -14,6 +14,9 @@ module Ruby2JS
|
|
14
14
|
attr_reader
|
15
15
|
attr_writer
|
16
16
|
method_missing
|
17
|
+
is_a?
|
18
|
+
kind_of?
|
19
|
+
instance_of?
|
17
20
|
}
|
18
21
|
|
19
22
|
CAPS_EXCEPTIONS = {
|
@@ -28,6 +31,8 @@ module Ruby2JS
|
|
28
31
|
}
|
29
32
|
|
30
33
|
def camelCase(symbol)
|
34
|
+
return symbol if ALLOWLIST.include?(symbol.to_s)
|
35
|
+
|
31
36
|
should_symbolize = symbol.is_a?(Symbol)
|
32
37
|
symbol = symbol
|
33
38
|
.to_s
|
@@ -99,6 +104,10 @@ module Ruby2JS
|
|
99
104
|
handle_generic_node(super, :arg)
|
100
105
|
end
|
101
106
|
|
107
|
+
def on_kwarg(node)
|
108
|
+
handle_generic_node(super, :kwarg)
|
109
|
+
end
|
110
|
+
|
102
111
|
def on_lvasgn(node)
|
103
112
|
handle_generic_node(super, :lvasgn)
|
104
113
|
end
|
@@ -111,6 +120,14 @@ module Ruby2JS
|
|
111
120
|
handle_generic_node(super, :cvasgn)
|
112
121
|
end
|
113
122
|
|
123
|
+
def on_match_pattern(node)
|
124
|
+
handle_generic_node(super, :match_pattern)
|
125
|
+
end
|
126
|
+
|
127
|
+
def on_match_var(node)
|
128
|
+
handle_generic_node(super, :match_var)
|
129
|
+
end
|
130
|
+
|
114
131
|
def on_sym(node)
|
115
132
|
handle_generic_node(super, :sym)
|
116
133
|
end
|
data/lib/ruby2js/filter/cjs.rb
CHANGED
@@ -7,6 +7,59 @@ module Ruby2JS
|
|
7
7
|
module CJS
|
8
8
|
include SEXP
|
9
9
|
|
10
|
+
def options=(options)
|
11
|
+
super
|
12
|
+
@cjs_autoexports = !@disable_autoexports && options[:autoexports]
|
13
|
+
end
|
14
|
+
|
15
|
+
def process(node)
|
16
|
+
return super unless @cjs_autoexports
|
17
|
+
|
18
|
+
list = [node]
|
19
|
+
while list.length == 1 and list.first.type == :begin
|
20
|
+
list = list.first.children.dup
|
21
|
+
end
|
22
|
+
|
23
|
+
replaced = []
|
24
|
+
list.map! do |child|
|
25
|
+
replacement = child
|
26
|
+
|
27
|
+
if [:module, :class].include? child.type and
|
28
|
+
child.children.first.type == :const and
|
29
|
+
child.children.first.children.first == nil \
|
30
|
+
then
|
31
|
+
replacement = s(:send, nil, :export, child)
|
32
|
+
elsif child.type == :casgn and child.children.first == nil
|
33
|
+
replacement = s(:send, nil, :export, child)
|
34
|
+
elsif child.type == :def
|
35
|
+
replacement = s(:send, nil, :export, child)
|
36
|
+
end
|
37
|
+
|
38
|
+
if replacement != child
|
39
|
+
replaced << replacement
|
40
|
+
@comments[replacement] = @comments[child] if @comments[child]
|
41
|
+
end
|
42
|
+
|
43
|
+
replacement
|
44
|
+
end
|
45
|
+
|
46
|
+
if replaced.length == 1 and @cjs_autoexports == :default
|
47
|
+
list.map! do |child|
|
48
|
+
if child == replaced.first
|
49
|
+
replacement = s(:send, nil, :export, s(:send, nil, :default,
|
50
|
+
*child.children[2..-1]))
|
51
|
+
@comments[replacement] = @comments[child] if @comments[child]
|
52
|
+
replacement
|
53
|
+
else
|
54
|
+
child
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
@cjs_autoexports = false
|
60
|
+
process s(:begin, *list)
|
61
|
+
end
|
62
|
+
|
10
63
|
def on_send(node)
|
11
64
|
return super unless node.children[1] == :export
|
12
65
|
|
@@ -23,9 +76,54 @@ module Ruby2JS
|
|
23
76
|
node.updated(nil, [
|
24
77
|
s(:attr, nil, :exports),
|
25
78
|
assign.children[0].to_s + '=',
|
26
|
-
*assign.children[1..-1]
|
79
|
+
*process_all(assign.children[1..-1])
|
27
80
|
])
|
28
81
|
|
82
|
+
elsif node.children[2].type == :casgn
|
83
|
+
assign = node.children[2]
|
84
|
+
if assign.children[0] == nil
|
85
|
+
node.updated(nil, [
|
86
|
+
s(:attr, nil, :exports),
|
87
|
+
assign.children[1].to_s + '=',
|
88
|
+
*process_all(assign.children[2..-1])
|
89
|
+
])
|
90
|
+
else
|
91
|
+
node
|
92
|
+
end
|
93
|
+
|
94
|
+
elsif node.children[2].type == :class
|
95
|
+
assign = node.children[2]
|
96
|
+
if assign.children[0].children[0] != nil
|
97
|
+
node
|
98
|
+
elsif assign.children[1] == nil
|
99
|
+
node.updated(nil, [
|
100
|
+
s(:attr, nil, :exports),
|
101
|
+
assign.children[0].children[1].to_s + '=',
|
102
|
+
s(:block, s(:send, s(:const, nil, :Class), :new),
|
103
|
+
s(:args), *process_all(assign.children[2..-1]))
|
104
|
+
])
|
105
|
+
else
|
106
|
+
node.updated(nil, [
|
107
|
+
s(:attr, nil, :exports),
|
108
|
+
assign.children[0].children[1].to_s + '=',
|
109
|
+
s(:block, s(:send, s(:const, nil, :Class), :new,
|
110
|
+
assign.children[1]), s(:args),
|
111
|
+
*process_all(assign.children[2..-1]))
|
112
|
+
])
|
113
|
+
end
|
114
|
+
|
115
|
+
elsif node.children[2].type == :module
|
116
|
+
assign = node.children[2]
|
117
|
+
if assign.children[0].children[0] != nil
|
118
|
+
node
|
119
|
+
else
|
120
|
+
node.updated(nil, [
|
121
|
+
s(:attr, nil, :exports),
|
122
|
+
assign.children[0].children[1].to_s + '=',
|
123
|
+
s(:class_module, nil, nil, *process_all(assign.children[1..-1]))
|
124
|
+
])
|
125
|
+
end
|
126
|
+
|
29
127
|
elsif \
|
30
128
|
node.children[2].type == :send and
|
31
129
|
node.children[2].children[0..1] == [nil, :async] and
|
@@ -49,7 +147,7 @@ module Ruby2JS
|
|
49
147
|
node.updated(nil, [
|
50
148
|
s(:attr, nil, :module),
|
51
149
|
:exports=,
|
52
|
-
node.children[2]
|
150
|
+
process(node.children[2])
|
53
151
|
])
|
54
152
|
|
55
153
|
else
|
@@ -227,14 +227,19 @@ module Ruby2JS
|
|
227
227
|
if before.type == :regexp
|
228
228
|
before = before.updated(:regexp, [*before.children[0...-1],
|
229
229
|
s(:regopt, :g, *before.children.last)])
|
230
|
-
elsif before.type == :str
|
230
|
+
elsif before.type == :str and not es2021
|
231
231
|
before = before.updated(:regexp,
|
232
232
|
[s(:str, Regexp.escape(before.children.first)), s(:regopt, :g)])
|
233
233
|
end
|
234
234
|
if after.type == :str
|
235
235
|
after = s(:str, after.children.first.gsub(/\\(\d)/, "$\\1"))
|
236
236
|
end
|
237
|
-
|
237
|
+
|
238
|
+
if es2021
|
239
|
+
process node.updated nil, [target, :replaceAll, before, after]
|
240
|
+
else
|
241
|
+
process node.updated nil, [target, :replace, before, after]
|
242
|
+
end
|
238
243
|
|
239
244
|
elsif method == :ord and args.length == 0
|
240
245
|
if target.type == :str
|
@@ -767,10 +772,10 @@ module Ruby2JS
|
|
767
772
|
body.any? {|statement| statement.type == :def and
|
768
773
|
statement.children.first == :initialize}
|
769
774
|
then
|
770
|
-
body.unshift
|
771
|
-
s(:begin,
|
772
|
-
|
773
|
-
|
775
|
+
body.unshift s(:def, :initialize, s(:args, s(:arg, :message)),
|
776
|
+
s(:begin, s(:send, s(:self), :message=, s(:lvar, :message)),
|
777
|
+
s(:send, s(:self), :name=, s(:sym, name.children[1])),
|
778
|
+
s(:send, s(:self), :stack=, s(:attr, s(:send, nil, :Error,
|
774
779
|
s(:lvar, :message)), :stack))))
|
775
780
|
end
|
776
781
|
|
@@ -22,10 +22,19 @@ module Ruby2JS
|
|
22
22
|
|
23
23
|
def on_ivasgn(node)
|
24
24
|
return super unless @le_props&.include?(node.children.first)
|
25
|
+
return super unless node.children.length > 1
|
25
26
|
s(:send, s(:self), node.children.first.to_s[1..-1]+'=',
|
26
27
|
process(node.children[1]))
|
27
28
|
end
|
28
29
|
|
30
|
+
def on_op_asgn(node)
|
31
|
+
return super unless node.children.first.type == :ivasgn
|
32
|
+
var = node.children.first.children.first
|
33
|
+
return super unless @le_props&.include?(var)
|
34
|
+
super node.updated(nil, [s(:attr, s(:attr, nil, :this),
|
35
|
+
var.to_s[1..-1]), *node.children[1..-1]])
|
36
|
+
end
|
37
|
+
|
29
38
|
def on_class(node)
|
30
39
|
cname, inheritance, *body = node.children
|
31
40
|
return super unless inheritance == s(:const, nil, :LitElement)
|
@@ -66,9 +75,9 @@ module Ruby2JS
|
|
66
75
|
|
67
76
|
# render of a string is converted to a taglit :html
|
68
77
|
render = nodes.find_index {|child|
|
69
|
-
child
|
78
|
+
child&.type == :def and child.children.first == :render
|
70
79
|
}
|
71
|
-
if render and %i[str dstr].include?(nodes[render].children[2]
|
80
|
+
if render and %i[str dstr].include?(nodes[render].children[2]&.type)
|
72
81
|
nodes[render] = nodes[render].updated(:deff,
|
73
82
|
[*nodes[render].children[0..1],
|
74
83
|
s(:autoreturn, html_wrap(nodes[render].children[2]))])
|
@@ -76,9 +85,9 @@ module Ruby2JS
|
|
76
85
|
|
77
86
|
# self.styles returning string is converted to a taglit :css
|
78
87
|
styles = nodes.find_index {|child|
|
79
|
-
child
|
88
|
+
child&.type == :defs and child.children[0..1] == [s(:self), :styles]
|
80
89
|
}
|
81
|
-
if styles and %i[str dstr].include?(nodes[styles].children[3]
|
90
|
+
if styles and %i[str dstr].include?(nodes[styles].children[3]&.type)
|
82
91
|
string = nodes[styles].children[3]
|
83
92
|
string = s(:dstr, string) if string.type == :str
|
84
93
|
children = string.children.dup
|
@@ -100,13 +109,13 @@ module Ruby2JS
|
|
100
109
|
|
101
110
|
# insert super calls into initializer
|
102
111
|
initialize = nodes.find_index {|child|
|
103
|
-
child
|
112
|
+
child&.type == :def and child.children.first == :initialize
|
104
113
|
}
|
105
114
|
if initialize and nodes[initialize].children.length == 3
|
106
|
-
statements = nodes[initialize].children[2]
|
115
|
+
statements = nodes[initialize].children[2..-1]
|
107
116
|
|
108
|
-
if statements.length == 1 and statements.
|
109
|
-
statements = statements.children
|
117
|
+
if statements.length == 1 and statements.first.type == :begin
|
118
|
+
statements = statements.first.children
|
110
119
|
end
|
111
120
|
|
112
121
|
unless statements.any? {|statement| %i[super zuper].include? statement.type}
|
@@ -174,13 +183,18 @@ module Ruby2JS
|
|
174
183
|
# analyze ivar usage
|
175
184
|
def le_walk(node)
|
176
185
|
node.children.each do |child|
|
177
|
-
next unless Parser::AST::Node
|
178
|
-
le_walk(child)
|
186
|
+
next unless child.is_a? Parser::AST::Node
|
179
187
|
|
180
188
|
if child.type == :ivar
|
181
189
|
@le_props[child.children.first] ||= nil
|
182
|
-
elsif child.type == :ivasgn
|
183
|
-
|
190
|
+
elsif child.type == :ivasgn || child.type == :op_asgn
|
191
|
+
prop = child.children.first
|
192
|
+
unless prop.is_a? Symbol
|
193
|
+
prop = prop.children.first if prop.type == :ivasgn
|
194
|
+
next unless prop.is_a? Symbol
|
195
|
+
end
|
196
|
+
|
197
|
+
@le_props[prop] = case child.children.last.type
|
184
198
|
when :str, :dstr
|
185
199
|
:String
|
186
200
|
when :array
|
@@ -190,8 +204,10 @@ module Ruby2JS
|
|
190
204
|
when :true, :false
|
191
205
|
:Boolean
|
192
206
|
else
|
193
|
-
@le_props[
|
207
|
+
@le_props[prop] || :Object
|
194
208
|
end
|
209
|
+
else
|
210
|
+
le_walk(child)
|
195
211
|
end
|
196
212
|
end
|
197
213
|
end
|
data/lib/ruby2js/filter/react.rb
CHANGED
@@ -27,7 +27,12 @@ module Ruby2JS
|
|
27
27
|
|
28
28
|
REACT_IMPORTS = {
|
29
29
|
React: s(:import, ['react'], s(:attr, nil, :React)),
|
30
|
-
ReactDOM: s(:import, ['react-dom'], s(:attr, nil, :ReactDOM))
|
30
|
+
ReactDOM: s(:import, ['react-dom'], s(:attr, nil, :ReactDOM)),
|
31
|
+
Preact: s(:import,
|
32
|
+
[s(:pair, s(:sym, :as), s(:const, nil, :Preact)),
|
33
|
+
s(:pair, s(:sym, :from), s(:str, "preact"))],
|
34
|
+
s(:str, '*')),
|
35
|
+
PreactHook: s(:import, ["preact/hooks"], [s(:attr, nil, :useState)])
|
31
36
|
}
|
32
37
|
|
33
38
|
# the following command can be used to generate ReactAttrs:
|
@@ -71,17 +76,23 @@ module Ruby2JS
|
|
71
76
|
|
72
77
|
ReactLifecycle = %w(render componentDidMount shouldComponentUpdate
|
73
78
|
getShapshotBeforeUpdate componentDidUpdate componentWillUnmount
|
74
|
-
componentDidCatch)
|
79
|
+
componentDidCatch componentWillReceiveProps)
|
75
80
|
|
76
81
|
ReactAttrMap = Hash[ReactAttrs.map {|name| [name.downcase, name]}]
|
77
82
|
ReactAttrMap['for'] = 'htmlFor'
|
78
|
-
|
83
|
+
|
84
|
+
PreactAttrMap = {
|
85
|
+
htmlFor: 'for',
|
86
|
+
onDoubleClick: 'onDblClick',
|
87
|
+
tabIndex: 'tabindex'
|
88
|
+
}
|
79
89
|
|
80
90
|
def initialize(*args)
|
81
91
|
@react = nil
|
82
92
|
@reactApply = nil
|
83
93
|
@reactBlock = nil
|
84
94
|
@reactClass = nil
|
95
|
+
@reactMethod = nil
|
85
96
|
@react_props = []
|
86
97
|
@react_methods = []
|
87
98
|
@react_filter_functions = false
|
@@ -118,12 +129,23 @@ module Ruby2JS
|
|
118
129
|
def on_class(node)
|
119
130
|
cname, inheritance, *body = node.children
|
120
131
|
return super unless cname.children.first == nil
|
121
|
-
|
122
|
-
|
132
|
+
|
133
|
+
if inheritance == s(:const, nil, :React) or
|
123
134
|
inheritance == s(:const, s(:const, nil, :React), :Component) or
|
124
135
|
inheritance == s(:send, s(:const, nil, :React), :Component)
|
125
136
|
|
126
|
-
|
137
|
+
react = :React
|
138
|
+
prepend_list << REACT_IMPORTS[:React] if modules_enabled?
|
139
|
+
|
140
|
+
elsif inheritance == s(:const, nil, :Preact) or
|
141
|
+
inheritance == s(:const, s(:const, nil, :Preact), :Component) or
|
142
|
+
inheritance == s(:send, s(:const, nil, :Preact), :Component)
|
143
|
+
|
144
|
+
react = :Preact
|
145
|
+
prepend_list << REACT_IMPORTS[:Preact] if modules_enabled?
|
146
|
+
else
|
147
|
+
return super
|
148
|
+
end
|
127
149
|
|
128
150
|
# traverse down to actual list of class statements
|
129
151
|
if body.length == 1
|
@@ -141,12 +163,14 @@ module Ruby2JS
|
|
141
163
|
end
|
142
164
|
|
143
165
|
begin
|
144
|
-
react, @react = @react,
|
166
|
+
react, @react = @react, react
|
145
167
|
reactClass, @reactClass = @reactClass, true
|
146
168
|
|
147
169
|
pairs = []
|
148
170
|
|
149
|
-
|
171
|
+
createClass = (@react == :React and not es2015)
|
172
|
+
|
173
|
+
if createClass
|
150
174
|
# automatically capture the displayName for the class
|
151
175
|
pairs << s(:pair, s(:sym, :displayName),
|
152
176
|
s(:str, cname.children.last.to_s))
|
@@ -156,12 +180,11 @@ module Ruby2JS
|
|
156
180
|
statics = []
|
157
181
|
body.select {|child| child.type == :defs}.each do |child|
|
158
182
|
_parent, mname, args, *block = child.children
|
159
|
-
if
|
160
|
-
|
161
|
-
pairs << s(:defs, s(:self), mname, args, *block)
|
183
|
+
if not createClass
|
184
|
+
pairs << child
|
162
185
|
elsif child.is_method?
|
163
|
-
statics << s(:pair, s(:sym, mname),
|
164
|
-
[s(:send, nil, :proc), args, s(:autoreturn, *block)]))
|
186
|
+
statics << s(:pair, s(:sym, mname), child.updated(:block,
|
187
|
+
[s(:send, nil, :proc), args, s(:autoreturn, *block)]))
|
165
188
|
elsif \
|
166
189
|
block.length == 1 and
|
167
190
|
Converter::EXPRESSIONS.include? block.first.type
|
@@ -212,13 +235,53 @@ module Ruby2JS
|
|
212
235
|
scan_events[node.children]
|
213
236
|
end
|
214
237
|
end
|
215
|
-
scan_events[body]
|
238
|
+
scan_events[body] if createClass
|
216
239
|
|
217
240
|
# append statics (if any)
|
218
241
|
unless statics.empty?
|
219
242
|
pairs << s(:pair, s(:sym, :statics), s(:hash, *statics))
|
220
243
|
end
|
221
244
|
|
245
|
+
# determine if this class can be emitted as a hook
|
246
|
+
hook = (es2015 and inheritance.children.first == nil)
|
247
|
+
hookinit = nil
|
248
|
+
useState = []
|
249
|
+
body.each_with_index do |statement, index|
|
250
|
+
if statement.type == :def
|
251
|
+
method = statement.children.first
|
252
|
+
if method == :initialize
|
253
|
+
children = statement.children[2..-1]
|
254
|
+
children.pop unless children.last
|
255
|
+
while children.length == 1 and children.first.type == :begin
|
256
|
+
children = children.first.children
|
257
|
+
end
|
258
|
+
hookinit = index if children.any? {|child| child.type != :ivasgn}
|
259
|
+
elsif method == :render
|
260
|
+
nil
|
261
|
+
elsif ReactLifecycle.include? method.to_s
|
262
|
+
hook = false
|
263
|
+
elsif not statement.is_method?
|
264
|
+
hook = false
|
265
|
+
elsif method.to_s.end_with? '='
|
266
|
+
hook = false
|
267
|
+
end
|
268
|
+
elsif statement.type == :defs
|
269
|
+
hook = false
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
if hook
|
274
|
+
@reactClass = :hook
|
275
|
+
@react_props = []
|
276
|
+
@react_methods = []
|
277
|
+
|
278
|
+
if hookinit
|
279
|
+
body = body.dup
|
280
|
+
hookinit = body.delete_at(hookinit)
|
281
|
+
pairs.unshift process hookinit.children[2]
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
222
285
|
# create a default getInitialState method if there is no such method
|
223
286
|
# and there are either references to instance variables or there are
|
224
287
|
# methods that need to be bound.
|
@@ -230,7 +293,13 @@ module Ruby2JS
|
|
230
293
|
then
|
231
294
|
@reactIvars = {pre: [], post: [], asgn: [], ref: [], cond: []}
|
232
295
|
react_walk(node)
|
233
|
-
|
296
|
+
|
297
|
+
if hook
|
298
|
+
react_walk(hookinit) if hookinit
|
299
|
+
useState = (@reactIvars[:asgn] + @reactIvars[:ref]).uniq
|
300
|
+
end
|
301
|
+
|
302
|
+
if createClass and not @reactIvars.values.flatten.empty?
|
234
303
|
body = [s(:def, :getInitialState, s(:args),
|
235
304
|
s(:return, s(:hash))), *body]
|
236
305
|
elsif not needs_binding.empty? or not @reactIvars.values.flatten.empty?
|
@@ -242,16 +311,21 @@ module Ruby2JS
|
|
242
311
|
body.select {|child| child.type == :def}.each do |child|
|
243
312
|
mname, args, *block = child.children
|
244
313
|
@reactMethod = mname
|
245
|
-
|
314
|
+
|
315
|
+
if @reactClass == :hook
|
316
|
+
@reactProps = s(:lvar, :"prop$")
|
317
|
+
else
|
318
|
+
@reactProps = child.updated(:attr, [s(:self), :props])
|
319
|
+
end
|
246
320
|
|
247
321
|
# analyze ivar usage
|
248
322
|
@reactIvars = {pre: [], post: [], asgn: [], ref: [], cond: []}
|
249
323
|
react_walk(child) unless mname == :initialize
|
250
|
-
@reactIvars[:capture] =
|
251
|
-
|
324
|
+
@reactIvars[:capture] = (@reactIvars[:pre] + @reactIvars[:post]).uniq
|
325
|
+
@reactIvars[:pre] = @reactIvars[:post] = [] if @reactClass == :hook
|
252
326
|
|
253
327
|
if mname == :initialize
|
254
|
-
mname =
|
328
|
+
mname = createClass ? :getInitialState : :initialize
|
255
329
|
|
256
330
|
# extract real list of statements
|
257
331
|
if block.length == 1
|
@@ -333,7 +407,7 @@ module Ruby2JS
|
|
333
407
|
else
|
334
408
|
# wrap multi-line blocks with a React Fragment
|
335
409
|
block = [s(:return,
|
336
|
-
s(:block, s(:send, nil,
|
410
|
+
s(:block, s(:send, nil, :"_#{@react}.Fragment"), s(:args), *block))]
|
337
411
|
end
|
338
412
|
end
|
339
413
|
|
@@ -359,14 +433,14 @@ module Ruby2JS
|
|
359
433
|
type = :begin if block.first.type == :return
|
360
434
|
end
|
361
435
|
|
362
|
-
if
|
436
|
+
if createClass
|
437
|
+
pairs << s(:pair, s(:sym, mname), child.updated(:block,
|
438
|
+
[s(:send, nil, :proc), args, process(s(type, *block))]))
|
439
|
+
else
|
363
440
|
pairs << child.updated(
|
364
441
|
ReactLifecycle.include?(mname.to_s) ? :defm : :def,
|
365
442
|
[mname, args, process(s(type, *block))]
|
366
443
|
)
|
367
|
-
else
|
368
|
-
pairs << s(:pair, s(:sym, mname), child.updated(:block,
|
369
|
-
[s(:send, nil, :proc), args, process(s(type, *block))]))
|
370
444
|
end
|
371
445
|
|
372
446
|
# retain comment
|
@@ -374,38 +448,70 @@ module Ruby2JS
|
|
374
448
|
@comments[pairs.last] = @comments[child]
|
375
449
|
end
|
376
450
|
end
|
451
|
+
|
452
|
+
if createClass
|
453
|
+
# emit a createClass statement
|
454
|
+
node.updated(:casgn, [nil, cname.children.last,
|
455
|
+
s(:send, s(:const, nil, :React), :createClass, s(:hash, *pairs))])
|
456
|
+
elsif hook
|
457
|
+
initialize = pairs.find_index {|node| node.type == :def and node.children.first == :initialize}
|
458
|
+
|
459
|
+
hash = {}
|
460
|
+
if initialize
|
461
|
+
hash = pairs.delete_at(initialize)
|
462
|
+
hash = hash.children.last while %i(def begin send).include? hash&.type
|
463
|
+
hash = s(:hash) unless hash&.type == :hash
|
464
|
+
hash = hash.children.map {|pair|
|
465
|
+
[pair.children.first.children.first, pair.children.last]
|
466
|
+
}.to_h
|
467
|
+
end
|
468
|
+
|
469
|
+
useState.each do |symbol|
|
470
|
+
hash[symbol.to_s[1..-1]] ||= s(:nil)
|
471
|
+
end
|
472
|
+
|
473
|
+
hash.sort.reverse.each do |var, value|
|
474
|
+
if @react == :Preact
|
475
|
+
hooker = nil
|
476
|
+
prepend_list << REACT_IMPORTS[:PreactHook] if modules_enabled?
|
477
|
+
else
|
478
|
+
hooker = s(:const, nil, :React)
|
479
|
+
end
|
480
|
+
|
481
|
+
setter = 'set' + var[0].upcase + var[1..-1]
|
482
|
+
pairs.unshift(s(:masgn, s(:mlhs, s(:lvasgn, var),
|
483
|
+
s(:lvasgn, setter)), s(:send, hooker, :useState, value)))
|
484
|
+
end
|
485
|
+
|
486
|
+
render = pairs.find_index {|node| node.type == :defm and node.children.first == :render}
|
487
|
+
if render
|
488
|
+
render = pairs.delete_at(render)
|
489
|
+
pairs.push s(:autoreturn, render.children.last)
|
490
|
+
end
|
491
|
+
|
492
|
+
has_cvar = lambda {|list|
|
493
|
+
list.any? {|node|
|
494
|
+
next unless Parser::AST::Node === node
|
495
|
+
return true if node.type == :cvar
|
496
|
+
has_cvar.call(node.children)
|
497
|
+
}
|
498
|
+
}
|
499
|
+
args = has_cvar[node.children] ? s(:args, s(:arg, 'prop$')) : s(:args)
|
500
|
+
|
501
|
+
node.updated(:def, [cname.children.last, args, s(:begin, *pairs)])
|
502
|
+
else
|
503
|
+
# emit a class that extends React.Component
|
504
|
+
node.updated(:class, [s(:const, nil, cname.children.last),
|
505
|
+
s(:attr, s(:const, nil, @react), :Component), *pairs])
|
506
|
+
end
|
377
507
|
ensure
|
378
508
|
@react = react
|
379
509
|
@reactClass = reactClass
|
380
510
|
@reactMethod = nil
|
381
511
|
end
|
382
|
-
|
383
|
-
if es2015
|
384
|
-
# emit a class that extends React.Component
|
385
|
-
node.updated(:class, [s(:const, nil, cname.children.last),
|
386
|
-
s(:attr, s(:const, nil, :React), :Component), *pairs])
|
387
|
-
else
|
388
|
-
# emit a createClass statement
|
389
|
-
node.updated(:casgn, [nil, cname.children.last,
|
390
|
-
s(:send, s(:const, nil, :React), :createClass, s(:hash, *pairs))])
|
391
|
-
end
|
392
512
|
end
|
393
513
|
|
394
514
|
def on_send(node)
|
395
|
-
# convert Vue.utile.defineReactive to class fields or assignments
|
396
|
-
if node.children.first == s(:send, s(:const, nil, :Vue), :util)
|
397
|
-
if node.children[1] == :defineReactive
|
398
|
-
if node.children[2].type == :cvar
|
399
|
-
return process s(:cvasgn, node.children[2].children.first,
|
400
|
-
node.children[3])
|
401
|
-
elsif node.children[2].type == :send
|
402
|
-
assign = node.children[2]
|
403
|
-
return assign.updated(nil, [assign.children[0],
|
404
|
-
assign.children[1].to_s + '=', node.children[3]])
|
405
|
-
end
|
406
|
-
end
|
407
|
-
end
|
408
|
-
|
409
515
|
# calls to methods (including getters) defined in this class
|
410
516
|
if node.children[0]==nil and Symbol === node.children[1]
|
411
517
|
if node.is_method?
|
@@ -423,16 +529,12 @@ module Ruby2JS
|
|
423
529
|
end
|
424
530
|
end
|
425
531
|
|
426
|
-
if node.children.first == s(:const, nil, :Vue)
|
427
|
-
node = node.updated(nil, [s(:const, nil, :React),
|
428
|
-
*node.children[1..-1]])
|
429
|
-
end
|
430
|
-
|
431
532
|
if not @react
|
432
533
|
# enable React filtering within React class method calls or
|
433
534
|
# React component calls
|
434
535
|
if \
|
435
536
|
node.children.first == s(:const, nil, :React) or
|
537
|
+
node.children.first == s(:const, nil, :Preact) or
|
436
538
|
node.children.first == s(:const, nil, :ReactDOM)
|
437
539
|
then
|
438
540
|
if modules_enabled?
|
@@ -440,7 +542,8 @@ module Ruby2JS
|
|
440
542
|
end
|
441
543
|
|
442
544
|
begin
|
443
|
-
react
|
545
|
+
react = @react
|
546
|
+
@react = (node.children.first.children.last == :Preact ? :Preact : :React)
|
444
547
|
return on_send(node)
|
445
548
|
ensure
|
446
549
|
@react = react
|
@@ -461,13 +564,26 @@ module Ruby2JS
|
|
461
564
|
end
|
462
565
|
|
463
566
|
elsif \
|
464
|
-
@reactApply and node.children[1] == :createElement and
|
465
|
-
node.children[0] == s(:const, nil, :React)
|
567
|
+
(@reactApply and node.children[1] == :createElement and
|
568
|
+
node.children[0] == s(:const, nil, :React)) or
|
569
|
+
(@reactApply and node.children[1] == :h and
|
570
|
+
node.children[0] == s(:const, nil, :Preact))
|
466
571
|
then
|
467
572
|
# push results of explicit calls to React.createElement
|
468
573
|
s(:send, s(:gvar, :$_), :push, s(:send, *node.children[0..1],
|
469
574
|
*process_all(node.children[2..-1])))
|
470
575
|
|
576
|
+
elsif \
|
577
|
+
@react == :Preact and node.children[1] == :h and node.children[0] == nil
|
578
|
+
then
|
579
|
+
if @reactApply
|
580
|
+
# push results of explicit calls to Preact.h
|
581
|
+
s(:send, s(:gvar, :$_), :push, s(:send, s(:const, nil, :Preact), :h,
|
582
|
+
*process_all(node.children[2..-1])))
|
583
|
+
else
|
584
|
+
node.updated(nil, [s(:const, nil, :Preact), :h, *process_all(node.children[2..-1])])
|
585
|
+
end
|
586
|
+
|
471
587
|
elsif !@jsx and node.children[0] == nil and node.children[1] =~ /^_\w/
|
472
588
|
# map method calls starting with an underscore to React calls
|
473
589
|
# to create an element.
|
@@ -549,7 +665,12 @@ module Ruby2JS
|
|
549
665
|
else
|
550
666
|
value = s(:str, values.join(' '))
|
551
667
|
end
|
552
|
-
|
668
|
+
|
669
|
+
if @react == :Preact
|
670
|
+
pairs.unshift s(:pair, s(:sym, :class), value)
|
671
|
+
else
|
672
|
+
pairs.unshift s(:pair, s(:sym, :className), value)
|
673
|
+
end
|
553
674
|
end
|
554
675
|
|
555
676
|
# support controlled form components
|
@@ -559,13 +680,28 @@ module Ruby2JS
|
|
559
680
|
['value', :value].include? pair.children.first.children.first
|
560
681
|
end
|
561
682
|
|
562
|
-
|
683
|
+
event = (@react == :Preact ? :onInput : :onChange)
|
684
|
+
|
685
|
+
|
686
|
+
# search for the presence of a onInput/onChange attribute
|
563
687
|
onChange = pairs.find_index do |pair|
|
564
|
-
|
688
|
+
pair.children.first.children[0].to_s == event.to_s
|
689
|
+
end
|
690
|
+
|
691
|
+
if event == :onInput and not onChange
|
692
|
+
# search for the presence of a 'onChange' attribute
|
693
|
+
onChange = pairs.find_index do |pair|
|
694
|
+
pair.children.first.children[0].to_s == 'onChange'
|
695
|
+
end
|
696
|
+
|
697
|
+
if onChange
|
698
|
+
pairs[onChange] = s(:pair, s(:sym, event),
|
699
|
+
pairs[onChange].children.last)
|
700
|
+
end
|
565
701
|
end
|
566
702
|
|
567
703
|
if value and pairs[value].children.last.type == :ivar and !onChange
|
568
|
-
pairs << s(:pair, s(:sym,
|
704
|
+
pairs << s(:pair, s(:sym, event),
|
569
705
|
s(:block, s(:send, nil, :proc), s(:args, s(:arg, :event)),
|
570
706
|
s(:ivasgn, pairs[value].children.last.children.first,
|
571
707
|
s(:attr, s(:attr, s(:lvar, :event), :target), :value))))
|
@@ -578,7 +714,7 @@ module Ruby2JS
|
|
578
714
|
end
|
579
715
|
|
580
716
|
if checked and pairs[checked].children.last.type == :ivar
|
581
|
-
pairs << s(:pair, s(:sym,
|
717
|
+
pairs << s(:pair, s(:sym, event),
|
582
718
|
s(:block, s(:send, nil, :proc), s(:args),
|
583
719
|
s(:ivasgn, pairs[checked].children.last.children.first,
|
584
720
|
s(:send, pairs[checked].children.last, :!))))
|
@@ -586,13 +722,25 @@ module Ruby2JS
|
|
586
722
|
end
|
587
723
|
end
|
588
724
|
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
[
|
725
|
+
if @react == :Preact
|
726
|
+
# replace selected Reactisms with native HTML
|
727
|
+
pairs.each_with_index do |pair, index|
|
728
|
+
next if pair.type == :kwsplat
|
729
|
+
name = pair.children.first.children.first.to_sym
|
730
|
+
if PreactAttrMap[name]
|
731
|
+
pairs[index] = pairs[index].updated(nil,
|
732
|
+
[s(:str, PreactAttrMap[name]), pairs[index].children.last])
|
733
|
+
end
|
734
|
+
end
|
735
|
+
else
|
736
|
+
# replace attribute names with case-sensitive javascript properties
|
737
|
+
pairs.each_with_index do |pair, index|
|
738
|
+
next if pair.type == :kwsplat
|
739
|
+
name = pair.children.first.children.first.downcase
|
740
|
+
if ReactAttrMap[name] and name.to_s != ReactAttrMap[name]
|
741
|
+
pairs[index] = pairs[index].updated(nil,
|
742
|
+
[s(:str, ReactAttrMap[name]), pairs[index].children.last])
|
743
|
+
end
|
596
744
|
end
|
597
745
|
end
|
598
746
|
|
@@ -654,8 +802,14 @@ module Ruby2JS
|
|
654
802
|
# explicit call to React.createElement
|
655
803
|
next true if arg.children[1] == :createElement and
|
656
804
|
arg.children[0] == s(:const, nil, :React)
|
657
|
-
|
658
|
-
|
805
|
+
|
806
|
+
# explicit call to Preact.h
|
807
|
+
next true if arg.children[1] == :h and
|
808
|
+
arg.children[0] == s(:const, nil, :Preact)
|
809
|
+
|
810
|
+
# explicit call to h
|
811
|
+
next true if arg.children[1] == :h and
|
812
|
+
arg.children[0] == nil
|
659
813
|
|
660
814
|
# JSX
|
661
815
|
next true if arg.type == :xstr
|
@@ -717,8 +871,13 @@ module Ruby2JS
|
|
717
871
|
params.pop if params.last == s(:nil)
|
718
872
|
|
719
873
|
# construct element using params
|
720
|
-
|
721
|
-
:
|
874
|
+
if @react == :Preact
|
875
|
+
element = node.updated(:send, [s(:const, nil, :Preact),
|
876
|
+
:h, *params])
|
877
|
+
else
|
878
|
+
element = node.updated(:send, [s(:const, nil, :React),
|
879
|
+
:createElement, *params])
|
880
|
+
end
|
722
881
|
|
723
882
|
if @reactApply
|
724
883
|
# if apply is set, emit code that pushes result
|
@@ -846,8 +1005,13 @@ module Ruby2JS
|
|
846
1005
|
while node != child
|
847
1006
|
if node.children[1] !~ /!$/
|
848
1007
|
# convert method name to hash {className: name} pair
|
849
|
-
|
850
|
-
s(:
|
1008
|
+
if @react == :Preact
|
1009
|
+
pair = s(:pair, s(:sym, :class),
|
1010
|
+
s(:str, node.children[1].to_s.gsub('_','-')))
|
1011
|
+
else
|
1012
|
+
pair = s(:pair, s(:sym, :className),
|
1013
|
+
s(:str, node.children[1].to_s.gsub('_','-')))
|
1014
|
+
end
|
851
1015
|
else
|
852
1016
|
# convert method name to hash {id: name} pair
|
853
1017
|
pair = s(:pair, s(:sym, :id),
|
@@ -917,8 +1081,11 @@ module Ruby2JS
|
|
917
1081
|
# Base Ruby2JS processing will convert the 'splat' to 'apply'
|
918
1082
|
child = node.children.first
|
919
1083
|
if \
|
920
|
-
child.children[1] == :createElement and
|
921
|
-
child.children[0] == s(:const, nil, :React)
|
1084
|
+
(child.children[1] == :createElement and
|
1085
|
+
child.children[0] == s(:const, nil, :React)) or
|
1086
|
+
(child.children[1] == :h and
|
1087
|
+
(child.children[0] == s(:const, nil, :Preact) or
|
1088
|
+
child.children[0] == nil))
|
922
1089
|
then
|
923
1090
|
begin
|
924
1091
|
reactApply, @reactApply = @reactApply, true
|
@@ -931,11 +1098,13 @@ module Ruby2JS
|
|
931
1098
|
@reactApply = reactApply
|
932
1099
|
end
|
933
1100
|
|
1101
|
+
target = child.children[0] || s(:const, nil, :Preact)
|
1102
|
+
|
934
1103
|
if reactApply
|
935
1104
|
return child.updated(:send, [s(:gvar, :$_), :push,
|
936
|
-
s(:send,
|
1105
|
+
s(:send, target, child.children[1], *params)])
|
937
1106
|
else
|
938
|
-
return child.updated(:send, [
|
1107
|
+
return child.updated(:send, [target, child.children[1], *params])
|
939
1108
|
end
|
940
1109
|
end
|
941
1110
|
|
@@ -952,7 +1121,7 @@ module Ruby2JS
|
|
952
1121
|
block = s(:block, s(:send, nil, :proc), s(:args),
|
953
1122
|
*node.children[2..-1])
|
954
1123
|
return on_send node.children.first.updated(:send,
|
955
|
-
[nil,
|
1124
|
+
[nil, :"_#{@react}.Fragment", block])
|
956
1125
|
|
957
1126
|
elsif !@jsx and child.children[0] == nil and child.children[1] =~ /^_\w/
|
958
1127
|
if node.children[1].children.empty?
|
@@ -998,13 +1167,17 @@ module Ruby2JS
|
|
998
1167
|
# convert global variables to refs
|
999
1168
|
def on_gvar(node)
|
1000
1169
|
return super unless @reactClass
|
1170
|
+
return super if @reactClass == :hook
|
1001
1171
|
s(:attr, s(:attr, s(:self), :refs), node.children.first.to_s[1..-1])
|
1002
1172
|
end
|
1003
1173
|
|
1004
1174
|
# convert instance variables to state
|
1005
1175
|
def on_ivar(node)
|
1006
1176
|
return super unless @reactClass
|
1007
|
-
|
1177
|
+
|
1178
|
+
if @reactClass == :hook
|
1179
|
+
node.updated(:lvar, [node.children.first.to_s[1..-1]])
|
1180
|
+
elsif @reactMethod and @reactIvars[:capture].include? node.children.first
|
1008
1181
|
node.updated(:lvar, ["$#{node.children.first[1..-1]}"])
|
1009
1182
|
else
|
1010
1183
|
node.updated(:attr, [s(:attr, s(:self), :state),
|
@@ -1016,11 +1189,17 @@ module Ruby2JS
|
|
1016
1189
|
def on_ivasgn(node)
|
1017
1190
|
return super unless @react
|
1018
1191
|
|
1192
|
+
if @reactClass == :hook
|
1193
|
+
var = node.children.first.to_s[1..-1]
|
1194
|
+
return node.updated(:send, [nil, 'set' + var[0].upcase + var[1..-1],
|
1195
|
+
process(node.children.last)])
|
1196
|
+
end
|
1197
|
+
|
1019
1198
|
if @reactMethod and @reactIvars[:capture].include? node.children.first
|
1020
1199
|
ivar = node.children.first.to_s
|
1021
1200
|
if @reactBlock
|
1022
1201
|
return s(:send, s(:self), :setState, s(:hash, s(:pair,
|
1023
|
-
s(:
|
1202
|
+
s(:str, ivar[1..-1]), process(s(:lvasgn, "$#{ivar[1..-1]}",
|
1024
1203
|
*node.children[1..-1])))))
|
1025
1204
|
else
|
1026
1205
|
return s(:lvasgn, "$#{ivar[1..-1]}",
|
@@ -1072,10 +1251,14 @@ module Ruby2JS
|
|
1072
1251
|
return super unless @react
|
1073
1252
|
return super unless node.children.first.type == :ivasgn
|
1074
1253
|
var = node.children.first.children.first
|
1075
|
-
if @
|
1254
|
+
if @reactClass == :hook
|
1255
|
+
var = node.children.first.children.first.to_s[1..-1]
|
1256
|
+
node.updated(:send, [nil, 'set' + var[0].upcase + var[1..-1],
|
1257
|
+
s(:send, s(:lvar, var), *node.children[1..-1])])
|
1258
|
+
elsif @reactMethod and @reactIvars[:capture].include? var
|
1076
1259
|
if @reactBlock
|
1077
1260
|
s(:send, s(:self), :setState, s(:hash, s(:pair,
|
1078
|
-
s(:
|
1261
|
+
s(:str, var[1..-1]), process(s(node.type,
|
1079
1262
|
s(:lvasgn, "$#{var[1..-1]}"), *node.children[1..-1])))))
|
1080
1263
|
else
|
1081
1264
|
process s(node.type, s(:lvasgn, "$#{var[1..-1]}"),
|
@@ -1118,9 +1301,13 @@ module Ruby2JS
|
|
1118
1301
|
return true if node.children[1] == :createElement and
|
1119
1302
|
node.children[0] == s(:const, nil, :React)
|
1120
1303
|
|
1121
|
-
# explicit call to
|
1122
|
-
return true if node.children[1] == :
|
1123
|
-
node.children[0] == s(:const, nil, :
|
1304
|
+
# explicit call to Preact.h
|
1305
|
+
return true if node.children[1] == :h and
|
1306
|
+
node.children[0] == s(:const, nil, :Preact)
|
1307
|
+
|
1308
|
+
# explicit call to h
|
1309
|
+
return true if node.children[1] == :h and
|
1310
|
+
node.children[0] == nil
|
1124
1311
|
end
|
1125
1312
|
|
1126
1313
|
# wunderbar style call
|
@@ -1256,6 +1443,7 @@ module Ruby2JS
|
|
1256
1443
|
@reactIvars = {pre: [], post: [], asgn: [], ref: [], cond: []}
|
1257
1444
|
react_walk(node.children.last)
|
1258
1445
|
@reactIvars[:capture] = (@reactIvars[:pre] + @reactIvars[:post]).uniq
|
1446
|
+
@reactIvars[:pre] = @reactIvars[:post] = [] if @reactClass == :hook
|
1259
1447
|
node = super
|
1260
1448
|
block = react_process_ivars([node.children.last.dup])
|
1261
1449
|
node.updated(nil, [*node.children[0..-2], s(:begin, *block)])
|
@@ -1280,7 +1468,7 @@ module Ruby2JS
|
|
1280
1468
|
# update ivars that are set and later referenced
|
1281
1469
|
unless @reactIvars[:post].empty?
|
1282
1470
|
updates = @reactIvars[:post].uniq.sort.reverse.map do |ivar|
|
1283
|
-
s(:pair, s(:
|
1471
|
+
s(:pair, s(:str, ivar.to_s[1..-1]),
|
1284
1472
|
s(:lvar, "$#{ivar.to_s[1..-1]}"))
|
1285
1473
|
end
|
1286
1474
|
update = s(:send, s(:self), :setState, s(:hash, *updates))
|