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.
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,11 @@
1
+ module Ruby2JS
2
+ class Converter
3
+
4
+ # (lvar :a)
5
+ # (gvar :$a)
6
+
7
+ handle :lvar, :gvar do |var|
8
+ var
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,41 @@
1
+ module Ruby2JS
2
+ class Converter
3
+
4
+ # (lvasgn :a
5
+ # (int 1))
6
+
7
+ # (gvasgn :$a
8
+ # (int 1))
9
+
10
+ handle :lvasgn, :gvasgn do |name, value=nil|
11
+ begin
12
+ if value and value.type == :lvasgn and @state == :statement
13
+ undecls = []
14
+ undecls << name unless @vars.include? name
15
+
16
+ child = value
17
+ while child and child.type == :lvasgn
18
+ undecls << child.children[0] unless @vars.include? child.children[0]
19
+ child = child.children[1]
20
+ end
21
+
22
+ unless undecls.empty?
23
+ return parse s(:begin,
24
+ *undecls.map {|name| s(:lvasgn, name)}, @ast), @state
25
+ end
26
+ end
27
+
28
+ var = 'var ' unless @vars.include?(name) or @state != :statement
29
+
30
+ if value
31
+
32
+ "#{ var }#{ name } = #{ parse value }"
33
+ else
34
+ "#{ var }#{ name }"
35
+ end
36
+ ensure
37
+ @vars[name] = true
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,12 @@
1
+ module Ruby2JS
2
+ class Converter
3
+
4
+ # (while
5
+ # (true)
6
+ # (...))
7
+
8
+ handle :while do |condition, block|
9
+ "while (#{ parse condition }) {#@nl#{ scope block }#@nl}"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ module Ruby2JS
2
+ class Converter
3
+
4
+ # (while-post
5
+ # (true)
6
+ # (kwbegin
7
+ # (...)))
8
+
9
+ handle :while_post do |condition, block|
10
+ block = block.updated(:begin) if block.type == :kwbegin
11
+ "do {#@nl#{ scope block }#@nl} while (#{ parse condition })"
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ module Ruby2JS
2
+ class Converter
3
+
4
+ # (xstr
5
+ # (str 'a'))
6
+
7
+ handle :xstr do |*children|
8
+ str = eval children.map{ |child| parse child }.join
9
+ if @binding
10
+ @binding.eval(str).to_s
11
+ else
12
+ eval(str).to_s
13
+ end
14
+ end
15
+ end
16
+ end
@@ -63,7 +63,7 @@ module Ruby2JS
63
63
  @ngApp = nil
64
64
 
65
65
  # replace module with a constant assign followed by the module contents
66
- node.updated :begin, [casgn, *block]
66
+ node.updated :begin, [casgn, *block.compact]
67
67
  end
68
68
 
69
69
  # input:
@@ -1,4 +1,52 @@
1
1
  require 'ruby2js'
2
+ #
3
+ # Jquery functions are either invoked using jQuery() or, more commonly, $().
4
+ # The former presents no problem, the latter is not legal Ruby.
5
+ #
6
+ # Accordingly, the first accomodation this filter provides is to map $$ to
7
+ # $. This works find for $$.ajax and the like, but less so for direct calls
8
+ # as $$(this) is also a syntax error. $$.(this) and $$[this] will work
9
+ # but are a bit clumsy.
10
+ #
11
+ # So as a second accomodation, the rarely used binary one's complement unary
12
+ # operator (namely, ~) is usurped, and the AST is rewritten to provide the
13
+ # effect of this operator being of a higher precedence than method calls.
14
+ #
15
+ # As a part of this rewriting, calls to getters and setters are rewritten
16
+ # to match jQuery's convention for getters and setters:
17
+ # http://learn.jquery.com/using-jquery-core/working-with-selections/
18
+ #
19
+ # Of course, using jQuery's style of getter and setter calls is supported,
20
+ # and indeed is convenient when using method chaining.
21
+ #
22
+ # Finally, the tilde AST rewriting can be avoided by using consecutive tildes
23
+ # (~~ is a common Ruby idiom for Math.floor, ~~~ will return the binary
24
+ # one's complement.); and the getter and setter AST rewriting can be avoided
25
+ # by the use of parenthesis, e.g. (~this).text.
26
+ #
27
+ # Some examples of before/after conversions:
28
+ #
29
+ # `this.val
30
+ # $(this).val()
31
+ #
32
+ # `"button.continue".html = "Next Step..."
33
+ # $("button.continue").html("Next Step...")
34
+ #
35
+ # $$.ajax(
36
+ # url: "/api/getWeather",
37
+ # data: {zipcode: 97201},
38
+ # success: proc do |data|
39
+ # `"#weather-temp".html = "<strong>#{data}</strong> degrees"
40
+ # end
41
+ # )
42
+ #
43
+ # $.ajax({
44
+ # url: "/api/getWeather",
45
+ # data: {zipcode: 97201},
46
+ # success: function(data) {
47
+ # $("#weather-temp").html("<strong>" + data + "</strong> degrees");
48
+ # }
49
+ # })
2
50
 
3
51
  module Ruby2JS
4
52
  module Filter
@@ -19,13 +67,59 @@ module Ruby2JS
19
67
  end
20
68
 
21
69
  def on_send(node)
22
- if node.children[1] == :call
70
+ if [:call, :[]].include? node.children[1]
71
+ # map $$.call(..), $$.(..), and $$[...] to $(...)
23
72
  target = process(node.children.first)
24
73
  if target.type == :gvar and target.children == ['$']
25
74
  s(:send, nil, '$', *process_all(node.children[2..-1]))
26
75
  else
27
76
  super
28
77
  end
78
+
79
+ elsif node.children[1] == :~
80
+ # map ~expression.method to $(expression).method
81
+
82
+ # See http://api.jquery.com/category/properties/
83
+ props = :context, :jquery, :browser, :fx, :support, :length, :selector
84
+
85
+ rewrite_tilda = proc do |node|
86
+ # Example conversion:
87
+ # before:
88
+ # (send (send (send (send nil :a) :b) :c) :~)
89
+ # after:
90
+ # (send (send (send nil "$" (send nil :a)) :b) :c)
91
+ if node.type == :send and node.children[0]
92
+ if node.children[1] == :~ and node.children[0].children[1] == :~
93
+ # consecutive tildes
94
+ if node.children[0].children[0].children[1] == :~
95
+ result = process(node.children[0].children[0].children[0])
96
+ else
97
+ result = s(:send, process(node.children[0].children[0]), :~)
98
+ end
99
+ s(:send, s(:send, result, :~), :~)
100
+ else
101
+ # possible getter/setter
102
+ method = node.children[1]
103
+ method = method.to_s.chomp('=') if method =~ /=$/
104
+ rewrite = [rewrite_tilda[node.children[0]],
105
+ method, *process_all(node.children[2..-1])]
106
+ if props.include? node.children[1]
107
+ node.updated nil, rewrite
108
+ else
109
+ s(:send, *rewrite)
110
+ end
111
+ end
112
+ elsif node.type == :block
113
+ # method call with a block parameter
114
+ node.updated nil, [rewrite_tilda[node.children[0]],
115
+ *process_all(node.children[1..-1])]
116
+ else
117
+ # innermost expression
118
+ s(:send, nil, '$', process(node))
119
+ end
120
+ end
121
+
122
+ rewrite_tilda[node].children[0]
29
123
  else
30
124
  super
31
125
  end
@@ -1,7 +1,7 @@
1
1
  module Ruby2JS
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 1
4
- MINOR = 0
4
+ MINOR = 1
5
5
  TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
data/ruby2js.gemspec CHANGED
@@ -2,14 +2,14 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "ruby2js"
5
- s.version = "1.0.0"
5
+ s.version = "1.1.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Sam Ruby"]
9
- s.date = "2013-11-15"
9
+ s.date = "2013-11-18"
10
10
  s.description = " The base package maps Ruby syntax to JavaScript semantics.\n Filters may be provided to add Ruby-specific or framework specific\n behavior.\n"
11
11
  s.email = "rubys@intertwingly.net"
12
- s.files = ["ruby2js.gemspec", "README.md", "lib/ruby2js", "lib/ruby2js/version.rb", "lib/ruby2js/converter.rb", "lib/ruby2js/filter", "lib/ruby2js/filter/return.rb", "lib/ruby2js/filter/angularrb.rb", "lib/ruby2js/filter/functions.rb", "lib/ruby2js/filter/jquery.rb", "lib/ruby2js.rb"]
12
+ s.files = ["ruby2js.gemspec", "README.md", "lib/ruby2js", "lib/ruby2js/version.rb", "lib/ruby2js/converter", "lib/ruby2js/converter/orasgn.rb", "lib/ruby2js/converter/kwbegin.rb", "lib/ruby2js/converter/const.rb", "lib/ruby2js/converter/return.rb", "lib/ruby2js/converter/opasgn.rb", "lib/ruby2js/converter/xstr.rb", "lib/ruby2js/converter/args.rb", "lib/ruby2js/converter/literal.rb", "lib/ruby2js/converter/array.rb", "lib/ruby2js/converter/if.rb", "lib/ruby2js/converter/nil.rb", "lib/ruby2js/converter/logical.rb", "lib/ruby2js/converter/next.rb", "lib/ruby2js/converter/while.rb", "lib/ruby2js/converter/whilepost.rb", "lib/ruby2js/converter/arg.rb", "lib/ruby2js/converter/case.rb", "lib/ruby2js/converter/break.rb", "lib/ruby2js/converter/hash.rb", "lib/ruby2js/converter/for.rb", "lib/ruby2js/converter/boolean.rb", "lib/ruby2js/converter/var.rb", "lib/ruby2js/converter/undef.rb", "lib/ruby2js/converter/blockpass.rb", "lib/ruby2js/converter/until.rb", "lib/ruby2js/converter/regexp.rb", "lib/ruby2js/converter/untilpost.rb", "lib/ruby2js/converter/masgn.rb", "lib/ruby2js/converter/block.rb", "lib/ruby2js/converter/ivar.rb", "lib/ruby2js/converter/send.rb", "lib/ruby2js/converter/vasgn.rb", "lib/ruby2js/converter/defined.rb", "lib/ruby2js/converter/def.rb", "lib/ruby2js/converter/sym.rb", "lib/ruby2js/converter/ivasgn.rb", "lib/ruby2js/converter/casgn.rb", "lib/ruby2js/converter/self.rb", "lib/ruby2js/converter/andasgn.rb", "lib/ruby2js/converter/begin.rb", "lib/ruby2js/converter/dstr.rb", "lib/ruby2js/converter/class.rb", "lib/ruby2js/converter.rb", "lib/ruby2js/filter", "lib/ruby2js/filter/return.rb", "lib/ruby2js/filter/angularrb.rb", "lib/ruby2js/filter/functions.rb", "lib/ruby2js/filter/jquery.rb", "lib/ruby2js.rb"]
13
13
  s.homepage = "http://github.com/rubys/ruby2js"
14
14
  s.licenses = ["MIT"]
15
15
  s.require_paths = ["lib"]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby2js
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Ruby
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-15 00:00:00.000000000 Z
11
+ date: 2013-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -34,6 +34,48 @@ files:
34
34
  - ruby2js.gemspec
35
35
  - README.md
36
36
  - lib/ruby2js/version.rb
37
+ - lib/ruby2js/converter/orasgn.rb
38
+ - lib/ruby2js/converter/kwbegin.rb
39
+ - lib/ruby2js/converter/const.rb
40
+ - lib/ruby2js/converter/return.rb
41
+ - lib/ruby2js/converter/opasgn.rb
42
+ - lib/ruby2js/converter/xstr.rb
43
+ - lib/ruby2js/converter/args.rb
44
+ - lib/ruby2js/converter/literal.rb
45
+ - lib/ruby2js/converter/array.rb
46
+ - lib/ruby2js/converter/if.rb
47
+ - lib/ruby2js/converter/nil.rb
48
+ - lib/ruby2js/converter/logical.rb
49
+ - lib/ruby2js/converter/next.rb
50
+ - lib/ruby2js/converter/while.rb
51
+ - lib/ruby2js/converter/whilepost.rb
52
+ - lib/ruby2js/converter/arg.rb
53
+ - lib/ruby2js/converter/case.rb
54
+ - lib/ruby2js/converter/break.rb
55
+ - lib/ruby2js/converter/hash.rb
56
+ - lib/ruby2js/converter/for.rb
57
+ - lib/ruby2js/converter/boolean.rb
58
+ - lib/ruby2js/converter/var.rb
59
+ - lib/ruby2js/converter/undef.rb
60
+ - lib/ruby2js/converter/blockpass.rb
61
+ - lib/ruby2js/converter/until.rb
62
+ - lib/ruby2js/converter/regexp.rb
63
+ - lib/ruby2js/converter/untilpost.rb
64
+ - lib/ruby2js/converter/masgn.rb
65
+ - lib/ruby2js/converter/block.rb
66
+ - lib/ruby2js/converter/ivar.rb
67
+ - lib/ruby2js/converter/send.rb
68
+ - lib/ruby2js/converter/vasgn.rb
69
+ - lib/ruby2js/converter/defined.rb
70
+ - lib/ruby2js/converter/def.rb
71
+ - lib/ruby2js/converter/sym.rb
72
+ - lib/ruby2js/converter/ivasgn.rb
73
+ - lib/ruby2js/converter/casgn.rb
74
+ - lib/ruby2js/converter/self.rb
75
+ - lib/ruby2js/converter/andasgn.rb
76
+ - lib/ruby2js/converter/begin.rb
77
+ - lib/ruby2js/converter/dstr.rb
78
+ - lib/ruby2js/converter/class.rb
37
79
  - lib/ruby2js/converter.rb
38
80
  - lib/ruby2js/filter/return.rb
39
81
  - lib/ruby2js/filter/angularrb.rb