ruby2js 4.0.1 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +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
|
-
[](https://travis-ci.org/rubys/ruby2js)
|
7
6
|
[](https://badge.fury.io/rb/ruby2js)
|
8
7
|
[](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
|