ruby2js 4.0.5 → 4.1.4
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/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))
|