ruby2js 4.0.1 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +0 -1
- data/lib/ruby2js.rb +13 -2
- data/lib/ruby2js/converter.rb +31 -0
- data/lib/ruby2js/converter/args.rb +1 -1
- data/lib/ruby2js/converter/class.rb +6 -4
- data/lib/ruby2js/converter/class2.rb +4 -4
- data/lib/ruby2js/converter/def.rb +7 -1
- data/lib/ruby2js/converter/dstr.rb +3 -1
- data/lib/ruby2js/converter/for.rb +1 -1
- data/lib/ruby2js/converter/next.rb +10 -2
- data/lib/ruby2js/converter/redo.rb +14 -0
- data/lib/ruby2js/converter/return.rb +1 -1
- data/lib/ruby2js/converter/send.rb +1 -0
- data/lib/ruby2js/converter/taglit.rb +9 -2
- data/lib/ruby2js/converter/while.rb +1 -1
- data/lib/ruby2js/converter/whilepost.rb +1 -1
- data/lib/ruby2js/filter/functions.rb +44 -9
- data/lib/ruby2js/filter/lit-element.rb +202 -0
- data/lib/ruby2js/filter/react.rb +155 -91
- data/lib/ruby2js/filter/stimulus.rb +4 -2
- data/lib/ruby2js/filter/tagged_templates.rb +4 -2
- data/lib/ruby2js/rails.rb +6 -59
- data/lib/ruby2js/serializer.rb +16 -11
- data/lib/ruby2js/sprockets.rb +40 -0
- data/lib/ruby2js/version.rb +2 -2
- data/lib/tasks/README.md +4 -0
- data/lib/tasks/install/app/javascript/elements/index.js +2 -0
- data/lib/tasks/install/config/webpack/loaders/ruby2js.js +20 -0
- data/lib/tasks/install/litelement.rb +9 -0
- data/lib/tasks/install/preact.rb +3 -0
- data/lib/tasks/install/react.rb +2 -0
- data/lib/tasks/install/stimulus-sprockets.rb +32 -0
- data/lib/tasks/install/stimulus-webpacker.rb +5 -0
- data/lib/tasks/install/webpacker.rb +80 -0
- data/lib/tasks/nodetest.js +47 -0
- data/lib/tasks/ruby2js_tasks.rake +47 -0
- data/ruby2js.gemspec +1 -1
- metadata +18 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46b6cba0b33ebf62cb966def9b680eda35f5e84ff0c3adaea058fc2aae242269
|
4
|
+
data.tar.gz: 6c5843992eccd24e8460b16f805eab16701d70d85e8ef4dcaffee948243666c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6910f39474f2c22c321b91ad742ab10f7fff08bc5408e53f9b4d0cdee4f4fead414519a1b31bf7e6f781dc31da71fbda55bc747132c0d78e8eeb62a8693ca419
|
7
|
+
data.tar.gz: 07b1ddbff32682c2ea3fa65570e40f97907eea4765d00ea4b7921bca5156f83f8f855178ab13ed3fc70b9edb8035fc801cdb4031c6f8176e044699099ac7dccd
|
data/README.md
CHANGED
@@ -3,7 +3,6 @@ Ruby2JS
|
|
3
3
|
|
4
4
|
Minimal yet extensible Ruby to JavaScript conversion.
|
5
5
|
|
6
|
-
[![Build Status](https://travis-ci.org/rubys/ruby2js.svg)](https://travis-ci.org/rubys/ruby2js)
|
7
6
|
[![Gem Version](https://badge.fury.io/rb/ruby2js.svg)](https://badge.fury.io/rb/ruby2js)
|
8
7
|
[![Gitter](https://badges.gitter.im/ruby2js/community.svg)](https://gitter.im/ruby2js/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
9
8
|
|
data/lib/ruby2js.rb
CHANGED
@@ -92,6 +92,17 @@ module Ruby2JS
|
|
92
92
|
include_only(options[:include_only]) if options[:include_only]
|
93
93
|
include(options[:include]) if options[:include]
|
94
94
|
exclude(options[:exclude]) if options[:exclude]
|
95
|
+
|
96
|
+
filters = options[:filters] || DEFAULTS
|
97
|
+
@modules_enabled =
|
98
|
+
(defined? Ruby2JS::Filter::ESM and
|
99
|
+
filters.include? Ruby2JS::Filter::ESM) or
|
100
|
+
(defined? Ruby2JS::Filter::CJS and
|
101
|
+
filters.include? Ruby2JS::Filter::CJS)
|
102
|
+
end
|
103
|
+
|
104
|
+
def modules_enabled?
|
105
|
+
@modules_enabled
|
95
106
|
end
|
96
107
|
|
97
108
|
def es2015
|
@@ -169,7 +180,7 @@ module Ruby2JS
|
|
169
180
|
def on_xnode(node); end
|
170
181
|
def on_export(node); end
|
171
182
|
def on_import(node); end
|
172
|
-
def on_taglit(node); end
|
183
|
+
def on_taglit(node); on_pair(node); end
|
173
184
|
|
174
185
|
# provide a method so filters can call 'super'
|
175
186
|
def on_sym(node); node; end
|
@@ -279,7 +290,7 @@ module Ruby2JS
|
|
279
290
|
|
280
291
|
def self.parse(source, file=nil, line=1)
|
281
292
|
buffer = Parser::Source::Buffer.new(file, line)
|
282
|
-
buffer.source = source.encode('
|
293
|
+
buffer.source = source.encode('UTF-8')
|
283
294
|
parser = Parser::CurrentRuby.new
|
284
295
|
parser.diagnostics.all_errors_are_fatal = true
|
285
296
|
parser.diagnostics.consumer = lambda {|diagnostic| nil}
|
data/lib/ruby2js/converter.rb
CHANGED
@@ -60,12 +60,14 @@ module Ruby2JS
|
|
60
60
|
@class_parent = nil
|
61
61
|
@class_name = nil
|
62
62
|
@jsx = false
|
63
|
+
@autobind = true
|
63
64
|
|
64
65
|
@eslevel = :es5
|
65
66
|
@strict = false
|
66
67
|
@comparison = :equality
|
67
68
|
@or = :logical
|
68
69
|
@underscored_private = true
|
70
|
+
@redoable = false
|
69
71
|
end
|
70
72
|
|
71
73
|
def width=(width)
|
@@ -243,6 +245,34 @@ module Ruby2JS
|
|
243
245
|
end
|
244
246
|
end
|
245
247
|
|
248
|
+
def redoable(block)
|
249
|
+
save_redoable = @redoable
|
250
|
+
|
251
|
+
has_redo = proc do |node|
|
252
|
+
node.children.any? do |child|
|
253
|
+
next false unless child.is_a? Parser::AST::Node
|
254
|
+
next true if child.type == :redo
|
255
|
+
next false if %i[for while while_post until until_post].include? child.type
|
256
|
+
has_redo[child]
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
@redoable = has_redo[@ast]
|
261
|
+
|
262
|
+
if @redoable
|
263
|
+
put es2015 ? 'let ' : 'var '
|
264
|
+
put "redo$#@sep"
|
265
|
+
puts 'do {'
|
266
|
+
put "redo$ = false#@sep"
|
267
|
+
scope block
|
268
|
+
put "#@nl} while(redo$)"
|
269
|
+
else
|
270
|
+
scope block
|
271
|
+
end
|
272
|
+
ensure
|
273
|
+
@redoable = save_redoable
|
274
|
+
end
|
275
|
+
|
246
276
|
def timestamp(file)
|
247
277
|
super
|
248
278
|
|
@@ -335,6 +365,7 @@ require 'ruby2js/converter/nil'
|
|
335
365
|
require 'ruby2js/converter/nthref'
|
336
366
|
require 'ruby2js/converter/opasgn'
|
337
367
|
require 'ruby2js/converter/prototype'
|
368
|
+
require 'ruby2js/converter/redo'
|
338
369
|
require 'ruby2js/converter/regexp'
|
339
370
|
require 'ruby2js/converter/return'
|
340
371
|
require 'ruby2js/converter/self'
|
@@ -32,7 +32,7 @@ module Ruby2JS
|
|
32
32
|
elsif kw.type == :kwoptarg
|
33
33
|
put kw.children.first
|
34
34
|
unless kw.children.last == s(:send, nil, :undefined)
|
35
|
-
put '
|
35
|
+
put '='; parse kw.children.last
|
36
36
|
end
|
37
37
|
elsif kw.type == :kwrestarg
|
38
38
|
raise 'Rest arg requires ES2018' unless es2018
|
@@ -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 == :def
|
62
|
+
node = if m.type == :def or m.type == :defm
|
62
63
|
if m.children.first == :initialize and !visible[:initialize]
|
63
64
|
# constructor: remove from body and overwrite init function
|
64
65
|
init = m
|
@@ -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
|
@@ -156,7 +156,7 @@ module Ruby2JS
|
|
156
156
|
end
|
157
157
|
end
|
158
158
|
|
159
|
-
if
|
159
|
+
if %i[def defm deff async].include? m.type
|
160
160
|
@prop = m.children.first
|
161
161
|
|
162
162
|
if @prop == :initialize and !@rbstack.last[:initialize]
|
@@ -190,11 +190,11 @@ module Ruby2JS
|
|
190
190
|
end
|
191
191
|
|
192
192
|
elsif \
|
193
|
-
[:defs, :asyncs].include? m.type and m.children.first.type == :self
|
193
|
+
[:defs, :defp, :asyncs].include? m.type and m.children.first.type == :self
|
194
194
|
then
|
195
195
|
|
196
196
|
@prop = "static #{m.children[1]}"
|
197
|
-
if not m.is_method?
|
197
|
+
if m.type == :defp or not m.is_method?
|
198
198
|
@prop = "static get #{m.children[1]}"
|
199
199
|
m = m.updated(m.type, [*m.children[0..2],
|
200
200
|
s(:autoreturn, m.children[3])])
|
@@ -142,7 +142,13 @@ module Ruby2JS
|
|
142
142
|
end
|
143
143
|
|
144
144
|
if style == :expression
|
145
|
-
expr.type == :
|
145
|
+
if expr.type == :taglit
|
146
|
+
parse expr
|
147
|
+
elsif expr.type == :hash
|
148
|
+
group(expr)
|
149
|
+
else
|
150
|
+
wrap('(', ')') { parse(expr) }
|
151
|
+
end
|
146
152
|
elsif body.type == :begin and body.children.length == 0
|
147
153
|
put "{}"
|
148
154
|
else
|
@@ -25,7 +25,9 @@ module Ruby2JS
|
|
25
25
|
put '`'
|
26
26
|
children.each do |child|
|
27
27
|
if child.type == :str
|
28
|
-
str = child.children.first.inspect[1..-2].
|
28
|
+
str = child.children.first.inspect[1..-2].
|
29
|
+
gsub('${', '$\{').gsub('`', '\\\`')
|
30
|
+
str = str.gsub(/\\"/, '"') unless str.include? '\\\\'
|
29
31
|
if heredoc
|
30
32
|
put! str.gsub("\\n", "\n")
|
31
33
|
else
|
@@ -5,8 +5,16 @@ module Ruby2JS
|
|
5
5
|
# (int 1))
|
6
6
|
|
7
7
|
handle :next do |n=nil|
|
8
|
-
|
9
|
-
|
8
|
+
if @next_token == :return
|
9
|
+
put 'return'
|
10
|
+
if n
|
11
|
+
put ' '
|
12
|
+
parse n
|
13
|
+
end
|
14
|
+
else
|
15
|
+
raise Error.new("next argument #{ n.inspect }", @ast) if n
|
16
|
+
put @next_token.to_s
|
17
|
+
end
|
10
18
|
end
|
11
19
|
end
|
12
20
|
end
|
@@ -15,7 +15,7 @@ module Ruby2JS
|
|
15
15
|
EXPRESSIONS = [ :array, :float, :hash, :int, :lvar, :nil, :send, :attr,
|
16
16
|
:str, :sym, :dstr, :dsym, :cvar, :ivar, :zsuper, :super, :or, :and,
|
17
17
|
:block, :const, :true, :false, :xnode, :taglit, :self,
|
18
|
-
:op_asgn, :and_asgn, :or_asgn ]
|
18
|
+
:op_asgn, :and_asgn, :or_asgn, :taglit, :gvar ]
|
19
19
|
|
20
20
|
handle :autoreturn do |*statements|
|
21
21
|
return if statements == [nil]
|
@@ -6,8 +6,15 @@ module Ruby2JS
|
|
6
6
|
# (dstr)
|
7
7
|
|
8
8
|
handle :taglit do |tag, *children|
|
9
|
-
|
10
|
-
|
9
|
+
begin
|
10
|
+
# disable autobinding in tag literals
|
11
|
+
save_autobind, @autobind = @autobind, false
|
12
|
+
|
13
|
+
put tag.children.first
|
14
|
+
parse_all(*children, join: '')
|
15
|
+
ensure
|
16
|
+
@autobind = save_autobind
|
17
|
+
end
|
11
18
|
end
|
12
19
|
end
|
13
20
|
end
|
@@ -11,7 +11,7 @@ module Ruby2JS
|
|
11
11
|
begin
|
12
12
|
next_token, @next_token = @next_token, :continue
|
13
13
|
|
14
|
-
puts 'do {';
|
14
|
+
puts 'do {'; redoable block; sput '} while ('; parse condition; put ')'
|
15
15
|
ensure
|
16
16
|
@next_token = next_token
|
17
17
|
end
|
@@ -210,10 +210,10 @@ module Ruby2JS
|
|
210
210
|
s(:block, s(:send, nil, :proc), s(:args, s(:arg, :s)),
|
211
211
|
s(:send, s(:lvar, :s), :slice, s(:int, 1))))
|
212
212
|
else
|
213
|
-
# str.match(/.../g).map(s => s.match(/.../).slice(1))
|
213
|
+
# (str.match(/.../g) || []).map(s => s.match(/.../).slice(1))
|
214
214
|
s(:block, s(:send,
|
215
|
-
s(:send, process(target), :match, gpattern), :
|
216
|
-
s(:args, s(:arg, :s)),
|
215
|
+
s(:or, s(:send, process(target), :match, gpattern), s(:array)),
|
216
|
+
:map), s(:args, s(:arg, :s)),
|
217
217
|
s(:return, s(:send, s(:send, s(:lvar, :s), :match, arg),
|
218
218
|
:slice, s(:int, 1))))
|
219
219
|
end
|
@@ -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
|
@@ -508,6 +513,36 @@ module Ruby2JS
|
|
508
513
|
elsif method == :floor and args.length == 0
|
509
514
|
process S(:send, s(:const, nil, :Math), :floor, target)
|
510
515
|
|
516
|
+
elsif method == :rand and target == nil
|
517
|
+
if args.length == 0
|
518
|
+
process S(:send!, s(:const, nil, :Math), :random)
|
519
|
+
elsif %i[irange erange].include? args.first.type
|
520
|
+
range = args.first
|
521
|
+
multiplier = s(:send, range.children.last, :-, range.children.first)
|
522
|
+
if range.children.all? {|child| child.type == :int}
|
523
|
+
multiplier = s(:int, range.children.last.children.last - range.children.first.children.last)
|
524
|
+
multiplier = s(:int, multiplier.children.first + 1) if range.type == :irange
|
525
|
+
elsif range.type == :irange
|
526
|
+
if multiplier.children.last.type == :int
|
527
|
+
diff = multiplier.children.last.children.last - 1
|
528
|
+
multiplier = s(:send, *multiplier.children[0..1], s(:int, diff))
|
529
|
+
multiplier = multiplier.children.first if diff == 0
|
530
|
+
multiplier = s(:send, multiplier.children[0], :+, s(:int, -diff)) if diff < 0
|
531
|
+
else
|
532
|
+
multiplier = s(:send, multiplier, :+, s(:int, 1))
|
533
|
+
end
|
534
|
+
end
|
535
|
+
raw = s(:send, s(:send, s(:const, nil, :Math), :random), :*, multiplier)
|
536
|
+
if range.children.first != s(:int, 0)
|
537
|
+
raw = s(:send, raw, :+, range.children.first)
|
538
|
+
end
|
539
|
+
process S(:send, nil, :parseInt, raw)
|
540
|
+
else
|
541
|
+
process S(:send, nil, :parseInt,
|
542
|
+
s(:send, s(:send, s(:const, nil, :Math), :random),
|
543
|
+
:*, args.first))
|
544
|
+
end
|
545
|
+
|
511
546
|
elsif method == :sum and args.length == 0
|
512
547
|
process S(:send, target, :reduce, s(:block, s(:send, nil, :proc),
|
513
548
|
s(:args, s(:arg, :a), s(:arg, :b)),
|
@@ -737,10 +772,10 @@ module Ruby2JS
|
|
737
772
|
body.any? {|statement| statement.type == :def and
|
738
773
|
statement.children.first == :initialize}
|
739
774
|
then
|
740
|
-
body.unshift
|
741
|
-
s(:begin,
|
742
|
-
|
743
|
-
|
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,
|
744
779
|
s(:lvar, :message)), :stack))))
|
745
780
|
end
|
746
781
|
|
@@ -0,0 +1,202 @@
|
|
1
|
+
require 'ruby2js'
|
2
|
+
|
3
|
+
module Ruby2JS
|
4
|
+
module Filter
|
5
|
+
module LitElement
|
6
|
+
include SEXP
|
7
|
+
extend SEXP
|
8
|
+
|
9
|
+
LITELEMENT_IMPORT = s(:import,
|
10
|
+
[s(:pair, s(:sym, :from), s(:str, "lit-element"))],
|
11
|
+
[s(:const, nil, :LitElement), s(:attr, nil, :css), s(:attr, nil, :html)])
|
12
|
+
|
13
|
+
def initialize(node)
|
14
|
+
super
|
15
|
+
@le_props = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def on_ivar(node)
|
19
|
+
return super unless @le_props&.include?(node.children.first)
|
20
|
+
s(:attr, s(:self), node.children.first.to_s[1..-1])
|
21
|
+
end
|
22
|
+
|
23
|
+
def on_ivasgn(node)
|
24
|
+
return super unless @le_props&.include?(node.children.first)
|
25
|
+
s(:send, s(:self), node.children.first.to_s[1..-1]+'=',
|
26
|
+
process(node.children[1]))
|
27
|
+
end
|
28
|
+
|
29
|
+
def on_class(node)
|
30
|
+
cname, inheritance, *body = node.children
|
31
|
+
return super unless inheritance == s(:const, nil, :LitElement)
|
32
|
+
|
33
|
+
@le_props = {}
|
34
|
+
le_walk(node)
|
35
|
+
|
36
|
+
prepend_list << LITELEMENT_IMPORT if modules_enabled?
|
37
|
+
|
38
|
+
nodes = body.dup
|
39
|
+
if nodes.length == 1 and nodes.first&.type == :begin
|
40
|
+
nodes = nodes.first.children.dup
|
41
|
+
end
|
42
|
+
|
43
|
+
# insert/update static get properties() {}
|
44
|
+
unless @le_props.empty?
|
45
|
+
values = nodes.find_index {|child|
|
46
|
+
child.type == :defs and child.children[0..1] == [s(:self), :properties]
|
47
|
+
}
|
48
|
+
|
49
|
+
if values == nil
|
50
|
+
nodes.unshift s(:defp, s(:self), :properties, s(:args), s(:return,
|
51
|
+
s(:hash, *@le_props.map {|name, type| s(:pair, s(:str, name.to_s[1..-1]),
|
52
|
+
s(:hash, s(:pair, s(:sym, :type), s(:const, nil, type || :String))))})))
|
53
|
+
elsif nodes[values].children[3].type == :hash
|
54
|
+
le_props = @le_props.map {|name, type|
|
55
|
+
[s(:sym, name.to_s[1..-1].to_sym),
|
56
|
+
s(:hash, s(:pair, s(:sym, :type), s(:const, nil, type || :String)))]
|
57
|
+
}.to_h.merge(
|
58
|
+
nodes[values].children[3].children.map {|pair| pair.children}.to_h
|
59
|
+
)
|
60
|
+
|
61
|
+
nodes[values] = nodes[values].updated(nil,
|
62
|
+
[*nodes[values].children[0..2], s(:hash,
|
63
|
+
*le_props.map{|name, value| s(:pair, name, value)})])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# render of a string is converted to a taglit :html
|
68
|
+
render = nodes.find_index {|child|
|
69
|
+
child.type == :def and child.children.first == :render
|
70
|
+
}
|
71
|
+
if render and %i[str dstr].include?(nodes[render].children[2].type)
|
72
|
+
nodes[render] = nodes[render].updated(:deff,
|
73
|
+
[*nodes[render].children[0..1],
|
74
|
+
s(:autoreturn, html_wrap(nodes[render].children[2]))])
|
75
|
+
end
|
76
|
+
|
77
|
+
# self.styles returning string is converted to a taglit :css
|
78
|
+
styles = nodes.find_index {|child|
|
79
|
+
child.type == :defs and child.children[0..1] == [s(:self), :styles]
|
80
|
+
}
|
81
|
+
if styles and %i[str dstr].include?(nodes[styles].children[3].type)
|
82
|
+
string = nodes[styles].children[3]
|
83
|
+
string = s(:dstr, string) if string.type == :str
|
84
|
+
children = string.children.dup
|
85
|
+
|
86
|
+
while children.length > 1 and children.last.type == :str and
|
87
|
+
children.last.children.last.strip == ''
|
88
|
+
children.pop
|
89
|
+
end
|
90
|
+
|
91
|
+
if children.last.type == :str
|
92
|
+
children << s(:str, children.pop.children.first.chomp)
|
93
|
+
end
|
94
|
+
|
95
|
+
nodes[styles] = nodes[styles].updated(nil,
|
96
|
+
[*nodes[styles].children[0..2],
|
97
|
+
s(:autoreturn, s(:taglit, s(:sym, :css),
|
98
|
+
s(:dstr, *children)))])
|
99
|
+
end
|
100
|
+
|
101
|
+
# insert super calls into initializer
|
102
|
+
initialize = nodes.find_index {|child|
|
103
|
+
child.type == :def and child.children.first == :initialize
|
104
|
+
}
|
105
|
+
if initialize and nodes[initialize].children.length == 3
|
106
|
+
statements = nodes[initialize].children[2].children
|
107
|
+
|
108
|
+
if statements.length == 1 and statements.children.first.type == :begin
|
109
|
+
statements = statements.children
|
110
|
+
end
|
111
|
+
|
112
|
+
unless statements.any? {|statement| %i[super zuper].include? statement.type}
|
113
|
+
nodes[initialize] = nodes[initialize].updated(nil,
|
114
|
+
[*nodes[initialize].children[0..1],
|
115
|
+
s(:begin, s(:zsuper), *statements)])
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
props = @le_props.keys.map {|prop| [prop.to_sym, s(:self)]}.to_h
|
120
|
+
|
121
|
+
nodes.unshift s(:defineProps, props)
|
122
|
+
|
123
|
+
nodes.pop unless nodes.last
|
124
|
+
|
125
|
+
node.updated(nil, [*node.children[0..1], s(:begin, *process_all(nodes))])
|
126
|
+
ensure
|
127
|
+
@le_props = nil
|
128
|
+
end
|
129
|
+
|
130
|
+
def html_wrap(node)
|
131
|
+
if node.type == :str and node.children.first.strip.start_with? '<'
|
132
|
+
s(:taglit, s(:sym, :html), s(:dstr, node))
|
133
|
+
elsif node.type == :dstr
|
134
|
+
prefix = ''
|
135
|
+
node.children.each do |child|
|
136
|
+
break unless child.type == :str
|
137
|
+
prefix += child.children.first
|
138
|
+
end
|
139
|
+
|
140
|
+
return node unless prefix.strip.start_with? '<'
|
141
|
+
|
142
|
+
children = node.children.map do |child|
|
143
|
+
if child.type == :str
|
144
|
+
child
|
145
|
+
else
|
146
|
+
html_wrap(child)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
while children.length > 1 and children.last.type == :str and
|
151
|
+
children.last.children.last.strip == ''
|
152
|
+
children.pop
|
153
|
+
end
|
154
|
+
|
155
|
+
if children.last.type == :str
|
156
|
+
children << s(:str, children.pop.children.first.chomp)
|
157
|
+
end
|
158
|
+
|
159
|
+
s(:taglit, s(:sym, :html), node.updated(nil, children))
|
160
|
+
elsif node.type == :begin
|
161
|
+
node.updated(nil, node.children.map {|child| html_wrap(child)})
|
162
|
+
elsif node.type == :if
|
163
|
+
node.updated(nil, [node.children.first,
|
164
|
+
*node.children[1..2].map {|child| html_wrap(child)}])
|
165
|
+
elsif node.type == :block and
|
166
|
+
node.children.first.children[1] == :map
|
167
|
+
node.updated(nil, [*node.children[0..1],
|
168
|
+
html_wrap(node.children[2])])
|
169
|
+
else
|
170
|
+
node
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
# analyze ivar usage
|
175
|
+
def le_walk(node)
|
176
|
+
node.children.each do |child|
|
177
|
+
next unless Parser::AST::Node === child
|
178
|
+
le_walk(child)
|
179
|
+
|
180
|
+
if child.type == :ivar
|
181
|
+
@le_props[child.children.first] ||= nil
|
182
|
+
elsif child.type == :ivasgn
|
183
|
+
@le_props[child.children.first] = case child.children.last.type
|
184
|
+
when :str, :dstr
|
185
|
+
:String
|
186
|
+
when :array
|
187
|
+
:Array
|
188
|
+
when :int, :float
|
189
|
+
:Number
|
190
|
+
when :true, :false
|
191
|
+
:Boolean
|
192
|
+
else
|
193
|
+
@le_props[child.children.first] || :Object
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
DEFAULTS.push LitElement
|
201
|
+
end
|
202
|
+
end
|