ruby2js 1.0.0 → 1.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 +8 -8
- data/lib/ruby2js.rb +2 -2
- data/lib/ruby2js/converter.rb +68 -474
- data/lib/ruby2js/converter/andasgn.rb +12 -0
- data/lib/ruby2js/converter/arg.rb +14 -0
- data/lib/ruby2js/converter/args.rb +13 -0
- data/lib/ruby2js/converter/array.rb +33 -0
- data/lib/ruby2js/converter/begin.rb +13 -0
- data/lib/ruby2js/converter/block.rb +16 -0
- data/lib/ruby2js/converter/blockpass.rb +11 -0
- data/lib/ruby2js/converter/boolean.rb +11 -0
- data/lib/ruby2js/converter/break.rb +12 -0
- data/lib/ruby2js/converter/case.rb +23 -0
- data/lib/ruby2js/converter/casgn.rb +16 -0
- data/lib/ruby2js/converter/class.rb +75 -0
- data/lib/ruby2js/converter/const.rb +10 -0
- data/lib/ruby2js/converter/def.rb +91 -0
- data/lib/ruby2js/converter/defined.rb +15 -0
- data/lib/ruby2js/converter/dstr.rb +16 -0
- data/lib/ruby2js/converter/for.rb +19 -0
- data/lib/ruby2js/converter/hash.rb +24 -0
- data/lib/ruby2js/converter/if.rb +34 -0
- data/lib/ruby2js/converter/ivar.rb +10 -0
- data/lib/ruby2js/converter/ivasgn.rb +11 -0
- data/lib/ruby2js/converter/kwbegin.rb +44 -0
- data/lib/ruby2js/converter/literal.rb +12 -0
- data/lib/ruby2js/converter/logical.rb +43 -0
- data/lib/ruby2js/converter/masgn.rb +20 -0
- data/lib/ruby2js/converter/next.rb +12 -0
- data/lib/ruby2js/converter/nil.rb +10 -0
- data/lib/ruby2js/converter/opasgn.rb +20 -0
- data/lib/ruby2js/converter/orasgn.rb +12 -0
- data/lib/ruby2js/converter/regexp.rb +21 -0
- data/lib/ruby2js/converter/return.rb +15 -0
- data/lib/ruby2js/converter/self.rb +10 -0
- data/lib/ruby2js/converter/send.rb +98 -0
- data/lib/ruby2js/converter/sym.rb +10 -0
- data/lib/ruby2js/converter/undef.rb +12 -0
- data/lib/ruby2js/converter/until.rb +12 -0
- data/lib/ruby2js/converter/untilpost.rb +13 -0
- data/lib/ruby2js/converter/var.rb +11 -0
- data/lib/ruby2js/converter/vasgn.rb +41 -0
- data/lib/ruby2js/converter/while.rb +12 -0
- data/lib/ruby2js/converter/whilepost.rb +14 -0
- data/lib/ruby2js/converter/xstr.rb +16 -0
- data/lib/ruby2js/filter/angularrb.rb +1 -1
- data/lib/ruby2js/filter/jquery.rb +95 -1
- data/lib/ruby2js/version.rb +1 -1
- data/ruby2js.gemspec +3 -3
- metadata +44 -2
@@ -0,0 +1,14 @@
|
|
1
|
+
module Ruby2JS
|
2
|
+
class Converter
|
3
|
+
|
4
|
+
# (arg :a)
|
5
|
+
# (blockarg :b)
|
6
|
+
|
7
|
+
# NOTE: process_all appends a nil child for unknown reasons
|
8
|
+
|
9
|
+
handle :arg, :blockarg do |arg, unknown=nil|
|
10
|
+
raise NotImplementedError, "argument #{ unknown.inspect }" if unknown
|
11
|
+
arg
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Ruby2JS
|
2
|
+
class Converter
|
3
|
+
|
4
|
+
# (array
|
5
|
+
# (int 1)
|
6
|
+
# (int 2))
|
7
|
+
|
8
|
+
handle :array do |*items|
|
9
|
+
splat = items.rindex { |a| a.type == :splat }
|
10
|
+
if splat
|
11
|
+
item = items[splat].children.first
|
12
|
+
if items.length == 1
|
13
|
+
parse item
|
14
|
+
elsif splat == items.length - 1
|
15
|
+
parse s(:send, s(:array, *items[0..-2]), :concat, item)
|
16
|
+
elsif splat == 0
|
17
|
+
parse s(:send, item, :concat, s(:array, *items[1..-1]))
|
18
|
+
else
|
19
|
+
parse s(:send,
|
20
|
+
s(:send, s(:array, *items[0..splat-1]), :concat, item),
|
21
|
+
:concat, s(:array, *items[splat+1..-1]))
|
22
|
+
end
|
23
|
+
else
|
24
|
+
items.map! { |item| parse item }
|
25
|
+
if items.map {|item| item.length+2}.reduce(&:+).to_i < 72
|
26
|
+
"[#{ items.join(', ') }]"
|
27
|
+
else
|
28
|
+
"[#@nl#{ items.join(",#@ws") }#@nl]"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Ruby2JS
|
2
|
+
class Converter
|
3
|
+
|
4
|
+
# (block
|
5
|
+
# (send nil :x)
|
6
|
+
# (args
|
7
|
+
# (arg :a))
|
8
|
+
# (lvar :a))
|
9
|
+
|
10
|
+
handle :block do |call, args, block|
|
11
|
+
block ||= s(:begin)
|
12
|
+
function = s(:def, nil, args, block)
|
13
|
+
parse s(:send, *call.children, function)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Ruby2JS
|
2
|
+
class Converter
|
3
|
+
|
4
|
+
# (case
|
5
|
+
# (send nil :a)
|
6
|
+
# (when
|
7
|
+
# (int 1)
|
8
|
+
# (...))
|
9
|
+
# (...))
|
10
|
+
|
11
|
+
handle :case do |expr, *whens, other|
|
12
|
+
whens.map! do |node|
|
13
|
+
*values, code = node.children
|
14
|
+
cases = values.map {|value| "case #{ parse value }:#@ws"}.join
|
15
|
+
"#{ cases }#{ parse code }#{@sep}break#@sep"
|
16
|
+
end
|
17
|
+
|
18
|
+
other = "#{@nl}default:#@ws#{ parse other }#@nl" if other
|
19
|
+
|
20
|
+
"switch (#{ parse expr }) {#@nl#{whens.join(@nl)}#{other}}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Ruby2JS
|
2
|
+
class Converter
|
3
|
+
|
4
|
+
# (casgn nil :a
|
5
|
+
# (int 1))
|
6
|
+
|
7
|
+
handle :casgn do |cbase, var, value|
|
8
|
+
begin
|
9
|
+
var = "#{ parse cbase }.var" if cbase
|
10
|
+
"const #{ var } = #{ parse value }"
|
11
|
+
ensure
|
12
|
+
@vars[var] = true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Ruby2JS
|
2
|
+
class Converter
|
3
|
+
|
4
|
+
# (class
|
5
|
+
# (const nil :A)
|
6
|
+
# (const nil :B)
|
7
|
+
# (...)
|
8
|
+
|
9
|
+
handle :class do |name, inheritance, *body|
|
10
|
+
init = s(:def, :initialize, s(:args))
|
11
|
+
body.compact!
|
12
|
+
|
13
|
+
if body.length == 1 and body.first.type == :begin
|
14
|
+
body = body.first.children.dup
|
15
|
+
end
|
16
|
+
|
17
|
+
body.map! do |m|
|
18
|
+
if m.type == :def
|
19
|
+
if m.children.first == :initialize
|
20
|
+
# constructor: remove from body and overwrite init function
|
21
|
+
init = m
|
22
|
+
nil
|
23
|
+
else
|
24
|
+
# method: add to prototype
|
25
|
+
s(:send, s(:attr, name, :prototype), "#{m.children[0]}=",
|
26
|
+
s(:block, s(:send, nil, :proc), *m.children[1..-1]))
|
27
|
+
end
|
28
|
+
elsif m.type == :defs and m.children.first == s(:self)
|
29
|
+
# class method definition: add to prototype
|
30
|
+
s(:send, name, "#{m.children[1]}=",
|
31
|
+
s(:block, s(:send, nil, :proc), *m.children[2..-1]))
|
32
|
+
elsif m.type == :send and m.children.first == nil
|
33
|
+
# class method call
|
34
|
+
s(:send, name, *m.children[1..-1])
|
35
|
+
elsif m.type == :lvasgn
|
36
|
+
# class variable
|
37
|
+
s(:send, name, "#{m.children[0]}=", *m.children[1..-1])
|
38
|
+
elsif m.type == :casgn and m.children[0] == nil
|
39
|
+
# class constant
|
40
|
+
s(:send, name, "#{m.children[1]}=", *m.children[2..-1])
|
41
|
+
else
|
42
|
+
raise NotImplementedError, "class #{ m.type }"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
if inheritance
|
47
|
+
body.unshift s(:send, name, :prototype=, s(:send, inheritance, :new))
|
48
|
+
else
|
49
|
+
# look for a sequence of methods
|
50
|
+
methods = 0
|
51
|
+
body.compact.each do |node|
|
52
|
+
break unless node and node.type == :send and node.children[0]
|
53
|
+
break unless node.children[0].type == :attr
|
54
|
+
break unless node.children[0].children[0..1] == [name, :prototype]
|
55
|
+
break unless node.children[1] =~ /=$/
|
56
|
+
methods += 1
|
57
|
+
end
|
58
|
+
|
59
|
+
# collapse sequence of methods to a single assignment
|
60
|
+
if methods > 1
|
61
|
+
pairs = body[0...methods].map do |node|
|
62
|
+
s(:pair, s(:str, node.children[1].chomp('=')), node.children[2])
|
63
|
+
end
|
64
|
+
body.shift(methods)
|
65
|
+
body.unshift s(:send, name, :prototype=, s(:hash, *pairs))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# prepend constructor
|
70
|
+
body.unshift s(:def, parse(name), *init.children[1..-1])
|
71
|
+
|
72
|
+
parse s(:begin, *body.compact)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Ruby2JS
|
2
|
+
class Converter
|
3
|
+
|
4
|
+
# (def :f
|
5
|
+
# (args
|
6
|
+
# (arg :x)
|
7
|
+
# (...)
|
8
|
+
|
9
|
+
handle :def do |name, args, body=nil|
|
10
|
+
body ||= s(:begin)
|
11
|
+
if name =~ /[!?]$/
|
12
|
+
raise NotImplementedError, "invalid method name #{ name }"
|
13
|
+
end
|
14
|
+
|
15
|
+
vars = {}
|
16
|
+
vars.merge! @vars unless name
|
17
|
+
if args and !args.children.empty?
|
18
|
+
# splats
|
19
|
+
if args.children.last.type == :restarg
|
20
|
+
if args.children[-1].children.first
|
21
|
+
body = s(:begin, body) unless body.type == :begin
|
22
|
+
assign = s(:lvasgn, args.children[-1].children.first,
|
23
|
+
s(:send, s(:attr,
|
24
|
+
s(:attr, s(:const, nil, :Array), :prototype), :slice),
|
25
|
+
:call, s(:lvar, :arguments),
|
26
|
+
s(:int, args.children.length-1)))
|
27
|
+
body = s(:begin, assign, *body.children)
|
28
|
+
end
|
29
|
+
|
30
|
+
args = s(:args, *args.children[0..-2])
|
31
|
+
|
32
|
+
elsif args.children.last.type == :blockarg and
|
33
|
+
args.children.length > 1 and args.children[-2].type == :restarg
|
34
|
+
body = s(:begin, body) unless body.type == :begin
|
35
|
+
blk = args.children[-1].children.first
|
36
|
+
vararg = args.children[-2].children.first
|
37
|
+
last = s(:send, s(:attr, s(:lvar, :arguments), :length), :-,
|
38
|
+
s(:int, 1))
|
39
|
+
|
40
|
+
# set block argument to the last argument passed
|
41
|
+
assign2 = s(:lvasgn, blk, s(:send, s(:lvar, :arguments), :[], last))
|
42
|
+
|
43
|
+
if vararg
|
44
|
+
# extract arguments between those defined and the last
|
45
|
+
assign1 = s(:lvasgn, vararg, s(:send, s(:attr, s(:attr, s(:const,
|
46
|
+
nil, :Array), :prototype), :slice), :call, s(:lvar, :arguments),
|
47
|
+
s(:int, args.children.length-1), last))
|
48
|
+
# push block argument back onto args if not a function
|
49
|
+
pushback = s(:if, s(:send, s(:send, nil, :typeof, s(:lvar, blk)),
|
50
|
+
:"!==", s(:str, "function")), s(:begin, s(:send, s(:lvar,
|
51
|
+
vararg), :push, s(:lvar, blk)), s(:lvasgn, blk, s(:nil))), nil)
|
52
|
+
# set block argument to null if all arguments were defined
|
53
|
+
pushback = s(:if, s(:send, s(:attr, s(:lvar, :arguments),
|
54
|
+
:length), :<=, s(:int, args.children.length-2)), s(:lvasgn,
|
55
|
+
blk, s(:nil)), pushback)
|
56
|
+
# combine statements
|
57
|
+
body = s(:begin, assign1, assign2, pushback, *body.children)
|
58
|
+
else
|
59
|
+
# set block argument to null if all arguments were defined
|
60
|
+
ignore = s(:if, s(:send, s(:attr, s(:lvar, :arguments),
|
61
|
+
:length), :<=, s(:int, args.children.length-2)), s(:lvasgn,
|
62
|
+
blk, s(:nil)), nil)
|
63
|
+
body = s(:begin, assign2, ignore, *body.children)
|
64
|
+
end
|
65
|
+
|
66
|
+
args = s(:args, *args.children[0..-3])
|
67
|
+
end
|
68
|
+
|
69
|
+
# optional arguments
|
70
|
+
args.children.each_with_index do |arg, i|
|
71
|
+
if arg.type == :optarg
|
72
|
+
body = s(:begin, body) unless body.type == :begin
|
73
|
+
argname, value = arg.children
|
74
|
+
children = args.children.dup
|
75
|
+
children[i] = s(:arg, argname)
|
76
|
+
args = s(:args, *children)
|
77
|
+
body = s(:begin, body) unless body.type == :begin
|
78
|
+
default = s(:if, s(:send, s(:defined?, s(:lvar, argname)), :!),
|
79
|
+
s(:lvasgn, argname, value), nil)
|
80
|
+
body = s(:begin, default, *body.children)
|
81
|
+
end
|
82
|
+
vars[arg.children.first] = true
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
nl = @nl unless body == s(:begin)
|
87
|
+
"function#{ " #{name}" if name }(#{ parse args }) " +
|
88
|
+
"{#{nl}#{ scope body, vars}#{nl}}"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Ruby2JS
|
2
|
+
class Converter
|
3
|
+
|
4
|
+
# (defined? :@a)
|
5
|
+
|
6
|
+
# (undefined? :@a)
|
7
|
+
|
8
|
+
# NOTE: undefined is not produced directly by Parser
|
9
|
+
|
10
|
+
handle :defined?, :undefined? do |var|
|
11
|
+
op = (@ast.type == :defined? ? "!==" : "===")
|
12
|
+
"typeof #{ parse var } #{ op } 'undefined'"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Ruby2JS
|
2
|
+
class Converter
|
3
|
+
|
4
|
+
# (xstr
|
5
|
+
# (str 'a'))
|
6
|
+
# (for
|
7
|
+
# (lvasgn :i)
|
8
|
+
# (array
|
9
|
+
# (int 1))
|
10
|
+
# (...)
|
11
|
+
|
12
|
+
handle :for do |var, expression, block|
|
13
|
+
parse s(:block,
|
14
|
+
s(:send, expression, :forEach),
|
15
|
+
s(:args, s(:arg, var.children.last)),
|
16
|
+
block);
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Ruby2JS
|
2
|
+
class Converter
|
3
|
+
|
4
|
+
# (hash
|
5
|
+
# (pair
|
6
|
+
# (sym :name)
|
7
|
+
# (str "value")))
|
8
|
+
|
9
|
+
handle :hash do |*pairs|
|
10
|
+
pairs.map! do |node|
|
11
|
+
left, right = node.children
|
12
|
+
key = parse left
|
13
|
+
key = $1 if key =~ /\A"([a-zA-Z_$][a-zA-Z_$0-9]*)"\Z/
|
14
|
+
"#{key}: #{parse right}"
|
15
|
+
end
|
16
|
+
|
17
|
+
if pairs.map {|item| item.length+2}.reduce(&:+).to_i < 72
|
18
|
+
"{#{ pairs.join(', ') }}"
|
19
|
+
else
|
20
|
+
"{#@nl#{ pairs.join(",#@ws") }#@nl}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|