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,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