ruby2js 4.0.2 → 4.1.1
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 +1 -1
- data/lib/ruby2js/converter.rb +1 -0
- data/lib/ruby2js/converter/class.rb +7 -5
- 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/return.rb +1 -1
- data/lib/ruby2js/converter/send.rb +1 -0
- data/lib/ruby2js/converter/taglit.rb +13 -2
- data/lib/ruby2js/filter/cjs.rb +100 -2
- data/lib/ruby2js/filter/functions.rb +11 -6
- data/lib/ruby2js/filter/lit-element.rb +218 -0
- data/lib/ruby2js/filter/react.rb +276 -88
- data/lib/ruby2js/filter/tagged_templates.rb +4 -2
- data/lib/ruby2js/rails.rb +10 -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
- metadata +15 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6b96695d82101133b8d791e19d0f04fa5c6c56c16bb6504b447cf26e0e1291db
|
4
|
+
data.tar.gz: 9a7711f281076e14e354bcab9fd8f96de5b884153360a9b5fdb57b6fa9c5a792
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f64daa6dad4b3ed8d475654e588a8f921782fc11aceecb01886b8c039139bdc716f863eb25f57c119410da1a180273cbf9f66992da0555ce66b1131c31deab44
|
7
|
+
data.tar.gz: f5ffccf5acc15710797fc566ba89730f34d5884492892d4972fa9d4ad6ef785e1875bd4e3ffb25a9cb0148d77c4501aed8ea21e3f1171c55c5ca13104c274f56
|
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
@@ -180,7 +180,7 @@ module Ruby2JS
|
|
180
180
|
def on_xnode(node); end
|
181
181
|
def on_export(node); end
|
182
182
|
def on_import(node); end
|
183
|
-
def on_taglit(node); end
|
183
|
+
def on_taglit(node); on_pair(node); end
|
184
184
|
|
185
185
|
# provide a method so filters can call 'super'
|
186
186
|
def on_sym(node); node; end
|
data/lib/ruby2js/converter.rb
CHANGED
@@ -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
|
@@ -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
|
@@ -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,19 @@ 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
|
+
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
|
19
|
+
ensure
|
20
|
+
@autobind = save_autobind
|
21
|
+
end
|
11
22
|
end
|
12
23
|
end
|
13
24
|
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
|
|
@@ -0,0 +1,218 @@
|
|
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
|
+
return super unless node.children.length > 1
|
26
|
+
s(:send, s(:self), node.children.first.to_s[1..-1]+'=',
|
27
|
+
process(node.children[1]))
|
28
|
+
end
|
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
|
+
|
38
|
+
def on_class(node)
|
39
|
+
cname, inheritance, *body = node.children
|
40
|
+
return super unless inheritance == s(:const, nil, :LitElement)
|
41
|
+
|
42
|
+
@le_props = {}
|
43
|
+
le_walk(node)
|
44
|
+
|
45
|
+
prepend_list << LITELEMENT_IMPORT if modules_enabled?
|
46
|
+
|
47
|
+
nodes = body.dup
|
48
|
+
if nodes.length == 1 and nodes.first&.type == :begin
|
49
|
+
nodes = nodes.first.children.dup
|
50
|
+
end
|
51
|
+
|
52
|
+
# insert/update static get properties() {}
|
53
|
+
unless @le_props.empty?
|
54
|
+
values = nodes.find_index {|child|
|
55
|
+
child.type == :defs and child.children[0..1] == [s(:self), :properties]
|
56
|
+
}
|
57
|
+
|
58
|
+
if values == nil
|
59
|
+
nodes.unshift s(:defp, s(:self), :properties, s(:args), s(:return,
|
60
|
+
s(:hash, *@le_props.map {|name, type| s(:pair, s(:str, name.to_s[1..-1]),
|
61
|
+
s(:hash, s(:pair, s(:sym, :type), s(:const, nil, type || :String))))})))
|
62
|
+
elsif nodes[values].children[3].type == :hash
|
63
|
+
le_props = @le_props.map {|name, type|
|
64
|
+
[s(:sym, name.to_s[1..-1].to_sym),
|
65
|
+
s(:hash, s(:pair, s(:sym, :type), s(:const, nil, type || :String)))]
|
66
|
+
}.to_h.merge(
|
67
|
+
nodes[values].children[3].children.map {|pair| pair.children}.to_h
|
68
|
+
)
|
69
|
+
|
70
|
+
nodes[values] = nodes[values].updated(nil,
|
71
|
+
[*nodes[values].children[0..2], s(:hash,
|
72
|
+
*le_props.map{|name, value| s(:pair, name, value)})])
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# render of a string is converted to a taglit :html
|
77
|
+
render = nodes.find_index {|child|
|
78
|
+
child&.type == :def and child.children.first == :render
|
79
|
+
}
|
80
|
+
if render and %i[str dstr].include?(nodes[render].children[2]&.type)
|
81
|
+
nodes[render] = nodes[render].updated(:deff,
|
82
|
+
[*nodes[render].children[0..1],
|
83
|
+
s(:autoreturn, html_wrap(nodes[render].children[2]))])
|
84
|
+
end
|
85
|
+
|
86
|
+
# self.styles returning string is converted to a taglit :css
|
87
|
+
styles = nodes.find_index {|child|
|
88
|
+
child&.type == :defs and child.children[0..1] == [s(:self), :styles]
|
89
|
+
}
|
90
|
+
if styles and %i[str dstr].include?(nodes[styles].children[3]&.type)
|
91
|
+
string = nodes[styles].children[3]
|
92
|
+
string = s(:dstr, string) if string.type == :str
|
93
|
+
children = string.children.dup
|
94
|
+
|
95
|
+
while children.length > 1 and children.last.type == :str and
|
96
|
+
children.last.children.last.strip == ''
|
97
|
+
children.pop
|
98
|
+
end
|
99
|
+
|
100
|
+
if children.last.type == :str
|
101
|
+
children << s(:str, children.pop.children.first.chomp)
|
102
|
+
end
|
103
|
+
|
104
|
+
nodes[styles] = nodes[styles].updated(nil,
|
105
|
+
[*nodes[styles].children[0..2],
|
106
|
+
s(:autoreturn, s(:taglit, s(:sym, :css),
|
107
|
+
s(:dstr, *children)))])
|
108
|
+
end
|
109
|
+
|
110
|
+
# insert super calls into initializer
|
111
|
+
initialize = nodes.find_index {|child|
|
112
|
+
child&.type == :def and child.children.first == :initialize
|
113
|
+
}
|
114
|
+
if initialize and nodes[initialize].children.length == 3
|
115
|
+
statements = nodes[initialize].children[2..-1]
|
116
|
+
|
117
|
+
if statements.length == 1 and statements.first.type == :begin
|
118
|
+
statements = statements.first.children
|
119
|
+
end
|
120
|
+
|
121
|
+
unless statements.any? {|statement| %i[super zuper].include? statement.type}
|
122
|
+
nodes[initialize] = nodes[initialize].updated(nil,
|
123
|
+
[*nodes[initialize].children[0..1],
|
124
|
+
s(:begin, s(:zsuper), *statements)])
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
props = @le_props.keys.map {|prop| [prop.to_sym, s(:self)]}.to_h
|
129
|
+
|
130
|
+
nodes.unshift s(:defineProps, props)
|
131
|
+
|
132
|
+
nodes.pop unless nodes.last
|
133
|
+
|
134
|
+
node.updated(nil, [*node.children[0..1], s(:begin, *process_all(nodes))])
|
135
|
+
ensure
|
136
|
+
@le_props = nil
|
137
|
+
end
|
138
|
+
|
139
|
+
def html_wrap(node)
|
140
|
+
if node.type == :str and node.children.first.strip.start_with? '<'
|
141
|
+
s(:taglit, s(:sym, :html), s(:dstr, node))
|
142
|
+
elsif node.type == :dstr
|
143
|
+
prefix = ''
|
144
|
+
node.children.each do |child|
|
145
|
+
break unless child.type == :str
|
146
|
+
prefix += child.children.first
|
147
|
+
end
|
148
|
+
|
149
|
+
return node unless prefix.strip.start_with? '<'
|
150
|
+
|
151
|
+
children = node.children.map do |child|
|
152
|
+
if child.type == :str
|
153
|
+
child
|
154
|
+
else
|
155
|
+
html_wrap(child)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
while children.length > 1 and children.last.type == :str and
|
160
|
+
children.last.children.last.strip == ''
|
161
|
+
children.pop
|
162
|
+
end
|
163
|
+
|
164
|
+
if children.last.type == :str
|
165
|
+
children << s(:str, children.pop.children.first.chomp)
|
166
|
+
end
|
167
|
+
|
168
|
+
s(:taglit, s(:sym, :html), node.updated(nil, children))
|
169
|
+
elsif node.type == :begin
|
170
|
+
node.updated(nil, node.children.map {|child| html_wrap(child)})
|
171
|
+
elsif node.type == :if
|
172
|
+
node.updated(nil, [node.children.first,
|
173
|
+
*node.children[1..2].map {|child| html_wrap(child)}])
|
174
|
+
elsif node.type == :block and
|
175
|
+
node.children.first.children[1] == :map
|
176
|
+
node.updated(nil, [*node.children[0..1],
|
177
|
+
html_wrap(node.children[2])])
|
178
|
+
else
|
179
|
+
node
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# analyze ivar usage
|
184
|
+
def le_walk(node)
|
185
|
+
node.children.each do |child|
|
186
|
+
next unless child.is_a? Parser::AST::Node
|
187
|
+
|
188
|
+
if child.type == :ivar
|
189
|
+
@le_props[child.children.first] ||= nil
|
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
|
198
|
+
when :str, :dstr
|
199
|
+
:String
|
200
|
+
when :array
|
201
|
+
:Array
|
202
|
+
when :int, :float
|
203
|
+
:Number
|
204
|
+
when :true, :false
|
205
|
+
:Boolean
|
206
|
+
else
|
207
|
+
@le_props[prop] || :Object
|
208
|
+
end
|
209
|
+
else
|
210
|
+
le_walk(child)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
DEFAULTS.push LitElement
|
217
|
+
end
|
218
|
+
end
|