ruby2js 0.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.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MThiMDkwZGYwN2EwNTUzNmM3ODY3NGExMzcwMDllMTUzODJmNWQ2MQ==
5
+ data.tar.gz: !binary |-
6
+ MzA3ODMzOWM1ZDcwMmI2YzhiNzFmZjdlNDE4NTU2ZGQ5OTkwZmIwNw==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ ZWI1ODMwODg3YzgxODhhZDZjMjRmYzAxM2RmMDU5MGUzZmQ1OTUyNDY5NDdi
10
+ NDgyODdkNjFlNjZmMWU3MDE1ZTYyZGY5YTJmM2NmN2Y3NjVhNDRmMjVkMjYw
11
+ NmFhMDVjZWMwNGEwZDVhNWE3MzQyNmRlNjI2YjI4YmQ5MzgyNzY=
12
+ data.tar.gz: !binary |-
13
+ NGU1YTAwOWZiODUyMWJmOTM3YTYyMjNmNTEwNzkwNDExNjBmZjAwMjI2ODky
14
+ YzhmNmRhMjQxYjk0ZGJjZjZlODFkZDc1MjVjNzIzZTExMThkNDBlZTRhMjM3
15
+ ZDgyZDBiZjQ2OGIxM2NmNmMwZmQ3ZjUyYWVmY2JjNzM3NzA3M2M=
data/README.md ADDED
@@ -0,0 +1,52 @@
1
+ ruby2js
2
+ =======
3
+
4
+ Minimal yet extensible Ruby to JavaScript conversion.
5
+
6
+ Description
7
+ ---
8
+
9
+ The base package maps Ruby syntax to JavaScript semantics. For example,
10
+ a Ruby Hash literal becomes a JavaScript Object literal. Ruby symbols
11
+ become JavaScript strings. Ruby method calls become JavaScript function
12
+ calls IF there are either one or more arguments passed OR parenthesis are
13
+ used, otherwise Ruby method calls become JavaScript property accesses.
14
+ By default, methods, lambdas, and procs return `undefined`.
15
+
16
+ Filters may be provided to add Ruby-specific or Framework specific
17
+ behavior. Filters are essentially macro facilities that operate on
18
+ an AST representation of the code.
19
+
20
+ Synopsis
21
+ ---
22
+
23
+ ```ruby
24
+ require 'ruby2js/filter/functions'
25
+ puts Ruby2JS.convert('"2A".to_i(16)', filters: [Ruby2JS::Filter::Functions])
26
+ ```
27
+
28
+ License
29
+ ---
30
+
31
+ (The MIT License)
32
+
33
+ Copyright (c) 2009,2013 Macario Ortega, Sam Ruby
34
+
35
+ Permission is hereby granted, free of charge, to any person obtaining
36
+ a copy of this software and associated documentation files (the
37
+ 'Software'), to deal in the Software without restriction, including
38
+ without limitation the rights to use, copy, modify, merge, publish,
39
+ distribute, sublicense, and/or sell copies of the Software, and to
40
+ permit persons to whom the Software is furnished to do so, subject to
41
+ the following conditions:
42
+
43
+ The above copyright notice and this permission notice shall be
44
+ included in all copies or substantial portions of the Software.
45
+
46
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
47
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
48
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
49
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
50
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
51
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
52
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/lib/ruby2js.rb ADDED
@@ -0,0 +1,79 @@
1
+ require 'parser/current'
2
+ require 'ruby2js/converter'
3
+
4
+ module Ruby2JS
5
+ def self.convert(source, options={})
6
+
7
+ if Proc === source
8
+ file,line = source.source_location
9
+ source = File.read(file)
10
+ ast = find_block( parse(source), line )
11
+ elsif Parser::AST::Node === source
12
+ ast = source
13
+ source = ast.loc.expression.source_buffer.source
14
+ else
15
+ ast = parse( source )
16
+ end
17
+
18
+ if options[:filters]
19
+ filter = Parser::AST::Processor
20
+ options[:filters].reverse.each do |mod|
21
+ filter = Class.new(filter) {include mod}
22
+ end
23
+ ast = filter.new.process(ast)
24
+ end
25
+
26
+ ruby2js = Ruby2JS::Converter.new( ast )
27
+
28
+ if source.include? "\n"
29
+ ruby2js.enable_vertical_whitespace
30
+ lines = ruby2js.to_js.split("\n")
31
+ pre = ''
32
+ pending = false
33
+ blank = true
34
+ lines.each do |line|
35
+ if line.start_with? '}' or line.start_with? ']'
36
+ pre.sub!(/^ /,'')
37
+ line.sub!(/;$/,";\n")
38
+ pending = true
39
+ else
40
+ pending = false
41
+ end
42
+
43
+ line.sub! /^/, pre
44
+ if line.end_with? '{' or line.end_with? '['
45
+ pre += ' '
46
+ line.sub!(/^/,"\n") unless blank or pending
47
+ pending = true
48
+ end
49
+
50
+ blank = pending
51
+ end
52
+ lines.join("\n")
53
+ else
54
+ ruby2js.to_js
55
+ end
56
+ end
57
+
58
+ def self.parse(source)
59
+ # workaround for https://github.com/whitequark/parser/issues/112
60
+ buffer = Parser::Source::Buffer.new('__SOURCE__')
61
+ buffer.raw_source = source.encode('utf-8')
62
+ Parser::CurrentRuby.new.parse(buffer)
63
+ end
64
+
65
+ def self.find_block(ast, line)
66
+ if ast.type == :block and ast.loc.expression.line == line
67
+ return ast.children.last
68
+ end
69
+
70
+ ast.children.each do |child|
71
+ if Parser::AST::Node === child
72
+ block = find_block child, line
73
+ return block if block
74
+ end
75
+ end
76
+
77
+ nil
78
+ end
79
+ end
@@ -0,0 +1,281 @@
1
+ require 'parser/current'
2
+
3
+ module Ruby2JS
4
+ class Converter
5
+ LOGICAL = :and, :not, :or
6
+ OPERATORS = [:[], :[]=], [:not, :!], [:*, :/, :%], [:+, :-], [:>>, :<<],
7
+ [:<=, :<, :>, :>=], [:==, :!=], [:and, :or]
8
+
9
+ def initialize( ast, vars = {} )
10
+ @ast, @vars = ast, vars.dup
11
+ @sep = '; '
12
+ @nl = ''
13
+ end
14
+
15
+ def enable_vertical_whitespace
16
+ @sep = ";\n"
17
+ @nl = "\n"
18
+ end
19
+
20
+ def to_js
21
+ parse( @ast, :statement )
22
+ end
23
+
24
+ def operator_index op
25
+ OPERATORS.index( OPERATORS.find{ |el| el.include? op } ) || -1
26
+ end
27
+
28
+ def scope( ast )
29
+ frame = self.class.new( nil, @vars )
30
+ frame.enable_vertical_whitespace if @nl == "\n"
31
+ frame.parse( ast, :statement )
32
+ end
33
+
34
+ def s(type, *args)
35
+ Parser::AST::Node.new(type, args)
36
+ end
37
+
38
+ def is_method?(node)
39
+ return false unless node.type == :send
40
+ return true unless node.loc
41
+ selector = node.loc.selector
42
+ return true unless selector.source_buffer
43
+ selector.source_buffer.source[selector.end_pos] == '('
44
+ end
45
+
46
+ def parse(ast, state=:expression)
47
+ return ast unless Parser::AST::Node === ast
48
+
49
+ case ast.type
50
+
51
+ when :int, :float, :str
52
+ ast.children.first.inspect
53
+
54
+ when :sym
55
+ ast.children.first.to_s.inspect
56
+
57
+ when :lvar, :gvar
58
+ ast.children.first
59
+
60
+ when :true, :false
61
+ ast.type.to_s
62
+
63
+ when :nil
64
+ 'null'
65
+
66
+ when :lvasgn
67
+ var, value = ast.children
68
+ output = value ? "#{ 'var ' unless @vars.keys.include? var }#{ var } = #{ parse value }" : var
69
+ @vars[var] = true
70
+ output
71
+
72
+ when :op_asgn
73
+ var, op, value = ast.children
74
+
75
+ if [:+, :-].include?(op) and value.type==:int and value.children==[1]
76
+ if state == :statement
77
+ "#{ parse var }#{ op }#{ op }"
78
+ else
79
+ "#{ op }#{ op }#{ parse var }"
80
+ end
81
+ else
82
+ "#{ parse var } #{ op }= #{ parse value }"
83
+ end
84
+
85
+ when :casgn
86
+ cbase, var, value = ast.children
87
+ var = "#{cbase}.var" if cbase
88
+ output = "const #{ var } = #{ parse value }"
89
+ @vars[var] = true
90
+ output
91
+
92
+ when :gvasgn
93
+ name, value = ast.children
94
+ "#{ name } = #{ parse value }"
95
+
96
+ when :ivasgn
97
+ name, expression = ast.children
98
+ "#{ name.to_s.sub('@', 'this._') } = #{ parse expression }"
99
+
100
+ when :or_asgn
101
+ var, value = ast.children
102
+ "#{ parse var } = #{parse var} || #{ parse value }"
103
+
104
+ when :and_asgn
105
+ var, value = ast.children
106
+ "#{ parse var } = #{parse var} && #{ parse value }"
107
+
108
+ when :ivar
109
+ name = ast.children.first
110
+ name.to_s.sub('@', 'this._')
111
+
112
+ when :hash
113
+ hashy = ast.children.map do |node|
114
+ left, right = node.children
115
+ key = parse left
116
+ key = $1 if key =~ /\A"([a-zA-Z_$][a-zA-Z_$0-9]*)"\Z/
117
+ "#{key}: #{parse right}"
118
+ end
119
+ "{#{ hashy.join(', ') }}"
120
+
121
+ when :array
122
+ list = ast.children.map { |a| parse a }
123
+ if list.join(', ').length < 80
124
+ "[#{ list.join(', ') }]"
125
+ else
126
+ "[\n#{ list.join(",\n") }\n]"
127
+ end
128
+
129
+ when :begin
130
+ ast.children.map{ |e| parse e, :statement }.join(@sep)
131
+
132
+ when :return
133
+ "return #{ parse ast.children.first }"
134
+
135
+ when *LOGICAL
136
+ left, right = ast.children
137
+ left = left.children.first if left and left.type == :begin
138
+ right = right.children.first if right.type == :begin
139
+ op_index = operator_index ast.type
140
+ lgroup = LOGICAL.include?( left.type ) && op_index <= operator_index( left.type )
141
+ left = parse left
142
+ left = "(#{ left })" if lgroup
143
+ rgroup = LOGICAL.include?( right.type ) && op_index <= operator_index( right.type ) if right.children.length > 0
144
+ right = parse right
145
+ right = "(#{ right })" if rgroup
146
+
147
+ case ast.type
148
+ when :and
149
+ "#{ left } && #{ right }"
150
+ when :or
151
+ "#{ left } || #{ right }"
152
+ else
153
+ "!#{ left }"
154
+ end
155
+
156
+ when :send, :attr
157
+ receiver, method, *args = ast.children
158
+ if method == :new and receiver and receiver.children == [nil, :Proc]
159
+ return parse args.first
160
+ elsif method == :lambda and not receiver
161
+ return parse args.first
162
+ end
163
+
164
+ op_index = operator_index method
165
+ if op_index != -1
166
+ target = args.first
167
+ target = target.children.first if target and target.type == :begin
168
+ receiver = receiver.children.first if receiver.type == :begin
169
+ end
170
+
171
+ group_receiver = receiver.type == :send && op_index <= operator_index( receiver.children[1] ) if receiver
172
+ group_target = target.type == :send && op_index <= operator_index( target.children[1] ) if target
173
+
174
+ case method
175
+ when :!
176
+ group_receiver ||= (receiver.children.length > 1)
177
+ "!#{ group_receiver ? group(receiver) : parse(receiver) }"
178
+
179
+ when :call
180
+ "#{ parse receiver }(#{ parse args.first })"
181
+
182
+ when :[]
183
+ raise 'parse error' unless receiver
184
+ "#{ parse receiver }[#{ parse args.first }]"
185
+
186
+ when :-@, :+@
187
+ "#{ method.to_s[0] }#{ parse receiver }"
188
+
189
+ when *OPERATORS.flatten
190
+ "#{ group_receiver ? group(receiver) : parse(receiver) } #{ method } #{ group_target ? group(target) : parse(target) }"
191
+
192
+ when /=$/
193
+ "#{ parse receiver }#{ '.' if receiver }#{ method.to_s.sub(/=$/, ' =') } #{ parse args.first }"
194
+
195
+ else
196
+ if args.length == 0 and not is_method?(ast)
197
+ "#{ parse receiver }#{ '.' if receiver }#{ method }"
198
+ else
199
+ args = args.map {|a| parse a}.join(', ')
200
+ "#{ parse receiver }#{ '.' if receiver }#{ method }(#{ args })"
201
+ end
202
+ end
203
+
204
+ when :const
205
+ receiver, name = ast.children
206
+ "#{ parse receiver }#{ '.' if receiver }#{ name }"
207
+
208
+ when :masgn
209
+ lhs, rhs = ast.children
210
+ block = []
211
+ lhs.children.zip rhs.children.zip do |var, val|
212
+ block << s(var.type, *var.children, *val)
213
+ end
214
+ parse s(:begin, *block)
215
+
216
+ when :if
217
+ condition, true_block, else_block = ast.children
218
+ if state == :statement
219
+ output = "if (#{ parse condition }) {#@nl#{ scope true_block }#@nl}"
220
+ while else_block and else_block.type == :if
221
+ condition, true_block, else_block = else_block.children
222
+ output << " else if (#{ parse condition }) {#@nl#{ scope true_block }#@nl}"
223
+ end
224
+ output << " else {#@nl#{ scope else_block }#@nl}" if else_block
225
+ output
226
+ else
227
+ "(#{ parse condition } ? #{ parse true_block } : #{ parse else_block })"
228
+ end
229
+
230
+ when :while
231
+ condition, block = ast.children
232
+ "while (#{ parse condition }) {#@nl#{ scope block }#@nl}"
233
+
234
+ when :block
235
+ call, args, block = ast.children
236
+ block ||= s(:begin)
237
+ function = s(:def, name, args, block)
238
+ parse s(:send, *call.children, function)
239
+
240
+ when :def
241
+ name, args, body = ast.children
242
+ body ||= s(:begin)
243
+ body = s(:scope, body) unless body.type == :scope
244
+ body = parse body
245
+ body.sub! /return var (\w+) = ([^;]+)\z/, "var \\1 = \\2#{@sep}return \\1"
246
+ "function#{ " #{name}" if name }(#{ parse args }) {#@nl#{ body }#@nl}"
247
+
248
+ when :scope
249
+ body = ast.children.first
250
+ body = s(:begin, body) unless body.type == :begin
251
+ block = body.children
252
+ scope body
253
+
254
+ when :class
255
+ name, inheritance, *body = ast.children
256
+ body.compact!
257
+ body = body.first.children.dup if body.length == 1 and body.first.type == :begin
258
+ methods = body.select { |a| a.type == :def }
259
+ init = (body.delete methods.find { |m| m.children.first == :initialize }) || s(:def, :initialize)
260
+ block = body.collect { |m| parse( m ).sub(/function (\w+)/, "#{ parse name }.prototype.\\1 = function") }.join @sep
261
+ "#{ parse( s(:def, parse(name), init.children[1], init.children[2]) ).sub(/return (?:null|(.*))\}\z/, '\1}') }#{ @sep if block and not block.empty?}#{ block }"
262
+
263
+ when :args
264
+ ast.children.map { |a| a.children.first }.join(', ')
265
+
266
+ when :dstr
267
+ ast.children.map{ |s| parse s }.join(' + ')
268
+
269
+ when :self
270
+ 'this'
271
+
272
+ else
273
+ raise "unknown AST type #{ ast.type }"
274
+ end
275
+ end
276
+
277
+ def group( ast )
278
+ "(#{ parse ast })"
279
+ end
280
+ end
281
+ end
@@ -0,0 +1,167 @@
1
+ require 'parser/current'
2
+ require 'ruby2js'
3
+
4
+ module Ruby2JS
5
+ module Filter
6
+ module AngularRB
7
+ def initialize(*args)
8
+ @ngApp = nil
9
+ super
10
+ end
11
+
12
+ # input:
13
+ # module Angular::AppName
14
+ # use :Dependency
15
+ # ...
16
+ # end
17
+ #
18
+ # output:
19
+ # AppName = angular.module("AppName", ["Dependency"])
20
+ # ...
21
+
22
+ def on_module(node)
23
+ module_name = node.children[0]
24
+ parent_name = module_name.children[0]
25
+
26
+ return super unless parent_name and parent_name.type == :const
27
+ return super unless parent_name.children == [nil, :Angular]
28
+
29
+ @ngApp = module_name.children[1]
30
+
31
+ # find the block
32
+ block = process_all(node.children[1..-1])
33
+ while block.length == 1 and block.first.type == :begin
34
+ block = block.first.children.dup
35
+ end
36
+
37
+ # find use class method calls
38
+ uses = block.find_all do |node|
39
+ node.type == :send and node.children[0..1] == [nil, :use]
40
+ end
41
+
42
+ # convert use calls into dependencies
43
+ depends = []
44
+ uses.each do |use|
45
+ pending = []
46
+ use.children[2..-1].each do |node|
47
+ break unless [:str, :sym].include? node.type
48
+ pending << node
49
+ end
50
+ depends += pending
51
+ block.delete use
52
+ end
53
+
54
+ # build constant assignment statement
55
+ casgn = s(:casgn, nil, @ngApp, s(:send,
56
+ s(:lvar, :angular),
57
+ :module,
58
+ s(:str, @ngApp.to_s),
59
+ s(:array, *depends)))
60
+
61
+ @ngApp = nil
62
+
63
+ # replace module with a constant assign followed by the module contents
64
+ node.updated :begin, [casgn, *block]
65
+ end
66
+
67
+ # input:
68
+ # class Name < Angular::Controller
69
+ # use :$service
70
+ # ...
71
+ # end
72
+ #
73
+ # output:
74
+ # AppName.controller :Name do |$service|
75
+ # ...
76
+ # end
77
+
78
+ def on_class(node)
79
+ return super unless @ngApp
80
+ return super unless node.children.length == 3
81
+
82
+ # (const nil :Name)
83
+ name = node.children.first
84
+ return super unless name.type == :const and name.children.first == nil
85
+
86
+ # (const (const nil :Angular) :Controller)
87
+ parent = node.children[1]
88
+ return super unless parent and parent.children.length == 2
89
+ return super unless parent.children[0]
90
+ return super unless parent.children[0].type == :const
91
+ return super unless parent.children[0].children == [nil, :Angular]
92
+ return super unless [:Controller].include? parent.children[1]
93
+
94
+ # find the block
95
+ block = process_all(node.children[2..-1])
96
+ while block.length == 1 and block.first.type == :begin
97
+ block = block.first.children.dup
98
+ end
99
+
100
+ # find use class method calls
101
+ uses = block.find_all do |node|
102
+ node.type == :send and node.children[0..1] == [nil, :use]
103
+ end
104
+
105
+ # convert use calls into args
106
+ args = []
107
+ uses.each do |use|
108
+ pending = []
109
+ use.children[2..-1].each do |node|
110
+ break unless [:str, :sym].include? node.type
111
+ pending << s(:arg, *node.children)
112
+ end
113
+ args += pending
114
+ block.delete use
115
+ end
116
+
117
+ # build Appname.controller call statement
118
+ call = s(:send,
119
+ s(:const, nil, @ngApp),
120
+ :controller,
121
+ s(:sym, name.children.last))
122
+
123
+ # replace class with a block
124
+ node.updated :block, [call, s(:args, *args), s(:begin, *block)]
125
+ end
126
+
127
+ # input:
128
+ # filter :name do |input|
129
+ # ...
130
+ # end
131
+ #
132
+ # output:
133
+ # AppName.filter :name do
134
+ # return lambda {|input| return ... }
135
+ # end
136
+ def on_block(node)
137
+ return super unless @ngApp
138
+
139
+ call = node.children.first
140
+ return super unless call.children[0..1] == [nil, :filter]
141
+
142
+ # insert return
143
+ children = process_all(node.children[1..-1])
144
+ block = [children.pop || s(:nil)]
145
+ while block.length == 1 and block.first.type == :begin
146
+ block = block.first.children.dup
147
+ end
148
+ block.push s(:return, block.pop) unless block.last.type == :return
149
+ children.push (block.length == 1 ? block.first : s(:begin, *block))
150
+
151
+ # construct a function returning a function
152
+ inner = s(:block, s(:send, nil, :lambda), *children)
153
+ outer = s(:send, s(:lvar, @ngApp), :filter, *call.children[2..-1])
154
+
155
+ node.updated nil, [outer, s(:args), s(:return, inner)]
156
+ end
157
+
158
+ private
159
+
160
+ # construct an AST Node
161
+ def s(type, *args)
162
+ Parser::AST::Node.new type, args
163
+ end
164
+
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,41 @@
1
+ require 'ruby2js'
2
+
3
+ module Ruby2JS
4
+ module Filter
5
+ module Functions
6
+
7
+ # map $$ to $
8
+ def on_gvar(node)
9
+ if node.children[0] == :$$
10
+ node.updated nil, ['$']
11
+ else
12
+ super
13
+ end
14
+ end
15
+
16
+ def on_send(node)
17
+ if node.children[1] == :to_s
18
+ s(:send, node.children[0], :toString, *node.children[2..-1])
19
+
20
+ elsif node.children[1] == :to_i
21
+ node.updated nil, [nil, :parseInt, node.children[0],
22
+ *node.children[2..-1]]
23
+
24
+ elsif node.children[1] == :to_f
25
+ node.updated nil, [nil, :parseFloat, node.children[0],
26
+ *node.children[2..-1]]
27
+
28
+ else
29
+ super
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ # construct an AST Node
36
+ def s(type, *args)
37
+ Parser::AST::Node.new type, args
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,63 @@
1
+ require 'ruby2js'
2
+
3
+ module Ruby2JS
4
+ module Filter
5
+ module Return
6
+ EXPRESSIONS = [ :array, :float, :hash, :if, :int, :lvar, :nil, :send ]
7
+
8
+ def on_block(node)
9
+ children = process_all(node.children)
10
+
11
+ # find the block
12
+ block = [children.pop || s(:nil)]
13
+ while block.length == 1 and block.first.type == :begin
14
+ block = block.first.children.dup
15
+ end
16
+
17
+ if EXPRESSIONS.include? block.last.type
18
+ block.push s(:return, block.pop)
19
+ else
20
+ p block.last.type
21
+ end
22
+
23
+ if block.length == 1
24
+ children.push block.first
25
+ else
26
+ children.push s(:begin, *block)
27
+ end
28
+
29
+ node.updated nil, children
30
+ end
31
+
32
+ def on_def(node)
33
+ children = process_all(node.children[1..-1])
34
+ children.unshift node.children.first
35
+
36
+ # find the block
37
+ block = [children.pop || s(:nil)]
38
+ while block.length == 1 and block.first.type == :begin
39
+ block = block.first.children.dup
40
+ end
41
+
42
+ if EXPRESSIONS.include? block.last.type
43
+ block.push s(:return, block.pop)
44
+ end
45
+
46
+ if block.length == 1
47
+ children.push block.first
48
+ else
49
+ children.push s(:begin, *block)
50
+ end
51
+
52
+ node.updated nil, children
53
+ end
54
+
55
+ private
56
+
57
+ # construct an AST Node
58
+ def s(type, *args)
59
+ Parser::AST::Node.new type, args
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,10 @@
1
+ module Ruby2JS
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 1
5
+ TINY = 0
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end unless defined?(Ruby2JS::VERSION)
10
+
data/ruby2js.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "ruby2js"
5
+ s.version = "0.1.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Sam Ruby"]
9
+ s.date = "2013-11-11"
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
+ 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.rb"]
13
+ s.homepage = "http://github.com/rubys/ruby2js"
14
+ s.require_paths = ["lib"]
15
+ s.rubygems_version = "2.0.7"
16
+ s.summary = "Minimal yet extensible Ruby to JavaScript conversion."
17
+
18
+ if s.respond_to? :specification_version then
19
+ s.specification_version = 4
20
+
21
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
22
+ s.add_runtime_dependency(%q<parser>, [">= 0"])
23
+ else
24
+ s.add_dependency(%q<parser>, [">= 0"])
25
+ end
26
+ else
27
+ s.add_dependency(%q<parser>, [">= 0"])
28
+ end
29
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby2js
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sam Ruby
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: parser
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: ! " The base package maps Ruby syntax to JavaScript semantics.\n Filters
28
+ may be provided to add Ruby-specific or Framework specific\n behavior.\n"
29
+ email: rubys@intertwingly.net
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ruby2js.gemspec
35
+ - README.md
36
+ - lib/ruby2js/version.rb
37
+ - lib/ruby2js/converter.rb
38
+ - lib/ruby2js/filter/return.rb
39
+ - lib/ruby2js/filter/angularrb.rb
40
+ - lib/ruby2js/filter/functions.rb
41
+ - lib/ruby2js.rb
42
+ homepage: http://github.com/rubys/ruby2js
43
+ licenses: []
44
+ metadata: {}
45
+ post_install_message:
46
+ rdoc_options: []
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ requirements: []
60
+ rubyforge_project:
61
+ rubygems_version: 2.0.7
62
+ signing_key:
63
+ specification_version: 4
64
+ summary: Minimal yet extensible Ruby to JavaScript conversion.
65
+ test_files: []