ruby2js 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +8 -8
  2. data/lib/ruby2js.rb +2 -2
  3. data/lib/ruby2js/converter.rb +68 -474
  4. data/lib/ruby2js/converter/andasgn.rb +12 -0
  5. data/lib/ruby2js/converter/arg.rb +14 -0
  6. data/lib/ruby2js/converter/args.rb +13 -0
  7. data/lib/ruby2js/converter/array.rb +33 -0
  8. data/lib/ruby2js/converter/begin.rb +13 -0
  9. data/lib/ruby2js/converter/block.rb +16 -0
  10. data/lib/ruby2js/converter/blockpass.rb +11 -0
  11. data/lib/ruby2js/converter/boolean.rb +11 -0
  12. data/lib/ruby2js/converter/break.rb +12 -0
  13. data/lib/ruby2js/converter/case.rb +23 -0
  14. data/lib/ruby2js/converter/casgn.rb +16 -0
  15. data/lib/ruby2js/converter/class.rb +75 -0
  16. data/lib/ruby2js/converter/const.rb +10 -0
  17. data/lib/ruby2js/converter/def.rb +91 -0
  18. data/lib/ruby2js/converter/defined.rb +15 -0
  19. data/lib/ruby2js/converter/dstr.rb +16 -0
  20. data/lib/ruby2js/converter/for.rb +19 -0
  21. data/lib/ruby2js/converter/hash.rb +24 -0
  22. data/lib/ruby2js/converter/if.rb +34 -0
  23. data/lib/ruby2js/converter/ivar.rb +10 -0
  24. data/lib/ruby2js/converter/ivasgn.rb +11 -0
  25. data/lib/ruby2js/converter/kwbegin.rb +44 -0
  26. data/lib/ruby2js/converter/literal.rb +12 -0
  27. data/lib/ruby2js/converter/logical.rb +43 -0
  28. data/lib/ruby2js/converter/masgn.rb +20 -0
  29. data/lib/ruby2js/converter/next.rb +12 -0
  30. data/lib/ruby2js/converter/nil.rb +10 -0
  31. data/lib/ruby2js/converter/opasgn.rb +20 -0
  32. data/lib/ruby2js/converter/orasgn.rb +12 -0
  33. data/lib/ruby2js/converter/regexp.rb +21 -0
  34. data/lib/ruby2js/converter/return.rb +15 -0
  35. data/lib/ruby2js/converter/self.rb +10 -0
  36. data/lib/ruby2js/converter/send.rb +98 -0
  37. data/lib/ruby2js/converter/sym.rb +10 -0
  38. data/lib/ruby2js/converter/undef.rb +12 -0
  39. data/lib/ruby2js/converter/until.rb +12 -0
  40. data/lib/ruby2js/converter/untilpost.rb +13 -0
  41. data/lib/ruby2js/converter/var.rb +11 -0
  42. data/lib/ruby2js/converter/vasgn.rb +41 -0
  43. data/lib/ruby2js/converter/while.rb +12 -0
  44. data/lib/ruby2js/converter/whilepost.rb +14 -0
  45. data/lib/ruby2js/converter/xstr.rb +16 -0
  46. data/lib/ruby2js/filter/angularrb.rb +1 -1
  47. data/lib/ruby2js/filter/jquery.rb +95 -1
  48. data/lib/ruby2js/version.rb +1 -1
  49. data/ruby2js.gemspec +3 -3
  50. metadata +44 -2
@@ -0,0 +1,12 @@
1
+ module Ruby2JS
2
+ class Converter
3
+
4
+ # (and-asgn
5
+ # (lvasgn :a
6
+ # (int 1))
7
+
8
+ handle :and_asgn do |var, value|
9
+ "#{ parse var } = #{parse var} && #{ parse value }"
10
+ end
11
+ end
12
+ end
@@ -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,13 @@
1
+ module Ruby2JS
2
+ class Converter
3
+
4
+ # (args
5
+ # (arg :a)
6
+ # (restarg :b)
7
+ # (blockarg :c))
8
+
9
+ handle :args do |*args|
10
+ args.map { |arg| parse arg }.join(', ')
11
+ end
12
+ end
13
+ 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,13 @@
1
+ module Ruby2JS
2
+ class Converter
3
+
4
+ # (begin
5
+ # (...)
6
+ # (...))
7
+
8
+ handle :begin do |*statements|
9
+ state = @state
10
+ statements.map{ |statement| parse statement, state }.join(@sep)
11
+ end
12
+ end
13
+ 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,11 @@
1
+ module Ruby2JS
2
+ class Converter
3
+
4
+ # (block-pass
5
+ # (lvar :a))
6
+
7
+ handle :block_pass do |arg|
8
+ parse arg
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Ruby2JS
2
+ class Converter
3
+
4
+ # (true)
5
+ # (false)
6
+
7
+ handle :true, :false do
8
+ @ast.type.to_s
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module Ruby2JS
2
+ class Converter
3
+
4
+ # (break
5
+ # (int 1))
6
+
7
+ handle :break do |n=nil|
8
+ raise NotImplementedError, "break argument #{ n.inspect }" if n
9
+ 'break'
10
+ end
11
+ end
12
+ 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,10 @@
1
+ module Ruby2JS
2
+ class Converter
3
+
4
+ # (const nil :C)
5
+
6
+ handle :const do |receiver, name|
7
+ "#{ parse receiver }#{ '.' if receiver }#{ name }"
8
+ end
9
+ end
10
+ 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,16 @@
1
+ module Ruby2JS
2
+ class Converter
3
+
4
+ # (dstr
5
+ # (str 'a')
6
+ # (...))
7
+
8
+ # (dsym
9
+ # (str 'a')
10
+ # (...))
11
+
12
+ handle :dstr, :dsym do |*children|
13
+ children.map{ |child| parse child }.join(' + ')
14
+ end
15
+ end
16
+ 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