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
@@ -7,7 +7,7 @@ module Ruby2JS
7
7
  # resolve anonymous receivers against rbstack
8
8
  receiver ||= @rbstack.map {|rb| rb[name]}.compact.last
9
9
 
10
- "#{ parse receiver }#{ '.' if receiver }#{ name }"
10
+ parse receiver; put '.' if receiver; put name
11
11
  end
12
12
  end
13
13
  end
@@ -5,11 +5,12 @@ module Ruby2JS
5
5
 
6
6
  handle :cvar do |var|
7
7
  if @class_name
8
- var.to_s.sub('@@', "#{parse @class_name}._")
8
+ parse @class_name
9
+ put var.to_s.sub('@@', "._")
9
10
  elsif @prototype
10
- var.to_s.sub('@@', 'this._')
11
+ put var.to_s.sub('@@', 'this._')
11
12
  else
12
- var.to_s.sub('@@', 'this.constructor._')
13
+ put var.to_s.sub('@@', 'this.constructor._')
13
14
  end
14
15
  end
15
16
  end
@@ -6,17 +6,16 @@ module Ruby2JS
6
6
 
7
7
  handle :cvasgn do |var, expression=nil|
8
8
  if @class_name
9
- var = var.to_s.sub('@@', "#{parse @class_name}._")
9
+ parse @class_name
10
+ put var.to_s.sub('@@', "._")
10
11
  elsif @prototype
11
- var = var.to_s.sub('@@', 'this._')
12
+ put var.to_s.sub('@@', 'this._')
12
13
  else
13
- var = var.to_s.sub('@@', 'this.constructor._')
14
+ put var.to_s.sub('@@', 'this.constructor._')
14
15
  end
15
16
 
16
17
  if expression
17
- "#{ var } = #{ parse expression }"
18
- else
19
- var
18
+ put " = "; parse expression
20
19
  end
21
20
  end
22
21
  end
@@ -90,15 +90,27 @@ module Ruby2JS
90
90
 
91
91
  nl = @nl unless body == s(:begin)
92
92
  begin
93
+ if name
94
+ put "function #{name}"
95
+ elsif @prop
96
+ put @prop
97
+ @prop = nil
98
+ else
99
+ put 'function'
100
+ end
101
+
102
+ put '('; parse args; put ") {#{nl}"
103
+
93
104
  next_token, @next_token = @next_token, :return
94
105
  @block_depth += 1 if @block_depth
95
- body = scope body, vars
106
+ mark = output_location
107
+ scope body, vars
96
108
  if @block_this and @block_depth == 1
97
- body = "var self = this#{@sep}#{body}"
109
+ insert mark, "var self = this#{@sep}"
98
110
  @block_this = false
99
111
  end
100
112
 
101
- "function#{ " #{name}" if name }(#{ parse args }) {#{nl}#{ body }#{nl}}"
113
+ put "#{nl}}"
102
114
  ensure
103
115
  @next_token = next_token
104
116
  @block_depth -= 1 if @block_depth
@@ -9,7 +9,7 @@ module Ruby2JS
9
9
 
10
10
  handle :defined?, :undefined? do |var|
11
11
  op = (@ast.type == :defined? ? :"!==" : :===)
12
- "typeof #{ parse var } #{ op } 'undefined'"
12
+ put "typeof "; parse var; put " #{ op } 'undefined'"
13
13
  end
14
14
  end
15
15
  end
@@ -13,19 +13,23 @@ module Ruby2JS
13
13
 
14
14
  def transform_defs(target, method, args, body)
15
15
  if not @ast.is_method? or @ast.type == :defp
16
- s(:prop, target, method.to_s =>
16
+ node = s(:prop, target, method.to_s =>
17
17
  {enumerable: s(:true), configurable: s(:true),
18
18
  get: s(:block, s(:send, nil, :proc), args,
19
19
  s(:autoreturn, body))})
20
20
  elsif method =~ /=$/
21
- s(:prop, target, method.to_s.sub('=', '') =>
21
+ node = s(:prop, target, method.to_s.sub('=', '') =>
22
22
  {enumerable: s(:true), configurable: s(:true),
23
23
  set: s(:block, s(:send, nil, :proc), args,
24
24
  body)})
25
25
  else
26
- s(:send, target, "#{method}=",
26
+ node = s(:send, target, "#{method}=",
27
27
  s(:block, s(:send, nil, :lambda), args, body))
28
28
  end
29
+
30
+ @comments[node] = @comments[@ast] if @comments[@ast]
31
+
32
+ node
29
33
  end
30
34
  end
31
35
  end
@@ -10,7 +10,9 @@ module Ruby2JS
10
10
  # (...))
11
11
 
12
12
  handle :dstr, :dsym do |*children|
13
- children.map! do |child|
13
+ children.each_with_index do |child, index|
14
+ put ' + ' unless index == 0
15
+
14
16
  if child.type == :begin and child.children.length == 1
15
17
  child = child.children.first
16
18
  end
@@ -26,8 +28,6 @@ module Ruby2JS
26
28
  parse child
27
29
  end
28
30
  end
29
-
30
- children.join(' + ')
31
31
  end
32
32
  end
33
33
  end
@@ -12,18 +12,15 @@ module Ruby2JS
12
12
  handle :for do |var, expression, block|
13
13
  begin
14
14
  next_token, @next_token = @next_token, :continue
15
- if expression.type == :irange
16
- "for (var #{parse var} = #{ parse expression.children.first }; " +
17
- "#{ parse var } <= #{ parse expression.children.last }; " +
18
- "#{ parse var }++) {#@nl#{ scope block }#@nl}"
19
- elsif expression.type == :erange
20
- "for (var #{parse var} = #{ parse expression.children.first }; " +
21
- "#{ parse var } < #{ parse expression.children.last }; " +
22
- "#{ parse var }++) {#@nl#{ scope block }#@nl}"
15
+ put "for (var "; parse var
16
+ if [:irange, :erange].include? expression.type
17
+ put ' = '; parse expression.children.first; put '; '; parse var
18
+ (expression.type == :erange ? put(' < ') : put(' <= '))
19
+ parse expression.children.last; put '; '; parse var; puts '++'
23
20
  else
24
- "for (var #{parse var} in #{ parse expression }) " +
25
- "{#@nl#{ scope block }#@nl}"
21
+ put ' in '; parse expression;
26
22
  end
23
+ puts ') {'; scope block; sput '}'
27
24
  ensure
28
25
  @next_token = next_token
29
26
  end
@@ -7,50 +7,86 @@ module Ruby2JS
7
7
  # (str "value")))
8
8
 
9
9
  handle :hash do |*pairs|
10
- pairs.map! do |node|
11
- raise NotImplementedError, "kwsplat" if node.type == :kwsplat
10
+ compact do
11
+ singleton = pairs.length <= 1
12
12
 
13
- begin
14
- block_depth, block_this, block_hash = @block_depth, @block_this, false
15
- left, right = node.children
13
+ (singleton ? put('{') : puts('{'))
16
14
 
17
- if Hash === right or right.type == :block
18
- @block_depth, block_hash = 0, true
15
+ pairs.each_with_index do |node, index|
16
+ raise NotImplementedError, "kwsplat" if node.type == :kwsplat
17
+
18
+ (singleton ? put(', ') : put(",#@ws")) unless index == 0
19
+
20
+ if not @comments[node].empty?
21
+ (puts ''; singleton = false) if singleton
22
+ comments(node).each {|comment| put comment}
19
23
  end
20
24
 
21
- if left.type == :prop
22
- result = []
23
- if right[:get]
24
- result << "get #{left.children[0]}#{
25
- parse(right[:get]).sub(/^function/,'')}"
25
+ begin
26
+ block_depth,block_this,block_hash = @block_depth,@block_this,false
27
+ left, right = node.children
28
+
29
+ if Hash === right or right.type == :block
30
+ @block_depth, block_hash = 0, true
26
31
  end
27
- if right[:set]
28
- result << "set #{left.children[0]}#{
29
- parse(right[:set]).sub(/^function/,'')}"
32
+
33
+ if left.type == :prop
34
+ if right[:get]
35
+ unless @comments[right[:get]].empty?
36
+ (puts ''; singleton = false) if singleton
37
+ comments(right[:get]).each {|comment| put comment}
38
+ end
39
+
40
+ @prop = "get #{left.children[0]}"
41
+ parse(right[:get])
42
+ (singleton ? put(', ') : put(",#@ws")) if right[:set]
43
+ end
44
+
45
+ if right[:set]
46
+ unless @comments[right[:set]].empty?
47
+ (puts ''; singleton = false) if singleton
48
+ comments(right[:set]).each {|comment| put comment}
49
+ end
50
+
51
+ @prop = "set #{left.children[0]}"
52
+ parse(right[:set])
53
+ end
54
+ else
55
+ # hoist get/set comments to definition of property
56
+ if right.type == :hash
57
+ right.children.each do |pair|
58
+ next unless Parser::AST::Node === pair.children.last
59
+ if pair.children.last.type == :block
60
+ if @comments[pair.children.last]
61
+ (puts ''; singleton = false) if singleton
62
+ comments(pair.children.last).each do |comment|
63
+ put comment
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ if
71
+ left.children.first.to_s =~ /\A[a-zA-Z_$][a-zA-Z_$0-9]*\Z/
72
+ then
73
+ put left.children.first
74
+ else
75
+ parse left
76
+ end
77
+
78
+ put ': '; parse right
30
79
  end
31
- result
32
- else
33
- key = parse left
34
- key = $1 if key =~ /\A"([a-zA-Z_$][a-zA-Z_$0-9]*)"\Z/
35
- "#{key}: #{parse right}"
36
- end
37
80
 
38
- ensure
39
- if block_hash
40
- @block_depth = block_depth
41
- @block_this = block_this
81
+ ensure
82
+ if block_hash
83
+ @block_depth = block_depth
84
+ @block_this = block_this
85
+ end
42
86
  end
43
87
  end
44
- end
45
-
46
- pairs.flatten!
47
88
 
48
- if pairs.map {|item| item.length+2}.reduce(&:+).to_i < @width-10
49
- "{#{ pairs.join(', ') }}"
50
- elsif pairs.length == 1
51
- "{#{ pairs.join(', ') }}"
52
- else
53
- "{#@nl#{ pairs.join(",#@ws") }#@nl}"
89
+ (singleton ? put('}') : sput('}'))
54
90
  end
55
91
  end
56
92
  end
@@ -15,23 +15,45 @@ module Ruby2JS
15
15
  then_block ||= s(:nil)
16
16
 
17
17
  if @state == :statement
18
- output = "if (#{ parse condition }) {#@nl#{ scope then_block }#@nl}"
19
- while else_block and else_block.type == :if
20
- condition, then_block, else_block = else_block.children
21
- output << " else if (#{ parse condition }) " +
22
- "{#@nl#{ scope then_block }#@nl}"
23
- end
24
- output << " else {#@nl#{ scope else_block }#@nl}" if else_block
18
+ begin
19
+ scope, @scope = @scope, false
20
+ mark = output_location
25
21
 
26
- # use short form when appropriate
27
- unless output.length>@width-8 or else_block or then_block.type == :begin
28
- output = "if (#{ parse condition }) #{ scope then_block }"
29
- end
22
+ # use short form when appropriate
23
+ unless else_block or then_block.type == :begin
24
+ put "if ("; parse condition; put ') '
25
+ wrap { parse then_block, :statement }
26
+ else
27
+ put "if ("; parse condition; puts ') {'
28
+ parse then_block, :statement
29
+ sput '}'
30
+
31
+ while else_block and else_block.type == :if
32
+ condition, then_block, else_block = else_block.children
33
+ put ' else if ('; parse condition; puts ') {'
34
+ parse then_block, :statement
35
+ sput '}'
36
+ end
30
37
 
31
- output
38
+ if else_block
39
+ puts ' else {'; parse else_block, :statement; sput '}'
40
+ end
41
+ end
42
+
43
+ if scope
44
+ vars = @vars.select {|key, value| value == :pending}.keys
45
+ unless vars.empty?
46
+ insert mark, "var #{vars.join(', ')}#{@sep}"
47
+ vars.each {|var| @vars[var] = true}
48
+ end
49
+ end
50
+ ensure
51
+ @scope = scope
52
+ end
32
53
  else
33
54
  else_block ||= s(:nil)
34
- "(#{ parse condition } ? #{ parse then_block } : #{ parse else_block })"
55
+ put '('; parse condition; put ' ? '; parse then_block
56
+ put ' : '; parse else_block; put ')'
35
57
  end
36
58
  end
37
59
  end
@@ -6,7 +6,7 @@ module Ruby2JS
6
6
  # NOTE: in? is a synthetic
7
7
 
8
8
  handle :in? do |left, right|
9
- "#{ parse left } in #{ parse right }"
9
+ parse left; put " in "; parse right
10
10
  end
11
11
  end
12
12
  end
@@ -5,7 +5,7 @@ module Ruby2JS
5
5
  # (int 1))
6
6
 
7
7
  handle :ivasgn do |var, expression|
8
- "#{ var.to_s.sub('@', 'this._') } = #{ parse expression }"
8
+ put "#{ var.to_s.sub('@', 'this._') } = "; parse expression
9
9
  end
10
10
  end
11
11
  end
@@ -35,51 +35,51 @@ module Ruby2JS
35
35
  body = block
36
36
  end
37
37
 
38
- output = "try {#@nl#{ parse body, :statement }#@nl}"
38
+ if not recovers and not finally
39
+ return parse s(:begin, *children)
40
+ end
41
+
42
+ puts "try {"; parse body, :statement; sput '}'
39
43
 
40
44
  if recovers
41
45
  if recovers.length == 1 and not recovers.first.children.first
42
46
  # single catch with no exception named
43
- output += " catch (#{ parse var }) " +
44
- "{#@nl#{ parse recovers.first.children.last, :statement }#@nl}"
47
+ put " catch ("; parse var; puts ") {"
48
+ parse recovers.first.children.last, :statement; sput '}'
45
49
  else
46
- output += " catch (#{ parse var }) {#@nl"
50
+ put " catch ("; parse var; puts ') {'
47
51
 
48
52
  first = true
49
53
  recovers.each do |recover|
50
54
  exceptions, var, recovery = recover.children
51
55
 
52
56
  if exceptions
53
- tests = exceptions.children.map do |exception|
54
- "#{ parse var} instanceof #{ parse exception }"
55
- end
56
57
 
57
- output += "} else " if not first
58
+ put "} else " if not first
58
59
  first = false
59
60
 
60
- output += "if (#{ tests.join(' || ') }) {#@nl"
61
+ put 'if ('
62
+ exceptions.children.each_with_index do |exception, index|
63
+ put ' || ' unless index == 0
64
+ parse var; put ' instanceof '; parse exception
65
+ end
66
+ puts ') {'
61
67
  else
62
- output += "} else {#@nl"
68
+ puts '} else {'
63
69
  end
64
70
 
65
- output += "#{ parse recovery, :statement }#@nl"
71
+ parse recovery, :statement; puts ''
66
72
  end
67
73
 
68
74
  if recovers.last.children.first
69
- output += "} else {#{@nl}throw #{ parse var }#@nl"
75
+ puts "} else {"; put 'throw '; parse var; puts ''
70
76
  end
71
77
 
72
- output += "}#@nl}"
78
+ puts '}'; put '}'
73
79
  end
74
80
  end
75
81
 
76
- output += " finally {#@nl#{ parse finally, :statement }#@nl}" if finally
77
-
78
- if recovers or finally
79
- output
80
- else
81
- parse s(:begin, *children)
82
- end
82
+ (puts ' finally {'; parse finally, :statement; sput '}') if finally
83
83
  end
84
84
  end
85
85
  end
@@ -6,7 +6,7 @@ module Ruby2JS
6
6
  # (str "1"))
7
7
 
8
8
  handle :int, :float, :str do |value|
9
- value.inspect
9
+ put value.inspect
10
10
  end
11
11
  end
12
12
  end