ruby2js 1.14.1 → 1.15.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.
- 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.
|