ruby2js 1.14.1 → 1.15.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +2 -1
- data/lib/ruby2js/converter/hash.rb +2 -0
- data/lib/ruby2js/converter/in.rb +12 -0
- data/lib/ruby2js/converter/ivar.rb +41 -4
- data/lib/ruby2js/converter/return.rb +1 -1
- data/lib/ruby2js/converter/send.rb +3 -3
- data/lib/ruby2js/converter.rb +1 -0
- data/lib/ruby2js/filter/functions.rb +3 -0
- data/lib/ruby2js/filter/jquery.rb +1 -1
- data/lib/ruby2js/filter/react.rb +172 -26
- data/lib/ruby2js/filter/require.rb +8 -1
- data/lib/ruby2js/version.rb +2 -2
- data/lib/ruby2js.rb +17 -8
- data/ruby2js.gemspec +4 -4
- metadata +11 -10
data/README.md
CHANGED
@@ -51,7 +51,7 @@ With [ExecJS](https://github.com/sstephenson/execjs):
|
|
51
51
|
require 'ruby2js/execjs'
|
52
52
|
require 'date'
|
53
53
|
|
54
|
-
context = Ruby2JS.compile(Date.today.strftime('d = new Date(%Y, %-m, %-d)'))
|
54
|
+
context = Ruby2JS.compile(Date.today.strftime('d = new Date(%Y, %-m-1, %-d)'))
|
55
55
|
puts context.eval('d.getYear()')+1900
|
56
56
|
```
|
57
57
|
|
@@ -180,6 +180,7 @@ the script.
|
|
180
180
|
* `.ord` becomes `charCodeAt(0)`
|
181
181
|
* `puts` becomes `console.log`
|
182
182
|
* `.replace` becomes `.length = 0; ...push.apply(*)`
|
183
|
+
* `.respond_to?` becomes `right in left`
|
183
184
|
* `.start_with?` becomes `.substring(0, arg.length) == arg`
|
184
185
|
* `.sub` becomes `.replace`
|
185
186
|
* `.to_a` becomes `to_Array`
|
@@ -5,13 +5,50 @@ module Ruby2JS
|
|
5
5
|
|
6
6
|
handle :ivar do |var|
|
7
7
|
if self.ivars and self.ivars.include? var
|
8
|
-
|
9
|
-
ruby2js.width = @width
|
10
|
-
ruby2js.enable_vertical_whitespace if @nl == "\n"
|
11
|
-
ruby2js.to_js
|
8
|
+
parse s(:hostvalue, self.ivars[var])
|
12
9
|
else
|
13
10
|
parse s(:attr, s(:self), var.to_s.sub('@', '_'))
|
14
11
|
end
|
15
12
|
end
|
13
|
+
|
14
|
+
handle :hostvalue do |value|
|
15
|
+
case value
|
16
|
+
when Hash
|
17
|
+
parse s(:hash, *value.map {|key, value| s(:pair, s(:hostvalue, key),
|
18
|
+
s(:hostvalue, value))})
|
19
|
+
when Array
|
20
|
+
parse s(:array, *value.map {|value| s(:hostvalue, value)})
|
21
|
+
when String
|
22
|
+
parse s(:str, value)
|
23
|
+
when Integer
|
24
|
+
parse s(:int, value)
|
25
|
+
when Float
|
26
|
+
parse s(:float, value)
|
27
|
+
when true
|
28
|
+
parse s(:true)
|
29
|
+
when false
|
30
|
+
parse s(:false)
|
31
|
+
when nil
|
32
|
+
parse s(:nil)
|
33
|
+
when Symbol
|
34
|
+
parse s(:sym, value)
|
35
|
+
else
|
36
|
+
value = value.as_json if value.respond_to?(:as_json)
|
37
|
+
|
38
|
+
if value.respond_to?(:to_hash) and Hash === value.to_hash
|
39
|
+
parse s(:hostvalue, value.to_hash)
|
40
|
+
elsif value.respond_to?(:to_ary) and Array === value.to_ary
|
41
|
+
parse s(:hostvalue, value.to_ary)
|
42
|
+
elsif value.respond_to?(:to_str) and String === value.to_str
|
43
|
+
parse s(:str, value.to_str)
|
44
|
+
elsif value.respond_to?(:to_int) and Integer === value.to_int
|
45
|
+
parse s(:int, value.to_int)
|
46
|
+
elsif value.respond_to?(:to_sym) and Symbol === value.to_sym
|
47
|
+
parse s(:sym, value.to_sym)
|
48
|
+
else
|
49
|
+
parse s(:str, value.inspect)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
16
53
|
end
|
17
54
|
end
|
@@ -14,7 +14,7 @@ module Ruby2JS
|
|
14
14
|
|
15
15
|
EXPRESSIONS = [ :array, :float, :hash, :int, :lvar, :nil, :send, :attr,
|
16
16
|
:str, :sym, :dstr, :dsym, :cvar, :ivar, :zsuper, :super, :or, :and,
|
17
|
-
:block ]
|
17
|
+
:block, :const ]
|
18
18
|
|
19
19
|
handle :autoreturn do |*statements|
|
20
20
|
return if statements == [nil]
|
@@ -67,7 +67,7 @@ module Ruby2JS
|
|
67
67
|
elsif method == :[]=
|
68
68
|
"#{ parse receiver }[#{ args[0..-2].map {|arg| parse arg}.join(', ') }] = #{ parse args[-1] }"
|
69
69
|
|
70
|
-
elsif [:-@, :+@,
|
70
|
+
elsif [:-@, :+@, :~, '~'].include? method
|
71
71
|
"#{ method.to_s[0] }#{ parse receiver }"
|
72
72
|
|
73
73
|
elsif method == :=~
|
@@ -163,9 +163,9 @@ module Ruby2JS
|
|
163
163
|
call = (group_receiver ? group(receiver) : parse(receiver))
|
164
164
|
call = "#{ call }#{ '.' if receiver && method}#{ method }"
|
165
165
|
args = args.map {|a| parse a}
|
166
|
-
if args.
|
166
|
+
if args.map {|arg| arg.length+2}.reduce(&:+).to_i < width-10
|
167
167
|
"#{ call }(#{ args.join(', ') })"
|
168
|
-
elsif args.
|
168
|
+
elsif args.length == 1 and args.first.to_s.include? "\n"
|
169
169
|
"#{ call }(#{ args.join(', ') })"
|
170
170
|
else
|
171
171
|
"#{ call }(#@nl#{ args.join(",#@ws") }#@nl)"
|
data/lib/ruby2js/converter.rb
CHANGED
@@ -146,6 +146,7 @@ require 'ruby2js/converter/dstr'
|
|
146
146
|
require 'ruby2js/converter/for'
|
147
147
|
require 'ruby2js/converter/hash'
|
148
148
|
require 'ruby2js/converter/if'
|
149
|
+
require 'ruby2js/converter/in'
|
149
150
|
require 'ruby2js/converter/ivar'
|
150
151
|
require 'ruby2js/converter/ivasgn'
|
151
152
|
require 'ruby2js/converter/kwbegin'
|
@@ -116,6 +116,9 @@ module Ruby2JS
|
|
116
116
|
process s(:send, s(:send, target, :indexOf, args.first), :!=,
|
117
117
|
s(:int, -1))
|
118
118
|
|
119
|
+
elsif method == :respond_to? and args.length == 1
|
120
|
+
process s(:in?, args.first, target)
|
121
|
+
|
119
122
|
elsif method == :each
|
120
123
|
process node.updated nil, [target, :forEach, *args]
|
121
124
|
|
data/lib/ruby2js/filter/react.rb
CHANGED
@@ -21,6 +21,11 @@ module Ruby2JS
|
|
21
21
|
module React
|
22
22
|
include SEXP
|
23
23
|
|
24
|
+
def options=(options)
|
25
|
+
super
|
26
|
+
@react = true if options[:react]
|
27
|
+
end
|
28
|
+
|
24
29
|
# Example conversion
|
25
30
|
# before:
|
26
31
|
# (class (const nil :Foo) (const nil :React) nil)
|
@@ -42,7 +47,10 @@ module Ruby2JS
|
|
42
47
|
end
|
43
48
|
|
44
49
|
# abort conversion unless all body statements are method definitions
|
45
|
-
return super unless body.all?
|
50
|
+
return super unless body.all? do |child|
|
51
|
+
child.type == :def or
|
52
|
+
(child.type == :defs and child.children.first == s(:self))
|
53
|
+
end
|
46
54
|
|
47
55
|
begin
|
48
56
|
react, @react = @react, true
|
@@ -52,9 +60,82 @@ module Ruby2JS
|
|
52
60
|
pairs = [s(:pair, s(:sym, :displayName),
|
53
61
|
s(:str, cname.children.last.to_s))]
|
54
62
|
|
63
|
+
# collect static properties/functions
|
64
|
+
statics = []
|
65
|
+
body.select {|child| child.type == :defs}.each do |child|
|
66
|
+
parent, mname, args, *block = child.children
|
67
|
+
if child.is_method?
|
68
|
+
statics << s(:pair, s(:sym, mname),
|
69
|
+
s(:block, s(:send, nil, :proc), args, s(:autoreturn, *block)))
|
70
|
+
elsif
|
71
|
+
block.length == 1 and
|
72
|
+
Converter::EXPRESSIONS.include? block.first.type
|
73
|
+
then
|
74
|
+
statics << s(:pair, s(:sym, mname), *block)
|
75
|
+
else
|
76
|
+
statics << s(:pair, s(:prop, mname), {get:
|
77
|
+
s(:block, s(:send, nil, :proc), args, s(:autoreturn, *block))})
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# append statics (if any)
|
82
|
+
unless statics.empty?
|
83
|
+
pairs << s(:pair, s(:sym, :statics), s(:hash, *statics))
|
84
|
+
end
|
85
|
+
|
55
86
|
# add a proc/function for each method
|
56
|
-
body.each do |child|
|
87
|
+
body.select {|child| child.type == :def}.each do |child|
|
57
88
|
mname, args, *block = child.children
|
89
|
+
@reactMethod = mname
|
90
|
+
|
91
|
+
if mname == :initialize
|
92
|
+
mname = :getInitialState
|
93
|
+
|
94
|
+
# extract real list of statements
|
95
|
+
if block.length == 1
|
96
|
+
if not block.first
|
97
|
+
block = []
|
98
|
+
elsif block.first.type == :begin
|
99
|
+
block = block.first.children
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# peel off the initial set of instance variable assignment stmts
|
104
|
+
assigns = []
|
105
|
+
block = block.dup
|
106
|
+
while not block.empty? and block.first.type == :ivasgn
|
107
|
+
node = block.shift
|
108
|
+
vars = [node.children.first]
|
109
|
+
while node.children[1].type == :ivasgn
|
110
|
+
node = node.children[1]
|
111
|
+
vars << node.children.first
|
112
|
+
end
|
113
|
+
vars.each do |var|
|
114
|
+
assigns << s(:ivasgn, var, node.children.last)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# build a hash for state
|
119
|
+
state = s(:hash, *assigns.map {|node| s(:pair, s(:str,
|
120
|
+
node.children.first.to_s[1..-1]), node.children.last)})
|
121
|
+
|
122
|
+
# modify block to build and/or return state
|
123
|
+
if block.empty?
|
124
|
+
block = [s(:return, state)]
|
125
|
+
else
|
126
|
+
block.unshift(s(:send, s(:self), :state=, state))
|
127
|
+
block.push(s(:return, s(:attr, s(:self), :state)))
|
128
|
+
end
|
129
|
+
|
130
|
+
elsif mname == :render
|
131
|
+
if block.length!=1 or not block.last or block.last.type==:begin
|
132
|
+
# wrap multi-line blocks with a 'span' element
|
133
|
+
block = [s(:return,
|
134
|
+
s(:block, s(:send, nil, :_span), s(:args), *block))]
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# add method to class
|
58
139
|
pairs << s(:pair, s(:sym, mname), s(:block, s(:send, nil, :proc),
|
59
140
|
args, process(s((child.is_method? ? :begin : :autoreturn),
|
60
141
|
*block))))
|
@@ -62,6 +143,7 @@ module Ruby2JS
|
|
62
143
|
ensure
|
63
144
|
@react = react
|
64
145
|
@reactClass = reactClass
|
146
|
+
@reactMethod = nil
|
65
147
|
end
|
66
148
|
|
67
149
|
# emit a createClass statement
|
@@ -74,14 +156,13 @@ module Ruby2JS
|
|
74
156
|
# enable React filtering within React class method calls or
|
75
157
|
# React component calls
|
76
158
|
if
|
77
|
-
node.children.first == s(:const, nil, :React)
|
78
|
-
node.children.first == nil and node.children[1] =~ /^_[A-Z]/
|
159
|
+
node.children.first == s(:const, nil, :React)
|
79
160
|
then
|
80
161
|
begin
|
81
|
-
@react = true
|
162
|
+
react, @react = @react, true
|
82
163
|
return on_send(node)
|
83
164
|
ensure
|
84
|
-
@react =
|
165
|
+
@react = react
|
85
166
|
end
|
86
167
|
end
|
87
168
|
end
|
@@ -92,12 +173,20 @@ module Ruby2JS
|
|
92
173
|
# text nodes
|
93
174
|
if @reactApply
|
94
175
|
# if apply is set, emit code that pushes text
|
95
|
-
s(:send, s(:gvar, :$_), :push, node.children[2])
|
176
|
+
s(:send, s(:gvar, :$_), :push, process(node.children[2]))
|
96
177
|
else
|
97
178
|
# simple/normal case: simply return the text
|
98
|
-
node.children[2]
|
179
|
+
process(node.children[2])
|
99
180
|
end
|
100
181
|
|
182
|
+
elsif
|
183
|
+
@reactApply and node.children[1] == :createElement and
|
184
|
+
node.children[0] == s(:const, nil, :React)
|
185
|
+
then
|
186
|
+
# push results of explicit calls to React.createElement
|
187
|
+
s(:send, s(:gvar, :$_), :push, s(:send, *node.children[0..1],
|
188
|
+
*process_all(node.children[2..-1])))
|
189
|
+
|
101
190
|
elsif node.children[0] == nil and node.children[1] =~ /^_\w/
|
102
191
|
# map method calls starting with an underscore to React calls
|
103
192
|
# to create an element.
|
@@ -150,8 +239,13 @@ module Ruby2JS
|
|
150
239
|
end
|
151
240
|
end
|
152
241
|
pairs -= classes
|
153
|
-
|
154
|
-
|
242
|
+
if expr
|
243
|
+
value = s(:if, expr,
|
244
|
+
s(:send, s(:str, values.join(' ')), :+, expr),
|
245
|
+
s(:str, values.join(' ').strip))
|
246
|
+
else
|
247
|
+
value = s(:str, values.join(' '))
|
248
|
+
end
|
155
249
|
pairs.unshift s(:pair, s(:sym, :className), value)
|
156
250
|
end
|
157
251
|
|
@@ -191,6 +285,11 @@ module Ruby2JS
|
|
191
285
|
|
192
286
|
# check for normal case: only elements and text
|
193
287
|
simple = args.all? do |arg|
|
288
|
+
# explicit call to React.createElement
|
289
|
+
next true if arg.children[1] == :createElement and
|
290
|
+
arg.children[0] == s(:const, nil, :React)
|
291
|
+
|
292
|
+
# wunderbar style call
|
194
293
|
arg = arg.children.first if arg.type == :block
|
195
294
|
while arg.type == :send and arg.children.first != nil
|
196
295
|
arg = arg.children.first
|
@@ -244,6 +343,17 @@ module Ruby2JS
|
|
244
343
|
element
|
245
344
|
end
|
246
345
|
|
346
|
+
elsif node.children[0]==s(:send, nil, :_) and node.children[1]==:[]
|
347
|
+
if @reactApply
|
348
|
+
# if apply is set, emit code that pushes results
|
349
|
+
s(:send, s(:gvar, :$_), :push, *process_all(node.children[2..-1]))
|
350
|
+
elsif node.children.length == 3
|
351
|
+
process(node.children[2])
|
352
|
+
else
|
353
|
+
# simple/normal case: simply return the element
|
354
|
+
s(:splat, s(:array, *process_all(node.children[2..-1])))
|
355
|
+
end
|
356
|
+
|
247
357
|
# map method calls involving i/g/c vars to straight calls
|
248
358
|
#
|
249
359
|
# input:
|
@@ -259,7 +369,15 @@ module Ruby2JS
|
|
259
369
|
end
|
260
370
|
|
261
371
|
elsif node.children[1] == :~
|
262
|
-
#
|
372
|
+
# Locate a DOM Node
|
373
|
+
# map ~(expression) to document.querySelector(expression)
|
374
|
+
# map ~name to this.refs.name.getDOMNode()
|
375
|
+
# map ~"a b" to document.querySelector("a b")
|
376
|
+
# map ~"#a" to document.getElementById("a")
|
377
|
+
# map ~"a" to document.getElementsByTagName("a")[0]
|
378
|
+
# map ~".a.b" to document.getElementsByClassName("a b")[0]
|
379
|
+
# map ~~expression to ~~expression
|
380
|
+
# map ~~~expression to ~expression
|
263
381
|
|
264
382
|
if node.children[0] and node.children[0].type == :op_asgn
|
265
383
|
asgn = node.children[0]
|
@@ -267,10 +385,10 @@ module Ruby2JS
|
|
267
385
|
inner = asgn.children[0]
|
268
386
|
return on_send s(:send, s(:send, inner.children[0],
|
269
387
|
(inner.children[1].to_s+'=').to_sym,
|
270
|
-
s(:send, s(:send, s(:send, inner.children[0],
|
271
|
-
*inner.children[1..-1]), *asgn.children[1..-1])),
|
388
|
+
s(:send, s(:send, s(:send, inner.children[0], '~'),
|
389
|
+
*inner.children[1..-1]), *asgn.children[1..-1])), '~')
|
272
390
|
else
|
273
|
-
return on_send asgn.updated nil, [s(:send, asgn.children[0],
|
391
|
+
return on_send asgn.updated nil, [s(:send, asgn.children[0], '~'),
|
274
392
|
*asgn.children[1..-1]]
|
275
393
|
end
|
276
394
|
end
|
@@ -287,9 +405,9 @@ module Ruby2JS
|
|
287
405
|
if node.children[0].children[0].children[1] == :~
|
288
406
|
result = node.children[0].children[0].children[0]
|
289
407
|
else
|
290
|
-
result = s(:attr, node.children[0].children[0],
|
408
|
+
result = s(:attr, node.children[0].children[0], '~')
|
291
409
|
end
|
292
|
-
s(:attr, s(:attr, process(result),
|
410
|
+
s(:attr, s(:attr, process(result), '~'), '~')
|
293
411
|
else
|
294
412
|
# possible getter/setter
|
295
413
|
method = node.children[1]
|
@@ -304,9 +422,24 @@ module Ruby2JS
|
|
304
422
|
s(:send, s(:gvar, "$#{node.children[1]}"), :getDOMNode)
|
305
423
|
elsif node.type == :lvar
|
306
424
|
s(:send, s(:gvar, "$#{node.children[0]}"), :getDOMNode)
|
425
|
+
elsif node.type == :str
|
426
|
+
if node.children.first =~ /^#[-\w]+$/
|
427
|
+
s(:send, s(:attr, nil, :document), :getElementById,
|
428
|
+
s(:str, node.children.first[1..-1].gsub('_', '-')))
|
429
|
+
elsif node.children.first =~ /^(\.[-\w]+)+$/
|
430
|
+
s(:send, s(:send, s(:attr, nil, :document),
|
431
|
+
:getElementsByClassName, s(:str,
|
432
|
+
node.children.first[1..-1].gsub('.', ' ').gsub('_', '-'))),
|
433
|
+
:[], s(:int, 0))
|
434
|
+
elsif node.children.first =~ /^[-\w]+$/
|
435
|
+
s(:send, s(:send, s(:attr, nil, :document),
|
436
|
+
:getElementsByTagName, s(:str,
|
437
|
+
node.children.first.gsub('_', '-'))), :[], s(:int, 0))
|
438
|
+
else
|
439
|
+
s(:send, s(:attr, nil, :document), :querySelector, node)
|
440
|
+
end
|
307
441
|
else
|
308
|
-
|
309
|
-
node
|
442
|
+
s(:send, s(:attr, nil, :document), :querySelector, node)
|
310
443
|
end
|
311
444
|
end
|
312
445
|
|
@@ -362,16 +495,16 @@ module Ruby2JS
|
|
362
495
|
# convert blocks to proc arguments
|
363
496
|
def on_block(node)
|
364
497
|
if not @react
|
365
|
-
# enable React filtering
|
498
|
+
# enable React filtering within React class method calls or
|
499
|
+
# React component calls
|
366
500
|
if
|
367
|
-
node.children
|
368
|
-
node.children[0].children[1] =~ /^_[A-Z]/
|
501
|
+
node.children.first == s(:const, nil, :React)
|
369
502
|
then
|
370
503
|
begin
|
371
|
-
@react = true
|
504
|
+
reacth @react = @react, true
|
372
505
|
return on_block(node)
|
373
506
|
ensure
|
374
|
-
@react =
|
507
|
+
@react = react
|
375
508
|
end
|
376
509
|
end
|
377
510
|
end
|
@@ -423,9 +556,22 @@ module Ruby2JS
|
|
423
556
|
# convert instance variable assignments to setState calls
|
424
557
|
def on_ivasgn(node)
|
425
558
|
return super unless @react
|
426
|
-
|
427
|
-
|
428
|
-
|
559
|
+
|
560
|
+
vars = [node.children.first]
|
561
|
+
|
562
|
+
while node.children[1].type == :ivasgn
|
563
|
+
node = node.children[1]
|
564
|
+
vars << node.children.first
|
565
|
+
end
|
566
|
+
|
567
|
+
if @reactMethod == :initialize
|
568
|
+
s(:begin, *vars.map {|var| s(:send, s(:attr, s(:self), :state),
|
569
|
+
var.to_s[1..-1] + '=', process(node.children.last))})
|
570
|
+
else
|
571
|
+
s(:send, s(:self), :setState, s(:hash,
|
572
|
+
*vars.map {|var| s(:pair, s(:str, var.to_s[1..-1]),
|
573
|
+
process(node.children.last))}))
|
574
|
+
end
|
429
575
|
end
|
430
576
|
|
431
577
|
# convert class variables to props
|
@@ -45,7 +45,7 @@ module Ruby2JS
|
|
45
45
|
end
|
46
46
|
|
47
47
|
@options[:file2] = filename
|
48
|
-
process Ruby2JS.parse(File.read(filename))
|
48
|
+
process Ruby2JS.parse(File.read(filename), filename)
|
49
49
|
ensure
|
50
50
|
if file2
|
51
51
|
@options[:file2] = file2
|
@@ -69,6 +69,13 @@ module Ruby2JS
|
|
69
69
|
ensure
|
70
70
|
@require_expr = require_expr
|
71
71
|
end
|
72
|
+
|
73
|
+
def on_casgn(node)
|
74
|
+
require_expr, @require_expr = @require_expr, true
|
75
|
+
super
|
76
|
+
ensure
|
77
|
+
@require_expr = require_expr
|
78
|
+
end
|
72
79
|
end
|
73
80
|
|
74
81
|
DEFAULTS.push Require
|
data/lib/ruby2js/version.rb
CHANGED
data/lib/ruby2js.rb
CHANGED
@@ -2,6 +2,9 @@ require 'parser/current'
|
|
2
2
|
require 'ruby2js/converter'
|
3
3
|
|
4
4
|
module Ruby2JS
|
5
|
+
class SyntaxError < RuntimeError
|
6
|
+
end
|
7
|
+
|
5
8
|
module Filter
|
6
9
|
DEFAULTS = []
|
7
10
|
|
@@ -63,7 +66,7 @@ module Ruby2JS
|
|
63
66
|
ast = source
|
64
67
|
source = ast.loc.expression.source_buffer.source
|
65
68
|
else
|
66
|
-
ast = parse( source )
|
69
|
+
ast = parse( source, options[:file] )
|
67
70
|
end
|
68
71
|
|
69
72
|
filters = options[:filters] || Filter::DEFAULTS
|
@@ -96,24 +99,24 @@ module Ruby2JS
|
|
96
99
|
if source.include? "\n"
|
97
100
|
ruby2js.enable_vertical_whitespace
|
98
101
|
lines = ruby2js.to_js.split("\n")
|
99
|
-
pre =
|
102
|
+
pre = []
|
100
103
|
pending = false
|
101
104
|
blank = true
|
102
105
|
lines.each do |line|
|
103
106
|
next if line.empty?
|
104
107
|
|
105
108
|
if ')}]'.include? line[0]
|
106
|
-
pre.
|
109
|
+
pre.pop
|
107
110
|
line.sub!(/([,;])$/,"\\1\n")
|
108
111
|
pending = true
|
109
112
|
else
|
110
113
|
pending = false
|
111
114
|
end
|
112
115
|
|
113
|
-
line.
|
116
|
+
line.insert 0, pre.join
|
114
117
|
if '({['.include? line[-1]
|
115
|
-
pre
|
116
|
-
line.
|
118
|
+
pre.push ' '
|
119
|
+
line.insert 0, "\n" unless blank or pending
|
117
120
|
pending = true
|
118
121
|
end
|
119
122
|
|
@@ -126,11 +129,17 @@ module Ruby2JS
|
|
126
129
|
end
|
127
130
|
end
|
128
131
|
|
129
|
-
def self.parse(source)
|
132
|
+
def self.parse(source, file=nil)
|
130
133
|
# workaround for https://github.com/whitequark/parser/issues/112
|
131
|
-
buffer = Parser::Source::Buffer.new('__SOURCE__')
|
134
|
+
buffer = Parser::Source::Buffer.new(file || '__SOURCE__')
|
132
135
|
buffer.raw_source = source.encode('utf-8')
|
133
136
|
Parser::CurrentRuby.new.parse(buffer)
|
137
|
+
rescue Parser::SyntaxError => e
|
138
|
+
split = source[0..e.diagnostic.location.begin_pos].split("\n")
|
139
|
+
line, col = split.length, split.last.length
|
140
|
+
message = "line #{line}, column #{col}: #{e.diagnostic.message}"
|
141
|
+
message += "\n in file #{file}" if file
|
142
|
+
raise Ruby2JS::SyntaxError.new(message)
|
134
143
|
end
|
135
144
|
|
136
145
|
def self.find_block(ast, line)
|
data/ruby2js.gemspec
CHANGED
@@ -2,19 +2,19 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "ruby2js"
|
5
|
-
s.version = "1.
|
5
|
+
s.version = "1.15.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 = "2015-
|
9
|
+
s.date = "2015-03-07"
|
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/execjs.rb", "lib/ruby2js/converter.rb", "lib/ruby2js/version.rb", "lib/ruby2js/filter", "lib/ruby2js/filter/jquery.rb", "lib/ruby2js/filter/return.rb", "lib/ruby2js/filter/underscore.rb", "lib/ruby2js/filter/require.rb", "lib/ruby2js/filter/angularrb.rb", "lib/ruby2js/filter/minitest-jasmine.rb", "lib/ruby2js/filter/camelCase.rb", "lib/ruby2js/filter/rubyjs.rb", "lib/ruby2js/filter/strict.rb", "lib/ruby2js/filter/functions.rb", "lib/ruby2js/filter/angular-resource.rb", "lib/ruby2js/filter/react.rb", "lib/ruby2js/filter/angular-route.rb", "lib/ruby2js/sinatra.rb", "lib/ruby2js/rails.rb", "lib/ruby2js/cgi.rb", "lib/ruby2js/converter", "lib/ruby2js/converter/self.rb", "lib/ruby2js/converter/arg.rb", "lib/ruby2js/converter/dstr.rb", "lib/ruby2js/converter/xstr.rb", "lib/ruby2js/converter/sym.rb", "lib/ruby2js/converter/return.rb", "lib/ruby2js/converter/break.rb", "lib/ruby2js/converter/for.rb", "lib/ruby2js/converter/defined.rb", "lib/ruby2js/converter/cvasgn.rb", "lib/ruby2js/converter/whilepost.rb", "lib/ruby2js/converter/logical.rb", "lib/ruby2js/converter/args.rb", "lib/ruby2js/converter/def.rb", "lib/ruby2js/converter/prototype.rb", "lib/ruby2js/converter/class.rb", "lib/ruby2js/converter/nthref.rb", "lib/ruby2js/converter/opasgn.rb", "lib/ruby2js/converter/module.rb", "lib/ruby2js/converter/kwbegin.rb", "lib/ruby2js/converter/send.rb", "lib/ruby2js/converter/boolean.rb", "lib/ruby2js/converter/masgn.rb", "lib/ruby2js/converter/hash.rb", "lib/ruby2js/converter/cvar.rb", "lib/ruby2js/converter/ivasgn.rb", "lib/ruby2js/converter/case.rb", "lib/ruby2js/converter/const.rb", "lib/ruby2js/converter/vasgn.rb", "lib/ruby2js/converter/untilpost.rb", "lib/ruby2js/converter/begin.rb", "lib/ruby2js/converter/ivar.rb", "lib/ruby2js/converter/while.rb", "lib/ruby2js/converter/next.rb", "lib/ruby2js/converter/nil.rb", "lib/ruby2js/converter/blockpass.rb", "lib/ruby2js/converter/super.rb", "lib/ruby2js/converter/defs.rb", "lib/ruby2js/converter/array.rb", "lib/ruby2js/converter/block.rb", "lib/ruby2js/converter/if.rb", "lib/ruby2js/converter/until.rb", "lib/ruby2js/converter/regexp.rb", "lib/ruby2js/converter/casgn.rb", "lib/ruby2js/converter/undef.rb", "lib/ruby2js/converter/literal.rb", "lib/ruby2js/converter/var.rb", "lib/ruby2js.rb"]
|
12
|
+
s.files = ["ruby2js.gemspec", "README.md", "lib/ruby2js", "lib/ruby2js/execjs.rb", "lib/ruby2js/converter.rb", "lib/ruby2js/version.rb", "lib/ruby2js/filter", "lib/ruby2js/filter/jquery.rb", "lib/ruby2js/filter/return.rb", "lib/ruby2js/filter/underscore.rb", "lib/ruby2js/filter/require.rb", "lib/ruby2js/filter/angularrb.rb", "lib/ruby2js/filter/minitest-jasmine.rb", "lib/ruby2js/filter/camelCase.rb", "lib/ruby2js/filter/rubyjs.rb", "lib/ruby2js/filter/strict.rb", "lib/ruby2js/filter/functions.rb", "lib/ruby2js/filter/angular-resource.rb", "lib/ruby2js/filter/react.rb", "lib/ruby2js/filter/angular-route.rb", "lib/ruby2js/sinatra.rb", "lib/ruby2js/rails.rb", "lib/ruby2js/cgi.rb", "lib/ruby2js/converter", "lib/ruby2js/converter/self.rb", "lib/ruby2js/converter/arg.rb", "lib/ruby2js/converter/dstr.rb", "lib/ruby2js/converter/xstr.rb", "lib/ruby2js/converter/sym.rb", "lib/ruby2js/converter/return.rb", "lib/ruby2js/converter/break.rb", "lib/ruby2js/converter/for.rb", "lib/ruby2js/converter/defined.rb", "lib/ruby2js/converter/cvasgn.rb", "lib/ruby2js/converter/whilepost.rb", "lib/ruby2js/converter/logical.rb", "lib/ruby2js/converter/in.rb", "lib/ruby2js/converter/args.rb", "lib/ruby2js/converter/def.rb", "lib/ruby2js/converter/prototype.rb", "lib/ruby2js/converter/class.rb", "lib/ruby2js/converter/nthref.rb", "lib/ruby2js/converter/opasgn.rb", "lib/ruby2js/converter/module.rb", "lib/ruby2js/converter/kwbegin.rb", "lib/ruby2js/converter/send.rb", "lib/ruby2js/converter/boolean.rb", "lib/ruby2js/converter/masgn.rb", "lib/ruby2js/converter/hash.rb", "lib/ruby2js/converter/cvar.rb", "lib/ruby2js/converter/ivasgn.rb", "lib/ruby2js/converter/case.rb", "lib/ruby2js/converter/const.rb", "lib/ruby2js/converter/vasgn.rb", "lib/ruby2js/converter/untilpost.rb", "lib/ruby2js/converter/begin.rb", "lib/ruby2js/converter/ivar.rb", "lib/ruby2js/converter/while.rb", "lib/ruby2js/converter/next.rb", "lib/ruby2js/converter/nil.rb", "lib/ruby2js/converter/blockpass.rb", "lib/ruby2js/converter/super.rb", "lib/ruby2js/converter/defs.rb", "lib/ruby2js/converter/array.rb", "lib/ruby2js/converter/block.rb", "lib/ruby2js/converter/if.rb", "lib/ruby2js/converter/until.rb", "lib/ruby2js/converter/regexp.rb", "lib/ruby2js/converter/casgn.rb", "lib/ruby2js/converter/undef.rb", "lib/ruby2js/converter/literal.rb", "lib/ruby2js/converter/var.rb", "lib/ruby2js.rb"]
|
13
13
|
s.homepage = "http://github.com/rubys/ruby2js"
|
14
14
|
s.licenses = ["MIT"]
|
15
15
|
s.require_paths = ["lib"]
|
16
16
|
s.required_ruby_version = Gem::Requirement.new(">= 1.9.3")
|
17
|
-
s.rubygems_version = "1.8.23"
|
17
|
+
s.rubygems_version = "1.8.23.2"
|
18
18
|
s.summary = "Minimal yet extensible Ruby to JavaScript conversion."
|
19
19
|
|
20
20
|
if s.respond_to? :specification_version then
|
metadata
CHANGED
@@ -1,32 +1,32 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby2js
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.14.1
|
5
4
|
prerelease:
|
5
|
+
version: 1.15.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Sam Ruby
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-03-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
15
|
+
version_requirements: !ruby/object:Gem::Requirement
|
18
16
|
requirements:
|
19
17
|
- - ! '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
20
|
+
none: false
|
22
21
|
type: :runtime
|
22
|
+
name: parser
|
23
23
|
prerelease: false
|
24
|
-
|
25
|
-
none: false
|
24
|
+
requirement: !ruby/object:Gem::Requirement
|
26
25
|
requirements:
|
27
26
|
- - ! '>='
|
28
27
|
- !ruby/object:Gem::Version
|
29
28
|
version: '0'
|
29
|
+
none: false
|
30
30
|
description: ! " The base package maps Ruby syntax to JavaScript semantics.\n Filters
|
31
31
|
may be provided to add Ruby-specific or framework specific\n behavior.\n"
|
32
32
|
email: rubys@intertwingly.net
|
@@ -67,6 +67,7 @@ files:
|
|
67
67
|
- lib/ruby2js/converter/cvasgn.rb
|
68
68
|
- lib/ruby2js/converter/whilepost.rb
|
69
69
|
- lib/ruby2js/converter/logical.rb
|
70
|
+
- lib/ruby2js/converter/in.rb
|
70
71
|
- lib/ruby2js/converter/args.rb
|
71
72
|
- lib/ruby2js/converter/def.rb
|
72
73
|
- lib/ruby2js/converter/prototype.rb
|
@@ -111,20 +112,20 @@ rdoc_options: []
|
|
111
112
|
require_paths:
|
112
113
|
- lib
|
113
114
|
required_ruby_version: !ruby/object:Gem::Requirement
|
114
|
-
none: false
|
115
115
|
requirements:
|
116
116
|
- - ! '>='
|
117
117
|
- !ruby/object:Gem::Version
|
118
118
|
version: 1.9.3
|
119
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
119
|
none: false
|
120
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - ! '>='
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
|
+
none: false
|
125
126
|
requirements: []
|
126
127
|
rubyforge_project:
|
127
|
-
rubygems_version: 1.8.23
|
128
|
+
rubygems_version: 1.8.23.2
|
128
129
|
signing_key:
|
129
130
|
specification_version: 3
|
130
131
|
summary: Minimal yet extensible Ruby to JavaScript conversion.
|