ruby2js 1.15.1 → 2.0.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.
Files changed (53) hide show
  1. data/lib/ruby2js.rb +36 -36
  2. data/lib/ruby2js/converter.rb +59 -20
  3. data/lib/ruby2js/converter/arg.rb +1 -1
  4. data/lib/ruby2js/converter/args.rb +1 -1
  5. data/lib/ruby2js/converter/array.rb +3 -4
  6. data/lib/ruby2js/converter/begin.rb +15 -1
  7. data/lib/ruby2js/converter/block.rb +6 -5
  8. data/lib/ruby2js/converter/boolean.rb +1 -1
  9. data/lib/ruby2js/converter/break.rb +1 -1
  10. data/lib/ruby2js/converter/case.rb +27 -7
  11. data/lib/ruby2js/converter/casgn.rb +5 -2
  12. data/lib/ruby2js/converter/class.rb +41 -11
  13. data/lib/ruby2js/converter/const.rb +1 -1
  14. data/lib/ruby2js/converter/cvar.rb +4 -3
  15. data/lib/ruby2js/converter/cvasgn.rb +5 -6
  16. data/lib/ruby2js/converter/def.rb +15 -3
  17. data/lib/ruby2js/converter/defined.rb +1 -1
  18. data/lib/ruby2js/converter/defs.rb +7 -3
  19. data/lib/ruby2js/converter/dstr.rb +3 -3
  20. data/lib/ruby2js/converter/for.rb +7 -10
  21. data/lib/ruby2js/converter/hash.rb +70 -34
  22. data/lib/ruby2js/converter/if.rb +35 -13
  23. data/lib/ruby2js/converter/in.rb +1 -1
  24. data/lib/ruby2js/converter/ivasgn.rb +1 -1
  25. data/lib/ruby2js/converter/kwbegin.rb +20 -20
  26. data/lib/ruby2js/converter/literal.rb +1 -1
  27. data/lib/ruby2js/converter/logical.rb +4 -8
  28. data/lib/ruby2js/converter/next.rb +1 -1
  29. data/lib/ruby2js/converter/nil.rb +1 -1
  30. data/lib/ruby2js/converter/nthref.rb +1 -1
  31. data/lib/ruby2js/converter/opasgn.rb +3 -3
  32. data/lib/ruby2js/converter/regexp.rb +12 -9
  33. data/lib/ruby2js/converter/return.rb +3 -3
  34. data/lib/ruby2js/converter/self.rb +2 -2
  35. data/lib/ruby2js/converter/send.rb +31 -30
  36. data/lib/ruby2js/converter/super.rb +8 -11
  37. data/lib/ruby2js/converter/sym.rb +1 -1
  38. data/lib/ruby2js/converter/undef.rb +9 -2
  39. data/lib/ruby2js/converter/var.rb +1 -1
  40. data/lib/ruby2js/converter/vasgn.rb +13 -5
  41. data/lib/ruby2js/converter/while.rb +2 -1
  42. data/lib/ruby2js/converter/whilepost.rb +2 -1
  43. data/lib/ruby2js/converter/xstr.rb +4 -3
  44. data/lib/ruby2js/execjs.rb +3 -3
  45. data/lib/ruby2js/filter/camelCase.rb +8 -8
  46. data/lib/ruby2js/filter/functions.rb +64 -65
  47. data/lib/ruby2js/filter/react.rb +44 -16
  48. data/lib/ruby2js/filter/require.rb +4 -1
  49. data/lib/ruby2js/filter/underscore.rb +21 -21
  50. data/lib/ruby2js/serializer.rb +347 -0
  51. data/lib/ruby2js/version.rb +3 -3
  52. data/ruby2js.gemspec +3 -3
  53. metadata +3 -2
@@ -19,16 +19,14 @@ module Ruby2JS
19
19
  lgroup = LOGICAL.include?( left.type ) &&
20
20
  op_index < operator_index( left.type )
21
21
  lgroup = true if left and left.type == :begin
22
- left = parse left
23
- left = "(#{ left })" if lgroup
24
22
 
25
23
  rgroup = LOGICAL.include?( right.type ) &&
26
24
  op_index < operator_index( right.type )
27
25
  rgroup = true if right.type == :begin
28
- right = parse right
29
- right = "(#{ right })" if rgroup
30
26
 
31
- "#{ left } #{ type==:and ? '&&' : '||' } #{ right }"
27
+ put '(' if lgroup; parse left; put ')' if lgroup
28
+ put (type==:and ? ' && ' : ' || ')
29
+ put '(' if rgroup; parse right; put ')' if rgroup
32
30
  end
33
31
 
34
32
  # (not
@@ -49,10 +47,8 @@ module Ruby2JS
49
47
  group = LOGICAL.include?( expr.type ) &&
50
48
  operator_index( :not ) < operator_index( expr.type )
51
49
  group = true if expr and expr.type == :begin
52
- expr = parse expr
53
- expr = "(#{ expr })" if group
54
50
 
55
- "!#{ expr }"
51
+ put '!'; put '(' if group; parse expr; put ')' if group
56
52
  end
57
53
  end
58
54
  end
@@ -6,7 +6,7 @@ module Ruby2JS
6
6
 
7
7
  handle :next do |n=nil|
8
8
  raise NotImplementedError, "next argument #{ n.inspect }" if n
9
- @next_token.to_s
9
+ put @next_token.to_s
10
10
  end
11
11
  end
12
12
  end
@@ -4,7 +4,7 @@ module Ruby2JS
4
4
  # (nil)
5
5
 
6
6
  handle :nil do
7
- 'null'
7
+ put 'null'
8
8
  end
9
9
  end
10
10
  end
@@ -4,7 +4,7 @@ module Ruby2JS
4
4
  # (nthref 1)
5
5
 
6
6
  handle :nth_ref do |var|
7
- "$#{var}"
7
+ put "$#{var}"
8
8
  end
9
9
  end
10
10
  end
@@ -14,12 +14,12 @@ module Ruby2JS
14
14
 
15
15
  if [:+, :-].include?(op) and value.type==:int and value.children==[1]
16
16
  if @state == :statement
17
- "#{ parse var }#{ op }#{ op }"
17
+ parse var; put "#{ op }#{ op }"
18
18
  else
19
- "#{ op }#{ op }#{ parse var }"
19
+ put "#{ op }#{ op }"; parse var
20
20
  end
21
21
  else
22
- "#{ parse var } #{ op }= #{ parse value }"
22
+ parse var; put " #{ op }= "; parse value
23
23
  end
24
24
  end
25
25
 
@@ -17,27 +17,30 @@ module Ruby2JS
17
17
  str = parts.map {|part| part.children.first}.join
18
18
  str = str.gsub(/ #.*/,'').gsub(/\s/,'') if extended
19
19
  unless str.include? '/'
20
- return "/#{ str }/#{ opts.join }"
20
+ return put "/#{ str }/#{ opts.join }"
21
21
  end
22
- str = str.inspect
22
+ put "new RegExp(#{ str.inspect }"
23
23
  else
24
- parts.map! do |part|
24
+ put 'new RegExp('
25
+
26
+ parts.each_with_index do |part, index|
27
+ put ' + ' unless index == 0
28
+
25
29
  if part.type == :str
26
30
  str = part.children.first
27
31
  str = str.gsub(/ #.*/,'').gsub(/\s/,'') if extended
28
- str.inspect
32
+ put str.inspect
29
33
  else
30
34
  parse part
31
35
  end
32
36
  end
33
- str = parts.join(' + ')
34
37
  end
35
38
 
36
- if opts.empty?
37
- "new RegExp(#{ str })"
38
- else
39
- "new RegExp(#{ str }, #{ opts.join.inspect})"
39
+ unless opts.empty?
40
+ put ", #{ opts.join.inspect}"
40
41
  end
42
+
43
+ put ')'
41
44
  end
42
45
  end
43
46
  end
@@ -6,9 +6,9 @@ module Ruby2JS
6
6
 
7
7
  handle :return do |value=nil|
8
8
  if value
9
- "return #{ parse value }"
9
+ put 'return '; parse value
10
10
  else
11
- "return"
11
+ put 'return'
12
12
  end
13
13
  end
14
14
 
@@ -24,7 +24,7 @@ module Ruby2JS
24
24
  end
25
25
 
26
26
  if EXPRESSIONS.include? block.last.type
27
- block.push s(:return, block.pop)
27
+ block.push @ast.updated(:return, [block.pop])
28
28
  elsif block.last.type == :if
29
29
  node = block.pop
30
30
  if node.children[1] and node.children[2] and
@@ -6,9 +6,9 @@ module Ruby2JS
6
6
  handle :self do
7
7
  if @block_depth and @block_depth > 1
8
8
  @block_this = true
9
- 'self'
9
+ put 'self'
10
10
  else
11
- 'this'
11
+ put 'this'
12
12
  end
13
13
  end
14
14
  end
@@ -13,7 +13,7 @@ module Ruby2JS
13
13
  # interpretation as an attribute vs a function call with zero parameters.
14
14
  # Sendw forces parameters to be placed on separate lines.
15
15
 
16
- handle :send, :sendw, :attr do |receiver, method, *args|
16
+ handle :send, :sendw, :attr, :call do |receiver, method, *args|
17
17
  ast = @ast
18
18
 
19
19
  width = ((ast.type == :sendw && !@nl.empty?) ? 0 : @width)
@@ -32,8 +32,9 @@ module Ruby2JS
32
32
  if [:call, :[]].include? method and receiver and receiver.type == :block
33
33
  t2,m2,*args2 = receiver.children.first.children
34
34
  if not t2 and [:lambda, :proc].include? m2 and args2.length == 0
35
- receiver = (@state == :statement ? group(receiver) : parse(receiver))
36
- return parse s(:send, nil, receiver, *args)
35
+ (@state == :statement ? group(receiver) : parse(receiver))
36
+ put '('; parse_all *args, join: ', '; put ')'
37
+ return
37
38
  end
38
39
  end
39
40
 
@@ -62,31 +63,36 @@ module Ruby2JS
62
63
  parse s(:not, receiver)
63
64
 
64
65
  elsif method == :[]
65
- "#{ parse receiver }[#{ args.map {|arg| parse arg}.join(', ') }]"
66
+ parse receiver; put '['; parse_all *args, join: ', '; put ']'
66
67
 
67
68
  elsif method == :[]=
68
- "#{ parse receiver }[#{ args[0..-2].map {|arg| parse arg}.join(', ') }] = #{ parse args[-1] }"
69
+ parse receiver; put '['; parse_all *args[0..-2], join: ', '; put '] = '
70
+ parse args[-1]
69
71
 
70
72
  elsif [:-@, :+@, :~, '~'].include? method
71
- "#{ method.to_s[0] }#{ parse receiver }"
73
+ put method.to_s[0]; parse receiver
72
74
 
73
75
  elsif method == :=~
74
- "#{ parse args.first }.test(#{ parse receiver })"
76
+ parse args.first; put '.test('; parse receiver; put ')'
75
77
 
76
78
  elsif method == :!~
77
- "!#{ parse args.first }.test(#{ parse receiver })"
79
+ put '!'; parse args.first; put '.test('; parse receiver; put ')'
78
80
 
79
81
  elsif method == :<< and args.length == 1 and @state == :statement
80
- "#{ parse receiver }.push(#{ parse args.first })"
82
+ parse receiver; put '.push('; parse args.first; put ')'
81
83
 
82
84
  elsif method == :<=>
83
85
  raise NotImplementedError, "use of <=>"
84
86
 
85
87
  elsif OPERATORS.flatten.include?(method) and not LOGICAL.include?(method)
86
- "#{ group_receiver ? group(receiver) : parse(receiver) } #{ method } #{ group_target ? group(target) : parse(target) }"
88
+ (group_receiver ? group(receiver) : parse(receiver))
89
+ put " #{ method } "
90
+ (group_target ? group(target) : parse(target))
87
91
 
88
92
  elsif method =~ /=$/
89
- "#{ parse receiver }#{ '.' if receiver }#{ method.to_s.sub(/=$/, ' =') } #{ parse args.first }"
93
+ parse receiver
94
+ put "#{ '.' if receiver }#{ method.to_s.sub(/=$/, ' =') } "
95
+ parse args.first
90
96
 
91
97
  elsif method == :new
92
98
  if receiver
@@ -120,12 +126,9 @@ module Ruby2JS
120
126
  end
121
127
  end
122
128
 
123
- args = args.map {|a| parse a}.join(', ')
124
-
129
+ put "new "; parse receiver
125
130
  if ast.is_method?
126
- "new #{ parse receiver }(#{ args })"
127
- else
128
- "new #{ parse receiver }"
131
+ put '('; parse_all *args, join: ', '; put ')'
129
132
  end
130
133
  elsif args.length == 1 and args.first.type == :send
131
134
  # accommodation for JavaScript like new syntax w/argument list
@@ -140,35 +143,33 @@ module Ruby2JS
140
143
 
141
144
  elsif method == :raise and receiver == nil
142
145
  if args.length == 1
143
- "throw #{ parse args.first }"
146
+ put 'throw '; parse args.first
144
147
  else
145
- "throw new #{ parse args.first }(#{ parse args[1] })"
148
+ put 'throw new '; parse args.first; put '('; parse args[1]; put ')'
146
149
  end
147
150
 
148
151
  elsif method == :typeof and receiver == nil
149
- "typeof #{ parse args.first }"
152
+ put 'typeof '; parse args.first
150
153
 
151
154
  else
152
155
  if not ast.is_method?
153
156
  if receiver
154
- call = (group_receiver ? group(receiver) : parse(receiver))
155
- "#{ call }.#{ method }"
157
+ (group_receiver ? group(receiver) : parse(receiver))
158
+ put ".#{ method }"
156
159
  else
157
- parse s(:lvasgn, method), @state
160
+ parse ast.updated(:lvasgn, [method]), @state
158
161
  end
159
162
  elsif args.length > 0 and args.any? {|arg| arg.type == :splat}
160
163
  parse s(:send, s(:attr, receiver, method), :apply,
161
164
  (receiver || s(:nil)), s(:array, *args))
162
165
  else
163
- call = (group_receiver ? group(receiver) : parse(receiver))
164
- call = "#{ call }#{ '.' if receiver && method}#{ method }"
165
- args = args.map {|a| parse a}
166
- if args.map {|arg| arg.length+2}.reduce(&:+).to_i < width-10
167
- "#{ call }(#{ args.join(', ') })"
168
- elsif args.length == 1 and args.first.to_s.include? "\n"
169
- "#{ call }(#{ args.join(', ') })"
166
+ (group_receiver ? group(receiver) : parse(receiver))
167
+ put "#{ '.' if receiver && method}#{ method }"
168
+
169
+ if args.length <= 1
170
+ put "("; parse_all *args, join: ', '; put ')'
170
171
  else
171
- "#{ call }(#@nl#{ args.join(",#@ws") }#@nl)"
172
+ compact { puts "("; parse_all *args, join: ",#@ws"; sput ')' }
172
173
  end
173
174
  end
174
175
  end
@@ -10,13 +10,6 @@ module Ruby2JS
10
10
  raise NotImplementedError, "super outside of a method"
11
11
  end
12
12
 
13
- # what to call
14
- if @instance_method.type == :constructor
15
- method = ''
16
- else
17
- method = ".prototype.#{ @instance_method.children[1].to_s.chomp('=') }"
18
- end
19
-
20
13
  # what to pass
21
14
  if @ast.type == :zsuper
22
15
  if @instance_method.type == :method
@@ -28,11 +21,15 @@ module Ruby2JS
28
21
  end
29
22
  end
30
23
 
24
+ parse @class_parent
25
+
26
+ # what to call
27
+ if @instance_method.type != :constructor
28
+ puts ".prototype.#{ @instance_method.children[1].to_s.chomp('=') }"
29
+ end
30
+
31
31
  if args
32
- args = [s(:self), *args].map {|arg| parse arg}.join(', ')
33
- "#{ parse @class_parent }#{ method }.call(#{ args })"
34
- else
35
- "#{ parse @class_parent }#{ method }"
32
+ put '.call('; parse_all s(:self), *args, join: ', '; put ')'
36
33
  end
37
34
  end
38
35
  end
@@ -4,7 +4,7 @@ module Ruby2JS
4
4
  # (sym :sym))
5
5
 
6
6
  handle :sym do |sym|
7
- sym.to_s.inspect
7
+ put sym.to_s.inspect
8
8
  end
9
9
  end
10
10
  end
@@ -6,8 +6,15 @@ module Ruby2JS
6
6
  # (sym :bar))
7
7
 
8
8
  handle :undef do |*syms|
9
- "delete " + syms.
10
- map {|sym| sym.type == :sym ? sym.children.last : parse(sym)}.join(@sep)
9
+ syms.each_with_index do |sym, index|
10
+ put @sep unless index == 0
11
+
12
+ if sym.type == :sym
13
+ put "delete #{sym.children.last}"
14
+ else
15
+ put "delete "; parse sym
16
+ end
17
+ end
11
18
  end
12
19
  end
13
20
  end
@@ -5,7 +5,7 @@ module Ruby2JS
5
5
  # (gvar :$a)
6
6
 
7
7
  handle :lvar, :gvar do |var|
8
- var
8
+ put var
9
9
  end
10
10
  end
11
11
  end
@@ -8,6 +8,7 @@ module Ruby2JS
8
8
  # (int 1))
9
9
 
10
10
  handle :lvasgn, :gvasgn do |name, value=nil|
11
+ state = @state
11
12
  begin
12
13
  if value and value.type == :lvasgn and @state == :statement
13
14
  undecls = []
@@ -25,16 +26,23 @@ module Ruby2JS
25
26
  end
26
27
  end
27
28
 
28
- var = 'var ' unless @vars.include?(name) or @state != :statement
29
+ if state == :statement and @scope and not @vars.include?(name)
30
+ var = 'var '
31
+ end
29
32
 
30
33
  if value
31
-
32
- "#{ var }#{ name } = #{ parse value }"
34
+ put "#{ var }#{ name } = "; parse value
33
35
  else
34
- "#{ var }#{ name }"
36
+ put "#{ var }#{ name }"
35
37
  end
36
38
  ensure
37
- @vars[name] = true
39
+ if @scope
40
+ @vars[name] = true
41
+ elsif state == :statement
42
+ @vars[name] ||= :pending
43
+ else
44
+ @vars[name] ||= :implicit # console, document, ...
45
+ end
38
46
  end
39
47
  end
40
48
  end
@@ -8,7 +8,8 @@ module Ruby2JS
8
8
  handle :while do |condition, block|
9
9
  begin
10
10
  next_token, @next_token = @next_token, :continue
11
- "while (#{ parse condition }) {#@nl#{ scope block }#@nl}"
11
+
12
+ put 'while ('; parse condition; puts ') {'; scope block; sput '}'
12
13
  ensure
13
14
  @next_token = next_token
14
15
  end
@@ -10,7 +10,8 @@ module Ruby2JS
10
10
  block = block.updated(:begin) if block.type == :kwbegin
11
11
  begin
12
12
  next_token, @next_token = @next_token, :continue
13
- "do {#@nl#{ scope block }#@nl} while (#{ parse condition })"
13
+
14
+ puts 'do {'; scope block; sput '} while ('; parse condition; put ')'
14
15
  ensure
15
16
  @next_token = next_token
16
17
  end
@@ -5,11 +5,12 @@ module Ruby2JS
5
5
  # (str 'a'))
6
6
 
7
7
  handle :xstr do |*children|
8
- str = eval children.map{ |child| parse child }.join
8
+ str = eval capture { parse_all *children }
9
+
9
10
  if @binding
10
- @binding.eval(str).to_s
11
+ puts @binding.eval(str).to_s
11
12
  else
12
- eval(str).to_s
13
+ puts eval(str).to_s
13
14
  end
14
15
  end
15
16
  end
@@ -3,14 +3,14 @@ require 'execjs'
3
3
 
4
4
  module Ruby2JS
5
5
  def self.compile(source, options={})
6
- ExecJS.compile(convert(source, options))
6
+ ExecJS.compile(convert(source, options).to_s)
7
7
  end
8
8
 
9
9
  def self.eval(source, options={})
10
- ExecJS.eval(convert(source, options))
10
+ ExecJS.eval(convert(source, options).to_s)
11
11
  end
12
12
 
13
13
  def self.exec(source, options={})
14
- ExecJS.exec(convert(source, options))
14
+ ExecJS.exec(convert(source, options).to_s)
15
15
  end
16
16
  end